所以这是我的代码:
System.out.println("System Exiting...");
long current = System.currentTimeMillis();
long disired = current + 4000;
boolean done = false;
while (!done)
{
current = System.currentTimeMillis();
if (current == disired)
{
done = true;
System.exit(0);
}
}
我的问题是print语句没有运行,它确实运行了,但它与exit语句同时运行,所以你看不到它
[编辑]好的,所以我只是在自己的文件中运行此代码(没有其他内容),它可以正常工作,打印“系统退出...”等待4秒,然后代码退出。 所以它必须与我在事件监听器中有这个代码的事实有关
答案 0 :(得分:2)
你的if条件太多限制太多,因为你的代码几乎永远不会让时间完全相等,但所需的更改非常简单:
更改
// hitting this exactly is like finding the proverbial needle
// in the haystack -- almost impossible to do.
if (current == disired)
到
// this is guaranteed to work.
// note if this is in English, you'll want to change disired to desired
if (current >= disired)
说完这个之后,你的while (true)
循环不是一件好事,因为它会不必要地将CPU与空循环捆绑在一起。而是使用某种类型的事件通知或回调系统,如ChangeListener或PropertyChangeListener或Timer。
你说:
是的,它在swing GUI中
您在Swing事件线程上调用了一个长while (true)
代码块,导致此线程无效。由于事件线程负责所有Swing图形和用户交互,因此这有效地冻结了GUI,直到while循环完成。解决方案很明显:1)使用Swing Timer进行延迟,而不是使用真正的循环(这是我在原始答案中提到的回调机制),以及2)将来,请给我们这个重要的原始问题的相关信息,因为它改变了问题的整个性质。
e.g。
// caveat: code not tested
System.out.println("System Exiting...");
int delay = 4 * 1000;
new Timer(delay, new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
System.out. println("Exited");
System.exit(0);
}
}).start();
如,
import java.awt.Component;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class TestDelayedExit extends JPanel {
private static final int GAP = 100;
public TestDelayedExit() {
add(new JButton(new DisposeAction("Exit", KeyEvent.VK_X)));
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
}
private static void createAndShowGui() {
JFrame frame = new JFrame("TestDelayedExit");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new TestDelayedExit());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
private class DisposeAction extends AbstractAction {
private int count = 4;
private Timer timer;
public DisposeAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic); // for alt-key combo
}
@Override
public void actionPerformed(ActionEvent e) {
if (timer != null && timer.isRunning()) {
return;
}
final Component c = (Component) e.getSource();
int timerDelay = 1000;
putValue(NAME, String.valueOf(count));
timer = new Timer(timerDelay, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (count == 0) {
((Timer) e.getSource()).stop();
// this will not work for JMenuItems, and for that
// you would need to get the pop up window's parent component
Window win = SwingUtilities.getWindowAncestor(c);
if (win != null) {
win.dispose();
}
} else {
count--;
putValue(NAME, String.valueOf(count));
}
}
});
timer.start();
}
}
}