java - 有没有办法可以循环检查 Frame.state 的状态,而不循环检查中的代码?

标签 java swing jbutton

我希望能够连续检查 Frame.state 的值,而不需要在检查中连续循环代码。我希望能够检查值或检查按下按钮的时间,并相应地重新打印 Jpane 中的值。

我已经进行了检查并将其放入 Frame 中按钮“下一步”的 ActionListener() 中,但除非绝对必要,否则我不想这样做。我尝试将 if 检查放在 while 循环中,结果是根据按钮状态连续重复每个检查中的所有内容,即:第一个检查中的代码“if (Frame.state == 1){ array.setRandom(100);array.print();}"会不断地用随机数重新打印数组,而不是执行一次操作,然后等待再次按下按钮。

我不认为 ArrayObject2d 对于帮助或解决此问题很重要,因此选择将其排除在外,如果需要该代码,请告诉我。

public class MainClass {
public static void main(String[] args) {
        @SuppressWarnings("unused")
        Frame frame = new Frame();
        ArrayObject2d array = new ArrayObject2d(10, 5);

        if (Frame.state == 1) {
            array.setRandom(100);
            array.print();
        } else if (Frame.state == 2) {
            array.setAll(99999);
            array.print();
        } else if (Frame.state == 3) {
            array.numberAll();
            array.print();
        } else if (Frame.state == 4) {
            array.showIndex();
        }

    }

下面的代码位于另一个类中,在构造函数下,该类完全 创建包含所有组件的框架



//assume all imports have been written
public class Frame extends JFrame {
    public Frame() {
        super();
        setDefaultCloseOperation(3);
        setBackground(new Color(245, 252, 255));
        setResizable(false);
        setSize(1280, 720);
        setVisible(true);
        setLocationRelativeTo(null);
        JButton next = new JButton();

        next.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (state > 3) {
                    state = 1;
                } else {
                    state++;
                }       
            }
        });
    }   
}

我希望检查能够连续运行,但检查中的代码却连续运行。

最佳答案

不,不要循环并持续轮询你的对象的状态,因为这是非常低效的。相反,你应该制作 state一个“绑定(bind)”字段,并允许其他代码将属性更改监听器附加到该对象,以便 GUI 对象可以在状态更改时通知任何和所有监听器。

所以:

  • 将状态字段设为 Frame 类的私有(private)实例字段。
  • 给全类同学一个 public static final String STATE = "state";常数
  • 为状态创建 getter 和 setter 方法,public int getState() , public void setState(int state)
  • setState(...)内方法创建两个局部 int 变量 oldValue 和 newValue,并将各自的状态值(参数和 this 值)传递给这些变量。
  • 您的框架支持属性更改。因此,通过调用 firePropertyChange(STATE, oldValue, newValue); 使用它来通知任何附加的监听器状态已更改。

例如:

创建 ArrayObject2d 和 Frame 对象的主类(此处命名为 Frame2 以避免与 java.awt.Frame 混淆)

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.*;
import javax.swing.*;

public class MainClass {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            final Frame2 frame = new Frame2();
            frame.setVisible(true);
            final ArrayObject2d array = new ArrayObject2d(10, 5);

            frame.addPropertyChangeListener(Frame2.FRAME_STATE, propChngEvent -> {
                if (frame.getFrameState() == 1) {
                    array.setRandom(100);
                    array.print();
                } else if (frame.getFrameState() == 2) {
                    array.setAll(99999);
                    array.print();
                } else if (frame.getFrameState() == 3) {
                    array.numberAll();
                    array.print();
                } else if (frame.getFrameState() == 4) {
                    array.showIndex();
                }
            });
        });
    }
}

Frame2 类如下。请注意,状态字段已重命名为frameState,以避免与同名的内部Swing 字段混淆。

@SuppressWarnings("serial")
class Frame2 extends JFrame {
    public static final String FRAME_STATE = "frame state";
    private static final Dimension PANEL_SIZE = new Dimension(640, 400);
    private JLabel frameStateLabel = new JLabel("1");
    private int frameState = 1;    

    public Frame2() {
        super();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        JButton next = new JButton("Next");
        JPanel panel = new JPanel(new GridBagLayout());
        panel.setPreferredSize(PANEL_SIZE);
        panel.setBackground(new Color(245, 252, 255));
        panel.add(next);
        panel.add(Box.createHorizontalStrut(15));
        panel.add(new JLabel("Frame State: "));
        panel.add(frameStateLabel);

        next.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (frameState > 3) {
                    setFrameState(1);  // ***Always*** change frameState by the setter method
                } else {
                    setFrameState(frameState + 1);  // ** Ditto **
                }       
            }
        });

        add(panel);
        pack();
        setResizable(false);
        setLocationRelativeTo(null);
    }   

    public int getFrameState() {
        return frameState;
    }

    public void setFrameState(int frameState) {
        int oldValue = this.frameState;
        int newValue = frameState;
        this.frameState = frameState;
        firePropertyChange(FRAME_STATE, oldValue, newValue);
        frameStateLabel.setText("" + frameState);
    }
}

这是您的 ArrayObject2d 类的模拟类,因为我没有实际的代码。它将输出调用了什么方法:

class ArrayObject2d  {

    public ArrayObject2d(int rows, int columns) {
        // TODO finish
    }

    public void showIndex() {
        System.out.println("show index");
    }

    public void numberAll() {
        System.out.println("number all");
    }

    public void setAll(int i) {
        System.out.println("set all: " + i);
    }

    public void print() {
        System.out.println("print");
    }

    public void setRandom(int i) {
        System.out.println("set random: " + i);
    }

}

关于java - 有没有办法可以循环检查 Frame.state 的状态,而不循环检查中的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58469483/

相关文章:

java - 如何在 java 中为 Selenium webdriver 编写我自己的自定义定位器?

java - 如何使用 javascript 打印选择标签的下拉值?

java - 如何使用动态消息显示忙碌/工作/加载对话框

java - Swing 应用程序中的 JTable 设计指南

java - 如何操纵颜色值?

java - 如何为可变数量的按钮创建操作?

java - 如何让某些按钮执行不同的操作? Java Swing JButton

java - 禁用 Spring Boot 参数解析

java - 当达到阈值时,LinkedHashMap 是否也会treeifyBin/treefybucket?

java - JButton 不显示