我有一个带有多个JTextArea
的Java Swing界面,我正在实现一个"编辑"具有各种不同功能的菜单,例如"查找","复制","粘贴"等。当我点击JMenuItem
时我需要知道哪个JTextArea
有一个焦点可以通过TextAction
实现(我没有沿着FocusListener
的路线走下去并跟踪最后的焦点:
JMenuItem miFind = new JMenuItem(new EditHandler("Find"));
class EditHandler extends TextAction {
private String s = null;
public EditHandler(String vs) {
super(vs);
s = vs;
}
@Override
public void actionPerformed(ActionEvent e) {
JTextComponent c = getFocusedComponent();
if (s.equals("Find")) {
showFindDialog(c);
}
}
}
这很好但很好,但我希望能够禁用"查找" JMenuItem
在某些情况下(例如,如果特定的JTextArea
被停用或为空。我可以在ActionListener
上实施JMenu
但我无法使用{{} 1}}以确定getFocusedComponent()
具有焦点的内容。
根据Java文档,JTextArea
构造函数采用JMenu
(如Action
),我尝试了以下内容:
JMenuItem
但是,虽然构造函数会触发,mEdit = new JMenu(new EditHandler("Edit"));
事件不会在actionPerformed()
EditHandler
内触发JMenu
。如果我可以解雇它,那么我打算启用或禁用我的"查找" JMenuItem
。
答案 0 :(得分:1)
最好的方法是使用文本组件的动作映射来放置相应的动作。在这种情况下,您可以为某些文本组件禁用它。
@Override
public void actionPerformed(ActionEvent e) {
JTextComponent c = getFocusedComponent();
if (s.equals("Find")) {
Action a = c.getActionMap().get("Find");
if (a.isEnabled()) {
// generate new event to modify the source (menu item -> text component)
ActionEvent ae = new ActionEvent(c, e.getID(), e.getCommand());
a.actionPerformed(ae);
}
}
}
对于每个文本组件,您必须提供操作并使用组件的操作映射进行注册。
public class UniversalFindAction extends AbstractAction {
public void actionPerformed(ActionEvent ae) {
JTextComponent c = (JTextComponent) ae.getSource();
showFindDialog(c);
}
}
// registering of action
JTextComponent comp = new JTextArea();
comp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_DOWN_MASK), "Find");
comp.getActionMap().put("Find", new UniversalFindAction());
答案 1 :(得分:1)
感谢@ sergiy-medvynskyy我已经实施了一个全球焦点监听器来跟踪最后的JTextArea
:
KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("permanentFocusOwner", new PropertyChangeListener() {
@Override
public void propertyChange(final PropertyChangeEvent e) {
if (e.getNewValue() instanceof JTextArea) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
tFocused = (JTextArea)e.getNewValue();
}
});
}
}
});
然后,我使用tFocused
上的MenuListener
检查JMenu
对象,以验证JTextArea
当前具有焦点的内容。然后,我可以根据具体情况在setEnabled()
上调用JMenuItem
。