Java 用户创建的jpanel getter不更新

Java 用户创建的jpanel getter不更新,java,swing,Java,Swing,我想用JFrame做一个扫雷游戏。我在扩展了JPanel类的类中设置了菜单和游戏。问题是,当我试图获取按下按钮和使用getter按下的内容时,主类只获取变量的初始值。我需要做什么来解决这个问题 菜单课 package mines; import javax.swing.*; import java.awt.*; import java.awt.event.*; /** * @author joshua */ public class Menu extends JPanel { p

我想用JFrame做一个扫雷游戏。我在扩展了JPanel类的类中设置了菜单和游戏。问题是,当我试图获取按下按钮和使用getter按下的内容时,主类只获取变量的初始值。我需要做什么来解决这个问题

菜单课

package mines;

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

/**
 * @author joshua
 */
public class Menu extends JPanel
{
    private JButton m1, m2, m3;
    private int width, height, widthOne, heightOne, choice;

    public Menu()
    {
        choice = 0;
        widthOne = 250;
        heightOne = 150;
        width = widthOne * 2;
        height = heightOne * 2;
        m1 = new JButton("Easy: 8X8 10 mines");
        m2 = new JButton("Medium: 16X16 40 mines");
        m3 = new JButton("Hard: 32X16 99 mines");
        m1.setPreferredSize(new Dimension(widthOne, heightOne));
        m2.setPreferredSize(new Dimension(widthOne, heightOne));
        m3.setPreferredSize(new Dimension(widthOne, heightOne));
        setLayout(new GridLayout(2, 2));
        add(m1);
        add(m2);
        add(m3);

        m1.addActionListener(new ActionListener(){
            @Override 
            public void actionPerformed(ActionEvent e)
            {
                choice = 1;
            }
        }); 
        m2.addActionListener(new ActionListener(){
            @Override 
            public void actionPerformed(ActionEvent e)
            {
                choice = 2;
            }
        }); 
        m3.addActionListener(new ActionListener(){
            @Override 
            public void actionPerformed(ActionEvent e)
            {
                choice = 3;
            }
        }); 
    }

    @Override
    public Dimension getPreferredSize()
    {
        return new Dimension(width, height);
    }

    public int getChoice()
    {
        return choice;
    }

    public void resetChoice()
    {
        choice = 0;
    }
}
主课

package mines;

import javax.swing.*;

public class Main
{
    public static void main(String[] args)
    {
        new Main().go();
    }

    public void go()
    {
        JFrame frame = new JFrame();
        Grid grid = new Grid(1);
        Menu menu = new Menu();
        frame.add(menu);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);
        boolean done = false;
        boolean menuBool = true;

        while(!done)
        {
            if(menuBool)
            {
                if(menu.getChoice() != 0)
                {
                    System.out.println("" + menu.getChoice());
                    grid = new Grid(menu.getChoice());
                    menu.resetChoice();
                    frame.add(grid);
                }
            }
            else
            {
                if(grid.atEnd())
                {
                    frame.add(menu);
                }
            }
        }
    }
}

您使用的游戏循环无效:

  while (!done) {
     if (menuBool) {
        if (menu.getChoice() != 0) {
           System.out.println("" + menu.getChoice());
           grid = new Grid(menu.getChoice());
           menu.resetChoice();
           frame.add(grid);
        }
     } else {
        if (grid.atEnd()) {
           frame.add(menu);
        }
     }
  }
这不是事件驱动的Swing程序的工作方式。相反,要对事件、按钮按下、菜单按下或状态更改做出反应,而不是在(true)循环永久运行并有可能阻止Swing事件线程时做出反应

总之,摆脱这个循环,当事件被触发时,用监听器(比如添加到菜单项或按钮中的ActionListeners)对事件做出反应

例如,Swing支持PrimeTyrelististor及其内置的支持,我建议您考虑使用此属性。它可能看起来像:

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.*;

public class Main {
   public static void main(String[] args) {
      new Main().go();
   }

   public void go() {
      final JFrame frame = new JFrame();
      final Grid grid = new Grid(1);
      final Menu menu = new Menu();

      // .... etc...
      frame.pack();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setVisible(true);
      frame.setLocationRelativeTo(null);
      boolean done = true; //!! was false
      boolean menuBool = true;

//      while (!done) {
//         // get rid of this 
//      }

      // instead do this -- add a property change listener to your menu JPanel
      menu.addPropertyChangeListener(new PropertyChangeListener() {

         @Override
         public void propertyChange(PropertyChangeEvent pcEvt) {
            if (Menu.CHOICE.equals(pcEvt.getPropertyName())) {
               System.out.println("Choice is: " + menu.getChoice());
            }
         }
      });
   }
}

class Menu extends JPanel {
   public static final String CHOICE = "choice";

   // each variable should get its own line
   private JButton m1
   private JButton m2;
   private JButton m3;
   private int width; 
   private int height;
   private int widthOne;
   private int heightOne;

   private int choice;  // declare each variable separately

   public Menu() {
      setChoice(0);
      widthOne = 250;

      // .... etc

      m1.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            setChoice(1);
         }
      });
      m2.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            setChoice(2);
         }
      });
      m3.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            setChoice(3);
         }
      });
   }
   //...
}
另一方面,我会避免在选择中使用幻数,而是使用枚举。我也会使用一个JComboBox而不是一堆按钮,因为这些选项是互斥的