Java - Wait for component to be shown

Viewed 666

UPDATE #3: After madProgrammer's suggestions, maybe the timed solution is the best. But no answer has been given to this strange behaviour. I understand the fact that components are not shown immediately and need to be set.

The problem here is the onShow method, which executes correctly if called from onCreate, but doesn't work if called from the callback method "componentShown".


UPDATE #2: Added a componentListener on fragmentContentPane, to see when actually this component is shown and VALID

fragmentContentPane.addComponentListener(new ComponentAdapter(){

    public void componentShown(ComponentEvent e){

        if (e.getComponent().isValid()) System.out.println("SHOWN AND VALID!");
    }

});

UPDATE: The show method now gets called in EDT.

public void show() throws InvocationTargetException, InterruptedException{

    SwingUtilities.invokeAndWait(new Runnable(){

        public void run(){
            System.out.println("Showing..");
            frame.setVisible(true);
        }
    });
}

By now, the problem still exists.


Original Post:

I have this code:

import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class TEST {

    private JFrame frame;
    private JScrollPane contentPane;
    private JPanel contentViewport;

    private JScrollPane fragmentContentPane;
    private JPanel fragmentContentViewport;

    public TEST() throws InvocationTargetException, InterruptedException{

        SwingUtilities.invokeAndWait(new Runnable(){

            public void run(){

                onCreate();
            }
        });
    }

    public void onCreate(){

        System.out.println("On create!");
        frame=new JFrame();
        contentPane=new JScrollPane();
        contentViewport=new JPanel();
        contentPane.setViewportView(contentViewport);
        frame.setContentPane(contentPane);

        frame.addComponentListener(new ComponentAdapter(){

            public void componentShown(ComponentEvent e){

                onShow();
            }
        });
    }

    public void onShow(){

        System.out.println("On show!");
        fragmentContentViewport=new JPanel();
        fragmentContentPane=new JScrollPane(fragmentContentViewport);

        fragmentContentPane.addHierarchyListener(new HierarchyListener() {

            public void hierarchyChanged(HierarchyEvent e) {

                if (e.getChangeFlags()==HierarchyEvent.SHOWING_CHANGED && fragmentContentPane.isShowing()) {

                    System.out.println("Component is completely shown");
                }
            }
        });

        contentViewport.add(fragmentContentPane);
    }

    public void show(){

        frame.setVisible(true);
    }

    public static final void main(String[] args) throws InvocationTargetException, InterruptedException{

        TEST t=new TEST();

        t.show();
    }
}

The task is simple. I want to get known when the fragmentContentPane has been correctly added and is completely shown.

With this code this never happens, why?

Everything works if the onShow method is called in the ThreadEvent together with onCreate, for example:

public TEST() throws InvocationTargetException, InterruptedException{

        SwingUtilities.invokeAndWait(new Runnable(){

            public void run(){

                onCreate();
                onShow();
            }
        });
    }

any help is appreciated

0 Answers
Related