2013-01-18 6 views
1

이상한 기존 코드로 작업하고 있습니다. 그들은 JPanel을 구현하는 커스텀 객체를 가지고있다. 이 JPanel 개체는 주 응용 프로그램 내의 보조 팝업 화면입니다. 내가 가지고있는 문제는 보조 팝업 화면이 닫힐 때를 감지하는 것입니다.JPanel에서 닫기를 청취하는 방법

클래스에 WindowListener을 구현하려고했지만 추가하려고하면이 개체와 연결된 JFrame이 없습니다. 나는 이것이 사용자 정의 객체를 사용하고 있으며 임베디드 팝업 화면이기 때문에 이것이라고 가정합니다. NullPointerException에 실패

JFrame parentFrame = (JFrame) SwingUtilities.getWindowAncestor(this); 

을 :

내가 사용 JFrame를 검색하기 위해 노력했다. 이 페이지에서 오른쪽 코너 "x"닫기 버튼을 감지하는 것이 왜 그렇게 어려운지 잘 모릅니다! 나는 그들이 JPanel 안에 내장 된 테이블에 마우스와 키 리스너를 추가 할 수 있었다고 언급해야한다. 그러나 창문 외부의 청취자가 나를 괴롭 히고 있습니다.

(나와 함께하시기 바랍니다 곰이 내 첫 유래 포스트 내가 스윙 할 새로운입니다.)

감사를 이렇게 아주 많이!

답변

2

해당 이상한 패널에 대해 getParent()으로 문의하십시오. 상위 GUI 구성 요소를 리턴해야합니다. 여전히 프레임이 아니라 일부 중간 패널 인 경우 getParent()를 호출하십시오. 최상위 구성 요소가 null을 반환합니다.

는에서 "NullPointerException이"점점 이유
+0

이 기능은 getWindowAncestor()보다 훨씬 효과적입니다. JPanel 클래스에 어떻게 든 창 컨테이너가 없기 때문입니다. 그것은 기괴한 구조입니다. 나는 부모에 재귀 적으로 볼 때, 내가 얻을 : 는 JPNLCustomClass는 JPanel의 부모입니다 확장 ->하는 JViewport 부모는 -> JScrollPane의 부모는 -> JSplitPane의 부모가은 -> JPNLMainContainerCustomClass 연장하는 AbstractMainContainerCustomClass을 확장하는이 -> 널 이가 될 수 있을까요 이 비정상적인 구조로 인해 창 닫기를 감지하지 못할 수도 있습니다. 그래도 아무 것도 정말로 불가능합니다 :) 고마워요 !! – jspacek

0

이해할 수없는

Component p = strangePanel; 
    while (p != null && ! (p instanceof Window)) 
    p = p.getParent(); 

    ((Window) p).addWindowListener(..); 
:

JFrame parentFrame = (JFrame) SwingUtilities.getWindowAncestor(this); 

이가지 경우에 이런 일이 있습니다 : 당신이 귀하의 경우

JFrame parentFrame = (JFrame) SwingUtilities.getWindowAncestor(null); 

이 불가능합니다 을 매개 변수로 사용했습니다.

둘째, 당신처럼, 위의 코드 라인에서 다른 작업을하고있다 : 당신의 객체가 상단 창을 나타내는 경우이 경우

JFrame parentFrame = ((JFrame) SwingUtilities.getWindowAncestor(this)).someOperation(); 

, 당신은 때문에 "NullPointerException이"얻을로되어있다 상위 부모의 조상은 "null"로 반환됩니다. 다른 경우에는, 당신 이이 예외를 얻을 것으로 의심됩니다.

예외가 발생한 부분에 코드 블록을 게시 할 수 있습니까?

+0

위에 붙여 넣은 줄은 실패한 줄입니다. "SwingUtilities.getWindowAncestor (this);"부분 만 실행하면 디버거를 사용하면 널 포인터 예외가 발생합니다. "this"는 null이 아니며이 코드는 패널이 생성 된 후에 호출됩니다. (JPanel은 항상 JFrame의 자식입니까, 아니면이 부모 객체가 없을 수 있습니까?이 모든 도움을 주셔서 감사합니다. – jspacek

0

이 대답에 대해 언급 한 줄에서 Nullpointer가 throw되지 않고, 대신 parentFrame에 WindowListener를 추가하려고 시도하는 경우를 가정합니다. 이는 JPanel이 JFrame 계층에 추가되기 전에

JFrame parentFrame = (JFrame) SwingUtilities.getWindowAncestor(this); 

으로 호출되기 때문에 가장 가능성이 높습니다.

다음은이 문제를 해결하는 방법에 대한 대략적인 코드 샘플입니다. 패널이 계층 구조의 어딘가에있는 JFrame에 연결되었다는 통지를 패널이 기다리는 것으로 생각합니다.

package test; 

import java.awt.event.HierarchyEvent; 
import java.awt.event.HierarchyListener; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class HierarchyTest extends JPanel { 

    protected static void loadApp() { 
     HierarchyTest test = new HierarchyTest(); 
     JFrame frame = new JFrame(); 
     frame.add(test); 
     frame.setSize(200, 200); 
     frame.setVisible(true); 
    } 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       loadApp(); 

      } 
     }); 

    } 

    public HierarchyTest() { 
     this.addHierarchyListener(new HierarchyListener() { 

      @Override 
      public void hierarchyChanged(HierarchyEvent e) { 
       // This can be optimized by checking the right flags, but I leave that up to you to look into 
       boolean connected = setupListenersWhenConnected(); 

       if (connected) { 
        HierarchyTest.this.removeHierarchyListener(this); 
       } 
      } 
     }); 
    } 

    protected boolean setupListenersWhenConnected() { 
     JFrame parentFrame = (JFrame) SwingUtilities.getWindowAncestor(this); 
     if (parentFrame == null) { 
      return false; 
     } 
     parentFrame.addWindowListener(new WindowAdapter() { 

      @Override 
      public void windowClosing(WindowEvent e) { 
       // Implementation here 
       System.out.println("This window is closing!"); 
      } 
     }); 
     return true; 
    } 
} 
+0

아마도 어리석은 질문입니다 ...하지만 JPanels에는 항상 창 조상이 있습니까?이 객체의 부모 트리에 올라 갔고 그 유형의 것을 찾을 수 없었습니다. 아마도 숨겨져 있었을 것입니까? – jspacek

+0

어리석은 질문이 아닙니다. JPanel은 JFrame 아래에있는 계층 구조의 어딘가에 삽입되었을 때 Window (또는이 예제에서는 JPanel) 조상만을가집니다. JPanel이 생성되면 부모가 없습니다. 창 조상도 없으므로 컨테이너에 추가 한 후 화면에서 볼 수 있습니다. – JeroenWarmerdam

+0

Ok -이 위치를 찾기 위해 사냥을해야하는 것 같습니다. JPanel이 컨테이너에 추가됩니다 ... 결국. 그것은 레거시 코드이므로 1000 가지 클래스에서 찾을 수 있습니다. 정말 고마워! – jspacek

관련 문제