setvisible method in java swing hangs system

Adith picture Adith · Dec 10, 2010 · Viewed 13.1k times · Source

I have banking gui application that I am currently working on and there seems to be a problem with the setvisible method for my jdialog. After the user has withdrawn a valid amount I pop up a simple dialog that says "transaction in progress". In my dobackground method i keep polling to check if the transaction has been received. I tried using swingworker and I don't understand why it's not working. If i remove the setvisible call it works fine, so why does setvisible cause the system to hang? Here is the code that is inside my 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();

Answer

Jiri Patera picture Jiri Patera · Dec 10, 2010

First, it is recommended to do all the GUI updates in the Swing Event-Dispatch thread, i.e. using the SwingUtilites class.

Second, your JDialog is modal and so blocks the thread in which the setVisible(true) method is called (in your case the Main thread, in the following case the Swing Event-Dispatch Thread).

I do not say the following code is perfect, but it should put you on the track...


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);
  }
});

Hope this helps.