Swing/ComponentPopupMenu のバックアップの現在との差分(No.1)
TITLE:JPopupMenuをコンポーネントに追加
JPopupMenuをコンポーネントに追加
編集者:Terai Atsuhiro~
作成日:2008-03-10
更新日:2022-05-24 (火) 10:29:56
概要
JComponent
に右クリックなどでポップアップするJPopupMenu
を追加します。
Screenshot
Advertisement
概要
JPopupMenuをコンポーネントに追加します。サンプルコード
#spanend
#spanadd
JTextArea textArea = new JTextArea("ComponentPopupMenu Test");
#spanend
#spanadd
textArea.setComponentPopupMenu(new TextComponentPopupMenu());
#spanend
#spandel
#screenshot
#spanend
#spandel
#spanend
#spandel
**サンプルコード [#s7d9a0a6]
#spanend
#spandel
#code{{
#spanend
#spandel
JTextArea textArea = new JTextArea("ComponentPopupMenu Test");
#spanend
#spandel
textArea.setComponentPopupMenu(new TextComponentPopupMenu(textArea));
#spanend
#spandel
View in GitHub: Java, Kotlin#spanend
class TextComponentPopupMenu extends JPopupMenu {
private final Action cutAction = new DefaultEditorKit.CutAction();
private final Action copyAction = new DefaultEditorKit.CopyAction();
private final Action pasteAction = new DefaultEditorKit.PasteAction();
private final Action deleteAction;
private final Action selectAllAction;
public TextComponentPopupMenu(final JTextComponent textArea) {
public TextComponentPopupMenu() {
super();
add(cutAction);
add(copyAction);
add(pasteAction);
addSeparator();
add(deleteAction = new AbstractAction("delete") {
public void actionPerformed(ActionEvent evt) {
textArea.replaceSelection(null);
@Override public void actionPerformed(ActionEvent evt) {
((JTextComponent) getInvoker()).replaceSelection(null);
}
});
addSeparator();
add(selectAllAction = new AbstractAction("select all") {
public void actionPerformed(ActionEvent evt) {
textArea.selectAll();
@Override public void actionPerformed(ActionEvent evt) {
((JTextComponent) getInvoker()).selectAll();
}
});
// ActionMap am = textArea.getActionMap();
// add(cutAction = am.get("cut-to-clipboard"));
// add(copyAction = am.get("copy-to-clipboard"));
// add(am.get("paste-from-clipboard"));
// addSeparator();
// add(deleteAction = am.get("delete-next"));
// addSeparator();
// add(am.get("select-all"));
}
public void show(Component c, int x, int y) {
JTextComponent textArea = (JTextComponent)c;
boolean flg = textArea.getSelectedText()!=null;
#spanadd
#spanend
@Override public void show(Component c, int x, int y) {
JTextComponent textArea = (JTextComponent) c;
boolean flg = textArea.getSelectedText() != null;
cutAction.setEnabled(flg);
copyAction.setEnabled(flg);
deleteAction.setEnabled(flg);
super.show(c, x, y);
}
}
- &jnlp;
- &jar;
- &zip;
解説
上記のサンプルでは、JTextAreaにsetComponentPopupMenu(JPopupMenu)メソッドで、ポップアップメニューを追加しています。解説
上記のサンプルでは、JTextArea
にsetComponentPopupMenu(JPopupMenu)
メソッドで、ポップアップメニューを追加しています。
JDK1.5でこのメソッドが追加されたため、各コンポーネントにマウスリスナーを設定して、e.isPopupTrigger()でポップアップを表示するクリックかを判断するといったコードを書く必要が無くなっています。
-
JDK 1.5
でこのメソッドが追加されたため、各コンポーネントにマウスリスナーを設定してe.isPopupTrigger()
でポップアップを表示するクリックの判断が不要になった - ポップアップメニューを表示するときにコンポーネントの状態(例えば
JTable
やJList
などでの行選択の有無や、テキストが選択されてるかとどうかなどの条件)でメニューが実行可か不可かを変更したい場合は、JPopupMenu#show(Component, int, int)
メソッドをオーバーライドして使用可能 - このサンプルではテキストが選択されている場合だけカット、コピー、削除メニューが有効になるよう設定
- -
-
JPopupMenu#show(Component, int, int)
のオーバーライドではなく、PopupMenuListener
を使用する方法もある
コメント
#spanend
#spanadd
JPopupMenu popup = new JPopupMenu();
#spanend
#spanadd
Action cutAction = new DefaultEditorKit.CutAction();
#spanend
#spanadd
Action copyAction = new DefaultEditorKit.CopyAction();
#spanend
#spanadd
Action pasteAction = new DefaultEditorKit.PasteAction();
#spanend
#spanadd
Action deleteAction = new AbstractAction("delete") {
#spanend
@Override public void actionPerformed(ActionEvent e) {
((JTextComponent) getInvoker()).replaceSelection(null);
}
#spanadd
};
#spanend
#spanadd
Action selectAllAction = new AbstractAction("select all") {
#spanend
@Override public void actionPerformed(ActionEvent e) {
JPopupMenu p = (JPopupMenu) e.getSource();
((JTextComponent) p.getInvoker()).selectAll();
}
#spanadd
};
#spanend
#spanadd
popup.add(cutAction);
#spanend
#spanadd
popup.add(copyAction);
#spanend
#spanadd
popup.add(pasteAction);
#spanend
#spanadd
popup.addSeparator();
#spanend
#spanadd
popup.add(deleteAction);
#spanend
#spanadd
popup.addSeparator();
#spanend
#spanadd
popup.add(selectAllAction);
#spanend
#spanadd
popup.addPopupMenuListener(new PopupMenuListener() {
#spanend
@Override public void popupMenuCanceled(PopupMenuEvent e) {}
@Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
@Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
JPopupMenu p = (JPopupMenu) e.getSource();
JTextComponent c = (JTextComponent) p.getInvoker();
boolean flg = c.getSelectedText() != null;
cutAction.setEnabled(flg);
copyAction.setEnabled(flg);
deleteAction.setEnabled(flg);
}
#spanadd
});
#spanend
#spanadd
textArea.setComponentPopupMenu(popup);
#spanend
#spanadd
-
PopupMenuEvent
からはマウスでクリックした位置を取得できない- このため、
JTabbedPane
などでどのタブの上でポップアップが表示されるかなどを取得したい場合はJPopupMenu#show(...)
をオーバーライドする必要がある - JTabbedPaneでタブを追加削除
- このため、
参考リンク
- JComponent#setComponentPopupMenu(JPopupMenu) (Java Platform SE 8)
- JPopupMenuの取得を親に委譲
- JTabbedPaneでタブを追加削除
- Bug ID: 6675802 Regression: heavyweight popups cause SecurityExceptions in applets
- Bug ID: 6299213 The PopupMenu is not updated if the LAF is changed (incomplete fix of 4962731)