TL:DRの代わりにJCheckboxes
のJComboBox
を作成しますが、メインラベルにはこの場所にすべてのチェックボックスの値を表す文字列を保持します。私はそれを動作させることができましたが、マウスクリックでメニューを開いたままにしておくのにはいくつかの問題があります。私はまた、選択する項目とスペースキーを選択せずに矢印キーでボックスをナビゲートするだけでよい。チェックボックス付きのJComboBoxの作成
どんなに私は何をすべきか、私のActionListener
キャッチマウスの後にメニューがJComboBox
及び方法setPopupVisible
にネストされ、いくつかの他のリスナーを介して閉じ項目をクリックしないと選択 - それは私の醜い回避策で動作しますが、もっと良い方法があるように持っています
私はlistBox
ののマウスリスナーが必要ですが、どうやってそこに着くのですか?
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();
}
}
セルレンダリング:
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);
}
}
}
ランチャー:私はそれを狭める可能性があるので、コードの
として少量
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);
}
}