-1

我正在网上写一个回合制游戏。我尝试弹出一个应该在前面的窗口,直到输入流准备好。我像这样创建了 smth,但它似乎不起作用。

class CustomBlockerDialog extends JDialog {
/**
 * 
 */
private static final long serialVersionUID = 1L;

public CustomBlockerDialog(Frame owner, String text) {
    super(owner, true);
    setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
    setSize(300, 100); // Adjust if needed
    setTitle("");
    add(new JLabel(text, SwingConstants.CENTER));
} 
}




final CustomBlockerDialog block = new CustomBlockerDialog(null, "Not your turn");

SwingUtilities.invokeLater(new Runnable() {//A

    @Override
    public void run() {
        System.out.println("show");
        block.setVisible(true);
    }
});


boolean one_write_only = true;
while(in.ready()){ /* C*/ 
    if(one_write_only){
        System.out.println("waiting server");
        one_write_only = false;
    }
};

System.out.println("suppose to hide");

SwingUtilities.invokeLater(new Runnable() {//B

    @Override
    public void run() {
    System.out.println("hide");
    block.setVisible(false);
    }
});

看起来“A”和“B”是在“C”之后执行的,我不知道为什么。

4

2 回答 2

2

您的问题一定是由于在 Swing 事件线程上而不是在后台线程中调用了“C”,因为听起来“C”正在阻止事件线程运行“A”。解决方案:确保在 Swing 事件线程上没有调用“C”。此外,如果是这种情况,并且可以通过运行该SwingUtilities.isEventDispatchThread()方法进行测试,那么您不需要所有其他可运行文件。

// note that this all must be called on the Swing event thread:
final CustomBlockerDialog block = new CustomBlockerDialog(null, "Not your turn");

System.out.println("show");
// block.setVisible(true);  // !! no this will freeze!

final SwingWorker<Void, Void> worker = new SwingWorker<>() {
   public void doInBackground() throws Exception {
      boolean one_write_only = true;
      while(in.ready()){ /* C*/ 
         if(one_write_only){
            System.out.println("waiting server");
            one_write_only = false;
         }
      }
   }
}

worker.addPropertyChangeListener(new PropertyChangeListener() {
   public void propertyChanged(PropertyChangeEvent pcEvt) {
      if (pcEvt.getNewValue() == SwingWorker.StateValue.DONE) {
         System.out.println("hide");
         block.setVisible(false);

         // call worker's get() method here and catch exceptions
      }
   }
});

worker.execute();

// moved to down here since the dialog is modal!!!
block.setVisible(true);

警告:代码未经编译或测试。袖带打字时可能存在错误。

于 2014-07-23T22:36:44.763 回答
0

Thanks to Hovercraft Full Of Eels, I created a little different solution which works in my case:

final SwingWorker<Object,Object> worker2 = new SwingWorker<Object, Object>() {
        public Object doInBackground() throws Exception {
          boolean one_write_only = true;
            while(!in.ready()){ /* C*/ 
              if(one_write_only){
                System.out.println("waiting server");
                one_write_only = false;
              }
            }
            return one_write_only;
        }

        protected void done() {
            try {
                block.setVisible(false);
            } catch (Exception ignore) {}
        }

};
worker2.execute();
block.setVisible(true);
于 2014-08-07T06:56:18.650 回答