i've some issue using listener to JCombobox
.
I have JCombobox
with two CercleItemOption
which is a composition of a JLabel
and an object CercleSelection
extending from JPanel
. CercleSelection
draws a circle with certain color.
So i'm using ItemListener
to support the event. My goal is to print on frame the colored circle corresponding to the selected item.
import javax.swing.*;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import java.awt.*;
public class PanneauSelection extends JPanel {
private GridBagConstraints grid = new GridBagConstraints();
public PanneauSelection(){
super();
init();
setVisible(true);
}
private void init() {
LineBorder lb;
CompoundBorder cb;
setLayout(new GridBagLayout());
EmptyBorder eb = new EmptyBorder(5,10,5,10);
grid.fill = GridBagConstraints.BOTH;
grid.insets = new Insets(3,3,3,3);
JLabel[] appLabel = {
new JLabel("<html>Racc. <br/>Bac/conduite</html>", SwingConstants.CENTER),
new JLabel("Vanne", SwingConstants.CENTER),
new JLabel("Pompe", SwingConstants.CENTER),
new JLabel("Turbine", SwingConstants.CENTER),
};
CercleSelection[] appCircle = {
new CercleSelection(new Color(222, 146, 15)),
new CercleSelection(Color.BLUE),
new CercleSelection(new Color(67, 160, 53)),
new CercleSelection(Color.RED),
};
DefaultListCellRenderer dlcr = new DefaultListCellRenderer();
dlcr.setHorizontalAlignment(DefaultListCellRenderer.CENTER);
JComboBox<CercleItemOption> optionList = new JComboBox<>();
optionList.addItem(new CercleItemOption(new JLabel("Coude"), new CercleSelection(Color.cyan)));
optionList.addItem(new CercleItemOption(new JLabel("Chgt de section"), new CercleSelection(Color.PINK)));
optionList.setRenderer(dlcr);
for(int i=0; i<appLabel.length; i++){
grid.gridy = i;
//First column
grid.gridx = 0;
lb = new LineBorder(appCircle[i].getCouleur(), 2, true);
cb = new CompoundBorder(lb,eb);
appLabel[i].setBorder(cb);
add(appLabel[i], grid);
//Second column
grid.gridx = 1;
appCircle[i].setBorder(eb);
add(appCircle[i], grid);
}
grid.gridy = 4;
grid.gridx = 0;
add(optionList, grid);
grid.gridx = 1;
add(((CercleItemOption)optionList.getSelectedItem()).getCercle(), grid);
optionList.addItemListener(itemEvent -> {
setVisible(false);
grid.gridx = 1;
grid.gridy = 4;
CercleItemOption cs = (CercleItemOption) itemEvent.getItem();
add(cs.getCercle(), grid);
revalidate();
repaint();
setVisible(true);
});
this.setBorder(new EmptyBorder(0,20,0,0));
}
public static void main(String[] args){
JFrame f = new JFrame();
f.add(new PanneauSelection());
f.pack();
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
I expected something like :
"coude" -> [Circle] cyan
"chgt de section" -> [Circle] pink
With my code color doesn't change on the first call of ItemListener, but only on the second one. Finally on second click, i have :
"coude" -> [Circle] pink
"chgt de section" -> [Circle] cyan
CercleItemOption
class
import javax.swing.*;
public class CercleItemOption {
private JLabel label;
private CercleSelection cercle;
public CercleItemOption(JLabel l, CercleSelection c){
label = l;
cercle = c;
}
@Override
public String toString(){
return label.getText();
}
public JLabel getLabel() {
return label;
}
public CercleSelection getCercle() {
return cercle;
}
}
CercleSelection
class
import javax.swing.*;
import java.awt.*;
public class CercleSelection extends JPanel {
public final static int TAILLE = 11;
Color couleur;
public CercleSelection(Color c){
super();
couleur = c;
setSize(TAILLE,TAILLE);
setVisible(true);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(couleur);
//Draw in the middle
g.fillOval(TAILLE/2,TAILLE/2,TAILLE,TAILLE);
}
public Color getCouleur() {
return couleur;
}
}
Thank you in advance for help
For someone who have the same issue, the solution was to remove the existed component and replace it to the new one.
To get the actual component, i add a new variable.
Class PanneauSelection
:
private CercleItemOption cercleSelectionne;
init()
method :
private void init(){
//...
grid.gridy = 4;
grid.gridx = 0;
add(optionList, grid);
grid.gridx = 1;
cercleSelectionne = ((CercleItemOption) optionList.getSelectedItem());
add(cercleSelectionne.getCercle(), grid);
optionList.addItemListener(itemEvent -> {
remove(cercleSelectionne.getCercle());
grid.gridx = 1;
grid.gridy = 4;
cercleSelectionne = (CercleItemOption) itemEvent.getItem();
add(cercleSelectionne.getCercle(), grid);
revalidate();
repaint();
});
}