Swing/CheckBoxCellEditor のバックアップ(No.1)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/CheckBoxCellEditor へ行く。
- title: JTableのセル内部にあるJCheckBoxのみクリック可能に設定する tags: [JTable, JCheckBox, TableCellEditor, JPanel] author: aterai pubdate: 2015-07-20T03:20:06+09:00 description: JTableのセル内部に配置したJCheckBoxをクリックした場合だけ、そのJCheckBoxの選択状態が変化するように可能に設定します。
概要
JTableのセル内部に配置した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();
}
}