我有一个带有多个 Pane 的 Swing 应用程序。有些 Pane 是文本 Pane (JTextPane),有些是类似对话框的(带有按钮和 slider ),有些是图形的(自定义绘制)。我在主菜单中使用简单的加速器定义了一些操作,例如 K、P 或 O。
我希望仅当当前聚焦的 Pane 未处理这些加速器时,菜单操作才会处理它们。具体来说,当用户只是在文本 Pane 中键入内容时,我不希望菜单处理它们。
我正在使用以下方法创建操作和菜单项:
action = new javax.swing.AbstractAction
new MenuItem(action)
我正在注册加速器:
action.putValue(javax.swing.Action.ACCELERATOR_KEY, keyStroke)
是否可以“吃掉”(抑制)在文本 Pane 中处理的按键的按键事件,以便它们不会传递到主菜单进行全局处理?
如果没有,是否有一些替代方法可以执行类似的操作,例如注册我知道仅在某些 Pane 的文本 Pane 中不应处理的加速器?
我将根据答案添加代码,以使问题更清晰(并使开发替代解决方案更容易):
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
public class TestMenuBindings {
public static void main(String[] args) {
JMenuBar menuBar = new JMenuBar();
final JMenu menu = new JMenu("Print");
final Action oAction = new PrintAction("O",KeyStroke.getKeyStroke(KeyEvent.VK_O, 0));
menu.add(oAction);
menuBar.add(menu);
JFrame frm = new JFrame("Frame");
frm.setJMenuBar(menuBar);
JTextArea area = new JTextArea("Here I want no accelerators", 10, 40);
frm.add(new JScrollPane(area));
frm.add(new JTextField("Here I want accelerators working"), BorderLayout.SOUTH);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.pack();
frm.setVisible(true);
}
private static class PrintAction extends AbstractAction {
private String str;
public PrintAction(String aPrintStr, KeyStroke aMnemonic) {
super("Print: " + aPrintStr);
str = aPrintStr;
putValue(Action.ACCELERATOR_KEY, aMnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(str);
}
}
}
最佳答案
这是一个例子。在文本区域中没有键绑定(bind)工作。在文本字段中使用所有键绑定(bind)。此外,所有菜单项都可以从菜单访问(启用)。
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
public class TestMenuBindings {
public static void main(String[] args) {
JMenuBar menuBar = new JMenuBar();
final JMenu menu = new JMenu("Print");
menu.add(new PrintAction("O", KeyStroke.getKeyStroke(KeyEvent.VK_O, 0)));
menu.add(new PrintAction("K", KeyStroke.getKeyStroke(KeyEvent.VK_K, 0)));
menu.add(new PrintAction("P", KeyStroke.getKeyStroke(KeyEvent.VK_P, 0)));
menuBar.add(menu);
JFrame frm = new JFrame("Frame");
frm.setJMenuBar(menuBar);
JTextArea area = new JTextArea("Here working no accelerators", 10, 40);
area.addFocusListener(new FocusListener() {
@Override
public void focusLost(FocusEvent e) {
setItemStatus(menu, true);
}
@Override
public void focusGained(FocusEvent e) {
setItemStatus(menu, false);
}
});
frm.add(new JScrollPane(area));
frm.add(new JTextField("Here working accelerators"), BorderLayout.SOUTH);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.pack();
frm.setVisible(true);
}
private static void setItemStatus(JMenu aMenu, boolean aStatus) {
for (Component item : aMenu.getMenuComponents()) {
((JMenuItem) item).getAction().setEnabled(aStatus);
}
}
private static class PrintAction extends AbstractAction {
private String str;
public PrintAction(String aPrintStr, KeyStroke aMnemonic) {
super("Print: " + aPrintStr);
str = aPrintStr;
putValue(Action.ACCELERATOR_KEY, aMnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(str);
}
}
}
关于java - 如何通过文本 Pane 隐藏 Swing 加速器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29252237/