Swing/CellEditorPopupMenu のバックアップ(No.11)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/CellEditorPopupMenu へ行く。
- 1 (2010-04-26 (月) 16:54:26)
- 2 (2010-04-27 (火) 17:37:06)
- 3 (2010-09-06 (月) 11:42:01)
- 4 (2010-12-14 (火) 16:46:44)
- 5 (2011-05-11 (水) 19:04:20)
- 6 (2013-01-02 (水) 14:06:33)
- 7 (2013-04-06 (土) 05:31:59)
- 8 (2013-07-16 (火) 13:15:23)
- 9 (2013-07-17 (水) 14:49:34)
- 10 (2014-11-26 (水) 18:23:09)
- 11 (2014-12-02 (火) 01:52:56)
- 12 (2015-01-27 (火) 16:59:36)
- 13 (2015-04-14 (火) 17:14:26)
- 14 (2016-05-26 (木) 14:34:34)
- 15 (2017-08-09 (水) 15:43:08)
- 16 (2018-02-24 (土) 19:51:30)
- 17 (2018-08-15 (水) 20:29:25)
- 18 (2019-04-19 (金) 13:43:27)
- 19 (2020-08-11 (火) 15:17:43)
- 20 (2022-01-02 (日) 17:38:50)
- title: JTableのセルエディタにJPopupMenuを設定 tags: [JTable, TableCellEditor, UndoManager, JPopupMenu, AncestorListener] author: aterai pubdate: 2010-04-26T16:54:26+09:00 description: JTableのセルエディタに、Copy、Paste、Undo、Redoなどを行うJPopupMenuを設定します。
概要
JTable
のセルエディタに、Copy
、Paste
、Undo
、Redo
などを行うJPopupMenu
を設定します。
Screenshot
Advertisement
サンプルコード
public static JPopupMenu installTextComponentPopupMenu(final JTextComponent tc) {
final UndoManager manager = new UndoManager();
final Action undoAction = new UndoAction(manager);
final Action redoAction = new RedoAction(manager);
final Action cutAction = new DefaultEditorKit.CutAction();
final Action copyAction = new DefaultEditorKit.CopyAction();
final Action pasteAction = new DefaultEditorKit.PasteAction();
final Action deleteAction = new AbstractAction("delete") {
@Override public void actionPerformed(ActionEvent e) {
JPopupMenu pop = (JPopupMenu) e.getSource();
((JTextComponent) pop.getInvoker()).replaceSelection(null);
}
};
tc.addAncestorListener(new AncestorListener() {
@Override public void ancestorAdded(AncestorEvent e) {
manager.discardAllEdits();
tc.requestFocusInWindow();
}
@Override public void ancestorMoved(AncestorEvent e) {}
@Override public void ancestorRemoved(AncestorEvent e) {}
});
tc.getDocument().addUndoableEditListener(manager);
tc.getActionMap().put("undo", undoAction);
tc.getActionMap().put("redo", redoAction);
InputMap imap = tc.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_DOWN_MASK), "undo");
imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_DOWN_MASK), "redo");
JPopupMenu popup = new JPopupMenu();
popup.add(cutAction);
popup.add(copyAction);
popup.add(pasteAction);
popup.add(deleteAction);
popup.addSeparator();
popup.add(undoAction);
popup.add(redoAction);
popup.addPopupMenuListener(new PopupMenuListener() {
@Override public void popupMenuCanceled(PopupMenuEvent e) {}
@Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
undoAction.setEnabled(true);
redoAction.setEnabled(true);
}
@Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
JPopupMenu pop = (JPopupMenu) e.getSource();
JTextField field = (JTextField) pop.getInvoker();
boolean flg = field.getSelectedText() != null;
cutAction.setEnabled(flg);
copyAction.setEnabled(flg);
deleteAction.setEnabled(flg);
undoAction.setEnabled(manager.canUndo());
redoAction.setEnabled(manager.canRedo());
}
});
tc.setComponentPopupMenu(popup);
return popup;
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、JTable
のセルエディタに、Cut
、Copy
、Paste
、Delete
、Undo
、Redo
を行うJPopupMenu
を設定しています。
セルエディタとして使用しているJTextField
は、おなじものを使い回しているので、別のセルでの編集が持ち越されないよう、AncestorListener
を使って表示されるたびに、UndoManager
を空(UndoManager#discardAllEdits()
を呼び出す)にしています。
もしくは、DefaultCellEditor#isCellEditable(...)
などをオーバーライドしてリセットする方法もあります。
DefaultCellEditor ce = new DefaultCellEditor(new JTextField()) {
@Override public boolean isCellEditable(EventObject e) {
boolean b = super.isCellEditable(e);
if (b) {
manager.discardAllEdits();
}
return b;
}
};
table.setDefaultEditor(Object.class, ce);
参考リンク
- Java Swing「JTable」メモ(Hishidama's Swing-JTable Memo)
- セルエディタだけではなく、行の追加、削除などを
Undo
、Redo
するサンプルが参考になります。
- セルエディタだけではなく、行の追加、削除などを