有没有一种方法可以循环检查Frame.state的状态,而不会循环检查中的代码?

问题描述 投票:0回答:1

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

我已经进行了检查,并将其放在Frame中按钮“ 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();
        }

    }

下面的代码在另一个类中,在完全创建具有所有组件的框架



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

我希望检查可以连续运行,但是检查中的代码却连续运行。

java swing jbutton
1个回答
2
投票

否,请不要循环并持续poll对象的状态,因为这效率很低。而是,应将state设置为“绑定”字段,并允许其他代码将属性更改侦听器附加到对象,以便GUI对象可以在状态更改时通知任何和所有侦听器。

所以:

  • 将状态字段设为Frame类的private实例字段。
  • 给类一个public static final String STATE = "state";常量
  • 为状态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);
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.