- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
背景
我有一个简单的游戏。我有一个 JPanel
类,里面什么都有(菜单、游戏、游戏结束)。
然后我决定,我应该让我的游戏更好,我制作了两个面板(一个用于菜单,第二个用于游戏等级)。
一切都很好,但是我的 KeyAdapter
类在我的 JPanel
上不起作用。我不知道为什么它不想聚焦。
这就是我所拥有的:
扩展 JFrame
的主类,在这里我添加了我的面板(和 KeyListener
到第一个面板)
public class JavaGame2 extends JFrame {
public JavaGame2(){
gamePanel = new GamePanel();
menuPanel = new MenuPanel();
setContentPane(menuPanel);
menuPanel.addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP) {
menuPanel.changeCursor();
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
menuPanel.changeCursor();
}
if (menuPanel.getCursorPos()==1){
if ((e.getKeyCode() == KeyEvent.VK_ENTER)) {
setContentPane(gamePanel);
//add(gamePanel);
}
}
else{
if ((e.getKeyCode() == KeyEvent.VK_ENTER)) {
System.exit(0);
}
}
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 600);
setLocationRelativeTo(null);
setTitle("JavaGame2");
setResizable(false);
}
public static void main(String[] args) {
JFrame jgame = new JavaGame2();
jgame.setVisible(true);
}
}
MenuPanel
类扩展 JPanel
public class MenuPanel extends JPanel implements ActionListener{
public MenuPanel(){
setFocusable(true);
setBackground(Color.BLACK);
setDoubleBuffered(true);
setSize(800,600);
}
public void actionPerformed(ActionEvent e) {
}
}
这里是 GamePanel
类
public class GamePanel extends JPanel implements ActionListener{
public GamePanel (){
addKeyListener(new GameAdapter());
setFocusable(true);
requestFocus();
setBackground(Color.BLACK);
setDoubleBuffered(true);
setSize(800,600);
}
private class GameAdapter extends KeyAdapter{
public void keyReleased(KeyEvent e) {
ship.keyReleased(e);
}
public void keyPressed(KeyEvent e) {
ship.keyPressed(e);
}
}
}
这是行不通的。 GamePanel
不想集中注意力,我试图做我阅读的每一件事。我想你会说 JPanel
不是可聚焦的组件。但是当有一个面板时,它以某种方式工作。
如何解决这个焦点问题?也许您会说您不喜欢使用 KeyAdapter
,但我认为它在我的代码中看起来相当不错。
setFocusable()
?或者 requestFocus()
? requestFocusInWindow()
?我应该如何使用它们?也许我之前有错误,这不是我的第一个问题?
提前致谢。
感谢编辑。
最佳答案
简答,使用key bindings API , 它允许您控制组件在触发关键事件之前所需的关注级别。
更长的答案, Activity 面板需要有键盘焦点。您可以使用 requestFocusInWindow
,但不能保证组件会真正获得焦点。何时调用它是一件棘手的事情。您可以尝试覆盖面板的 addNotify
并调用到那里,只要确保您先调用 super.addNotify
,当您不这样做时会发生奇怪的事情
你还需要考虑如果组件失去焦点会发生什么
作为旁注:
setDoubleBuffered(true);
是无关紧要的,因为默认情况下 Swing 组件是双缓冲的。如果您想打印组件,通常可以禁用此功能。不过这样称呼也无妨setSize
是无关紧要的,因为您的组件将处于布局管理器的控制之下,这将决定组件本身的大小。您最好覆盖 getPreferredSize
并为布局管理器返回适当的大小JFrame
上调用setSize
也是一个坏主意。框架有边框,这意味着您的可视区域将是 框架大小 - 框架边框插入
,这将小于您指定的 800x600。最好利用前面的注释并在 JFrame
上调用 pack
,这将围绕内容打包框架,使其满足内容要求...KeyListener
本地化到实际组件本身,这允许组件充当它自己的 Controller ,使其更便携...恕我直言更新了 Controller 的想法...
一个“真正”简化的概念是拥有某种“ Controller ”,菜单和游戏面板可以通过它进行通信,例如......
public interface GameController {
public void showMenu();
public void showGame();
}
然后您可以将此接口(interface)的引用传递给 MenuPanel
...
public class MenuPanel extends JPanel implements ActionListener{
public MenuPanel(GameController controller){
//...
}
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
还有游戏面板
...
public class GamePanel extends JPanel implements ActionListener{
public GamePanel (GameController controller){
//...
}
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
显然,您需要构建 Controller 的实现...
public class CardLayoutGameController implements GameController {
public static final String GAME_PANEL = "GamePanel";
public static final String MENU_PANEL = "MenuPanel";
private Container container;
private CardLayout cardLayout;
public CardLayoutGameController(Container parent, CardLayout layout) {
container = parent;
cardLayout = layout;
}
public void showMenu() {
cardLayout.show(container, MENU_PANEL);
}
public void showGame() {
cardLayout.show(container, GAME_PANEL);
}
}
然后您将围绕这个 Controller 构建您的 UI,例如...
public class JavaGame2 extends JFrame {
public JavaGame2(){
CardLayout layout = new CardLayout();
setLayout(layout);
GameController controller = new CardLayoutGameController(getContentPane(), layout);
gamePanel = new GamePanel(controller);
menuPanel = new MenuPanel(controller);
add(gamePanel, CardLayoutGameController.GAME_PANEL);
add(menuPanel, CardLayoutGameController.MENU_PANEL);
controller.showMenu();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setTitle("JavaGame2");
setResizable(false);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame jgame = new JavaGame2();
jgame.setVisible(true);
}
});
}
}
这只是一个帮助激发想法的“例子”吗,还没有测试过,只是在这里破解,所以它可能会爆炸:P
关于java - JPanel 不想聚焦所以 KeyAdapter 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23820556/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!