JComboBoxのドロップダウンリストとしてJTableを使用する
Total: 3268
, Today: 2
, Yesterday: 0
Posted by aterai at
Last-modified:
概要
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);
if (highlighter.isHighlightTableRow(row)) {
c.setForeground(
UIManager.getColor("Table.selectionForeground"));
c.setBackground(
UIManager.getColor("Table.selectionBackground").brighter());
} else if (isRowSelected(row)) {
c.setForeground(
UIManager.getColor("Table.selectionForeground"));
c.setBackground(
UIManager.getColor("Table.selectionBackground"));
} else {
c.setForeground(UIManager.getColor("Table.foreground"));
c.setBackground(UIManager.getColor("Table.background"));
}
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));
}
}
}