TL: DR Ich möchte eine JComboBox
erstellen, die JCheckboxes
anstelle von JLabels
überall, aber in der Haupt-Label hat - an dieser Stelle möchte ich Zeichenfolge, die Werte aller aktivierten Kästchen darstellen. Ich habe es geschafft, es funktioniert, aber ich habe ein paar Probleme mit dem Öffnen des Menüs auf Mausklick. Ich möchte auch, dass Pfeiltasten nur durch die Box navigieren, ohne die Elemente und die Leertaste auszuwählen.Erstellen von JComboBox mit Kontrollkästchen
Egal was ich tue, nach meinem ActionListener
Fängen per Mausklick und ein Element wählt das Menü durch einen anderen Zuhörer in den JComboBox
und Verfahren setPopupVisible
verschachtelt schließt - es mit meiner hässlichen Problemumgehung funktioniert, aber es hat doch ein besserer Weg zu sein, um dies zu tun ..
Ich glaube, ich brauche Maushörer auf listBox
in Klasse BasicComboBoxUI
aber wie komme ich dorthin?
so wenig Menge an Code, wie ich es verengen könnte:
ComboCheckBoxModel:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class ComboCheckBoxModel extends DefaultListModel implements ComboBoxModel, ItemSelectable {
private List<String> items = new ArrayList<>();
private List<String> checkedItems = new ArrayList<>();
private String selectedItem;
public ComboCheckBoxModel(List<String> items) {
if(!items.isEmpty()) {
selectedItem = items.get(0);
}
this.items = items;
}
public void check(Object item) {
String itemAsString = item.toString();
if(checkedItems.contains(itemAsString)) {
checkedItems.remove(itemAsString);
} else {
checkedItems.add(itemAsString);
}
fireContentsChanged(this, items.indexOf(item), items.indexOf(item));
}
public String getDataStringRepresentation() {
return checkedItems.stream().sorted().collect(Collectors.joining(", "));
}
@Override
public void setSelectedItem(Object anItem) {
selectedItem = anItem.toString();
}
@Override
public Object getSelectedItem() {
return selectedItem;
}
@Override
public int getSize() {
return items.size();
}
@Override
public Object getElementAt(int index) {
return items.get(index);
}
public boolean isChecked(String stringValue) {
return checkedItems.contains(stringValue);
}
@Override
public Object[] getSelectedObjects() {
return items.toArray();
}
@Override
public void addItemListener(ItemListener l) {
}
@Override
public void removeItemListener(ItemListener l) {
}
}
JComboBox:
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
public class JComboCheckBox extends JComboBox {
private final ComboCheckBoxModel model = new ComboCheckBoxModel(Stream.of("bum", "kabum", "dabum").collect(toList()));
private boolean shouldntClose;
public JComboCheckBox() {
super();
setRenderer(new CheckBoxCellRenderer());
setModel(model);
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getModifiers() == InputEvent.BUTTON1_MASK) {
System.out.println("LPM MASK");
model.check(model.getSelectedItem());
shouldntClose = true;
}
}
});
}
@Override
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
if (ks.getKeyCode() == KeyEvent.VK_SPACE && isPopupVisible()) {
if (ks.getKeyCode() == KeyEvent.VK_SPACE && condition == WHEN_FOCUSED && ks.isOnKeyRelease()) {
System.out.println("ks = [" + ks + "], e = [" + e + "], condition = [" + condition + "], pressed = [" + pressed + "]");
model.check(model.getSelectedItem());
}
return true;
}
return super.processKeyBinding(ks, e, condition, pressed);
}
@Override
public void setPopupVisible(boolean v) {
if (shouldntClose) {
shouldntClose = false;
return;
} else {
super.setPopupVisible(v);
}
}
@Override
public Object getSelectedItem() {
return model.getSelectedItem();
}
}
Zelle Renderer:
import javax.swing.*;
import java.awt.*;
public class CheckBoxCellRenderer extends JCheckBox implements ListCellRenderer {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
ComboCheckBoxModel model = (ComboCheckBoxModel) list.getModel();
if (index != -1) {
String stringValue = value == null ? "null" : value.toString();
setText(stringValue);
boolean checked = model.isChecked(stringValue);
setSelected(checked);
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
return this;
} else {
String stringValue = model.getDataStringRepresentation();
return new JLabel(stringValue);
}
}
}
Launcher:
import javax.swing.*;
public class Launcher {
public JFrame create() {
JFrame f=new JFrame("Type the name of frame");
f.add(new JComboCheckBox());
f.setSize(400,400);
return f;
}
public static void main(String[] args) {
Launcher launcher = new Launcher();
launcher.create().setVisible(true);
}
}