Swing/DropdownTableComboBox のバックアップ(No.6)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/DropdownTableComboBox へ行く。
- category: swing
folder: DropdownTableComboBox
title: JComboBoxのドロップダウンリストとしてJTableを使用する
tags: [JComboBox , JTable, BasicComboPopup]
author: aterai
pubdate: 2018-04-02T17:25:49+09:00
description: JComboBoxのドロップダウンリストとしてJListの代わりにJTableを使用します。
image: https://drive.google.com/uc?id=170XdYlh7LDQaucke8xUxSSN1qlcPWcrGrw
hreflang:
href: https://java-swing-tips.blogspot.com/2018/05/use-jtable-instead-of-jlist-as-drop.html lang: en
概要
JComboBox
のドロップダウンリストとしてJList
の代わりにJTable
を使用します。
Screenshot
Advertisement
サンプルコード
class DropdownTableComboBox<E extends List<Object>> extends JComboBox<E> {
protected final transient HighlightListener highlighter = new HighlightListener();
protected final JTable table = new JTable() {
@Override public Component prepareRenderer(
TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
c.setForeground(Color.BLACK);
if (highlighter.isHighlightableRow(row)) {
c.setBackground(new Color(255, 200, 200));
} else if (isRowSelected(row)) {
c.setBackground(Color.CYAN);
} else {
c.setBackground(Color.WHITE);
}
return c;
}
@Override public void updateUI() {
removeMouseListener(highlighter);
removeMouseMotionListener(highlighter);
super.updateUI();
addMouseListener(highlighter);
addMouseMotionListener(highlighter);
getTableHeader().setReorderingAllowed(false);
}
};
protected final List<E> list;
protected DropdownTableComboBox(List<E> list, DefaultTableModel model) {
super();
this.list = list;
table.setModel(model);
list.forEach(this::addItem);
// list.forEach(model::addRow);
list.forEach(v -> model.addRow(v.toArray(new Object[0])));
}
@Override public void updateUI() {
super.updateUI();
EventQueue.invokeLater(() -> {
setUI(new MetalComboBoxUI() {
@Override protected ComboPopup createPopup() {
return new ComboTablePopup(comboBox, table);
}
});
setEditable(false);
});
}
public List<Object> getSelectedRow() {
return list.get(getSelectedIndex());
}
}
View in GitHub: Java, Kotlin解説
JList
ではなくJTable
を使用するBasicComboPopup
を作成JTable
なので、ヘッダや複数列の設定などが可能
MetalComboBoxUI#createPopup()
メソッドをオーバーライドして、JComboBox
のドロップダウンリストとして設定- ドロップダウンリストの幅は、
240px
固定
- ドロップダウンリストの幅は、
class ComboTablePopup extends BasicComboPopup {
private final JTable table;
private final JScrollPane scroll;
protected ComboTablePopup(JComboBox<?> combo, JTable table) {
super(combo);
this.table = table;
ListSelectionModel sm = table.getSelectionModel();
sm.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
sm.addListSelectionListener(e -> {
combo.setSelectedIndex(table.getSelectedRow());
});
combo.addItemListener(e -> {
if (e.getStateChange() == ItemEvent.SELECTED) {
setRowSelection(combo.getSelectedIndex());
}
});
table.addMouseListener(new MouseAdapter() {
@Override public void mousePressed(MouseEvent e) {
combo.setSelectedIndex(table.rowAtPoint(e.getPoint()));
setVisible(false);
}
});
scroll = new JScrollPane(table);
setBorder(BorderFactory.createEmptyBorder());
}
@Override public void show() {
if (isEnabled()) {
Insets ins = scroll.getInsets();
int tableh = table.getPreferredSize().height;
int headerh = table.getTableHeader().getPreferredSize().height;
scroll.setPreferredSize(new Dimension(
240, tableh + headerh + ins.top + ins.bottom));
super.removeAll();
super.add(scroll);
setRowSelection(comboBox.getSelectedIndex());
super.show(comboBox, 0, comboBox.getBounds().height);
}
}
private void setRowSelection(int index) {
if (index != -1) {
table.setRowSelectionInterval(index, index);
table.scrollRectToVisible(table.getCellRect(index, 0, true));
}
}
}