2011-02-23 3 views
1

나는 매우 바보 같은 질문을하고있다.컨테이너 필드에 액세스

NetBeans를 사용하여 작은 응용 프로그램을 제작하고 있는데 다음과 같은 문제가 있습니다. 내 주요 클래스가 .. mainApp이라고하며 차례로 JPanel 나는 다양한 연장하는 drawingBoard라고 (와 오프 주제) 이유가있는 JFrame을 확장하고

핵심 문제는 어떤 점에서 내가 필요가있다 mainApp의 필드 중 하나에 액세스하지만 NetBeans가 기본 클래스를 인스턴스화하는 방식으로 인해 (익명 클래스로) 컨테이너에 대한 참조를 가져올 수 없습니다 (내 mainApp).

mainApp의 참조를 얻고 해당 필드의 값을 drawingBoard 범위 내로 설정하려면 어떻게해야합니까?

답변

1

Window win = SwingUtilities.getWindowAncestor (myComponent);를 사용하여 최상위 레벨 창에 대한 참조를 얻을 수 있습니다. 메소드 호출에 최상위 레벨 윈도우가 궁극적으로 보유하는 컴포넌트에 대한 참조를 전달합니다. 주 클래스가 최상위 JFrame (다른 JFrames를 초기화하지 않음) 인 경우 반환 된 Window를 최상위 클래스 유형으로 캐스팅하고 공용 메서드를 호출 할 수 있습니다. 예를 들어

:

glowcoder의 추천에 의해 수행 될 변경된
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 

public class Foo1 { 
    public static void main(String[] args) { 
     MainApp mainApp = new MainApp(); 
     mainApp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     mainApp.pack(); 
     mainApp.setLocationRelativeTo(null); 
     mainApp.setVisible(true); 
    } 
} 

class MainApp extends JFrame { 
    public MainApp() { 
     getContentPane().add(new DrawingBoard()); 
    } 

    public void mainAppMethod() { 
     System.out.println("This is being called from the Main App"); 
    } 
} 

class DrawingBoard extends JPanel { 
    public DrawingBoard() { 
     JButton button = new JButton("Button"); 
     button.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      MainApp mainApp = (MainApp) SwingUtilities.getWindowAncestor(DrawingBoard.this); 
      mainApp.mainAppMethod(); 
     } 
     }); 
     add(button); 
    } 
} 

:

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 

public class Foo2 { 
    public static void main(String[] args) { 
     MainApp2 mainApp = new MainApp2(); 
     mainApp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     mainApp.pack(); 
     mainApp.setLocationRelativeTo(null); 
     mainApp.setVisible(true); 
    } 
} 

class MainApp2 extends JFrame { 
    public MainApp2() { 
     getContentPane().add(new DrawingBoard2(this)); 
    } 

    public void mainAppMethod() { 
     System.out.println("This is being called from the Main App"); 
    } 
} 

class DrawingBoard2 extends JPanel { 
    private MainApp2 mainApp; 

    public DrawingBoard2(final MainApp2 mainApp) { 
     this.mainApp = mainApp; 
     JButton button = new JButton("Button"); 
     button.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      buttonActonPerformed(); 
     } 
     }); 
     add(button); 
    } 

    private void buttonActonPerformed() { 
     mainApp.mainAppMethod(); 

    } 
} 

또 다른 추천 : 당신은 스윙을 배우고 있기 때문에, 당신이 생성하는 넷빈즈를 사용하지 않는 오프 훨씬 더 좋을 것 같아 코드를 스윙하지만 스윙 앱을 직접 코딩하십시오. 이 작업을 수행하고 튜토리얼을 공부하면 Swing의 작동 방식을 훨씬 더 깊이 이해할 수 있으며 NetBeans 코드 생성기를 사용하여 가장 단순한 애플리케이션 이상을 만들어야 할 때 도움이 될 것입니다.

+0

매력처럼 작동합니다! 하지만 이제는 또 다른 질문을 던졌습니다.!이 두 클래스가 JFrame과 JPanel을 각각 확장하지 않으면 어떻게 될까요? SwingUtilities를 사용할 수 없어야하며 Glowcoder의 솔루션 만 작동 할 것입니다 ...! 아직도 그것을하는 또 다른 방법이 있습니다 ..? – kstratis

+0

glowcoder는 언급 한 바와 같이 참조에 대한 모든 것입니다. 하나의 객체에 대한 참조를 다른 객체로 전달하는 방법이 있어야하며, 종종 이것은 생성자 또는 설정자 (변형 자) 메소드를 통해 수행됩니다. –

+0

귀중한 의견을 보내 주셔서 감사합니다! – kstratis

3

확장하는 경우 생성자를 제어 할 수 있습니다. 생성자에 추가하여 (그리고 멤버 변수에 할당하여) 필요한 참조를 전달하십시오.

예 의존성 삽입!

+0

그게 ... 할 수 없다! 목표는 앱이 시작된 후 사용자가 drawingBoard를 클릭 한 다음 부모 필드가 업데이트 된 순간입니다. – kstratis

+0

glowcoder의 권장 사항은 여전히 ​​Kono5 (1+ 투표)에 해당합니다. 핵심은 JPanel 클래스에 MainApp 필드를 지정하고 DrawingBoard 생성자에서 설정하는 것입니다. 그런 다음 앱을 실행하는 동안, 특히 런타임에 메소드를 호출 할 수 있습니다. –

+0

True ... 생성자를 통해 전체 메인 클래스를 통과하면서 내 마음을 십자가에 못 박았습니다.이 방법도 마찬가지로 작동 할 수 있습니다. – kstratis

1

Glowcoder의 답변이 좋습니다. 다른 옵션은 mainApp을 싱글 톤으로 만드는 것입니다 (논리적으로 말하면 싱글 톤인 경우)

+0

JFrame을 싱글 톤으로 만드는 것이 좋지 않다고 생각합니다. glowcoder가 지적한 것처럼 필요한 모든 것이 간단한 참조이므로 필요는 없습니다. –