3

I'm wondering about this for quite a long time now.

I usually build my SWING programs by having a JFrame with a JPanel containing the window's content set as the content pane by setContentPane(). When I want my content to be replaced by another one (e.g. for getting a new mask after clicking a button) I call setContentPane() again and replace the content pane by another panel. But everytime I do this, I need to call repaint() after setContentPane() to make the change visible, so I created an own class I use for creating frames. This class extends JFrame and overrides setContentPane() like this:

@Override
public void setContentPane(Container c) {
  super.setContentPane(c);
  revalidate();
  repaint();
}

Why is this not implemented in the default JFrame class? Do I maybe have a bad side effect by doing this?

Froxx
  • 957
  • 4
  • 14
  • 27
  • What layout manager do you use? – Thorbjørn Ravn Andersen Feb 24 '15 at 11:03
  • 1
    Why should it? Generally speaking, you should set and leave the content pane as is. You may also be do more changes to the UI that you don't want to schedule a repaint until you're finished.... – MadProgrammer Feb 24 '15 at 11:05
  • You're also asking as to reach back some 15+ years into the minds of the developers who designed and wrote the API. There requirements were most definatly different from ours today, just look at the difference in concept of JavaFX for example – MadProgrammer Feb 24 '15 at 11:07
  • @MadProgrammer: Why should I do changes AFTER setContentPane()? I prepare the new mask completely, so I have the completely new mask in my "main panel". After this I call setContentPane(). This is the last step I'm doing. – Froxx Feb 24 '15 at 11:14
  • Use a [`CardLayout`](http://download.oracle.com/javase/8/docs/api/java/awt/CardLayout.html) as shown in [this answer](http://stackoverflow.com/a/5786005/418556). – Andrew Thompson Feb 24 '15 at 11:14
  • @ThorbjørnRavnAndersen: In my JFrame? I use the default layout manager there (should be FlowLayout). But why is that important? I don't think my JFrame's LM has some influence there. – Froxx Feb 24 '15 at 11:16
  • 1
    @Foxx Because I don't think that's what the designers had in mind for `setContentPane`, they idea was to "set" it once, then modify the contents of the `contentPane` itself. Again, you're asking as to guess at what the designers originally had in mind. – MadProgrammer Feb 24 '15 at 11:49

1 Answers1

4

I think it's for the same reason it is not called after adding or removing components from a Container. Setting the content pane would be the same as adding components to the already existing one. The component hierarchy becomes invalid, so you have to call revalidate() and repaint().

And the reason why it is not called automatically, is suggested in the documentation for Container.validate():

Validating the container may be a quite time-consuming operation. For performance reasons a developer may postpone the validation of the hierarchy till a set of layout-related operations completes, e.g. after adding all the children to the container.

But this is just my guess.

Community
  • 1
  • 1
Andrei Vajna II
  • 4,642
  • 5
  • 35
  • 38
  • Alright, but I always build my fully done mask in a panel first, and when I'm done I set this panel as content pane of my JFrame in the end. So I would just call that once per user action usually. I can't imagine a clean way of using setContentPane() in a different way. I thought that's what it was intended for. – Froxx Feb 24 '15 at 11:23
  • 1
    You can set the content pane and then add components to it afterwards. It's nothing wrong with that. Just like `Container.add` you can call `setContentPane` whenever you want. There's no rule that it has to be always called last. – Andrei Vajna II Feb 24 '15 at 11:28
  • Hm... Yeah that's right. I just think it's the nicest way to do it step by step, and my final step would be setContentPane() everytime. But okay, I accept it... ;) But it should be fine using my method from the start post, when using setContentPane() like I do, right? I see no bad side effect there. – Froxx Feb 24 '15 at 11:43
  • 1
    Yes, it's fine. Although, as Andrew Thompson suggested, you should consider using a `CardLayout`. resetting the whole content pane could take a longer amount of time, which would be noticeable as a short stutter in the GUI. – Andrei Vajna II Feb 24 '15 at 11:48