1

I just want to set certain JButton as the default button (i.e. when pressing ENTER, it executes its action). Following this answer and few others, I tried them all:

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

But they all return null...

Here is the code:

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...
    }
}
Community
  • 1
  • 1
Tar
  • 8,529
  • 9
  • 56
  • 127

1 Answers1

3

The problem is that the constructor of CommonPanel is called before you add it to the JFrame, so it really doesn't have a window, or root parent. You can change your CommonPanel to:

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

    }
}

and then instead of adding a new commonPanel, create one:

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

PS, very good of you to use unit testing, it's an excellent practice.

ItamarG3
  • 4,092
  • 6
  • 31
  • 44
  • It's working, but a bit awkward. I have to call `init()` explicitly. 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? – Tar Dec 24 '16 at 13:28
  • @Tar I don't think there is – ItamarG3 Dec 24 '16 at 13:56
  • @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?` - you can add an `AncestorListener` to the panel and handle the `ancestorAdded` event. – camickr Dec 24 '16 at 16:06
  • @camickr wait, `ancestorListener` has an `ancestorAdded`? wow I really need to reread the doc – ItamarG3 Dec 24 '16 at 16:09
  • @ItamarGreen, that's one reason why I keep answering questions. Keep getting tips/hints from other members of the forum. More fun for me than rereading the doc :) – camickr Dec 24 '16 at 16:27
  • @camickr good point :P. I guess i'll stick around a bit longer then – ItamarG3 Dec 24 '16 at 16:29
  • @camickr and ItamarGreen, thanks to you both! still can't get the default button to act like one - [here is the follow up question](http://stackoverflow.com/questions/41315304/jrootpanesetdefaultbuttonthebutton-does-nothing)... – Tar Dec 25 '16 at 09:42