Swing/DeleteButtonInCell のバックアップの現在との差分(No.3)
TITLE:JTableのセルにJButtonを追加して行削除
JTableのセルにJButtonを追加して行削除
編集者:Terai Atsuhiro~
作成日:2007-10-22
更新日:2024-02-02 (金) 12:05:06
概要
JTable
のセルにJButton
を追加し、クリックされたらその行を削除します。
Screenshot
Advertisement
概要
JTableのセルにJButtonを追加し、クリックされたらその行を削除します。主にSwing - JButton inside JTable Cellの投稿を参考にしています。サンプルコード
#spanend
#spanadd
class DeleteButton extends JButton {
#spanend
@Override public void updateUI() {
super.updateUI();
setBorder(BorderFactory.createEmptyBorder());
setFocusable(false);
setRolloverEnabled(false);
setText("X");
}
#spanadd
}
#spanend
#spandel
#screenshot
#spanend
#spanadd
class DeleteButtonRenderer extends DeleteButton implements TableCellRenderer {
#spanend
public DeleteButtonRenderer() {
super();
setName("Table.cellRenderer");
}
#spandel
**サンプルコード [#i9dca28f]
#spanend
#spandel
#code{{
#spanend
#spandel
class ButtonColumn extends AbstractCellEditor implements TableCellRenderer, TableCellEditor {
#spanend
private static final String LABEL = "...";
private final JButton renderButton = new JButton(LABEL);
private final JButton editorButton;
public ButtonColumn() {
@Override public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int column) {
return this;
}
#spanadd
}
#spanend
#spanadd
#spanend
#spanadd
class DeleteButtonEditor extends DeleteButton implements TableCellEditor {
#spanend
public DeleteButtonEditor(final JTable table) {
super();
editorButton = new JButton(new AbstractAction(LABEL) {
public void actionPerformed(ActionEvent e) {
addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent e) {
int row = table.convertRowIndexToModel(table.getEditingRow());
fireEditingStopped();
((DefaultTableModel) table.getModel()).removeRow(row);
}
});
editorButton.setFocusPainted(false);
editorButton.setRolloverEnabled(false);
//renderButton.setToolTipText("Delete(renderButton)");
//editorButton.setToolTipText("Delete(editorButton)");
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
return renderButton;
#spanadd
#spanend
@Override public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
return this;
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
return editorButton;
#spanadd
#spanend
@Override public Object getCellEditorValue() {
return "";
}
public Object getCellEditorValue() {
return LABEL;
}
#spanadd
#spanend
// Copied from AbstractCellEditor
// protected EventListenerList listenerList = new EventListenerList();
// transient protected ChangeEvent changeEvent = null;
// ...
}
View in GitHub: Java, Kotlin- &jnlp;
- &jar;
- &zip;
解説
上記のサンプルでは、ボタンがクリックされたときの削除自体は、JTableに追加したマウスリスナーで行っており、セルエディタやセルレンダラーに使っているJButtonは表示のためのダミーです。解説
- セルレンダラーに使用する
JButton
は表示専用でクリックイベントなどは無視される - セルエディタとして使用する
JButton
にActionListener
を追加し、このJButton
がクリックされたらAbstractCellEditor
からコピーしたfireEditingStopped()
メソッドでセルの編集を終了し、TableModel
から対象行を削除- セルレンダラー、セルエディタがコンポーネント(もしくは
DefaultCellEditor
)を継承していないとJTable
のLookAndFeel
を変更てもセルレンダラー、セルエディタのupdateUI()
が呼ばれない-
JTable#updateUI()
、Java 1.6.0
のJTable#updateSubComponentUI(...)
、Java 1.7.0
のSwingUtilities#updateRendererOrEditorUI(Object)
を参照
-
-
AbstractCellEditor
を継承していてもupdateUI()
は呼ばれない、DefaultCellEditor
は継承しづらい…
- セルレンダラー、セルエディタがコンポーネント(もしくは
参考リンク
コメント
- ボタンのセル内でマウスを移動しても削除するように変更。 -- aterai
- メモ:
修正済み: Bug ID: 6291631 JTable: rowAtPoint returns 0 for negative y (追記: このバグは未修正になっているけど、0
行目のボタンをクリックし、真上のヘッダ上でリリースしても削除可能JDK 1.6, 1.7
などのソースではコメントにある修正が追加されている) -- aterai
- メモ:
#spandel
public ButtonColumn(final JTable table) {
#spanend
super();
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
editorButton = new JButton(new AbstractAction(LABEL) {
public void actionPerformed(ActionEvent e) {
fireEditingStopped();
int row = table.convertRowIndexToModel(table.getSelectedRow());
((DefaultTableModel)table.getModel()).removeRow(row);
}
});
//...
#spanadd
//上記のBug Databaseにある回避方法
#spanend
#spanadd
JTable table = new JTable(model) {
#spanend
@Override public int rowAtPoint(Point pt) {
return (pt.y < 0) ? -1 : super.rowAtPoint(pt);
}
#spanadd
};
#spanend
複数選択を許可する場合は、Ctrlキーなどを押しながらのボタンクリックに注意する必要があります。
参考リンク
- Swing - JButton inside JTable Cell
- テスト -- aterai
- JTableのセルに複数のJButtonを配置するに移動。 -- aterai