Bonjour,
J'aimerais implémenter une JComboBox qui permette la sélection multiple. J'ai lu à pas mal d'endroits que c'était une mauvaise idée. Le problème c'est que je n'ai pas trouvé de solution satisfaisante. Je ne peux pas utiliser de JList car je n'ai pas assez de place.
J'ai donc finalement le code suivant (inspiré de diverses solutions trouvées sur divers forums).
J'ai également besoin que le menu popup reste ouvert quand l'utilisateur fait sa sélection, c'est pourquoi j'ai surchargé setPopupVisible pour que ça ne fasse rien.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 import javax.swing.JComboBox; /** * @author jbaudens */ public class CheckComboBox extends JComboBox{ public CheckComboBox () { super(); } public CheckComboBox(Object[] items){ super(items); } /** * This method needs to be overriden so that the popuplist won't close * when user selects one opion */ @Override public void setPopupVisible(boolean flag) { //Not code her prevents the populist from closing } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import javax.swing.JComboBox; /** * * @author jbaudens */ public class CheckComboBox extends JComboBox{ public CheckComboBox () { super(); } public CheckComboBox(Object[] items){ super(items); } /** * This method needs to be overriden so that the popuplist won't close * when user selects one opion */ @Override public void setPopupVisible(boolean flag) { //Not code her prevents the populist from closing } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 import java.awt.BorderLayout; import java.awt.HeadlessException; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JFrame; import javax.swing.JPanel; /** * @author jbaudens */ public class CheckComboBoxFrame extends JFrame implements ActionListener{ JPanel contentPane; CheckComboBox ccb; CheckComboBox ccb2; public CheckComboBoxFrame() throws HeadlessException { contentPane = (JPanel) this.getContentPane(); this.setSize(300,100); this.setTitle("MultiSelectionComboBox"); CheckComboStore[] array = new CheckComboStore[3]; array[0] = new CheckComboStore("Test1",false); array[1] = new CheckComboStore("Test2",false); array[2] = new CheckComboStore("Test3",false); ccb = new CheckComboBox(array); ccb.setRenderer(new CheckComboRenderer()); ccb.addActionListener(this); CheckComboStore[] array2 = new CheckComboStore[1]; array2[0] = new CheckComboStore("Test4",false); ccb2 = new CheckComboBox(array2); ccb2.setRenderer(new CheckComboRenderer()); ccb2.addActionListener(this); contentPane.setLayout(new BorderLayout()); ccb.setVisible(true); ccb2.setVisible(true); contentPane.add(ccb,BorderLayout.NORTH); contentPane.add(ccb2,BorderLayout.SOUTH); this.setDefaultCloseOperation(EXIT_ON_CLOSE); } @Override public void actionPerformed(ActionEvent e) { System.out.println("actionPerformed"); CheckComboBox cb = (CheckComboBox)e.getSource(); CheckComboStore store = (CheckComboStore)cb.getSelectedItem(); CheckComboRenderer ccr = (CheckComboRenderer)cb.getRenderer(); store.state = !store.state; ccr.checkBox.setSelected(store.state); } }Tout ceci est presque fonctionnel. Le problème est que dans certains cas, quand la sélection est faite par l'utilisateur, la CheckBox ne change pas d'état immédiatement mais après un délai ou lorsque la JComboBox perd le focus et que l'utilisateur clique sur un autre élément du GUI.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 package multiselectioncombobox; import java.awt.Component; import javax.swing.JCheckBox; import javax.swing.JList; import javax.swing.ListCellRenderer; /** adapted from comment section of ListCellRenderer api */ class CheckComboRenderer implements ListCellRenderer { JCheckBox checkBox; public CheckComboRenderer() { checkBox = new JCheckBox(); } @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { CheckComboStore store = (CheckComboStore)value; System.out.println("getListCellRendererComponent => " + store.id + " " + store.state); checkBox.setText(store.id); checkBox.setSelected(store.state); return checkBox; } } class CheckComboStore { String id; Boolean state; public CheckComboStore(String id, Boolean state) { this.id = id; this.state = state; } }
Le code ci-dessus est une reproduction de mon problème.
Quelqu'un saurait-il m'indiquer comment procéder ?
Merci d'avance pour votre aide.
Partager