JTableのセル内部にあるJCheckBoxのみクリック可能にする
Total: 8742
, Today: 7
, Yesterday: 4
Posted by aterai at
Last-modified:
概要
JTable
のセルエディタとしてJPanel
中央に配置したJCheckBox
を設定し、そのJCheckBox
をクリックした場合のみ選択状態が変化するように設定します。
Screenshot
Advertisement
サンプルコード
class CheckBoxPanelEditor extends AbstractCellEditor implements TableCellEditor {
private final JPanel p = new JPanel(new GridBagLayout());
private final JCheckBox checkBox = new JCheckBox();
public CheckBoxPanelEditor() {
super();
checkBox.setOpaque(false);
checkBox.setFocusable(false);
checkBox.setRolloverEnabled(false);
Handler handler = new Handler();
checkBox.addActionListener(handler);
checkBox.addMouseListener(handler);
p.addMouseListener(new MouseAdapter() {
@Override public void mousePressed(MouseEvent e) {
fireEditingStopped();
}
});
p.add(checkBox);
p.setBorder(UIManager.getBorder("Table.noFocusBorder"));
}
@Override public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column) {
checkBox.setSelected(Objects.equals(value, Boolean.TRUE));
// p.setBackground(table.getSelectionBackground());
return p;
}
@Override public Object getCellEditorValue() {
return checkBox.isSelected();
}
private class Handler extends MouseAdapter implements ActionListener {
@Override public void actionPerformed(ActionEvent e) {
fireEditingStopped();
}
@Override public void mousePressed(MouseEvent e) {
Container c = SwingUtilities.getAncestorOfClass(JTable.class, e.getComponent());
if (c instanceof JTable) {
JTable table = (JTable) c;
if (checkBox.getModel().isPressed()
&& table.isRowSelected(table.getEditingRow()) && e.isControlDown()) {
p.setBackground(table.getBackground());
} else {
p.setBackground(table.getSelectionBackground());
}
}
}
@Override public void mouseExited(MouseEvent e) {
Container c = SwingUtilities.getAncestorOfClass(JTable.class, e.getComponent());
if (c instanceof JTable) {
JTable table = (JTable) c;
if (table.isEditing() && !table.getCellEditor().stopCellEditing()) {
table.getCellEditor().cancelCellEditing();
}
}
}
}
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、JTable
のBoolean
に対応するTableCellEditor
として中央にJCheckBox
を配置したJPanel
を適用しています。
- デフォルトの
JTable.BooleanEditor
- セル全体が
JCheckBox
になるためチェックアイコン以外の余白をマウスでクリックした場合でも選択状態が変化する
- セル全体が
CheckBoxPanelEditor
JPanel
の中央にJCheckBox
を配置して作成- 余白となる
JPanel
部分をクリックしてもJCheckBox
の状態は変化しない JCheckBox
をマウスでクリックした場合のみその選択状態が変化する
- 以下のように
getTableCellEditorComponent(...)
内でJPanel
の背景色をセルの選択色にする場合、Ctrlキーを押しながらJCheckBox
をクリックするとセルの選択状態にズレが発生する- このサンプルでは、セルエディタの
JCheckBox
に以下のようなマウスリスナーを追加することで回避class CheckBoxPanelEditor extends AbstractCellEditor implements TableCellEditor { private final JPanel p = new JPanel(new GridBagLayout()); private final JCheckBox checkBox = new JCheckBox(); public CheckBoxPanelEditor() { super(); checkBox.setOpaque(false); checkBox.setFocusable(false); checkBox.setRolloverEnabled(false); checkBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { fireEditingStopped(); } }); p.add(checkBox); p.setBorder(UIManager.getBorder("Table.noFocusBorder")); } @Override public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column) { checkBox.setSelected(Objects.equals(value, Boolean.TRUE)); p.setBackground(table.getSelectionBackground()); return p; } @Override public Object getCellEditorValue() { return checkBox.isSelected(); } }
- このサンプルでは、セルエディタの