在窗口中获取所有现有的JTextField组件并为每个组件添加弹出菜单?

时间:2018-01-15 02:46:14

标签: java swing

我需要在应用程序窗口中获取所有现有的TextFields,以便我能够自动为所有这些菜单添加弹出菜单。你是怎样做的?

代码如下。我怎么称呼: JTextFieldRegularPopupMenu.addToAll(jpanel)它工作正常并影响所有相关的JTextField。但是当我使用来自常规JDialog netbeans类的JDialog - JTextFieldRegularPopupMenu.addToAll(this)时,它不起作用。可能是什么问题?

import java.awt.Component;
import java.awt.Container;
import javax.swing.*;
import java.awt.event.ActionEvent;
import javax.swing.JPopupMenu;
import javax.swing.undo.*;

public class JTextFieldRegularPopupMenu {
    public static void addToAll(Container frm) {
        JTextField txtTmp = null;
        Component[] components = frm.getComponents();

        for(int i=0;i<components.length;i++){
            if( components[i] instanceof JTextField ){
                txtTmp = (JTextField)components[i];
                addTo(txtTmp);
            }
        }
    }

    public static void addTo(JTextField txtField) 
    {
        JPopupMenu popup = new JPopupMenu();
        UndoManager undoManager = new UndoManager();
        txtField.getDocument().addUndoableEditListener(undoManager);


        Action undoAction = new AbstractAction("Undo") {
            @Override
            public void actionPerformed(ActionEvent ae) {
                if (undoManager.canUndo()) {
                    undoManager.undo();
                }
                else {
                  // No Undo
                }
            }
        };

       Action copyAction = new AbstractAction("Copy") {
            @Override
            public void actionPerformed(ActionEvent ae) {
                txtField.copy();
            }
        };

        Action cutAction = new AbstractAction("Cut") {
            @Override
            public void actionPerformed(ActionEvent ae) {
                txtField.cut();
            }
        };

        Action pasteAction = new AbstractAction("Paste") {
            @Override
            public void actionPerformed(ActionEvent ae) {
                txtField.paste();
            }
        };

        Action selectAllAction = new AbstractAction("Select All") {
            @Override
            public void actionPerformed(ActionEvent ae) {
                txtField.selectAll();
            }
        };

        cutAction.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control X"));
        copyAction.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control C"));
        pasteAction.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control V"));
        selectAllAction.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control A"));

        popup.add (undoAction);
        popup.addSeparator();
        popup.add (cutAction);
        popup.add (copyAction);
        popup.add (pasteAction);
        popup.addSeparator();
        popup.add (selectAllAction);

       txtField.setComponentPopupMenu(popup);
    }
}

Netbeans JFrame类

public class FrmAddNewUser extends javax.swing.JDialog {

    /**
     * Creates new form FrmAddNewUser
     */

    public FrmAddNewUser(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        myInitComponents();
    }   

    private void myInitComponents()
    {
        JTextFieldRegularPopupMenu.AddToAll(this); //this doesn't work... but works on jpanel objects..
    }

2 个答案:

答案 0 :(得分:1)

听起来你正在尝试对所有现有的JTextField进行统一更改,对吗?这实际上取决于,但将所有对象存储在数据结构中(如ArrayList)可能是您最好的选择。然后使用for循环在每个索引处应用相同的更改。

答案 1 :(得分:1)

嗯,你不能提前做到这一点,因为窗口和组件并非都是在应用程序启动时创建的。因此,您需要在应用程序创建并显示窗口时动态管理它。

一种方法可能是使用KeyboardFocusManager来监听焦点变化。

当焦点更改时,您可以调用getPopupMenuComponent()方法来获取组件的弹出菜单。如果菜单为null,则需要添加弹出菜单。

使用此概念查看Global Event Listeners以获取一个简单示例,其中显示了在文本字段获得焦点时如何选择所有文本。

因此,您需要修改所有应用程序以在启动应用程序时添加此侦听器。

编辑:

使用您当前的方法,您需要将Window对象传递给方法。然后,您可以使用getContentPane()方法获取包含组件的包含。

然后你可以使用像Swing Utils这样的类。这将对内容窗格进行递归搜索以查找所有组件。然后迭代List并添加逻辑。

然后此代码适用于帧,对话框等。

此外,您无需始终创建自定义操作。您可以使用DefaultEditorKit中的Actions。例如:

JMenuItem copy = new JMenuItem( new DefaultEditorKit.CopyAction() );

所有菜单项都可以共享动作。

或者您可以从文本字段的ActionMap中查找默认操作。有关用于查找的操作名称,请参阅Key Bindings。它还将显示用于Action的默认键绑定。