Java Swing main JFrame:为什么SwingUtilities.getAncestorOfClass返回null?

Java Swing main JFrame:为什么SwingUtilities.getAncestorOfClass返回null?,java,window,jframe,main,swingutilities,Java,Window,Jframe,Main,Swingutilities,我打算实现一个Swing应用程序,它将所有JComponents保持在主应用程序窗口JFrame中。给我所有的JPanel构造函数提供一个引用JFrame的参数似乎是一个笨拙的过程代码。因此,一些研究发现了SwingUtilities.getAncestorOfClass,这看起来像是解决方案。但我无法理解,当我试图在JPanel代码中使用它获取对JFrame的引用时,为什么它返回null 为了给您一个想法,这里是主JFrame的代码,它还创建了一个ViewPanel和一个在JFrame中的链接

我打算实现一个Swing应用程序,它将所有JComponents保持在主应用程序窗口JFrame中。给我所有的JPanel构造函数提供一个引用JFrame的参数似乎是一个笨拙的过程代码。因此,一些研究发现了SwingUtilities.getAncestorOfClass,这看起来像是解决方案。但我无法理解,当我试图在JPanel代码中使用它获取对JFrame的引用时,为什么它返回null

为了给您一个想法,这里是主JFrame的代码,它还创建了一个ViewPanel和一个在JFrame中的链接:

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编写的代码,当您按下“Try Me”按钮时,将导致NullPointerException,因为对ViewPanel的SwingUtilities.getAncestorOfClass的调用是null调用

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

如果您能帮助回答此问题,请提前感谢

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

非常感谢+1对于给定选项的准确性。希望这也能帮助其他Java人员。