Java - 为什么我的print语句没有运行

时间:2015-07-22 19:56:03

标签: java swing

所以这是我的代码:

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秒,然后代码退出。 所以它必须与我在事件监听器中有这个代码的事实有关

1 个答案:

答案 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();
      }
   }       
}