4

すべての JComponents をメイン アプリケーション ウィンドウ JFrame 内に保持する Swing アプリケーションを実装するつもりです。すべての JPanel コンストラクターに JFrame を参照するパラメーターを与えるのは、ぎこちない手続き型コードのようです。そのため、いくつかの調査により、ソリューションのように見える SwingUtilities.getAncestorOfClass が明らかになりました。しかし、JPanel コードで JFrame への参照を取得するために使用しようとすると、null が返される理由がわかりません。

アイデアを提供するために、メインの JFrame のコードを次に示します。これは、ViewPanel も作成し、JFrame でそれを plonk します。

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class SDA {
    public static void main (String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                SDAMainViewPanel sdaMainViewPanel = new SDAMainViewPanel();
                JFrame frame = new JFrame("SDApp");
                frame.setSize(400, 400);
                frame.setContentPane(sdaMainViewPanel);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);                    
                frame.setLocationRelativeTo(null);                
                frame.setVisible(true);
            }
        });
    }
}

ViewPanel の SwingUtilities.getAncestorOfClass への呼び出しが null 呼び出しであるため、[試してみる] ボタンを押すと、NullPointerException が発生します。

import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;

public class SDAMainViewPanel extends JPanel {

    public SDAMainViewPanel() {
        initComponents();
    }

    private void initComponents() {
        getAncClass = new JButton("Try me");
        // This is null even though there IS an Ancestor JFrame!?!?
        final JFrame parent = (JFrame)SwingUtilities.getAncestorOfClass(JFrame.class, this);
        getAncClass.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {                
                parent.getContentPane().removeAll();
            }
        });
        add(getAncClass);
    }

    private JButton getAncClass;
}

この質問にご協力いただける場合は、事前に感謝します。

4

1 に答える 1

3

SDAMainViewPanelのコンストラクターはinitComponentsを呼び出しますが、sdaMainViewPanelがJFrameに追加される前に呼び出されます。あなたはできる:

  • SDAMainViewPanelがJFrameに追加された後でのみ、initComponentsを呼び出します。
  • ActionListenerが呼び出されるたびに親フレームを取得します。

    public void actionPerformed(ActionEvent ae) {
        JFrame parent = (JFrame)SwingUtilities.getAncestorOfClass(JFrame.class, SDAMainViewPanel.this);
        parent.getContentPane().removeAll();
    }
    
于 2010-09-09T10:32:23.397 に答える