Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPanel which one of Listeners is proper for visibility is changed

Tags:

Are there some rules, or good/bad experiences with AncestorListener, ComponentListener or HierarchyListener listening for visibility of changes with JPanel and JComponents?

Is one of them better or safer than the others? I would especially like to know about when and how JPanel / JComponent is hidden.

Notice the following code contains incorrect Swing rules, like using Thread.sleep(int), in this case, to allow me to print-out correct order of Listeners in Swing GUI

import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.event.AncestorEvent; import javax.swing.event.AncestorListener;  public class CardlayoutTest extends JFrame {      private static final long serialVersionUID = 1L;     public CardLayout card = new CardLayout();      public CardlayoutTest() {         JPanel pnlA = new JPanel(new BorderLayout());         pnlA.add(new JButton("A"), BorderLayout.CENTER);         JPanel pnlB = new JPanel(new BorderLayout());         pnlB.add(new JButton("B"), BorderLayout.CENTER);         JPanel pnlC = new JPanel(new BorderLayout());         pnlC.add(new JButton("C"), BorderLayout.CENTER);          setDefaultCloseOperation(EXIT_ON_CLOSE);         setLayout(card);         add(pnlA, "A");         add(pnlB, "B");         add(pnlC, "C");          pnlA.addAncestorListener(new EventHandler());         pnlB.addAncestorListener(new EventHandler());         pnlC.addAncestorListener(new EventHandler());          pnlA.addHierarchyListener(new EventHandler());         pnlB.addHierarchyListener(new EventHandler());         pnlB.addHierarchyListener(new EventHandler());          pnlA.addComponentListener(new EventHandler());         pnlB.addComponentListener(new EventHandler());         pnlB.addComponentListener(new EventHandler());     }      class EventHandler implements AncestorListener, ComponentListener, HierarchyListener {          @Override         public void ancestorAdded(AncestorEvent event) {             System.out.println("CardlayoutTest.EventHandler.ancestorAdded()");         }          @Override         public void ancestorMoved(AncestorEvent event) {             System.out.println("CardlayoutTest.EventHandler.ancestorMoved()");         }          @Override         public void ancestorRemoved(AncestorEvent event) {             System.out.println("CardlayoutTest.EventHandler.ancestorRemoved()");         }          @Override         public void hierarchyChanged(HierarchyEvent e) {             System.out.println("Components Change: " + e.getChanged());             if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) {                 if (e.getComponent().isDisplayable()) {                     System.out.println("Components DISPLAYABILITY_CHANGED : " + e.getChanged());                 } else {                     System.out.println("Components DISPLAYABILITY_CHANGED : " + e.getChanged());                 }             }             if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {                 if (e.getComponent().isDisplayable()) {                     System.out.println("Components SHOWING_CHANGED : " + e.getChanged());                 } else {                     System.out.println("Components SHOWING_CHANGED : " + e.getChanged());                 }             }         }          public void componentHidden(ComponentEvent e) {             System.out.println(e.getComponent().getClass().getName() + " --- Hidden");         }          public void componentMoved(ComponentEvent e) {             System.out.println(e.getComponent().getClass().getName() + " --- Moved");         }          public void componentResized(ComponentEvent e) {             System.out.println(e.getComponent().getClass().getName() + " --- Resized ");         }          public void componentShown(ComponentEvent e) {             System.out.println(e.getComponent().getClass().getName() + " --- Shown");         }     }      public static void main(String[] args) {         CardlayoutTest t = new CardlayoutTest();         t.setSize(500, 500);         System.out.println("CardlayoutTest.main()------------------------ FIRST");         t.card.show(t.getContentPane(), "A");         t.setVisible(true);         System.out.print("\n");         try {             Thread.sleep(2000);         } catch (InterruptedException e) {         }         System.out.println("CardlayoutTest.main()------------------------ SECOND");         t.card.show(t.getContentPane(), "B");         System.out.print("\n");         try {             Thread.sleep(2000);         } catch (InterruptedException e) {         }         System.out.println("CardlayoutTest.main()------------------------ THIRD");         t.card.show(t.getContentPane(), "C");         System.out.print("\n");     } } 
like image 324
mKorbel Avatar asked Jun 04 '12 11:06

mKorbel


People also ask

How do you make a panel visible in Java?

You can't display a panel on its own; it has to be added to a container, of which the most popular type is the JFrame. You are also supposed to start a new thread; the details are in the API for any Swing class, where the link to "Swing threading policy" is.

Which of the following listener is supported by Button Swing component?

Because all Swing components descend from the AWT Component class, you can register the following listeners on any Swing component: component listener. Listens for changes in the component's size, position, or visibility. focus listener.


1 Answers

If you want to listen EXACTLY the visibility changes - use ComponentListener or ComponentAdapter:

    JPanel panel = new JPanel ();     panel.addComponentListener ( new ComponentAdapter ()     {         public void componentShown ( ComponentEvent e )         {             System.out.println ( "Component shown" );         }          public void componentHidden ( ComponentEvent e )         {             System.out.println ( "Component hidden" );         }     } ); 

But that visibility might not be the one you think about. isVisible() flag will be true even if the Component is not added to any Container and hence not showing at all!

That visibility a has a slightly different purpose. You can use it to manually hide the Component that is already added and shown somewhere in your application. In that case, (if you use setVisible(false)) it will become hidden and every ComponentListener of that Component will be informed about that change.

So, talking about actual visibility...

This is what you should use to listen to actual component appearance/disappearance:

    JPanel panel = new JPanel ();     panel.addAncestorListener ( new AncestorListener ()     {         public void ancestorAdded ( AncestorEvent event )         {             // Component added somewhere         }          public void ancestorRemoved ( AncestorEvent event )         {             // Component removed from container         }          public void ancestorMoved ( AncestorEvent event )         {             // Component container moved         }     } ); 

I always use that listener to determine when the Component is added somewhere and also to listen when it is moved/removed.

Also, you can always check if the Component is actually visible to application user by calling isShowing() method:

boolean userCanSeeThePanel = panel.isShowing(); 

This will return true ONLY if that panel is added to VISIBLE to user frame and isVisible() flag is also true (it is usually true, unless you set it to false).

I guess that's all I can tell you about visibility. I might have misunderstood your question. Correct me if I am wrong in that case.

like image 138
Mikle Garin Avatar answered Nov 14 '22 11:11

Mikle Garin