ProgressMonitor, JDialog, JFrame - wont draw contents

ethrbunny
ethrbunny used Ask the Experts™
on
Im trying to implement a frame/dialog/progressmonitor window inside of which a series of potentially lengthy operations will occur. Im missing a step somewhere in the implementation such that the contents of the window isn't being drawn until after all the processing is done!



import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
public class dlg extends javax.swing.JDialog {
   
    /** Creates new form dlg */
    public dlg(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
     //   initComponents();
        JButton button = new JButton("go");
                button.addActionListener(new buttonListener());

        getContentPane().add(button);
    }
   
    private class buttonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {        
            JFrame frame2 = new JFrame() {
            public Dimension getPreferredSize() {
                return new Dimension(200,100);
            }
        };
        frame2.setTitle("Debugging frame");
        frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame2.pack();
        frame2.setVisible(false);  
       
  ProgressMonitor pm = new ProgressMonitor(frame2, "one", "two", 0, 5);
       
                for (int nCount = 0; nCount < 5; nCount++)
                {
                    try
                    {
                        pm.setProgress(nCount);
                        Thread.sleep(1000);
                    }
                    catch(Exception ee)
                    {
                    }
              }        
        }
    }

    /** Closes the dialog */
    private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog
        setVisible(false);
        dispose();
    }//GEN-LAST:event_closeDialog
   
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        new dlg(new javax.swing.JFrame(), true).show();
    }
   
   
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
   
}

Originally I was trying to get my progress JDialog (which would also perform the lengthy operation) to update its own dialog. The process would be initiated in the WindowAdaptor::WindowOpened() function. The process runs just fine - it just doesn't draw any of the dialog contents until its finished. What have I missed?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
I believe the problem is that is the following fact:

   Inside your buttonListener class, you create and moniter the PerformanceMoniter in function actionPerformed.

The reason is that remember even reponse in Java (in this, running your buttonListener.actionPerformed()) is in one thread, which aslo responsible for all the painting/repaiting of all java GUI. Now the thread is stuck in your actionPerformed() function, during this time, naturally no painting is happenning (one thread is only one thread: it can execute one task at a time).

You need more you minitoring code (i.e., for (int nCount = 0; nCount < 5; nCount++) {...} ), like the following example, LongTask.

This page gives a similar example as yours, only difference is the monitering code is another thread: LongTask.

http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html

Your can run the example directly from the page using web start (who is cool I think). You can looked at the source code too: ProgressMonitorDemo.java, LongTask.java and SwingWorker.java (all available on the page).

Good luck

jf

Commented:
Typo: PerformanceMoniter should be ProgressMoniter.

Author

Commented:
So if I want to have a modal JDialog that does some work and shows a progressbar for status.. I need to delegate a new thread to this? (this exclusive of ProgressMonitor)
Should you be charging more for IT Services?

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Commented:
If by "this" you meant your "some work", the answer is yes.

The basical idea is any work that is done inside a event response function (like actiionPerformed() in a listener) in JAVA is done in the thread that also responsible for updating the GUI (and responses other event of course).
So if you want some work be done at the same time the Java GUI gets updated, you need a separated thread to do the work.

(Of course you can still create the ProgressMoniter in the buttonListener since you don't want any GUI update during such a (short) time while the moniter is created)

Author

Commented:
Ahh.. oh my.. ok. So (to be more clear)

1)  I have an ActionListener (button) to start the dialog
2)  The dialog (or JFrame?) knows its running when it gets WindowAdaptor::windowOpened()

     From this point I need to kick off a worker thread which would make calls to update the dialog? Would a modal dialog block any other threads from doing work and sending updates to its UI? Should I instantiate a JFrame instead?
Commented:
Yes, your workflow should work.

I don't know why you need create frame2 in your example (of course unless you need the UI part of the frame2 for application purpose other than just progress moniter).  To create a progress moniter, you don't need an additional frame or dialog: the first parameter to the constructor is the parent of the ProgressMoniter dialog (which I believe is modelless). This is the code from the sun demo (in the link I provided):

  class ButtonListener implements ActionListener {
        public void actionPerformed(ActionEvent evt) {
            progressMonitor = new ProgressMonitor(ProgressMonitorDemo.this,
                                      "Running a Long Task",
                                      "", 0, task.getLengthOfTask());
            progressMonitor.setProgress(0);
            progressMonitor.setMillisToDecideToPopup(2 * ONE_SECOND);

            startButton.setEnabled(false);
            task.go();
            timer.start();
        }
    }

Here  ProgressMonitorDemo.this is the main Dialog (and the only dialog) the demo has.

Author

Commented:
Thanks for your help. Im still on the v steep part of the learning curve. Id been staring at that sample all day but hadn't made the connection to the worker thread.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial