我正在创建自定义弹出菜单,只使用扩展JComponent
作为菜单项,并使用扩展JWindow
来保存它们。我的问题是 - 当JComponent
实例点击(MouseListener
)到JTextField
执行剪切/复制/粘贴操作时,如何发送信号?
修改
我会尝试更准确地解释。
JTextField类(简化):
public class TextInputField extends JTextField implements FocusListener {
private MenuPopupWindow popUp;
public TextInputField() {
popUp = new MenuPopupWindow();//MenuPopupWindow class extends JWindow
MenuItem paste = new MenuItem("Paste",
new ImageIcon(getClass().getResource("/images/paste_icon.png")),
"Ctrl+V");//MenuItem class extends JComponent, has implemented MouseListener - and when mouseClicked(MouseEvent e) occurs, somehow action signal have to be sent to this class
MenuItem copy = ....
MenuItem cut = ....
Action pasteAction = getActionMap().get(DefaultEditorKit.pasteAction);
paste.setAction(pasteAction);//How to make it to work?
popUp.addMenuItem(paste);
popUp.addMenuItem(cut);
popUp.addMenuItem(copy);
}
}
如何正确做到?
答案 0 :(得分:2)
我正在创建自定义弹出菜单,只使用扩展的JComponent作为菜单项,并使用扩展的JWindow来保存它们。
不确定这意味着什么。
您应该只使用JPopupMenu并向其添加JMenuItems。请阅读Bringing Up a Popup Menu上的Swing教程中的部分,以获取示例。
然后,如果您想要剪切/复制/粘贴功能,您可以使用DefaultEditorKit提供的默认操作:
popup.add( new JMenuItem(new DefaultEditorKit.CopyAction()) );
答案 1 :(得分:1)
根据您发布的代码,我认为您在TextInputField类中需要做的就是添加:
paste.addActionListener(pasteAction);
然后在您的MenuItem类中,您必须输入代码来调用这些动作侦听器。
public class MenuItem implements MouseListener
{
...
@Override public void mouseClicked(MouseEvent event)
{
ActionListener[] listeners = (ActionListener[])
MenuItem.this.getListeners(ActionListener.class);
for(int i = 0; i < listeners.length; i++)
{
listeners[i].actionPerformed
(
new ActionEvent(MenuItem.this,someID, someCMDName)
);
}
}
在扩展JComponent的类中(我将其称为类'A'),您需要获取对JTextField的引用。一种简单的方法是将类型为JTextField的私有实例变量添加到类A中,并通过构造函数传入JTextField。
所以你的课应该是这样的:
public class A extends JComponent implements ActionListener
{
private JTextField updateField;
public A(JTextField updateField[,<your other contructor arguments>...])
{
this.updateField = updateField;
this.addActionListener(this);
}
public void actionPerformed(ActionEvent event)
{
if(event.getSource().equals(this)
{
//copy, paste or do whatever with the JTextField
//by way of this.updateField;
//e.g. this.updateField.setText(...);
//or to simply pass the event along to the JTextField's handlers
//this.updateField.dispatchEvent(event);
}
}
}
然后你必须记住在创建组件时将jtextField传递给构造函数
答案 2 :(得分:0)
所以我的工作示例如下(简化):
public class TextInputField extends JTextField {
private MenuPopupWindow popUp;
private MenuItem copy,
cut,
paste,
selectAll;
public TextInputField() {
popUp = new MenuPopupWindow();
paste = new MenuItem(this, "Paste", new ImageIcon(getClass().getResource("/images/Paste-icon.png")), "Ctrl+V");
cut = new MenuItem(this, "Cut", new ImageIcon(getClass().getResource("/images/Cut-icon.png")), "Ctrl+X");
copy = new MenuItem(this, "Copy", new ImageIcon(getClass().getResource("/images/Copy-icon.png")), "Ctrl+C");
selectAll = new MenuItem(this, "Select All", null, "Ctrl+A");
popUp.addMenuItem(paste);
popUp.addMenuItem(cut);
popUp.addMenuItem(copy);
popUp.addMenuItem(selectAll);
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
if (getSelectedText() == null) {
copy.setEnabled(false);
cut.setEnabled(false);
} else {
copy.setEnabled(true);
cut.setEnabled(true);
}
if (getText().equals("")) {
selectAll.setEnabled(false);
} else {
selectAll.setEnabled(true);
}
Clipboard c = getToolkit().getSystemClipboard();
Transferable t = c.getContents(this);
if (t.isDataFlavorSupported(DataFlavor.stringFlavor)) {
String s;
try {
s = (String) t.getTransferData(DataFlavor.stringFlavor);
if (s.equals("")) {
paste.setEnabled(false);
} else {
paste.setEnabled(true);
}
} catch (UnsupportedFlavorException | IOException ex) {
Logger.getLogger(TextInputField.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
paste.setEnabled(false);
}
popUp.setLocation(e.getXOnScreen(), e.getYOnScreen());
getCaret().setVisible(false);
popUp.setVisible(true);
} else {
Object obj = e.getSource();
if (obj instanceof MenuItem) {
MenuItem menuItem = (MenuItem) obj;
if (paste == menuItem) {
paste();
} else if (cut == menuItem) {
cut();
} else if (copy == menuItem) {
copy();
} else if (selectAll == menuItem) {
selectAll();
}
}
getCaret().setVisible(true);
popUp.setVisible(false);
}
}
});
}
}
在MenuItem类添加(简化):
@Override
public void mouseClicked(MouseEvent e) {
textField.dispatchEvent(e);
}
精湛的工作:)
决定在MenuItem类中使用Component而不是JComponent,因为不需要paintComponent,paintBorder和paintChildren构造函数 - 节省资源。