# Java Swings/Responsive Swing Application

* Java Swing
* Overview
* AWT
* Dive into Swings
* First Examples
* Swing Top Level Containers
* Swing Layouts
* Event Handling
* MVC architecture
* Responsive Swing Application
* Large Examples
Appendix
In this section, we'll create an application that responds to a user action, namely the pressing of a button.

## The Program

Last section, we wrote a program that displays a text label along with a button. In this section, we'll add functionality to the application so that the text changes when the user presses the button. In order to accomplish this, we'll write a subclass of JLabel that can change its text, and implements the ActionListener interface. Because a JButton generates action events when pushed, we can connect our specialized JLabel to the JButton by registering it as a listener. Here's the code:
* A new listener
* import java.awt.event.ActionEvent;
* import java.awt.event.ActionListener;
* import javax.swing.SwingConstants;
* import javax.swing.JLabel;
* // ActionEvent and ActionListener
* // live in the java.awt.event
* // package
* class ChangingLabel extends JLabel implements ActionListener {
* // String constants which define the text that's displayed.
* private static final String TEXT1 = "Hello, World!";
* private static final String TEXT2 = "Hello again!";
* // Instance field to keep track of the text currently
* // displayed
* private boolean usingText1;
* // Constructor. Sets alignment and initial text, and
* // sets the usingText1 field appropriately.
* public ChangingLabel {
* this.setHorizontalAlignment(SwingConstants.CENTER);
* this.setText(TEXT1);
* usingText1 = true;
* // A method to change the label text. If the
* // current text is TEXT1, changes it to TEXT2,
* // and vice-versa. The method is private here,
* // because it is never called directly.
* private void changeLabel {
* if(usingText1)
* this.setText(TEXT2);
* else
* this.setText(TEXT1);
* usingText1 = !usingText1;
* // This method implements the ActionListener interface.
* // Any time that an action is performed by a component
* // that this object is registered with, this method
* // is called. We can analyze the event object received
* // here for more information if we want to, but it's not
* // necessary in this application.
* public void actionPerformed(ActionEvent e) {
* this.changeLabel;
* A Swing application with an active button
* import java.awt.BorderLayout;
* import javax.swing.JButton;
* import javax.swing.JFrame;
* // Application with a changing text field
* public class HelloWithButton2 {
* public static void main(String args) {
* // Constructs the ChangingLabel. All the
* // intialization is done be the default
* // constructor, defined in the ChangingLabel
* // class below.
* ChangingLabel changingLabel = new ChangingLabel;
* // Create the button
* JButton button = new JButton("Button");
* // Register the ChangingLabel as an action
* // listener to the button. Whenever the
* // button is pressed, its ActionEvent will
* // be sent the ChangingLabel's
* // actionPerformed method, and the code
* // there will be executed.
* button.addActionListener(changingLabel);
* // Create the frame
* JFrame frame = new JFrame("Hello");
* // Add the label and the button to the
* // frame, using layout constants.
* frame.add(changingLabel, BorderLayout.CENTER);
* frame.add(button, BorderLayout.SOUTH);
* frame.setSize(300, 300);
* frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
* frame.setVisible(true);
* frame.setLocationRelativeTo(null);
* frame.toFront;
In this application, class ChangingLabel defines a special type of label that is an action listener (ie, that can receive ActionEvents) by implementing the ActionListener interface. It also has the ability to change its text through the private method changeLabel. The actionPerformed method just calls changeLabel when it receives an ActionEvent.
The main program code in HelloWithButton2 is similar to the code in the last section, but uses a ChangeLabel instead of an ordinary JLabel object. It also registers the ChangeLabel as an ActionListener of the button with the button's addActionListener method. We can do this because JButtons create ActionEvents, and ChangeLabel is an ActionListener (ie, implements the ActionListener interface).
There's one thing to notice in the above example. Two classes are defined, one to contain the program code in the static main method, and another that defines a type used in the program. However, there's no reason that we can't put the main method directly in our new type's class. In fact, putting the program's main method in a customized subclass of a component is a common idiom in programming Swing applications. When reorganized this way, the program looks like this:
* The merged class
* import javax.swing.JButton;
* import javax.swing.JFrame;
* import javax.swing.SwingConstants;
* import java.awt.BorderLayout;
* import java.awt.event.ActionEvent;
* import java.awt.event.ActionListener;
* // ActionEvent and ActionListener
* // live in the java.awt.event
* // package
* // Application with a changing text field
* public class ChangingLabel extends JLabel implements ActionListener {
* // String constants which define the text that's displayed.
* private static final String TEXT1 = "Hello, World!";
* private static final String TEXT2 = "Hello again!";
* // Instance field to keep track of the text currently
* // displayed
* private boolean usingText1;
* // Constructor. Sets alignment and initial text, and
* // sets the usingText1 field appropriately.
* public ChangingLabel {
* this.setHorizontalAlignment(SwingConstants.CENTER);
* this.setText(TEXT1);
* usingText1 = true;
* // A method to change the label text. If the
* // current text is TEXT1, changes it to TEXT2,
* // and vice-versa. The method is private here,
* // because it is never called directly.
* private void changeLabel {
* if(usingText1) {
* this.setText(TEXT2);
* usingText1 = false;
* } else {
* this.setText(TEXT1);
* usingText1 = true;
* // This method implements the ActionListener interface.
* // Any time that an action is performed by a component
* // that this object is registered with, this method
* // is called. We can analyze the event object received
* // here for more information if we want to, but it's not
* // necessary in this application.
* public void actionPerformed(ActionEvent e) {
* this.changeLabel;
* // Main method. This is the code that is executed when the
* // program is run
* public static void main(String args) {
* // Constructs the ChangingLabel. All the
* // intialization is done be the default
* // constructor, defined in the ChangingLabel
* // class below.
* ChangingLabel changingLabel = new ChangingLabel;
* // Create the button
* JButton button = new JButton("Button");
* // Register the ChangingLabel as an action
* // listener to the button. Whenever the
* // button is pressed, its ActionEvent will
* // be sent the ChangingLabel's
* // actionPerformed method, and the code
* // there will be executed.
* button.addActionListener(changingLabel);
* // Create the frame
* JFrame frame = new JFrame("Hello");
* // Add the label and the button to the
* // frame, using layout constants.
* frame.add(changingLabel, BorderLayout.CENTER);
* frame.add(button, BorderLayout.SOUTH);
* frame.setSize(300, 300);
* frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
* frame.setVisible(true);
* frame.setLocationRelativeTo(null);
* frame.toFront;
This program does exactly the same thing as the first, but organizes all the code into one class.

## Multi-threading in Swing

The thread that performs actions inside the action, change, mouse and other listeners is called a Swing thread. These methods must execute and return quickly, as the Swing thread that must be available for the Swing framework to keep the application responsive. In other words, if you perform some time-consuming calculation or other activities, you must do this in a separate thread, not in the Swing thread. However then you access Swing components from the non-swing thread you initiated yourself, they may hang due race conditions if manipulated by the Swing thread at the same time. Because of that, Swing component from the non-Swing thread must be accessed through intermediate Runnable, using the SwingUtilities.invokeAndWait method:
* Multi-threading
* String myMessage = "abc";
* final String message = myMessage; // Making final allows to access from inner class here.
* SwingUtilities.invokeAndWait(new Runnable {
* public void run {
* myLabel.setText(message);
This call will fire setText(message) in the appropriate time, when the Swing thread will be ready to respond. This approach is also usual when implementing the moving progress bar that only works properly if the slow process itself is implemented outside the Swing thread.