2013-03-21 2 views
2

다음 코드를 사용하여 구성 요소를 추가/제거 할 때 이벤트 수신기를 등록/등록 취소 할 수 있습니다.Swing AncestorListener : 탭 전환을 실행하지 않습니까?

addAncestorListener(new AncestorListener() { 
     @Override public void ancestorRemoved(AncestorEvent event) { 
      log.info("========= Remove listeners by " + ContentViewingComponent.this); 
      ... 
     } 
     @Override public void ancestorMoved(AncestorEvent event) {} 
     @Override public void ancestorAdded(AncestorEvent event) { 
      log.info("========= Add listeners by " + ContentViewingComponent.this); 
      ... 
     } 
    }); 

내 의도는 두 이벤트 모두 (추가 및 제거) 기본적으로 대부분의 상황에서 한 번 해고이었다, 즉 구성 요소가 추가 & 생성되고이 잊어 &을 제거 할 때 때.

그러나이 구성 요소가있는 탭 (JTabbedPane)이 선택되거나 숨겨지면 해고된다는 것을 알고 있습니다. 그것을 우회/탐지하는 방법이 있습니까?

아마도 추가/제거 대신 표시/숨기기를 사용하는 JTabbedPane의 버전일까요? 업데이트 : 더 많은 조사 결과에 따르면 구성 요소가 실제로 제거되지는 않지만 숨겨진 탭이 표시되고 ancestorRemoved()도 실행됩니다. 구성 요소가 여전히 루트 *를 가지고 있는지 여부를 감지 할 수 있으면 이벤트를 무시할 수 있지만 구성 요소가 실제로 제거되면 (보이지 않는 동안에는) 다시 시작되지 않는 문제가 있습니다.

* 글쎄요. 실제 제거하기 전에 ancestorRemoved()이 실행됩니다. 따라서 getParent() 체인을 따라 가야 구성 요소의 루트가 있는지 여부를 알 수 없습니다. 업데이트 : SwingUtilities.invokeLater()을 사용하여 한 번에 확인하여 해결되었습니다.


(플래시/AS3에 익숙한 사람들을 위해, 나는 ADDED_TO_STAGE/ REMOVED_FROM_STAGE 이벤트의 스윙 상당을 찾고 있어요.)

+0

스윙 청취자는 그들이 발동 할 때 발사합니다. 그러나 리스너의 if 문을 사용하여 원하는 이벤트에 대해서만 코드를 실행할 수 있습니다. –

+0

@GilbertLeBlanc 예,하지만 문제가 있습니다. 나는 "보이지 않는"것을 의미하는 이벤트를 무시할 수 있습니다.하지만 구성 요소가 제거되면 (보이지 않는 동안에도) 알려주지 않습니다. –

답변

1

내 의도는 두 이벤트 모두 (추가 및 제거)이었다 것이다 기본적으로 대부분의 상황, 즉 구성 요소가 &가 을 추가하고이 &을 제거 할 때

를 잊어을 만들 때 한 번 화재가 AncestorListener,있는 ComponentListener과 된 HierarchyListenerr하고 사용 SwingUtilities의 된 HierarchyListenerr를 사용하여 고정 예를

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.ComponentEvent; 
import java.awt.event.ComponentListener; 
import java.awt.event.HierarchyEvent; 
import java.awt.event.HierarchyListener; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JTabbedPane; 
import javax.swing.event.AncestorEvent; 
import javax.swing.event.AncestorListener; 

public class MyTabbedPane { 

    private JTabbedPane tabbedPane = new JTabbedPane(); 
    private JFrame f = new JFrame(); 
    private JLabel label1 = new JLabel("Tab1"); 
    private JLabel label2 = new JLabel("Tab2"); 
    private JLabel label3 = new JLabel("Tab3"); 
    private JLabel label4 = new JLabel("Tab4"); 

