java GUI程序卡住

e0bqpujr  于 2023-01-29  发布在  Java
关注(0)|答案(3)|浏览(130)

我正在设计一个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;

我知道这是很多,但我明确要求张贴它。

xfyts7mz

xfyts7mz1#

你在这里误用了Swing组件。你应该显示你的应用并通过事件监听器对事件做出React。这不需要循环等。
例如

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本身是单线程的-但它涉及到线程化来执行各种任务,这些任务会降低应用程序的速度或使其无法响应。
我强烈建议你开始钻研甲骨文的Swing教程。
https://docs.oracle.com/javase/tutorial/uiswing/index.html

2eafrhcq

2eafrhcq2#

你根本就没有修改main.safeToContinue,这就是为什么它会陷入无限while循环

lf3rwulv

lf3rwulv3#

假设我们有一个类。

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有它自己的示例变量,所以我希望输出是。
五、一
在代码中调用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.
        }
    }

}

相关问题