在空的无限循环中检查选项与在无限循环中进行检查 [英] Checking options in empty Infinite loop vs dosomething infite loop
问题描述
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
.
谢谢
推荐答案
您的问题是:
- 您称紧"为循环,它占用CPU并阻止其他代码运行.
System.out.println(...)
语句添加的代码会减慢该循环的速度,从而使CPU从紧密循环的棘爪中释放出来,从而允许其他线程运行,这就是您所提出的问题. - 话又说回来,您的编码方法也不好,因为您使用了
while (true)
循环来代替对事件的响应,而这正是Swing GUI的编码方式. - 您指出,这样做的原因是while循环中的一部分代码调用了
Thread.sleep
,并且如果该代码在Swing事件线程上(例如在ActionListener中)被调用,则会阻塞该事件线程,冻结您的GUI-完全正确. - 但是您的解决方案是错误的.正确的解决方案不是在main方法的
while (true)
循环中调用此方法,而是从后台线程(例如在doInBackground()方法中)调用 Thread.sleep
://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html"rel =" nofollow noreferrer> SwingWorker (链接到本教程),或者更好的方法是使用 Swing Timer (同样,链接指向教程)代替了.这将使您的代码暂停某些代码而不会阻塞Swing事件线程. - 如果需要显示对话框(子)窗口,另一种选择是使用模式JDialog来显示窗口,同时阻止与主GUI窗口的交互,直到对话框窗口不再可见为止.
- 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 theThread.sleep
from a background thread, such as within thedoInBackground()
method of a SwingWorker (link is to tutorial), or better still, to use a Swing Timer (again, link is to tutorial) in place of theThread.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屋!