java swing中的setvisible方法挂起系统

时间:2010-12-10 21:04:03

标签: java swing visibility swingworker

我有正在处理的银行gui应用程序,我的jdialog的setvisible方法似乎有问题。在用户撤回有效金额后,我弹出一个简单的对话框,其中显示“正在进行交易”。在我的dobackground方法中,我继续轮询以检查是否已收到交易。我尝试使用swingworker,我不明白为什么它不起作用。如果我删除setvisible调用它工作正常,那么为什么setvisible导致系统挂起?这是我的jbutton mouselistener中的代码:

SwingWorker<String,Integer> worker = new SwingWorker<String,Integer>(){

  JDialog waitForTrans = new JDialog((JFrame)null,true);
  public String doInBackground() throws Exception {
     waitForTrans.add(new JLabel("Updating balance in system. Please Wait..."));
     waitForTrans.setMinimumSize(new Dimension(300,100));
     waitForTrans.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
     waitForTrans.setVisible(true);
     Bank.getInstance().sendTransaction(currentPin,"-"+withdraw);
     while(!Bank.getInstance().hasCompletedTransaction){

     }
     return null;

  }

  public void done(){
   try {
        this.get();
       } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {

        e.printStackTrace();
    }
    waitForTrans.setVisible(false);
    newField.setText(String.valueOf(Bank.getInstance().getAccountList().get(currentPin).getBalance()));
  }

 };
 worker.execute();

4 个答案:

答案 0 :(得分:14)

首先,建议在Swing Event-Dispatch线程中进行所有GUI更新,即使用SwingUtilites类。

其次,你的JDialog是模态的,因此会阻塞调用setVisible(true)方法的线程(在你的情况下是主线程,在下面的例子中是Swing Event-Dispatch Thread)。 / p>

我没有说下面的代码是完美的,但它应该让你走上正轨......


final JDialog waitForTrans = new JDialog((JFrame) null, true);

SwingWorker worker = new SwingWorker() {

  public String doInBackground() throws Exception {
    Thread.sleep(5000);
    return null;
  }

  public void done() {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        waitForTrans.setVisible(false);
        waitForTrans.dispose();
      }
    });
  }

};

worker.execute();
SwingUtilities.invokeLater(new Runnable() {
  public void run() {
    waitForTrans.add(new JLabel("Please Wait..."));
    waitForTrans.setMinimumSize(new Dimension(300, 100));
    waitForTrans.setVisible(true);
  }
});

希望这有帮助。

答案 1 :(得分:5)

您正在显示模式对话框,因此在对话框关闭之前,后台代码无法执行。

在setVisible之后添加一个System.out.println(...)语句,你会发现它永远不会执行。

答案 2 :(得分:1)

setVisible是一种影响GUI的方法,会导致显示某些内容(对于像你这样的模态对话框,会阻止对话框关闭)。除了Swing事件调度线程之外,它(除了修改可见UI的所有其他内容)应该从不调用。您是从doInBackground SwingWorker方法调用它,它在后台线程上运行。

要解决此问题,您需要在waitForClose上调用final之前将execute对话框设为SwingWorker变量,然后调用{{1}在启动worker之后立即

setVisible

您需要按此顺序执行此操作,否则模态对话框将阻止您启动工作程序。

答案 3 :(得分:0)

camickr为您提供正确的答案。我想补充一点,你可能修改事件调度线程之外的用户界面(正如你在#doInBackground中所做的那样),Swing是单线程的,因此违反了这条规则可能会导致UI中出现非常棘手的错误和奇怪的事情。