有没有办法循环检查 Frame.state 的状态,w/out 循环检查中的代码?

Is there a way I can loop the checking of the state of Frame.state, w/out looping the code in the check?

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

我已经检查并将其放入框架中按钮 "next" 的 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();
        }

    }

下面的代码在另一个 class 中,在构造函数下完全 使用所有组件创建框架



//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 成为 "bound" 字段,并允许其他代码将 属性 更改侦听器附加到对象,以便 GUI 对象可以在状态更改时通知任何和所有侦听器。

所以:

  • 使状态字段成为您的框架的 私有 实例字段 class。
  • 给class一个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);
  • 来通知任何附加的侦听器状态已更改

例如:

Main class 创建 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 class 在下面。请注意,状态字段已重新命名为 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 的模型 class,因为我没有实际代码。它将输出调用了什么方法:

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);
    }

}