Java 用户创建的jpanel getter不更新
我想用JFrame做一个扫雷游戏。我在扩展了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
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而不是一堆按钮,因为这些选项是互斥的