When is a Swing component 'displayable'?

2019-06-22 16:24发布

问题:

Is there a way (e.g., via an event?) to determine when a Swing component becomes 'displayable' -- as per the Javadocs for Component.getGraphics?

The reason I'm trying to do this is so that I can then call getGraphics(), and pass that to my 'rendering strategy' for the component.

I've tried adding a ComponentListener, but componentShown doesn't seem to get called. Is there anything else I can try?

Thanks.

And additionally, is it OK to keep hold of the Graphics object I receive? Or is there potential for a new one to be created later in the lifetime of the Component? (e.g., after it is resized/hidden?)

回答1:

Add a HierarchyListener

public class MyShowingListener {
private JComponent component;
public MyShowingListener(JComponent jc) { component=jc; }

public void hierarchyChanged(HierarchyEvent e) {
    if((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED)>0 && component.isShowing()) {
        System.out.println("Showing");
    }
}
}

JTable t = new JTable(...);
t.addHierarchyListener(new MyShowingListener(t));


回答2:

You can listen for a resize event. When a component is first displayed, it is resized from 0,0 to whatever the layout manager determines (if it has one).



回答3:

You need to check up the component hierarchy. Check after AncestorListener.ancestorAdded is called.



回答4:

I've always used Coomponent.addNotify to know when the component is ready to be rendered.Not sure if is the the best way, but it works for me. Of course you must subclass the component.

Component.isDisplayable should be the right answer but I know it didn't worked for me as I thought it will(I don't remember why, but there was something and I switched to addNotify).

Looking in the SUN's source code, I can see addNotify fires a HierarchyEvent.SHOWING_CHANGED so this is the best way to be notified.