Java Swing основной JFrame: почему SwingUtilities.getAncestorOfClass возвращает ноль? - PullRequest
4 голосов
/ 09 сентября 2010

Я намерен реализовать приложение Swing, которое хранит все свои JComponents в главном окне приложения JFrame.Это выглядит как неуклюжий процедурный код, чтобы дать всем моим конструкторам JPanel параметр, относящийся к JFrame.Таким образом, некоторые исследования обнаружили SwingUtilities.getAncestorOfClass, который выглядел как решение.Но я не могу понять, почему он возвращает ноль, когда я пытаюсь использовать его, чтобы получить ссылку на JFrame в моем коде JPanel.

Чтобы дать вам представление, вот код для основного JFrame, который также создает ViewPanel и добавляет в JFrame, что:Когда вы нажимаете кнопку «Попробуйте», возникает исключение NullPointerException, поскольку вызов SwingUtilities.getAncestorOfClass для ViewPanel является нулевым вызовом

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

Заранее спасибо, если вы можете помочь с этим вопросом.

1 Ответ

3 голосов
/ 09 сентября 2010

Конструктор SDAMainViewPanel вызывает initComponents, но вызывается до того, как sdaMainViewPanel был добавлен в JFrame. Вы можете:

  • Вызывайте initComponents только после добавления SDAMainViewPanel в JFrame.
  • Получать родительский кадр каждый раз, когда вызывается ActionListener:

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