ComboBoxEditorとして複数アイテムが表示可能なJListを使用する
Total: 1070
, Today: 2
, Yesterday: 1
Posted by aterai at
Last-modified:
概要
ComboBoxEditor
として複数アイテムが表示やスクロールが可能なニュースペーパースタイルのJList
を使用します。
Screenshot
Advertisement
サンプルコード
ListModel<ListItem> model = makeModel();
JList<ListItem> list = new NewspaperStyleList<>(model);
JScrollPane scroll = new JScrollPane(list) {
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.width = 62 * 3 + 10;
d.height = 32;
return d;
}
};
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
scroll.setBorder(BorderFactory.createEmptyBorder());
scroll.setViewportBorder(BorderFactory.createEmptyBorder());
JList<ListItem> list2 = new NewspaperStyleList<>(model);
JScrollPane scroll2 = new JScrollPane(list2) {
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.width = 62 * 4 + 10;
return d;
}
};
scroll2.setBorder(BorderFactory.createEmptyBorder());
scroll2.setViewportBorder(BorderFactory.createEmptyBorder());
JPopupMenu popup = new JPopupMenu();
popup.setLayout(new BorderLayout());
list2.addMouseListener(new MouseAdapter() {
@Override public void mouseClicked(MouseEvent e) {
if (popup.isVisible() && e.getClickCount() >= 2) {
popup.setVisible(false);
}
}
});
popup.add(scroll2);
popup.setBorder(BorderFactory.createLineBorder(Color.GRAY));
JToggleButton dropDown = new JToggleButton(new DropDownArrowIcon());
popup.addPopupMenuListener(new PopupMenuListener() {
@Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
list2.setSelectedIndex(list.getSelectedIndex());
EventQueue.invokeLater(popup::pack);
}
@Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
dropDown.setSelected(false);
list.requestFocusInWindow();
int i = list2.getSelectedIndex();
if (i >= 0) {
list.setSelectedIndex(i);
list.scrollRectToVisible(list.getCellBounds(i, i));
}
}
@Override public void popupMenuCanceled(PopupMenuEvent e) {
popupMenuWillBecomeInvisible(e);
}
});
dropDown.setBorder(BorderFactory.createEmptyBorder());
dropDown.setContentAreaFilled(false);
dropDown.setFocusPainted(false);
dropDown.setFocusable(false);
dropDown.addItemListener(e -> {
AbstractButton b = (AbstractButton) e.getItemSelectable();
if (e.getStateChange() == ItemEvent.SELECTED) {
popup.show(b, -scroll.getWidth(), b.getHeight());
}
});
JScrollBar verticalScrollBar = scroll.getVerticalScrollBar();
JPanel verticalBox = new JPanel(new BorderLayout()) {
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.height = 32 + 5 + 5;
return d;
}
};
verticalBox.setOpaque(false);
verticalBox.add(verticalScrollBar);
verticalBox.add(dropDown, BorderLayout.SOUTH);
JPanel panel = new JPanel(new BorderLayout(0, 0));
panel.add(scroll);
panel.add(verticalBox, BorderLayout.EAST);
panel.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
View in GitHub: Java, Kotlin解説
JList + JPopupMenu
- エディタ部分にニュースペーパースタイルで複数アイテムが表示可能な
JList
、その親JScrollPane
から縦JScrollBar
、ドロップダウン表示用のJToggleButton
を組み合わせてJComboBox
風のコンポーネントを作成 - ドロップダウンリストは
JPopupMenu
で作成し、その子コンポーネントとしてエディタ部分のJList
とは別のJList
を追加 MouseListener
やPopupMenuListener
でドロップダウンリスト内のJList
の選択状態変更をエディタ部分のJList
に反映するよう設定
- エディタ部分にニュースペーパースタイルで複数アイテムが表示可能な
JComboBox + ComboBoxEditor
ComboBoxEditor#getEditorComponent()
をオーバーライドしてニュースペーパースタイルで複数アイテムが表示可能なJList
をJComboBox
のエディタとして設定ComboPopup
からドロップダウンリスト内のJList
を取得し、そのスタイルをニュースペーパー・スタイルに変更JComboBox
のエディタと矢印ボタンの間に意図しない余白が生成されてしまう?
ListModel<ListItem> model = makeModel();
JList<ListItem> list = new NewspaperStyleList<>(model);
JScrollPane scroll = new JScrollPane(list) {
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.width = 62 * 4;
d.height = 40;
return d;
}
};
scroll.setBorder(BorderFactory.createEmptyBorder());
scroll.setViewportBorder(BorderFactory.createEmptyBorder());
DefaultComboBoxModel<ListItem> cm = new DefaultComboBoxModel<>();
for (int i = 0; i < model.getSize(); i++) {
cm.addElement(model.getElementAt(i));
}
JComboBox<ListItem> combo = new JComboBox<ListItem>(cm) {
@Override public void updateUI() {
super.updateUI();
setMaximumRowCount(4);
setPrototypeDisplayValue(new ListItem("red", new ColorIcon(Color.RED)));
EventQueue.invokeLater(() -> {
ComboPopup popup = (ComboPopup) getAccessibleContext().getAccessibleChild(0);
JList<?> lst = popup.getList();
lst.setLayoutOrientation(JList.HORIZONTAL_WRAP);
lst.setVisibleRowCount(0);
lst.setFixedCellWidth(62);
lst.setFixedCellHeight(40);
lst.setOpaque(true);
lst.setBackground(new Color(0x32_32_32));
lst.setForeground(Color.WHITE);
});
}
};
combo.setRenderer(new ListItemListCellRenderer<>());
combo.setEditable(true);
combo.setEditor(new ComboBoxEditor() {
@Override public Component getEditorComponent() {
return scroll;
}
@Override public void setItem(Object anObject) {
combo.setSelectedIndex(list.getSelectedIndex());
}
@Override public Object getItem() {
return list.getSelectedValue();
}
@Override public void selectAll() {
// System.out.println("selectAll");
}
@Override public void addActionListener(ActionListener l) {
// System.out.println("addActionListener");
}
@Override public void removeActionListener(ActionListener l) {
// System.out.println("removeActionListener");
}
});