Java Can';t setDefaultButton(btn):没有可调用的对象

Java Can';t setDefaultButton(btn):没有可调用的对象,java,swing,awt,Java,Swing,Awt,我只想将某些JButton设置为默认按钮(即,当按下ENTER时,它执行其操作)。除了以下几项,我几乎不做其他尝试: SwingUtilities.windowForComponent(此) SwingUtilities.getWindowSenior(此) someJPanelObj.getParent() SwingUtilities.getRootPane(someJButtonObj) 但它们都返回空值 代码如下: public class HierarchyTest { @

我只想将某些
JButton
设置为默认按钮(即,当按下
ENTER
时,它执行其操作)。除了以下几项,我几乎不做其他尝试:

  • SwingUtilities.windowForComponent(此)
  • SwingUtilities.getWindowSenior(此)
  • someJPanelObj.getParent()
  • SwingUtilities.getRootPane(someJButtonObj)
但它们都返回空值

代码如下:

public class HierarchyTest {
    @Test
    public void test(){
        JFrame frame = new JFrame();
        frame.add(new CommonPanel());
    }
}
公共小组:

class CommonPanel extends JPanel {
    CommonPanel() {
        JButton btn = new JButton();
        add(btn);

        Window win = SwingUtilities.windowForComponent(this); // null :-(
        Window windowAncestor = SwingUtilities.getWindowAncestor(this); // null :-(
        Container parent = getParent(); // null :-(
        JRootPane rootPane = SwingUtilities.getRootPane(btn); // null :-(

        rootPane.setDefaultButton(btn); // obvious NullPointerException...
    }
}

问题是,
CommonPanel
的构造函数在添加到
JFrame
之前被调用,因此它实际上没有窗口或根父级。您可以将
CommonPanel
更改为:

class CommonPanel extends JPanel {
    JButton btn = new JButton();

    CommonPanel() {

        add(btn);

    }

    public void init() {
        Window win = SwingUtilities.windowForComponent(this); // null :-(
        Window windowAncestor = SwingUtilities.getWindowAncestor(this); // null
                                                                        // :-(
        Container parent = getParent(); // null :-(
        JRootPane rootPane = SwingUtilities.getRootPane(btn); // null :-(

        rootPane.setDefaultButton(btn); // obvious NullPointerException...

    }
}
然后,不要添加新的
公共面板
,而是创建一个:

JFrame frame = new JFrame();
CommonPanel panel = new CommonPanel();
frame.add(panel);
panel.init();

PS,非常感谢您使用单元测试,这是一个很好的实践。

@ItamarGreen,我一回到我心爱的笔记本电脑就会尝试:-DIt工作正常,但有点尴尬。我必须显式地调用
init()
。有没有什么方法我可以重写,比如
onload()
OnInitialized()
或者类似的,在
JPanel
添加到它的容器后自动调用的方法?@Tar我想没有is@Tar
难道没有我可以重写的方法吗,比如OnLoaded()、OnInitialized()或类似的方法,将JPanel添加到其容器后,会自动调用它?
-您可以向面板添加
AncestorListener
,并处理
ancestorAdded
事件。@camickr wait,
AncestorListener
有一个
ancestorAdded
?哇,我真的需要重读这本书doc@ItamarGreen,这就是我不断回答问题的原因之一。不断从论坛的其他成员那里获得提示。对我来说,比重读博士更有趣:)