1

編集:今は正常に動作しますが、「ゲーム」JPanelに切り替えると、KeyListenerが機能しません:(これを修正する方法はありますか?

Javaゲームをプログラミングしているだけで、repaint()メソッドに問題があります。メニューからゲームに移動したいので、メニューパネルを削除してゲームパネルを追加します(「Zeichnen」はJPanelを拡張します)。再描画しようとすると、eclipseで次のエラーが発生します:「メソッドrepaint()はタイプnew ActionListener(){}に対して未定義です」誰か助けてくれませんか?:(

コード:

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 を使用するのではなく、コンポーネントのフォーカスに関してはるかに寛容なキー バインディングを使用してください。
  • 「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());
         }
      });
   }
}
于 2013-03-11T21:37:05.743 に答える
1

作成した匿名クラスには repaint() というメソッドがないため、 game.repaint() を呼び出す必要があります。

于 2013-03-11T21:28:55.457 に答える
1

これは、その構造 (つまり、Frame→ anonymous ActionListener) 内のどのクラスにも、拡張Componentしてメソッドを持つrepaintメソッドがないためです。

Frameメインクラスを extendsJFrameにするか、呼び出すことができますgame.repaint()。あなたはおそらく前者をやりたいと思うでしょう。

于 2013-03-11T21:29:10.847 に答える