views:

91

answers:

5

I am trying to figure out how the Swing based Hello World application works. This is the code I have:

import java.awt.*;
import javax.swing.*;


public class HelloWorldSwing extends JFrame {

        JTextArea m_resultArea = new JTextArea(6, 30);

        //====================================================== constructor
        public HelloWorldSwing() {
            //... Set initial text, scrolling, and border.
            m_resultArea.setText("Enter more text to see scrollbars");
            JScrollPane scrollingArea = new JScrollPane(m_resultArea);
            scrollingArea.setBorder(BorderFactory.createEmptyBorder(10,5,10,5));

            // Get the content pane, set layout, add to center
            Container content = this.getContentPane();
            content.setLayout(new BorderLayout());
            content.add(scrollingArea, BorderLayout.CENTER);
            this.pack();
        }

        //============================================================= main
        public static void main(String[] args) {
            JFrame win = new HelloWorldSwing();
            win.setTitle("TextAreaDemo");
            win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            win.setVisible(true);
        }


}

The code was taken from here (I slightly modified it). I have two main questions about the example but if you answer at leas one of them would appreciate it a lot. Here are my questions:

1. As far as I understand the "main" method is run automatically. In this method we instantiate a "win" object and, as a consequence the constructor of the class will be executed. But when the first line of the class is executed (JTextArea m_resultArea = new JTextArea(6, 30));.

2. Is there a good reason to instantiate the text area (m_resultArea) outside the constructor and then set its parameters (setText) within the constructor. Why we cannot instantiate the text area in the constructor? Why we cannot set the parameters of the text area beyond the constructor? (Just for the sake of consistency).

+1  A: 

1- The instantiation of the JTextArea is the first thing that happens when you create an object of HelloWorldSwing. The constructor is executed right after that. Since it's not static, you cannot access it without and object (in this case, win).

2- There is a good reason, but it could be instantiated inside the constructor. It's like that because that way you make sure it is not null when you want to use it. If you used it in the constructor before you instantiated, you would get an Exception. It's just a way to make sure it's already created before the class object is contructed.

Mike42
+1  A: 
  1. the line is executed automatically when the HelloWorldSwing object is created. All fields of the class are initialized before the constructor is actually called.

  2. you can do it either way. In this case, as resultArea is modified inside the constructor, I would put the instantiation inside the constructor as well, but it is IMHO a style issue. And you are also free to modify the properties of resultArea anytime after the constructor has finished.

Péter Török
Do I understand correctly?1.When an object of a class is instantiated, all lines, written in the class before the constructor, are executed.2. I can instantiate a JTextArea, then use this object in the constructor and then "after the constructor is finished" I cam modify the properties of the objects. Would it be not more logical if I first modify the properties of an object and then I use this object in the constructor?
Roman
@Roman: 1. Not exactly. Simple field definitions aren't "executed" per se, but if you have any field initializations, then they are executed before the constructor is run.
Joachim Sauer
@Roman 1. "before" should not be taken literally. All lines which actually define (initialize) nonstatic class members are executed before the constructor, even if they are physically at the very end of the class. By convention members are listed at the beginning of the class though. 2. Not sure what you mean by this. Anyway, you can only use an object _after_ it has been properly created.
Péter Török
+1  A: 

1) No, you do not instantiate a "win" object; you instantiate a HelloWorldSwing object. Instance variables are initialized before the body of the constructor runs.

2) There's no reason why you can't instantiate the text area in the constructor. You can set various properties of the TextArea any time you like.

Jonathan Feinberg
I still have two options in my mind. 1) All lines of the class are executed after the class is called (if these lines do not belong to any of the methods defined in the class). 2). First of all, main method is executed and when something instantiate the class (for example from main method), all lines of the class are executed.
Roman
I don't understand your comment. If you read the article I linked to, perhaps those "options" will be appropriately obliterated from your mind!
Jonathan Feinberg
+3  A: 

The code you posted violates Swing threading rules. The code in main method has to run on Event Dispatch Thread and should look like:

public static void main(String[] args) {
   SwingUtilities.invokeLater(new Runnable() {
          public void run() {
              JFrame win = new HelloWorldSwing();
              win.setTitle("TextAreaDemo");
              win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              win.setVisible(true);
          }
   });
}
eugener
+2  A: 

Side note:

This is a typical example of where using a debugger will greatly help you understand the flow of execution. If you don't know how to use a debugger, I recommend these great free video tutorials for the Eclipse debugger.


Now, to answer your questions:

As far as I understand the "main" method is run automatically. In this method we instantiate a "win" object and, as a consequence the constructor of the class will be executed.

The object being instantiated is of type HelloWorldSwing, not win. win is just the name of the variable.

Is there a good reason to instantiate the text area (m_resultArea) outside the constructor and then set its parameters (setText) within the constructor.

Instantiation can occur outside of the constructor, but regular method calls like setText() must occur within another method.

But when the first line of the class is executed (JTextArea m_resultArea = new JTextArea(6, 30));.

The first line of the class is executed before the constructor.

Why we cannot instantiate the text area in the constructor?

You can as well, up to you.

Why we cannot set the parameters of the text area beyond the constructor? (Just for the sake of consistency).

As I said before, loops, method calls, etc. must occur within a method (constructor, or main, or any other method).

For more info on field initialization, you can refer to the Sun tutorial here.

JRL
+1 You merit a SuperTeacher badge as well.
unhillbilly