我只想将某些JButton设置为默认按钮(即按ENTER时,它将执行其操作)。跟随this answer和其他几个人,我都尝试了全部:


SwingUtilities.windowForComponent(this)
SwingUtilities.getWindowAncestor(this)
someJPanelObj.getParent()
SwingUtilities.getRootPane(someJButtonObj)


但是它们都返回null ...

这是代码:

public class HierarchyTest {
    @Test
    public void test(){
        JFrame frame = new JFrame();
        frame.add(new CommonPanel());
    }
}


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...

    }
}


然后,而不是添加一个新的commonPanel,创建一个:

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


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

10-05 17:53