0

我创建了一个代码,每当您单击 jmenuitem New Game int x 时,其值为 1 但遗憾的是它不会返回任何值

    package sprite;

    import java.awt.event.*;

    import javax.swing.*;
    import  sprite.Intro;
    import sprite.Fishes;

    public class Ken{

    static int x;

    public static void main(String args[])
    {   
        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame f = new JFrame("Save the FISH.");
        Fishes fs = new Fishes();
        Intro in = new Intro();
        Arrow a = new Arrow();          
        f.setResizable(false);
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(800,600);
        if(x == 0){
            f.add(a);
        }           
        if(x == 1){
            f.add(fs);
        }           
        JMenuBar mb = new JMenuBar();
        JMenu opt = new JMenu("Game");
        JMenu sd = new JMenu("Select Difficulty");
        JMenuItem ng = new JMenuItem("New Game");
        JMenuItem ex = new JMenuItem("Exit");
        JMenuItem l1 = new JMenuItem("Easy");
        JMenuItem l2 = new JMenuItem("Average");
        JMenuItem l3 = new JMenuItem("Hard");           
        f.setJMenuBar(mb);    
        mb.add(opt);
        mb.add(sd);         
        opt.add(ng);
        opt.add(ex);            
        sd.add(l1);
        sd.add(l2);
        sd.add(l3);

        class exit implements ActionListener{

            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        }

        class newGame implements ActionListener{

            public void actionPerformed(ActionEvent e) {
                x = 1;
            }
        }           
        ng.addActionListener(new newGame());
        ex.addActionListener(new exit());
    }       
}

我打算做的是 x 的值为 1,所以我可以在另一个类中使用它来继续,每当 x 获得 1 的值时,就会出现一个新面板。

4

1 回答 1

2

跳出静态世界,创建一个真正的 OOP 类,一个带有“状态”的类——带有实例字段。您可以从 actionPerformed 中设置实例字段,从而解决您的问题。

您的公共静态主要方法应该仅用于创建您的 GUI 对象并将它们设置为运行,仅此而已。


编辑
您在评论中说,

你到底什么意思?我只是一个新手,我还没有完全理解java中的每一个元素。

抱歉,我的最后一个回答有点匆忙,因为我的午餐时间快结束了,我不得不回去工作。目前,您的程序只不过是一个静态 main 方法,所有东西都试图硬塞进这个方法中。如果您正在创建最基本的控制台程序,例如向用户询问 2 个数字,然后将数字相加并返回答案,那么这会很好,但您不再尝试这样做。相反,您正在尝试创建一个 Swing GUI 程序,如果用户以事件驱动的方式与之交互,您希望更改其状态,换句话说,您希望它在用户按下按钮或选择时更改状态菜单项。

由于您的需求和要求变得越来越复杂,您的程序结构将需要更改以反映这一点。这是您这样做的绝对要求吗?不——称为图灵等效的东西告诉我们可以在单个静态主方法中编写可以想象的最复杂的程序,但是由于复杂性增加,程序将变得非常难以理解并且几乎无法调试。

我特别推荐的是你创建一个或多个行为良好的面向对象类,具有非静态变量和非静态方法的类,并使用它们来构建你的 GUI 及其模型(GUI 程序应该使用的非 GUI 核心)有)。同样,主要方法应该很短,非常短,并且应该只涉及创建上述类和设置 GUI 可见,仅此而已。

你要做的是学习Java的基本概念,特别是如何创建Java类。Java 教程可以帮助您解决这个问题。


编辑 2
您的程序还有一个主要问题是您正遭受新手谬误的困扰,即通过更改变量的状态,这将神奇地改变以前使用该变量的某些内容。

例如,在您的程序中,您使用静态变量 x 来保存值 0 或 1,然后您尝试根据该变量的状态将组件添加到 JFrame:

// Code Block (A)
if(x == 0){
   f.add(a);
}           
if(x == 1){
   f.add(fs);
} 

请注意,当调用此代码时,程序刚刚开始运行,因此x默认值为 0,因此a将添加到您的 JFrame。

稍后在 ActionListener 中将 x 的值更改为 1:

// Code Block (B)
class newGame implements ActionListener {
   public void actionPerformed(ActionEvent e) {
      x = 1;
    }
}  

但是您需要了解,在代码块 (B) 中更改 x 的值不会影响 JFrame 显示的内容,因为代码块 (A) 已经运行并完成,并且永远不会在此程序中再次运行。

解决方案是从 (B) 内重新运行代码块 (A),这是我不推荐的,或者更好的是,使用 CardLayout 从卡块 (B) 内交换 JFrame 显示的 JPanel。

您可以在CardLayout 教程中了解有关 CardLayout 的更多信息。另外,请在此站点上使用代码查看我以前的答案,您可以在此处找到:

于 2013-10-17T17:06:45.147 回答