6

When I learned creating Java GUI:s in my first Java course, I was taught to create my windows as JFrame instances, and then add a JPanel to each JFrame and finally add all the GUI components to the JPanel:

class Example extends JFrame {
    Example() {
        JPanel panel = new JPanel();
        this.add(panel);

        // Create components here and add them to panel
        // Perhaps also change the layoutmanager of panel

        this.pack();
        this.setVisibility(true);
    }

    public static void main(String[] args) {
        new Example();
    }
}

I always though "well, this smells a little; I don't like creating an extra object just to be a container," but I didn't know any other way to do it so I just went on with it. Until recently, when I stumbled over this "pattern":

class AnotherExample extends JFrame {
    AnotherExample() {
        Container pane = this.getContentPane();

        // Add components to and change layout of pane instead

        this.pack();
        this.setVisibility(true);
    }

    public static void main(String[] args) {
        new AnotherExample();
    }
}

Still being quite new to Java, I feel better about the second approach just because it doesn't involve creating a JPanel just to wrap the other components. But what are the real differences between the approaches, except from that? Does any one of them have any great benefits over the other?

Tomas Aschan
  • 58,548
  • 56
  • 243
  • 402
  • 1
    Read this tutorial for more info: http://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html – Eng.Fouad Jan 08 '12 at 02:53
  • Great tutorial! I recommend anyone who finds this question to read it. – Tomas Aschan Jan 08 '12 at 03:14
  • doesn't matter (both are bad, no need to do either, simply add to the frame) - the real smell is _extends JFrame_ : good ol' OO rule is to extend only if there's a sound is-a relationship (vs. mere usage, as is the case in 99.99% in all gui applications) – kleopatra Jan 08 '12 at 12:28

1 Answers1

4

I prefer to create a JPanel (which, being a Swing container, can have a border) and set it as the content pane.

To get a JComponent out of the content pane requires casting, which has an even worse smell than creating an extra component.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • ...and why do you do that? What makes that approach better (or different) than the two I posted? – Tomas Aschan Jan 08 '12 at 02:47
  • And by the way: good idea! This is probably the approach I (ignorant of the actual facts) like best so far =) – Tomas Aschan Jan 08 '12 at 02:48
  • I'm guessing that first comment was made before I'd edited my answer. After submitting it I re-read the question to see that my answer ..didn't answer it. ;) – Andrew Thompson Jan 08 '12 at 02:56
  • BTW - as a promoter of [nested layouts](http://stackoverflow.com/a/5630271/418556) (layouts within layouts, each of which needs a container like `JPanel`), I am rather desensitized to the idea that creating extra components just to make a GUI work is in any way 'unclean'. :) – Andrew Thompson Jan 08 '12 at 03:01
  • I'm not in any way opposed to creating more components to make things work - it's just that if there already *is* a container defined on the `JFrame` I have found it hard to find a reason to put another one that will still cover the same area of the GUI. Until now, when I find there is perfect reason in it. – Tomas Aschan Jan 08 '12 at 07:37
  • -1 (what a rare event :-) generally, there is no need to cast anything nor is there to replace the contentpane - its existence is an (mostly rather uninteresting) implementation detail. – kleopatra Jan 08 '12 at 12:35
  • Even though this really doesn't answer my question, it does solve my problem: now I have a way to do *both* what my teachers showed me *and* what my gut tells me is good =) – Tomas Aschan Jan 09 '12 at 22:10