Swing 文本组件没有带有剪切/复制/粘贴/等的上下文菜单。我想添加一个,让它表现得更流畅,就像一个原生应用程序。我为此编写了一个菜单,它工作正常。我使用以下方法将其添加到每个文本框中:
someTextBox.setComponentPopupMenu(TextContextMenu.INSTANCE);
问题是,到处添加这个很烦人。其次,如果我忘记了某处的文本框,则应用程序不一致。第三,我不能为我不控制创建代码的文本框添加它,比如来自JOptionPane.showInputDialog
或JFileChooser
对话框的文本框。
有没有办法覆盖JTextComponent
应用程序范围的默认上下文菜单?我知道这将是一种远距离的诡异动作,但我可以接受。也欢迎对菜单本身发表评论。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.JTextComponent;
public class TextContextMenu extends JPopupMenu implements ActionListener {
public static final TextContextMenu INSTANCE = new TextContextMenu();
private final JMenuItem itemCut;
private final JMenuItem itemCopy;
private final JMenuItem itemPaste;
private final JMenuItem itemDelete;
private final JMenuItem itemSelectAll;
private TextContextMenu() {
itemCut = newItem("Cut", 'T');
itemCopy = newItem("Copy", 'C');
itemPaste = newItem("Paste", 'P');
itemDelete = newItem("Delete", 'D');
addSeparator();
itemSelectAll = newItem("Select All", 'A');
}
private JMenuItem newItem(String text, char mnemonic) {
JMenuItem item = new JMenuItem(text, mnemonic);
item.addActionListener(this);
return add(item);
}
@Override
public void show(Component invoker, int x, int y) {
JTextComponent tc = (JTextComponent)invoker;
boolean changeable = tc.isEditable() && tc.isEnabled();
itemCut.setVisible(changeable);
itemPaste.setVisible(changeable);
itemDelete.setVisible(changeable);
super.show(invoker, x, y);
}
@Override
public void actionPerformed(ActionEvent e) {
JTextComponent tc = (JTextComponent)getInvoker();
tc.requestFocus();
boolean haveSelection = tc.getSelectionStart() != tc.getSelectionEnd();
if (e.getSource() == itemCut) {
if (!haveSelection) tc.selectAll();
tc.cut();
} else if (e.getSource() == itemCopy) {
if (!haveSelection) tc.selectAll();
tc.copy();
} else if (e.getSource() == itemPaste) {
tc.paste();
} else if (e.getSource() == itemDelete) {
if (!haveSelection) tc.selectAll();
tc.replaceSelection("");
} else if (e.getSource() == itemSelectAll) {
tc.selectAll();
}
}
}