1

皆さん、こんにちは

プロジェクトのメインメニューをコーディングしています。メニューは正常に表示されます。メニューの 3 つのボタンの ActionListeners もセットアップしました。

私がやりたいことは、ユーザーが「新しいゲームを開始する」を選択したときに、ラジオ ボタンの新しいセットに JPanel を再利用することです。

しかし、JPanel から既存のコンポーネントを削除するために ActionPerformed をコーディングすると、困惑してしまいます。removeAll が何らかの形で重要であることは知っていますが、残念ながら NetBeans から、ActionPerformed 内の mainMenu JPanel オブジェクトでそれを呼び出せないことが通知されます。そのため、以下のコードでコメントアウトしましたが、残したままにして、私が何をしようとしているのかを確認してください。

あなたの考えやヒントは大歓迎です。

ここに私のメインコードがあります:

public class Main {

    public static void main(String[] args) {
        MainMenu menu = new MainMenu();
        menu.pack();
        menu.setVisible(true);
    }
}

ここに私のmainMenuコードがあります:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

    public class MainMenu extends JFrame implements ActionListener {
        JButton startNewGame = new JButton("Start a New Game");
        JButton loadOldGame = new JButton("Load an Old Game");
        JButton seeInstructions = new JButton("Instructions");

        public MainMenu() {
            super("RPG Main Menu");
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JPanel mainMenu = new JPanel();
            mainMenu.setLayout(new FlowLayout());
            startNewGame.setMnemonic('n');
            loadOldGame.setMnemonic('l');
            seeInstructions.setMnemonic('i');
            startNewGame.addActionListener(this);
            loadOldGame.addActionListener(this);
            seeInstructions.addActionListener(this);
            mainMenu.add(startNewGame);
            mainMenu.add(loadOldGame);
            mainMenu.add(seeInstructions);
            setContentPane(mainMenu);

        }

        public void actionPerformed(ActionEvent evt) {
            Object source = evt.getSource();
            if (source == startNewGame) {
                // StartNewGame code goes here
                // mainMenu.removeAll();
            }
            if (source == loadOldGame) {
                // LoadOldGame code goes here
            }
            if (source == seeInstructions) {
                // Quit code goes here
            }
        }
    }
4

5 に答える 5

2

CardLayout代わりに、同じ表示スペースを共有する 2 つ以上のコンポーネント (通常はJPanelインスタンス)を管理するの使用を検討してください。そうすれば、実行時にコンポーネントを追加したり削除したりする必要はありません。

于 2009-02-22T07:15:43.300 に答える
1

mainMenu actionPerformed への参照がありません。ボタンで mainMenu を宣言する場合。それはうまくいくでしょう。

于 2009-02-22T07:12:54.180 に答える
1

mainMenu をメンバー変数にする必要があります。

 public class MainMenu extends JFrame implements ActionListener {
        JButton startNewGame = new JButton("Start a New Game");
        JButton loadOldGame = new JButton("Load an Old Game");
        JButton seeInstructions = new JButton("Instructions");
        JPanel mainMenu = new JPanel();

このオブジェクトを再利用する必要性を感じたのはなぜですか?

于 2009-02-22T07:13:04.040 に答える
0

ものを「再利用」しようとしないでください。コンピューターはかなり片付けができます。コードを明確にすることに集中してください。

したがって、パネルを整理する代わりに、新しいパネルと交換するだけです。

一般に、リスナーを作成するためのより良い方法は、匿名の内部クラスとしてです。これら内のコードは、囲んでいるスコープ内の最終変数と囲んでいるクラスのメンバーにアクセスできます。したがって、mainMenufinalを作成ActionListenerし、匿名の内部クラスを作成する場合、コードは少なくともコンパイルする必要があります。

また、クラスを「再利用」しようとしないでください。各クラスに1つの賢明なことを実行させ、(実装の)継承を回避するようにしてください。延長する必要はほとんどないJFrameので、そうしないでください。ActionListenerイベントソースを特定するのではなく、アクションごとにを作成します。

また、AWTイベントディスパッチスレッドでは常にSwingコンポーネントを使用する必要があることに注意してください。main次のような定型文を追加するように方法を変更します。

public static void main(final String[] args) {
    java.awt.EventQueue.invokeLater(new Runnable() { public void run() {
        runEDT();
    }});
}
于 2009-02-22T11:54:35.017 に答える
0

問題は、actionPerformedメソッドがスコープ外の を呼び出そうとしてJPanel mainMenuいることです。つまり、mainMenu変数がactionPerformedメソッドから見えません。

これを回避する 1 つの方法はJPanel mainMenu、クラス自体で宣言を行い、クラスのすべてのインスタンス メソッドからアクセスできるインスタンス フィールドにすることです。

例えば:

public class MainMenu extends JFrame implements ActionListener
{
    ...
    JPanel mainMenu;

    public MainMenu()
    {
        ...
        mainMenu = new JPanel();
        ...
    }

    public void actionPerformed(ActionEvent e)
    {
        ...
        mainMenu.removeAll();
    }
}
于 2009-02-22T07:13:51.977 に答える