为什么键绑定不适用于 CardLayout?
Why are the keybindings not working with CardLayout?
在我的问题中 Frakcool 给了我使用键绑定的建议,但有一件事没有奏效:当 JButton 将另一个 JPanel 放在框架的前面时,键绑定没有响应。这是代码:
private JFrame frame;
private JPanel[] statePanels;
private CardLayout layout;
private JPanel mainPanel;
private JButton button;
private String status;
void initAndShow()
{
//Init stuff
mainPanel = new JPanel(layout);
statePanels = new JPanel[2];
button = new JButton("Exit");
status = "Menu";
button.addActionListener(e -> {
status = status.equals("Menu") ? "World" : "Menu";
layout.show(mainPanel, status);
});
statePanels[0] = new OutWorldHandler();
statePanels[1] = new InWorldHandler();
mainPanel.add(statePanels[0], "Menu");
mainPanel.add(statePanels[1], "World");
mainPanel.getInputMap().put(KeyStroke.getKeyStroke('f'), "close");
mainPanel.getActionMap().put("close", this);
frame.add(mainPanel);
frame.add(button, BorderLayout.SOUTH);
}
@Override
public void actionPerformed(ActionEvent e)
{
System.out.println("hi");
}
预期的输出是,当我一直按下 f
时,控制台会打印出 "hi",但只有当我没有按下按钮时才会打印
对我有用的解决方案:我只是在 button.addActionListener
lambda 中添加了一条语句,将焦点放在 mainPanel
上:mainPanel.grabFocus();
.
完整的代码看起来像这样:
button.addActionListener(e -> {
status = status.equals("Menu") ? "World" : "Menu";
layout.show(mainPanel, status);
button.setText("Exit " + status);
mainPanel.grabFocus();
});
键绑定不是特别复杂,但可能需要一点时间才能习惯。为此,手头有How to Use Key Bindings and the JavaDocs for JComponent
,以供参考。
键绑定的目标之一 API 是可配置性,使我们能够更好地控制确定击键何时应触发事件。
JComponent#getInputMap
方法 returns 绑定到 "when has focused" 上下文的映射。这意味着在触发绑定之前组件需要有焦点(并且显然是可聚焦的)。
如果您希望在不同级别触发绑定,则需要使用 JComponent#getInputMap(int)
并将其传递给三个可用上下文之一:
JComponent.WHEN_IN_FOCUSED_WINDOW
JComponent.WHEN_FOCUSED
JComponent. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
你使用哪个取决于你的需要,但我通常很懒,当我想要 "global" 状态时就选择 JComponent.WHEN_IN_FOCUSED_WINDOW
在我的问题中
private JFrame frame;
private JPanel[] statePanels;
private CardLayout layout;
private JPanel mainPanel;
private JButton button;
private String status;
void initAndShow()
{
//Init stuff
mainPanel = new JPanel(layout);
statePanels = new JPanel[2];
button = new JButton("Exit");
status = "Menu";
button.addActionListener(e -> {
status = status.equals("Menu") ? "World" : "Menu";
layout.show(mainPanel, status);
});
statePanels[0] = new OutWorldHandler();
statePanels[1] = new InWorldHandler();
mainPanel.add(statePanels[0], "Menu");
mainPanel.add(statePanels[1], "World");
mainPanel.getInputMap().put(KeyStroke.getKeyStroke('f'), "close");
mainPanel.getActionMap().put("close", this);
frame.add(mainPanel);
frame.add(button, BorderLayout.SOUTH);
}
@Override
public void actionPerformed(ActionEvent e)
{
System.out.println("hi");
}
预期的输出是,当我一直按下 f
时,控制台会打印出 "hi",但只有当我没有按下按钮时才会打印
对我有用的解决方案:我只是在 button.addActionListener
lambda 中添加了一条语句,将焦点放在 mainPanel
上:mainPanel.grabFocus();
.
完整的代码看起来像这样:
button.addActionListener(e -> {
status = status.equals("Menu") ? "World" : "Menu";
layout.show(mainPanel, status);
button.setText("Exit " + status);
mainPanel.grabFocus();
});
键绑定不是特别复杂,但可能需要一点时间才能习惯。为此,手头有How to Use Key Bindings and the JavaDocs for JComponent
,以供参考。
键绑定的目标之一 API 是可配置性,使我们能够更好地控制确定击键何时应触发事件。
JComponent#getInputMap
方法 returns 绑定到 "when has focused" 上下文的映射。这意味着在触发绑定之前组件需要有焦点(并且显然是可聚焦的)。
如果您希望在不同级别触发绑定,则需要使用 JComponent#getInputMap(int)
并将其传递给三个可用上下文之一:
JComponent.WHEN_IN_FOCUSED_WINDOW
JComponent.WHEN_FOCUSED
JComponent. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
你使用哪个取决于你的需要,但我通常很懒,当我想要 "global" 状态时就选择 JComponent.WHEN_IN_FOCUSED_WINDOW