1

编辑:现在它工作正常,但是当我切换到“游戏”JPanel 时,KeyListener 不起作用:(有什么办法解决这个问题吗?

我只是在编写一个 java 游戏,repaint() 方法有问题:我想从菜单进入游戏,所以我删除了菜单面板并添加了游戏面板(“Zeichnen”扩展了 JPanel)但每次我尝试重新绘制,eclipse 给了我以下错误:“对于类型 new ActionListener(){},方法 repaint() 是未定义的”有人可以帮我吗?:(

代码:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class Frame {

JFrame frame;
JPanel menu;
JButton start;
Zeichnen game;

public Frame() {

    start = new JButton("Start Game");
    menu = new JPanel();
    game = new Zeichnen();
    frame = new JFrame("Epic Game");

    start.addActionListener(new ActionListener () {
        public void actionPerformed(ActionEvent e) {

            frame.remove(menu);
            frame.add(game);
            repaint();

    }});

    frame.setVisible(true);
    frame.setSize(640,480);
    game.addKeyListener(new Listener(game));
    menu.add(start);
    frame.add(menu);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);

}
}
4

3 回答 3

2

建议:

  • 您应该使用 CardLayout 来让容器交换组件,因为这是更改视图的最简单和最可靠的方法。在此站点上的先前问题中有许多使用此方法的示例。
  • 不要使用 KeyListener 而是使用 Key Bindings,因为它们在组件焦点方面更加宽容。
  • 将您的“框架”类重命名为与核心 Java 类不匹配的名称。这是一个非常混乱的名字。

例如:

import java.awt.event.*;
import java.awt.*;

import javax.swing.*;

public class ContentPane extends JPanel {

   public static final String MENU = "menu";
   public static final String GAME = "game";
   private static final int PREF_W = 640;
   private static final int PREF_H = 480;

   private CardLayout cardlayout = new CardLayout();
   private JPanel menu = new JPanel();
   private JButton start;
   private Zeichnen game;

   public ContentPane() {
      setLayout(cardlayout);
      start = new JButton("Start Game");
      game = new Zeichnen();

      add(menu, MENU);
      add(game, GAME);

      start.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            cardlayout.next(ContentPane.this);
         }
      });

      menu.add(start);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("Epic Game");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new ContentPane());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

和键绑定:

@SuppressWarnings("serial")
class Zeichnen extends JPanel {
   private static final String DOWN = "down";

   public Zeichnen() {
      int condition = WHEN_IN_FOCUSED_WINDOW;
      InputMap inputMap = getInputMap(condition);
      ActionMap actionMap = getActionMap();

      inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), DOWN);
      actionMap.put(DOWN, new AbstractAction(DOWN) {
         {
            putValue(ACTION_COMMAND_KEY, DOWN);
         }

         @Override
         public void actionPerformed(ActionEvent evt) {
            System.out.println(evt.getActionCommand());
         }
      });
   }
}
于 2013-03-11T21:37:05.743 回答
1

您需要调用 game.repaint() 因为您创建的匿名类没有称为 repaint()的方法

于 2013-03-11T21:28:55.457 回答
1

那是因为在该结构中的任何类(即Frame→ 匿名ActionListener)中都没有扩展Component并具有方法的repaint方法。

你可以让你的主Frame类扩展JFrame,或者调用game.repaint(). 你可能想做前者。

于 2013-03-11T21:29:10.847 回答