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

发布于 2024-09-18 13:15:40 字数 1985 浏览 3 评论 0原文

我打算实现一个 Swing 应用程序,将其所有 JComponent 保留在主应用程序窗口 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 的调用是空调用。

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

如果您能帮助解决这个问题,请先致谢。

I intend to implement a Swing application which keeps all its JComponents within the main application window JFrame. It seems like clunky procedural code to give all my JPanel constructors a parameter referring to the JFrame. So some research uncovered SwingUtilities.getAncestorOfClass, which looked like the solution. But I cannot understand why it returns null when I try to use it to get a reference to the JFrame in my JPanel code.

To give you an idea, here is code for the main JFrame, which also creates a ViewPanel and plonks that in the 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);
            }
        });
    }
}

Here is my code for the ViewPanel, which, when you press the button "Try Me", results in a NullPointerException, because the call to SwingUtilities.getAncestorOfClass for the ViewPanel is a null call.

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

Thanks in advance if you can assist with this question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

仙女山的月亮 2024-09-25 13:15:40

SDMainViewPanel 的构造函数调用 initComponents,但它是在 sdaMainViewPanel 添加到 JFrame 之前调用的。您可以:

  • 仅在 SDMainViewPanel 添加到 JFrame 后调用 initComponents。
  • 每次调用 ActionListener 时获取父框架:

    public void actionPerformed(ActionEvent ae) {
        JFrame 父 = (JFrame)SwingUtilities.getAncestorOfClass(JFrame.class, SDAMainViewPanel.this);
        parent.getContentPane().removeAll();
    }
    

SDAMainViewPanel's constructor calls initComponents, but it gets called before sdaMainViewPanel has been added to a JFrame. You can:

  • Call initComponents only after the SDAMainViewPanel has been added to the JFrame.
  • Get the parent frame each time the ActionListener is called:

    public void actionPerformed(ActionEvent ae) {
        JFrame parent = (JFrame)SwingUtilities.getAncestorOfClass(JFrame.class, SDAMainViewPanel.this);
        parent.getContentPane().removeAll();
    }
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文