    public MyTabbedPane() { 
     tabbedPane.addTab("Tab1", label1); 
     tabbedPane.addTab("Tab2", label2); 
     tabbedPane.addTab("Tab3", label3); 
     tabbedPane.addTab("Tab4", label4); 
     tabbedPane.setTabPlacement(JTabbedPane.TOP); 
     tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); 

     label1.addAncestorListener(new EventHandler()); 
     label2.addAncestorListener(new EventHandler()); 
     label3.addAncestorListener(new EventHandler()); 
     label4.addAncestorListener(new EventHandler()); 

     label1.addHierarchyListener(new EventHandler()); 
     label2.addHierarchyListener(new EventHandler()); 
     label3.addHierarchyListener(new EventHandler()); 
     label4.addAncestorListener(new EventHandler()); 

     label1.addComponentListener(new EventHandler()); 
     label2.addComponentListener(new EventHandler()); 
     label3.addComponentListener(new EventHandler()); 
     label4.addComponentListener(new EventHandler()); 

     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(tabbedPane, BorderLayout.CENTER); 
     f.setPreferredSize(new Dimension(600, 400)); 
     f.pack(); 
     f.setVisible(true); 
    } 

    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()); 
       } 
      } 
     } 

     @Override 
     public void componentHidden(ComponentEvent e) { 
      System.out.println(e.getComponent().getClass().getName() + " --- Hidden"); 
     } 

     @Override 
     public void componentMoved(ComponentEvent e) { 
      System.out.println(e.getComponent().getClass().getName() + " --- Moved"); 
     } 

     @Override 
     public void componentResized(ComponentEvent e) { 
      System.out.println(e.getComponent().getClass().getName() + " --- Resized "); 
     } 

     @Override 
     public void componentShown(ComponentEvent e) { 
      System.out.println(e.getComponent().getClass().getName() + " --- Shown"); 
     } 
    } 

    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       MyTabbedPane frame = new MyTabbedPane(); 

      } 
     }); 
    } 
} 
+0

그동안 나는 (내 자신의 대답을 보자) '고정'하지만이 대답의 요소들을 통합 할 수도있다. –

3

에 대한

에 의해 해당 이벤트 또는 조상에서 당신이 getComponent 위해 할 수있는 비동기, 같은 방법을, 수 있습니다.

public static void addDisplayableListeners(final Component comp, final Runnable onDisplayable, final Runnable onNotDisplayable) { 
    comp.addHierarchyListener(new HierarchyListener() { 
     @Override public void hierarchyChanged(HierarchyEvent e) { 
      System.out.println("HIERARCHY CHANGE ===== " + comp); 
      final boolean dc = (e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0; 
      if (dc) { 
       System.out.println("DISPLAYABILITY_CHANGED"); 
       if (comp.isDisplayable()) { 
        onDisplayable.run(); 
       } else { 
        onNotDisplayable.run(); 
       } 
      } 
     } 
    }); 
} 

올드 버전 :

addHierarchyListener(new HierarchyListener() { 

     private boolean hadRoot = false; 

     @Override public void hierarchyChanged(HierarchyEvent e) { 

      System.out.println("HIERARCHY CHANGE ===== " + ContentViewingComponent.this); 

      final boolean hasRoot = Swing.hasRoot(ContentViewingComponent.this); 
      System.out.println("Has root: " + hasRoot); 

      if (hasRoot != hadRoot) { 

       System.out.println("...which is not what was."); 
       hadRoot = hasRoot; 

       if (hasRoot) { 
        log.info("========= Add listeners by " + ContentViewingComponent.this); 
        ... 
       } else { 
        log.info("========= Remove listeners by " + ContentViewingComponent.this); 
        ... 
       } 
      } 

     } 
    }); 

참고 : 나는 @ mKorbel의 대답에 언급 된 공식 방법과 여기에 내 자신의 헬퍼 (hadRoothasRoot()를) 대체 할 수 있을지는 살펴 보겠습니다.