【问题标题】:GUI program stuckGUI程序卡住了
【发布时间】:2020-04-22 05:13:41
【问题描述】:

所以我正在设计一个 GUI(GUI 本身位于一个名为 mainGUI 的单独类中)。 GUI 有 2 个按钮,每个按钮将 main.subProgramNumber 设置为 1 或 2(取决于按钮),将 main.safeToContinue 设置为 false,然后使用 dispose() 处理 GUI。但是当我单击 GUI 中的按钮时,GUI 会关闭,然后什么也没有发生。我已经使用了调试器,奇怪的是,使用调试工具的代码表现得不同。使用调试工具时,我单击按钮后 GUI 保持打开状态并永久加载。欢迎任何帮助。

 genData main = new genData();
 main.safeToContinue = false;
 main.running = true;

 while(main.running == true){

        //trigger GUI    
        mainGUI MG = new mainGUI();
        MG.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        MG.setSize(250, 275);
        MG.setVisible(true);

        //wait tell the GUI says its safe to continue
        while(main.safeToContinue == false){
            try {
                TimeUnit.MILLISECONDS.sleep(1);
            } catch (InterruptedException ex) {
                Logger.getLogger(mainGUI.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        //check if main.subProgram is 1
        if(main.subProgramNumber == 1){
            System.out.println("subProgram = 1");
        }

        //check if main.subProgram is 2
        if(main.subProgramNumber == 2){
           System.out.println("subProgram = 2");
        }


}

下面是我的 GUI 代码的简化版本。 (对不起,它的代码很多,但我不知道如何使它比这更简单......)

public class mainGUI extends JFrame{

    public JButton add;
    public JButton remove;
    public JButton edit;
    public JButton report;
    public JButton close;

    public mainGUI(){
        super("Guest Manager");
        setLayout(new FlowLayout());

        add = new JButton("Add a Guest");
        remove = new JButton("Remove a Guest");
        close = new JButton("Close");

        add(add);
        add(remove);
        add(close);

        addGuest ag = new addGuest();
        add.addActionListener(ag);

        removeGuest rg = new removeGuest();
        remove.addActionListener(rg);

        Close c = new Close();
        close.addActionListener(c);

    }

    private class addGuest implements ActionListener{

        public void actionPerformed(ActionEvent e){
            genData main = new genData();
            main.subProgramNumber = 1; 
            main.safeToContinue = true;
            dispose();
        }
    }

    private class removeGuest implements ActionListener{

        public void actionPerformed(ActionEvent e){
            genData main = new genData();
            main.subProgramNumber = 2;  
            main.safeToContinue = true;
            dispose();
        }
    }

    private class Close implements ActionListener{

        public void actionPerformed(ActionEvent e){

            genData main = new genData();
            main.safeToContinue = true;
            dispose();
        }
    }
}

下面是我使用过(并且正在使用上面)的技术的一个请求的、可行的示例

主程序(点击开始时调用):

 varData MC = new varData();
        do{

            MC.safeToContinue = false;

            //open and run the main GUI
            ExerciseMainGUI EM = new ExerciseMainGUI();
            EM.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            EM.setSize(250, 275);
            EM.setVisible(true);

            //System.out.println("debug 1");

            //wait tell the sub program closes to continue
            do{
                hutLib.pause(1);
            }while(MC.safeToContinue==false);

            hutLib.pause(1);

        }while(MC.running == true);

我在上面调用的 GUI:

public class ExerciseMainGUI extends JFrame{

    private JButton bottlePacker;
    private JButton triangleTester;
    private JButton primeChecker;
    private JButton averager;
    private JButton rollTheDice;
    private JButton close;

    public ExerciseMainGUI(){
        super("Java Exercises");
        setLayout(new FlowLayout());

        bottlePacker = new JButton("   Bottle Packer   ");
        triangleTester = new JButton("  Triangle Tester  ");
        primeChecker = new JButton("   Prime Checker   ");
        averager = new JButton ("Averager (offline)");
        rollTheDice = new JButton("Roll the Dice (offline)");
        close = new JButton("       Close       ");

        add(bottlePacker);
        add(triangleTester);
        add(primeChecker);
        add(averager);
        add(rollTheDice);
        add(close);

        bottlePacker bp = new bottlePacker();
        bottlePacker.addActionListener(bp);

        triangleTester tt = new triangleTester();
        triangleTester.addActionListener(tt);

        primeChecker pc = new primeChecker();
        primeChecker.addActionListener(pc);

        averager a = new averager();
        averager.addActionListener(a);

        rollTheDice rtd = new rollTheDice();
        rollTheDice.addActionListener(rtd);

        close c = new close();
        close.addActionListener(c);
    }

    private class bottlePacker implements ActionListener{

        public void actionPerformed(ActionEvent e){
            dispose();
            //runs a subprogram

        }
    }

    private class triangleTester implements ActionListener{

        public void actionPerformed(ActionEvent e){
            dispose();
            //runs a subprogram
        }
    }

    private class primeChecker implements ActionListener{

        public void actionPerformed(ActionEvent e){
            dispose();
            //runs a subprogram

        }
    }

    private class averager implements ActionListener{

        public void actionPerformed(ActionEvent e){
            dispose();
            //runs a subprogram

        }
    }

    private class rollTheDice implements ActionListener{

        public void actionPerformed(ActionEvent e){
            dispose();
            //runs a subprogram

            //JOptionPane.showMessageDialog(null, "NOTE: Roll the Dice will run in the command line.");

            //oldCodeStorage.rollTheDice.rollTheDice();

        }
    }

    private class close implements ActionListener{

        public void actionPerformed(ActionEvent e){
            dispose();
            varData MC = new varData();
            MC.running = false;
            MC.safeToContinue = true;

        }
    }
}

注意:每个子程序完成后会运行以下代码:

varData MC = new varData();
MC.safeToContinue = true;

我知道这很多,但我被明确要求发布。

【问题讨论】:

标签: java swing user-interface


【解决方案1】:

您在这里误用了 Swing 组件。您应该展示您的应用并通过事件侦听器对事件做出反应。这不需要循环等。

例如

public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setLayout(new GridLayout(1, 2));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        JButton b1 = new JButton("Action 1");
        JButton b2 = new JButton("Action 2");
        b1.addActionListener((e)->System.out.println("Action 1 taken")); // your subcommand 1 
        b2.addActionListener((e)->System.out.println("Action 2 taken")); //your subcomand 2
        frame.add(b1);
        frame.add(b2);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

还记得不要在 actionListeners 中调用昂贵的操作,而是将这些操作委托给后台作业 - 否则它将冻结您的 UI。在 Swing 中编写 UI 应用程序并不像您想象的那么简单,并且需要少量的基础知识(关于 Swing 本身)。尝试一下也不错,但是如果不熟悉 Swing 的基础知识,你会遇到无数次的问题 - 相信我,我去过那里。

您提到您是线程新手 - Swing 本身是单线程的 - 但它涉及线程来执行各种会减慢应用程序或使其无响应的任务。

我强烈建议你开始挖掘例如 Oracle 的 Swing 教程。

https://docs.oracle.com/javase/tutorial/uiswing/index.html

【讨论】:

  • 我将编辑我的原始帖子以包含我的 GUI 代码。我想我已经以一种更 lvl1-java-student 的方式这样做了。
  • @hutonahill level 1 java 与否,您仍然可以使用 java 命名约定。基因数据与基因数据。此外,一个 lvl 1 的 java 学生应该了解静态变量和实例变量之间的区别。
  • 不在我的 java 类中。我们几乎已经完成了这个学期,并且完全触及了静态变量和静态变量。
【解决方案2】:

您根本没有修改main.safeToContinue。这就是为什么它卡在无限循环中的原因

【讨论】:

  • main.safeToContinue 正在被 GUI 修改,正如我在代码上方的文本中所说的那样。我已经在我的其他几个项目中测试并使用了它。它有效。
【解决方案3】:

假设我们有一堂课。

class GenData{
    static int x = 0;
    int y = 1;
}

现在我有该对象的两个实例

GenData a = new GenData();
GenData b = new GenData();

a.x = 5;
a.y = 10;

System.out.println( b.x + ", " + b.y );

你期望输出是什么?

b 有它自己的实例变量。所以我希望输出是。

5、1

在您的代码中,您调用new genData() 创建一个新的类实例。如果您的字段不是静态的,那么它将不会与您正在检查的 genData 版本共享。

还请使用 java 命名约定。 GenData 更适合类名。

如何解决。

public class mainGUI extends JFrame{

    public JButton add;
    public JButton remove;
    public JButton edit;
    public JButton report;
    public JButton close;
    genData main;
    public mainGUI(genData main){
        this.main = main;
        //don't change the rest.
    }

    private class addGuest implements ActionListener{

        public void actionPerformed(ActionEvent e){
            //genData main = new genData();
            //don't call new here, use the reference you 
            //received.
        }
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-24
    • 2023-03-07
    • 1970-01-01
    • 2021-02-25
    • 2017-03-15
    • 2021-12-05
    相关资源
    最近更新 更多