Extends JFrame vs. creating it inside the program

When making an application using Swing, I've seen people do one of the two things to create a JFrame. Which is a better approach and why?

I'm a beginner at Java and programming. My only source of learning is books, YouTube and Stack Overflow.

import {imports};

public class GuiApp1 {

    public static void main(String[] args) {

        new GuiApp1();
    }

    public GuiApp1()  {
        JFrame guiFrame = new JFrame();

        guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        guiFrame.setTitle("Example GUI");
        guiFrame.setSize(300,250);
        ................
    }

AND

import {imports};

public class GuiApp1 extends JFrame {

    public Execute() {
        getContentPane().setBackground(Color.WHITE);
        getContentPane().setLayout(null);
        setSize(800, 600);
        .............
    }

    public static void main(String[] args) {
        Execute frame1 = new Execute();
        frame1.setVisible(true);

    }
}

Thoughts:

  • Avoid extending JFrame as it ties your GUI to being, well a JFrame. If instead you concentrate on creating JPanels instead, then you have the freedom to use these JPanels anywhere needed -- in a JFrame, or JDialog, or JApplet, or inside of another JPanel, or swapped with other JPanels via a CardLayout.
  • Avoid inheritance in general, especially of complex classes. This will prevent pernicious errors, such as inadvertent method overrides (try creating a JFrame or JPanel that has a getX() and getY() method to see what I mean!).
  • Avoid inheritance of complex classes if you are using an IDE: If you override a complex class, when you call methods on objects of these classes, you will have many, too many, choices of methods offered to you.
  • Encapsulation is good, is and allows for creation of safer code. Expose only that which needs to be exposed, and control that exposure as much as possible.

Prefer composition over inheritance.

The 2nd example uses inheritance, but for no good reason, since it does not change the functionality of JFrame.


As an aside, if those are examples of code you are seeing, find a new source1 supplementary. Even in the few code lines shown, each does highly questionable things. E.G.

  1. Neither GUI is created on the Event Dispatch Thread.
  2. getContentPane().setBackground(Color.WHITE); getContentPane().setLayout(null); setSize(800, 600);
    • The first part of the 1st line (getContentPane()) has not been necessary since Java 1.5
    • The second line uses a null layout, which will break in more ways I can count or describe.
    • The third line should best be replaced with pack();
  3. JFrame guiFrame = new JFrame(); guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); guiFrame.setTitle("Example GUI"); guiFrame.setSize(300,250);
    • The first and 3rd lines could be contracted to:
      JFrame guiFrame = new JFrame("Example GUI");
    • The 2nd line is better set to guiFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    • The 3rd line again sets a size to the frame.

Supplement

  1. Having mentioned you do search SO, here is a tip. Check out the posts of the top 15 providers of answers in the Swing top users. Whatever advice/code you glean from these people, would commit few if any of the mistakes in those code samples.

    Some don't often (or ever) provide self contained examples like a few of us commonly do (and don't look to those examples necessarily for OO design as opposed to just technique), but whatever code they provide, or advice they give, should be highly considered.