在空的无限循环中检查选项与在无限循环中进行检查 [英] Checking options in empty Infinite loop vs dosomething infite loop

查看:96
本文介绍了在空的无限循环中检查选项与在无限循环中进行检查的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

public static void main(String... s) {
        StartUp obj = new StartUp();
          
        while(true) {
            //System.out.println("Option - " + option);
            if(option == 1) {
                option = 0;
                obj.setVisible(false);
                obj.dispose();
                new Test();
                break;
            }else if(option == 2) {
                option = 0;
                obj.setVisible(false);
                obj.dispose();
                new PWorld.Splash().load();
                break;
            }
        }
    }
    

我需要将System.out.println("Option - " + option);放入while循环中,以使其正常工作,否则程序会在运行StartUp obj = new StartUp()后冻结.

I need to put System.out.println("Option - " + option); inside the while loop for it to work otherwise the programe freezes after running StartUp obj = new StartUp();

option是StartUp类中的静态int,由Actionlistener进行更改 option中的值已由ActionListener更改,但while循环似乎不起作用.

option is a static int inside StartUp class and is changed by a Actionlistener the value in option is changed by ActionListener but while loop doesn't seems to work.

但是,如果我将System.out.println("Option - " + option);放入while循环中,它将起作用. 为什么!

But if I put System.out.println("Option - " + option); inside while loop, it works. WHY!

我正在使用此while循环,因为new PWorld.Splash().load();具有Thread.sleep(),并且

I'm using this while loop because new PWorld.Splash().load(); has Thread.sleep(), and as in this answere new JFrame will not be drawn if called from ActionListener(in UI Thread)which has Thread.

谢谢

推荐答案

您的问题是:

  • You're calling a "tight" loop, one that hogs the CPU and blocks other code from running. The System.out.println(...) statement adds code that slows this loop, releasing the CPU from the jaws of the tight loop, allowing other threads to run, and this is the genesis of your question.
  • Having said that, again, your coding approach is not good, in that you're using a while (true) loop in place of responding to an event, which is how Swing GUI's should be coded.
  • You state that the reason for this is that one bit of code in the while loop calls a Thread.sleep and that this code, if called on the Swing event thread, such as within an ActionListener, will block the event thread, freezing your GUI -- all true.
  • But your solution is wrong. The correct solution is not to call this in a while (true) loop in the main method, but rather to either call the Thread.sleep from a background thread, such as within the doInBackground() method of a SwingWorker (link is to tutorial), or better still, to use a Swing Timer (again, link is to tutorial) in place of the Thread.sleep. This will allow your code to pause some code without blocking the Swing event thread.
  • Another option, if you need to show a dialog (sub) window is to use a modal JDialog to show a window while blocking interaction with the main GUI window, until the dialog window is no longer visible.

再次提供更详细,全面的解决方案,请考虑创建并发布您的最小,可复制示例程序提出您的问题.

For a more detailed and comprehensive solution, again, please consider creating and posting your Minimal, Reproducible Example program with your question.

例如,这是我的最小可重复示例:

For example, here is my Minimal, Reproducible Example:

import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Window;
import javax.swing.*;

public class MinReproExample {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            Startup startup = new Startup();
            startup.showStartUp();

            Option option = startup.getOption();
            if (option == Option.TEST) {
                JOptionPane.showMessageDialog(null, "Test selected", "Selection", JOptionPane.DEFAULT_OPTION);
            } else if (option == Option.PWORLD) {
                PWorld pworld = new PWorld();
                pworld.showSplash();
            }   
        });
    }
}

class Startup {
    private JDialog startupDialog;
    private Option option = null;
    
    public Startup() {
        ButtonGroup buttonGroup = new ButtonGroup();
        JPanel optionsPanel = new JPanel(new GridLayout(1, 0, 10, 10));
        optionsPanel.setBorder(BorderFactory.createTitledBorder("Options"));
        for (final Option op : Option.values()) {
            JRadioButton rBtn = new JRadioButton(op.getText());
            rBtn.setActionCommand(op.getText());
            optionsPanel.add(rBtn);
            buttonGroup.add(rBtn);
            rBtn.addActionListener(e -> {
                option = op;
                Window window = SwingUtilities.getWindowAncestor(optionsPanel);
                window.dispose();
            });
        }
        
        startupDialog = new JDialog(null, "Select Option", ModalityType.APPLICATION_MODAL);
        startupDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        startupDialog.add(optionsPanel);
        startupDialog.pack();
        startupDialog.setLocationRelativeTo(null);
    }
    
    public void showStartUp() {
        if (startupDialog != null) {
            startupDialog.setVisible(true);
        }
    }
    
    public Option getOption() {
        return option;
    }
}

class PWorld {
    private static final Color ROBINS_EGG_BLUE = new Color(0, 204, 204);
    private JDialog pworldSplashDialog;
    private JFrame mainPWorldFrame;

    public PWorld() {
        JLabel splashLabel = new JLabel("Splash Window", SwingConstants.CENTER);
        JPanel splashPanel = new JPanel(new GridBagLayout());
        splashPanel.add(splashLabel);
        splashPanel.setBackground(Color.PINK);
        splashPanel.setPreferredSize(new Dimension(300, 250));

        pworldSplashDialog = new JDialog(null, "Splash", ModalityType.MODELESS);
        pworldSplashDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        pworldSplashDialog.add(splashPanel);
        pworldSplashDialog.pack();
        pworldSplashDialog.setLocationRelativeTo(null);

        JLabel mainLabel = new JLabel("Main GUI Window", SwingConstants.CENTER);
        JPanel mainPanel = new JPanel(new GridBagLayout());
        mainPanel.add(mainLabel);
        mainPanel.setBackground(ROBINS_EGG_BLUE);
        mainPanel.setPreferredSize(new Dimension(500, 350));

        mainPWorldFrame = new JFrame("Main PWorld GUI");
        mainPWorldFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainPWorldFrame.add(mainPanel);
        mainPWorldFrame.pack();
        mainPWorldFrame.setLocationRelativeTo(null);

    }

    public void showSplash() {
        int timerDelay = 2000; // two second delay
        Timer timer = new Timer(timerDelay, e -> {
            if (pworldSplashDialog != null && pworldSplashDialog.isVisible()) {
                pworldSplashDialog.dispose();
                showMainPWorldFrame();
            }
        });
        timer.setRepeats(false);
        timer.start();

        pworldSplashDialog.setVisible(true);
    }

    private void showMainPWorldFrame() {
        mainPWorldFrame.setVisible(true);
    }
}

// options to choose from
enum Option {
    TEST("Test"), PWORLD("PWorld");
    private String text;

    private Option(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }
}

这篇关于在空的无限循环中检查选项与在无限循环中进行检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