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

Java 在一个窗口中获取所有现有的JTextField组件,并为每个组件添加弹出菜单?,java,swing,Java,Swing,我需要在一个应用程序窗口中获取所有现有的文本字段,以便我能够自动将弹出菜单添加到所有这些字段中。你是怎么做到的 代码如下。为什么当我打电话时: JTextFieldRegularPopupMenu.addToAll(jpanel)它工作正常,并影响所有相关的JTextFields。但是,当我使用常规JDialog netbeans类中的JDialog-JTextFieldRegularPopupMenu.addToAll(这个)执行此操作时,它不起作用。有什么问题吗 import java.aw

我需要在一个应用程序窗口中获取所有现有的文本字段,以便我能够自动将弹出菜单添加到所有这些字段中。你是怎么做到的

代码如下。为什么当我打电话时: JTextFieldRegularPopupMenu.addToAll(jpanel)它工作正常,并影响所有相关的JTextFields。但是,当我使用常规JDialog netbeans类中的JDialog-JTextFieldRegularPopupMenu.addToAll(这个)执行此操作时,它不起作用。有什么问题吗

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);
    }
}

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

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

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

一种方法可能是使用
键盘FocusManager
来监听焦点更改

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

查看使用此概念的简单示例,该示例演示如何在文本字段获得焦点时选择所有文本

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

编辑:

使用当前方法,您可能希望将
窗口
对象传递给方法。然后可以使用
getContentPane()
方法获取包含组件的容器

然后你可以使用一个类,比如。这将对内容窗格进行递归搜索以查找所有组件。然后遍历列表并添加逻辑

然后该代码将适用于两个框架、对话框等

此外,您不必总是创建自定义操作。您可以使用DefaultEditorKit中的操作。例如:

JMenuItem copy = new JMenuItem( new DefaultEditorKit.CopyAction() );
所有菜单项都可以共享该操作


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

因为窗口和组件并非都是在应用程序启动时创建的,所以您不能预先执行此操作。因此,您需要在应用程序创建和显示窗口时动态地管理它

一种方法可能是使用
键盘FocusManager
来监听焦点更改

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

查看使用此概念的简单示例,该示例演示如何在文本字段获得焦点时选择所有文本

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

编辑:

使用当前方法,您可能希望将
窗口
对象传递给方法。然后可以使用
getContentPane()
方法获取包含组件的容器

然后你可以使用一个类,比如。这将对内容窗格进行递归搜索以查找所有组件。然后遍历列表并添加逻辑

然后该代码将适用于两个框架、对话框等

此外,您不必总是创建自定义操作。您可以使用DefaultEditorKit中的操作。例如:

JMenuItem copy = new JMenuItem( new DefaultEditorKit.CopyAction() );
所有菜单项都可以共享该操作


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

JFrame通常不包含JTextField对象。它包含JPanel对象,其中可能包含其他JPanel对象。。。最终,其中一些可能包含JTextField对象。您将需要递归搜索。方法名称不应以大写字符开头。学习并使用Java命名约定。JFrame通常不包含JTextField对象。它包含JPanel对象,其中可能包含其他JPanel对象。。。最终,其中一些可能包含JTextField对象。您将需要递归搜索。方法名称不应以大写字符开头。学习并使用Java命名约定。您的示例与我的建议完全不同。它还假设1)只有一个面板添加到框架中。如果你使用嵌套面板,那么你的文本字段就不会有问题2)你也不会创建额外的对话框等。我给了你一个简单的方法来处理上述所有问题。你的例子与我的建议完全不同。它还假设1)只有一个面板添加到框架中。如果你使用嵌套面板,你的文本字段就不会变好2)你也不会处理额外对话框的创建等。我给了你一个简单的方法来处理上述所有问题。