如何在单击某些 JComponent 时将文本剪切/复制/粘贴到 JTextField



我正在创建自定义弹出菜单,仅使用扩展JComponent作为菜单项,并使用扩展JWindow来保存它们。我的问题是 - 如何在单击(MouseListener(时从JComponent实例发送信号以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);
        }
        }

怎么做对?

我正在创建自定义弹出菜单,仅使用扩展的JComponent作为菜单项,并使用扩展的JWindow来保存它们。

不太确定这一切意味着什么。

您应该只使用JPopupMenu并将JMenuItems添加到其中。有关示例,请阅读 Swing 教程中有关调出弹出菜单的部分。

然后,如果需要剪切/复制/粘贴功能,可以使用 DefaultEditorKit 提供的默认操作:

popup.add( new JMenuItem(new DefaultEditorKit.CopyAction()) );

根据您发布的代码,我认为您在 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传递给构造函数

所以我

的工作示例如下(简化(:

    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 构造函数 - 节省资源。

最新更新