我需要在应用程序窗口中获取所有现有的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..
}
答案 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的默认键绑定。