我有这个类,我想在调用它后立即将焦点切换到 Game 类。我可能不明白焦点的目的,但当我按下开始时,我必须单击游戏 Canvas 本身,以便我可以使用键盘。换句话说:我怎样才能做到这样我就不必点击它来使用键盘?
package com.runner.panels;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
import com.runner.main.Game;
import com.runner.main.Main;
public class PlayPanel extends JPanel{
private static final long serialVersionUID = 1L;
public PlayPanel(){
//setting the layout of the playpanel to null
setLayout(null);
//setting up the info panel : high score, meters ran, pause button etc...
JPanel info = new JPanel();
info.setBounds(0,0,1200,50);
add(info);
//back button
JButton back = new JButton("Back");
info.add(back);
Game game = new Game();
game.setBounds(0,50,1200,521);
game.setBackground(Color.black);
add(game);
back.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
CardLayout cl = (CardLayout) Main.mainp.getLayout();
cl.show(Main.mainp, "Menu");
}
});
}
}
最佳答案
偏离主题:(有点)
事实上,您正在执行 Main.mainp.getLayout();
,静态调用面板告诉我您的设计很差,应该考虑其他选项,例如 Model-view-controller pattern ,一个Observer pattern ,或者至少将 Main
的引用传递给面板,而不是使用静态对象/调用。
回到主题
听起来像是一个常见的 KeyListener 问题。通常要获得焦点,您可以调用 requestFocusInWindow()
。但您仍然需要担心其他组件会在事后窃取焦点。
我建议使用 Key Bindings而不是 KeyListener。您可以更好地控制焦点。例如,通过使用
InputMap im = panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke("SPACE"), "hitSpace");
panel.getActionMap().put("hitSpace", new AbstractAction(){
public void actionPerformed(ActionEvent e) {
// do something.
}
});
一旦您从 CardLayout
显示操作,面板将立即访问该操作。如果您碰巧使用任何其他会夺走面板焦点的组件,由于 WHEN_IN_FOCUSED_WINDOW
输入映射
这是一个简单的例子。如果它位于面板 A 上,则键入 A,您将看到它被打印出来。如果您键入 B,则不会打印,因为面板 A 在窗口中。此外,如果您尝试按下面板中的按钮来窃取焦点,您仍然可以打字并且仍然可以打印。面板 B 也是如此
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class Main {
CardLayout layout = new CardLayout();
JPanel panel = new JPanel(layout);
JPanel p1 = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
};
JPanel p2 = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
};
JButton b1 = new JButton("panelA");
JButton b2 = new JButton("panelB");
public Main() {
addKeyBind(p1, "pressA", "A");
addKeyBind(p2, "pressB", "B");
p1.add(new JButton("Button for Panel A"));
p2.add(new JButton("Button for Panel B"));
panel.add(p1, "panelA");
panel.add(p2, "panelB");
b1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
show("panelA");
}
});
b2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
show("panelB");
}
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(b1);
buttonPanel.add(b2);
JFrame frame = new JFrame();
frame.add(panel);
frame.add(buttonPanel, BorderLayout.PAGE_END);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void show(String panelName) {
layout.show(panel, panelName);
}
private void addKeyBind(JComponent comp, String name, final String stroke) {
InputMap im = comp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke(stroke), name);
comp.getActionMap().put(name, new AbstractAction(){
public void actionPerformed(ActionEvent e) {
System.out.println(stroke + " pressed");
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new Main();
}
});
}
}
请花一些时间查看我为您提供的按键绑定(bind)链接,以了解更多信息。
偏离主题
看看@AndrewThompson 关于空布局的评论。学习how to use the LayoutManagers
关于java - 如何将焦点切换到 Canvas ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25227045/