9

Why do we need to extend the JFrame class when building a Swing application. As far as I know extends is used for inheriting the base class. None of the functions of the JFrame class are used in the following program but still it is extended. I know I am missing out on some information. Is it like some of the functions of JFrame class are running in the background.

1) Code

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JPasswordField;
import javax.swing.JOptionPane;

public class tuna extends JFrame{

   private JTextField item1;
   private JTextField item2;
   private JTextField item3;
   private JPasswordField passwordField;
   Container contentPane ;
   public tuna(){
      super("The title");

      setLayout(new FlowLayout());

      item1 = new JTextField(10);
      contentPane.add(item1);

      item2 = new JTextField("enter text here");
      add(item2);

      item3 = new JTextField("uneditable", 20);
      item3.setEditable(false);
      add(item3);

      passwordField = new JPasswordField("mypass");
      add(passwordField);

      thehandler handler = new thehandler();

      item1.addActionListener(handler);
      item2.addActionListener(handler);
      item3.addActionListener(handler);
      passwordField.addActionListener(handler);
   }

   public static void main(String[] args){
      tuna aye = new tuna();
   }

   private class thehandler implements ActionListener{

      public void actionPerformed(ActionEvent event){
         String string = "";

         if(event.getSource()==item1)
            string=String.format("field 1: %s",event.getActionCommand());
         else if (event.getSource()==item2)
            string=String.format("field 2: %s",event.getActionCommand());
         else if (event.getSource()==item3)
            string=String.format("field 3: %s",event.getActionCommand());
         else if (event.getSource()==passwordField)
            string=String.format("password field is: %", event.getActionCommand());
      }
   }
}
Wizard Sultan
  • 830
  • 7
  • 22
  • 45
  • 9
    The premise of this question is false. You don't have to extend a JFrame in order to use it. – barjak Apr 07 '13 at 20:06
  • 4
    actually, you should _not_ extend a JFrame (nor any other class except when you really enhance functionality, that is implement something that can't be achieved by using/configuring that class) - most tutorials and Netbeans are giving bad examples :-) – kleopatra Apr 07 '13 at 22:13

4 Answers4

19

You don't need to extend JFrame and in fact many of us who do a lot of Swing programming make it a point not to extend this class. Myself, I try to extend classes where I plan on altering the innate behavior of the class -- i.e., override one of the non-static methods of the class. Since I rarely have to do this for a JFrame, I'll rarely want to extend it.

Another reason to avoid extending it: what if you later want to display the GUI you've just created in a JDialog or a JOptionPane or in another container as part of a complex GUI? If your class extends JFrame this will be hard to do. Myself, I try to gear my GUI classes towards creating JPanels so that this is much easier to do.

A silly example based on your code:

import javax.swing.*;

// this guy extends *nothing*
public class TunaExample {
   private static final int COLS = 10;
   private JPanel mainPanel = new JPanel(); // this is what I'll add to contentPane
   private JTextField field1 = new JTextField(COLS);
   private JTextField field2 = new JTextField(COLS);
   private JPasswordField passwordField = new JPasswordField(COLS);
   private JComponent[] allComponents = { new JLabel("Field 1:"), field1,
         new JLabel("Field 2:"), field2, new JLabel("Password:"), passwordField };

   public TunaExample() {
      field2.setEditable(false);
      field2.setFocusable(false);
      field1.setText("Field 1");
      field2.setText("Uneditable");

      for (JComponent comp : allComponents) {
         mainPanel.add(comp);
      }
   }

   public JComponent getMainComponent() {
      return mainPanel;
   }

   private static void createAndShowGui() {
      TunaExample tunaExample = new TunaExample();

      // creating my JFrame only when I need it and where I need it
      JFrame frame = new JFrame("Tuna Example");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(tunaExample.getMainComponent());
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
4

The first thing to note in your code is this:

super("The title");

This actually calls the JFrame constructor, and passed it "The title" as a title String. This is an explicit example of using the Jframe functionality in your code. This will build the window that appears for you.

Using methods like add are all inherited from the JFrame class. These add Components to the JFrame object.

Why Inheritance?

Well, simply, your class IS a JFrame, with a little more. When you have a Is A operation, you use inheritance. The other advantage of this method is that your class can be referred to as a JFrame. That is:

JFrame tuna = new tuna();
// Note: All classes are meant to start with a capital letter.

Another viewpoint

It's important to note that you don't strictly HAVE TO inherit from a JFrame class. You can use Composition. In this instance you'd have something like:

 public class Tuna {
      private JFrame parentWindow;
      // Rest of class.
 }

As mentioned above, the convention is to follow the Is A and Has A approach. If class A Is an example of class B, we tend to use inheritance. If class A has an instance of class B, then you use composition, although in most cases, inheritance is interchangeable with Composition.

Another another Viewpoint

As mentioned in the comments, you should always look for an existing API that offers this kind of functionality, before attempting to implement it yourself.

christopher
  • 26,815
  • 5
  • 55
  • 89
  • I have one more question. When I am writing `JFrame tuna = new tuna();` am I creating object of JFrame class or am I referring the `tuna` class as a JFrame – Wizard Sultan Apr 07 '13 at 20:19
  • 2
    @AmlanKarmakar: you are doing both. You are creating a tuna object (which should be named "Tuna" since it's a class) but since Tuna extends JFrame, it also *is a* JFrame. It is being held by a JFrame *variable* though and so the variable will not be able to reference any new methods that aren't already part of JFrame. 1+ to Chris's decent answer by the way. – Hovercraft Full Of Eels Apr 07 '13 at 20:20
  • @HovercraftFullOfEels Learn something new every day! – christopher Apr 07 '13 at 20:21
  • a rule of thumb is: never extend if you can reach the same by _using_ existing api. Consequently, most of the later part of your answer is .. suboptimal :-) And _inheritance is interchangeable with Composition_ is simply wrong – kleopatra Apr 07 '13 at 21:40
  • @kleopatra In most cases, you can achieve the same functionality with Composition as you can with inheritance. I believe that's a perfectly sound statement. OP's question was about *why* we inherit from a superclass in the context of a JFrame. I feel that I have explained that quite well. I didn't think about API's, and I'll edit that in now. – christopher Apr 07 '13 at 21:45
  • repeating a statement that's incorrect doesn't make it correct ;-) – kleopatra Apr 07 '13 at 21:49
  • Being condescending doesn't help either. Can you explain why it's an incorrect statement? – christopher Apr 07 '13 at 21:49
  • sure - as can (better than me) any serious textbook on OO basics. No condescending intended, btw. – kleopatra Apr 07 '13 at 22:06
  • Agreed, but could you just quickly summarize it for me? If it's on here, any other readers will see this and I can ammend my answer accordingly. – christopher Apr 07 '13 at 23:37
2

To use JFrame in your application You can extend it as you did it in your code or make an object as

JFrame frame= new JFrame();

and then you can do it

frame.setTitle("Title");
frame.setLayout(layout);

do it in either way as you are easy but to use JFrame in Application and to access its methods etc you have to use one of these methods

Sikander
  • 2,799
  • 12
  • 48
  • 100
0

If you want to create a standalone application, you can either extend JPanel or JFrame or create their instance in your class implementation.

As a rule, a standalone application with a Swing-based GUI has at least one containment hierarchy with a JFrame as its root. For example, if an application has one main window and two dialogs, then the application has three containment hierarchies, and thus three top-level containers. http://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html?

http://docs.oracle.com/javase/tutorial/uiswing/components/frame.html