Java Can';t在ActionListener中重新绘制

Java Can';t在ActionListener中重新绘制,java,swing,actionlistener,repaint,Java,Swing,Actionlistener,Repaint,编辑:现在它工作得很好,但是当我切换到“游戏”JPanel时,KeyListener不工作:(有办法解决这个问题吗 我正在编写一个java游戏,repaint()方法有一个问题: 我想从菜单进入游戏,所以我删除了菜单面板并添加了游戏面板(“Zeichnen”扩展了JPanel),但每次我尝试重新绘制时,eclipse都会给我以下错误:“对于类型new ActionListener(){}的方法repaint()未定义”有人能帮我吗( 代码: 您需要调用game.repaint(),因为您创建的匿

编辑:现在它工作得很好,但是当我切换到“游戏”JPanel时,KeyListener不工作:(有办法解决这个问题吗

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

代码:


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

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

这是因为该结构中的任何类中都没有方法(即,
→ 匿名
ActionListener
),它扩展了
组件
,并具有一个
重绘
方法


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

这是因为在该结构中的任何类中都没有方法(即
Frame
→ 匿名
ActionListener
),它扩展了
组件
,并具有一个
重绘
方法

您可以将主
Frame
类扩展为
JFrame
,或者调用
game.repaint()
。您可能希望执行前者。

建议:

  • 您应该使用CardLayout来交换容器组件,因为这是更改视图的最简单和最可靠的方法。在本网站先前的问题中有许多使用此方法的示例
  • 不要使用KeyListener,而是使用键绑定,因为它们在组件焦点方面更加宽容
  • 将“Frame”类重命名为与核心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());
         }
      });
   }
}
建议:

  • 您应该使用CardLayout来交换容器组件,因为这是更改视图的最简单和最可靠的方法。在本网站先前的问题中有许多使用此方法的示例
  • 不要使用KeyListener,而是使用键绑定,因为它们在组件焦点方面更加宽容
  • 将“Frame”类重命名为与核心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());
         }
      });
   }
}

请参阅答案:你应该使用键绑定而不是键侦听器。请参阅答案:你应该使用键绑定而不是键侦听器。感谢上帝你救了我一天,我差点把笔记本扔到墙上,因为我无法解决问题…感谢上帝你救了我一天,我差点把笔记本扔到墙上,因为我无法解决问题相对长度单位。。。