Panel Display Problem

JDK1.3.1 / Windows 2000

I have two panels. First panel has a button clicking which causes first panel to be removed and second panel to be added in the frame. The moment second panel is added a method on it "start()" is called that shows some progress info. This all I tried using the follwing program. The problem is that the second panel is DISPLAYED only when it is fully processed (by the start() method call). I want the second panel to be displayed immediately once the Start button is clicked on the first panel and see the progress details real time. What is wrong in the following code.

I tried using "SwingUtilities.invokeLater(r)" but!



import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class DisplayProblem extends JFrame implements ActionListener {
    JPanel p1    = new JPanel();
    ProgressPanel p2 = new ProgressPanel();
    JButton startBtn = new JButton("Start");

    DisplayProblem() {
        startBtn.addActionListener(this);
        p1.add(startBtn);
        getContentPane().add(p1, BorderLayout.SOUTH);
    }

    public void actionPerformed(ActionEvent e) {
        getContentPane().remove(p1);
        getContentPane().add(p2);

        p2.start();         // <-------------- NOTE THIS -------------

        /* COMMENT ABOVE LINE AND UNCOMMENT FOLLOWING BLOCK */
        /*
        Runnable start = new Runnable() {
            public void run() {
                p2.start();
            }
        };
        SwingUtilities.invokeLater(start);
        */
    }

    public static void main(String[] args) {
        DisplayProblem f = new DisplayProblem();
        f.setLocation(300, 200);
        f.setSize(400, 100);
        f.setVisible(true);
    }
}

class ProgressPanel extends JPanel {
    JLabel l1 = new JLabel("Doing this work...");
    JLabel l2 = new JLabel("    ");
    JLabel l3 = new JLabel("Doing that work...");
    JLabel l4 = new JLabel("    ");

    ProgressPanel() {
       setLayout(new GridLayout(0, 2, 5, 5));
       add(l1);
       add(l2);
       add(l3);
       add(l4);
    }

    public void start() {
        DELAY();
        l2.setText("DONE!");
        DELAY();
        l4.setText("DONE!");
    }

    private void DELAY() {
        for (int i = 0; i < 1000000000; i++) { i=i; }
    }
}
javaq092999Asked:
Who is Participating?
 
objectsConnect With a Mentor Commented:
> Do I need to run this method in a separate thread?

yes.
0
 
objectsCommented:
1. you should call revalidate() after changing your container hierarchy so everything gets layed out correctly.

2. your call DELAY() from the event dispatch thread, which will block any gui updates. Time consuming tasks should not be performed in the event dispatch thread.
0
 
javaq092999Author Commented:
>>> 2. your call DELAY() from the event dispatch thread, which will block any gui updates. Time consuming tasks should not be performed in the event dispatch thread.

But then how to call a process method (in my case p2.start()) automatically when my panel 2 is up and displayed without any user interaction. Do I need to run this method in a separate thread? or something else.
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

 
objectsCommented:
Swing is single threaded, so if you block it's thread then all gui activity is blocked.
0
 
javaq092999Author Commented:
Right objects! I already tried this and is working fine.

However just to know what it is, I tried SwingUtilities.invokeLater(mythread) and SwingUtilities.invokeAndWait(mythread) but could not get anywhere. invokeAndWait is even cannot be called from within the dispatcher event. Wondering in what situation then the invokeLater is used.

Anyway it is working now for me and I will be accepting your comment as answer soon (just keeping this open for a while).

Thanks
0
 
objectsCommented:
> invokeAndWait is even cannot be called from
> within the dispatcher event.

Doesn't make any sense to call it from the event dispatch thread.

> Wondering in what situation then the invokeLater is used.

If you don't mind exactly when the code is executed, and you want to let the current thread continue it's processing.
0
 
heyhey_Commented:
> Wondering in what situation then the invokeLater is used.

invokeLater is used when you want to execute some code inside the Swing system Thread.

Since almost all Swing components are not Thread safe, you shouldn't call their methods directly from another Threads but use SwingUtilities.invokeLater()
0
 
heyhey_Commented:
> If you don't mind exactly when the code is executed

not exactly :) code will be executed inside Swing event dispatcher Thread with all the pros (you can do anything you want with Swing components) and cons (you cannot/should not execute any long tasks).
0
 
objectsCommented:
Poor grammar on my part :)
What I meant was that you don't want the current thread to wait until the code has been completed. So you'd use it in cases were the thread was not dependant on the code having been executed.
0
 
javaq092999Author Commented:
Thanks Object and all
0
 
objectsCommented:
Only a 'B' ;-(

Thanks for the points :)

http://www.objects.com.au/staff/mick
Brainbench MVP for Java 1
http://www.brainbench.com
0
 
javaq092999Author Commented:
Never mind grade B, it is realistic I believe. Reason "I derived on the answer" rather "I got the answer".
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.