【问题标题】:Can't setDefaultButton(btn): no object to call upon无法设置默认按钮(btn):没有可调用的对象
【发布时间】:2016-12-24 08:54:12
【问题描述】:

我只想将某些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());
    }
}

通用面板:

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

【问题讨论】:

  • @ItamarGreen,我一回到我心爱的笔记本电脑就试试看:-D

标签: java swing awt


【解决方案1】:

问题是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,你使用单元测试非常好,这是一个很好的实践。

【讨论】:

  • 它工作正常,但有点尴尬。我必须明确致电init()。是不是有一些我可以覆盖的方法,比如OnLoaded()OnInitialized() 或类似的方法,在将JPanel 添加到其容器后会自动调用?
  • @Tar 我不认为有
  • @Tar Isn't there some method I can override, like OnLoaded(), OnInitialized() or something like that, that is automatically called just after the JPanel is added to its container? - 您可以将AncestorListener 添加到面板并处理ancestorAdded 事件。
  • @camickr 等等,ancestorListener 有一个ancestorAdded?哇,我真的需要重新阅读文档
  • @ItamarGreen,这就是我不断回答问题的原因之一。不断从论坛的其他成员那里获得提示/提示。对我来说比重读文档更有趣:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-11
  • 2023-03-26
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多