Java GUI Basics

In this article, the framework of Java GUI API will be introduced. We can use the GUI components to develop user-friendly interfaces for Java applications.

What is Swing?

Swing is a GUI widget toolkit for Java. It is part of Oracle’s Java Foundation Classes – an API for providing a graphical user interface for Java programs. Swing was developed to provide a more sophisticated set of GUI components than the earlier Abstract Window Toolkit.

Common GUI Objects in Swing:

Swing vs. AWT

  • So why do the GUI component classes have a prefix J?

Because there is already a old GUI class in java.awt package.

What is AWT?

When Java was introduced, the GUI classes were bundled in a library known as the Abstract Windows Toolkit (AWT). For every platform on which Java runs, the AWT components are automatically mapped to the platform-specific components through their respective agents, known as peers.

  • AWT is fine for developing simple graphical user interfaces, but not for developing comprehensive GUI projects.
  • Besides, AWT is prone to platform-specific bugs because its peer-based approach relies heavily on the underlying platform.

To distinguish new Swing component classes from their AWT counterparts, Swing GUI component classes are named with a prefix J.

Why We are using Swing for GUI components?

With the release of Java 2, the AWT user-interface components were replaced by Swing components.

  • Swing components are painted directly on canvases using Java code, except for components that are subclasses of java.awt.Window or java.awt.Panel, which must be drawn using native GUI on a specific platform.
  • Swing components are less dependent on the target platform and use less of the native GUI resource.

For this reason, Swing components that do not rely on native GUI are referred to as lightweight components, and AWT components are referred to as heavyweight components.

Note we will still be using both AWT and Swing.

Frames

Frames are under Swing.

Frame is a window that is not contained inside another window.

  • the basis to contain other user interface components in Java GUI applications
  • For Swing GUI programs, use JFrame class to create windows.
  • A container such as JFrame is also a component.

Code Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
import javax.swing.*; // * means import all

public class myFrame{
public static void main(String[] args) {
JFrame frame = new JFrame("Frame name");
int x = 400;
int y = 300;
frame.setSize(x,y);
frame.setVisible(true); //Otherwise the frame will not show up
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
// By running the program, you get a blank window with title "Frame name"
  • For components, the default Visible is true.
  • For frames, the dafault Visible is false.

The setDefaultCloseOperation() method is used to specify one of several options for the close button. Use one of the followinng constants to specify your choice:

  • JFrame.EXIT_ON_CLOSE - Exit the application.
  • JFrame.HIDE_ON_CLOSE - Hide the frame, but keep the application running.
  • JFrame.DISPOSE_ON_CLOSE - Dispose of the frame object but keep the application runnning.
  • JFrame.DO_NOTHING_ON_CLOSE - Ignore the click

Note: If you forget to call setDefaultCloseOperation() you will get JFrame.HIDE_ON_CLOSE by default. This can be frustrating, because it looks like you have “killed” the program, but it keeps on running, and you see no frame.

Adding Common GUI Objects into Frame

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import javax.swing.*; // * means import all

public class myFrame{
public static void main(String[] args) {
JFrame frame = new JFrame("Frame name");

// Add a button into the frame
frame.getContentPane().add(new JButton("OK"));

// Add a Label into the frame
frame.getContentPane().add(new JLabel("Enter your name: "));

// Add a Text field into the frame
frame.getContentPane().add(new JTextField("Type name here"));

// Add a check box with text
frame.getContentPane().add(new JCheckBox("Over 18"));

// Add a radio button
frame.getContentPane().add(new JRadioButton("Happy"));

// Add a combo box (dropdown menu)
frame.getContentPane().add(new JComboBox(new String[]{"a","b","c"}));

int x = 400;
int y = 300;
frame.setSize(x,y);
frame.setVisible(true); //Otherwise the frame will not show up
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Color and Fonts

Color and Fonts are under AWT.

We can use the java.awt.Color class and java.awt.Font class to set Color and Font of the Swing GUI Objects.

Color Class

  • Colors are made of red, green, and blue components, each of which is represented by a byte value that describes its intensity, ranging from 0 (darkest shade) to 255 (lightest shade).
  • We can use RGB to represent a color
    • e.g. Color c = new Color(r, g, b) where r g b are the r g b values
  • 13 Standard colors are also provided
    • BLACK or black
    • BLUE or blue
    • CYAN or cyan
    • DARK_GRAY or darkGray
    • GRAY or gray
    • GREEN or green
    • LIGHT_GRAY or lightGray
    • MAGENTA or magenta
    • ORANGE or orange
    • PINK or pink
    • RED or red
    • WHITE or white
    • YELLOW or yellow

The standard color names are constants, but they are named like variables with lowercase for the first word and uppercase for the first letter of subsequent words. Thus the color names violate the Java naming convention. Since JDK 1.4, you can also use the new constants which are the uppercase version.

We can set the component’s background and foreground colors.

To create color: Color c = new Color(r, g, b);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import javax.swing.*; // * means import all
import java.awt.Color;

public class myFrame{
public static void main(String[] args) {
JFrame frame = new JFrame("Frame name");

JButton jbtn = new JButton("OK");
Color c = new Color(288, 100, 255); // RGB, purple color
jbtn.setBackground(Color.YELLOW);
jbtn.setForeground(Color.RED);

// Add a button into the frame
frame.getContentPane().add();

int x = 400;
int y = 300;
frame.setSize(x,y);
frame.setVisible(true); //Otherwise the frame will not show up
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Font Class

  • Standard font names that are supported in all platforms are:
    • SansSerif
    • Serif
    • Monospaced
    • Dialog
    • DialogInput
  • Font Style:
    • Font.PLAIN (0)
    • Font.BOLD (1)
    • Font.ITALIC (2)
    • Font.BOLD + Font.ITALIC (3)

To use the create the Font: Font myFont = new Font(name, style, size);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import javax.swing.*; // * means import all
import java.awt.Font;

public class myFrame{
public static void main(String[] args) {
JFrame frame = new JFrame("Frame name");

JButton jbtn = new JButton("OK");
Font myFont = new Font("Serif", Font.BOLD+Font.ITALIC, 12);
jbtn.setFont(myFont);

// Add a button into the frame
frame.getContentPane().add();

int x = 400;
int y = 300;
frame.setSize(x,y);
frame.setVisible(true); //Otherwise the frame will not show up
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Finding All available Font Names

The following statements print all the available font names in the system:

1
2
3
4
5
import java.awt.GraphicsEnvironment;
GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fontnames = e.getAvailableFontFamilyNames();
for (int i = 0; i < fontnames.length; i++)
System.out.println(fontnames[i]);

Borders

Border is also under Swing.

You can set a border on any object of the JComponent class.

import javax.swing.border.*

Titled Border

  • To create a titled border, use: new TitledBorder(String title)
1
2
3
JPanel panel = new JPanel();
panel.setBorder(new TitledBorder("My Panel"));
frame.getContentPane().add(panel);

Line Border

  • To create a line border, use: new LineBorder(Color color, int width)
1
2
3
JPanel panel = new JPanel();
panel.setBorder(new LineBorder(Color.RED, 5));
frame.getContentPane().add(panel);

Layout Managers

Layout Managers is under AWT.

Java’s layout managers provide a level of abstraction to automatically map your user interface on all window systems.

  • The Java GUI components are placed in containers.
  • Each container has a layout manager to arrange the Java GUI components within the container.

Types of Layout

Layout managers are set in containers using the setLayout(LayoutManager) method in a container.

  • FlowLayout
  • GridLayout
  • BorderLayout

FlowLayout Manager

  • The components are arranged in the container from left to right in the order in which they were added.
  • When one row is filled, a new row is started.
  • The default layout of a JPanel is FlowLayout.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JFrame;
import java.awt.FlowLayout;

public class ShowFlowLayout extends JFrame {
public ShowFlowLayout() {
// Set FlowLayout, aligned left with horizontal gap 10
// and vertical gap 20 between components
setLayout(new FlowLayout(FlowLayout.LEFT, 10, 20));

// Add labels and text fields to the frame
add(new JLabel("First Name"));
add(new JTextField(8));
add(new JLabel("MI"));
add(new JTextField(1));
add(new JLabel("Last Name"));
add(new JTextField(8));
}

/** Main method */
public static void main(String[] args) {
ShowFlowLayout frame = new ShowFlowLayout();
frame.setTitle("ShowFlowLayout");
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
// Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

You should use FlowLayout to position a Component within an application Frame if you want the size of the Component NOT affected by the Frame size.

GridLayout Manager

  • components arranged in a grid (matrix) formation.
  • The components are placed in the grid from left to right, starting from the first row, then the second, and so on, in the order in which they were added.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JFrame;
import java.awt.GridLayout;

public class ShowGridLayout extends JFrame {
public ShowGridLayout() {
// Set GridLayout, 3 rows, 2 columns, and gaps 5 between
// components horizontally and vertically
setLayout(new GridLayout(3, 2, 5, 5));
// Add labels and text fields to the frame
add(new JLabel("First Name"));
add(new JTextField(8));
add(new JLabel("MI"));
add(new JTextField(1));
add(new JLabel("Last Name"));
add(new JTextField(8));
}

/** Main method */
public static void main(String[] args) {
ShowGridLayout frame = new ShowGridLayout();
frame.setTitle("ShowGridLayout");
frame.setSize(200, 125);
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

Note

  • GridLayout(int rows, int cols)
  • GridLayout(int rows, int cols, int hgap, int vgap)

Rows or Cols can be 0. which means that any number of objects can be placed in a row or in a column.

However if you set both rows and cols as 0 there will be a runtime error.

If the components number is more than the grid itself can hold, It will expands the columns.

E.g. Suppose a JFrame uses the GridLayout(2, 2). If you add six buttons to the frame, 3 columns are displayed.

BorderLayout Manager

  • BorderLayout manager divides the container into five areas: East, South, West, North, and Center.
  • Components are added to a BorderLayout by using the add method.
  • The default layout of a contentPane in a JFrame is BorderLayout.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.BorderLayout;

public class ShowBorderLayout extends JFrame {
public ShowBorderLayout() {
// Set BorderLayout with horizontal gap 5 and vertical gap 10
setLayout(new BorderLayout(5, 10));
// Add buttons to the frame
add(new JButton("East"), BorderLayout.EAST);
add(new JButton("South"), BorderLayout.SOUTH);
add(new JButton("West"), BorderLayout.WEST);
add(new JButton("North"), BorderLayout.NORTH);
add(new JButton("Center"), BorderLayout.CENTER);
}
/** Main method */
public static void main(String[] args) {
ShowBorderLayout frame = new ShowBorderLayout();
frame.setTitle("ShowBorderLayout");
frame.setSize(300, 200);
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

Using Panels as Sub-Containers

JPanel is under Swing.

Panels act as sub-containers for grouping user interface components.

  • **It is recommended that you place the user interface components in panels and place the panels in a frame. **

You can also place panels in a panel.

  • You can use new JPanel() to create a panel with a default FlowLayout manager or new JPanel(LayoutManager) to create a panel with the specified layout manager.
  • To add a component to a panel, you add it directly to the panel using the add method, just like what we did to the frame.
1
2
JPanel p = new JPanel(); // default FlowLayout
p.add(new JButton("OK"));

Example using Panels with LayoutManager

  • This example uses panels to organize components.
  • The program creates a user interface for a Microwave oven.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.awt.*;
import javax.swing.*;

public class TestPanels extends JFrame{
public TestPanels(){
// Create panel p1 for the buttons and set GridLayout
JPanel p1 = new JPanel();
p1.setLayout(GridLayout(4, 3)); // Set GridLayout, 4 rows, 3 columns

//Add buttons to the panel
for (int i = 1; i <= 9; i++){
p1.add(new JButton("" + i));
}

p1.add(new JButton("" + 0));
p1.add(new JButton("Start"));
p1.add(new JButton("Stop"));

// Create panel p2 to hold a text field and p1
JPanel p2 = new JPanel(new BorderLayout());
//It is better to always choose the first component position as CENTER
p2.add(new JTextField("Time to be displayed here"), BorderLayout.CENTER);
p2.add(p1, BorderLayout.SOUTH);

//add contents into the frame
setLayout(new BorderLayout());
//It is better to always choose the first component position as CENTER
add(p2, BorderLayout.CENTER);
add(new JButton("Food to be placed here"), BorderLayout.WEST);

/** Main method */
public static void main(String[] args){
TestPanels frame = new TestPanels();
frame.setTitle("The Front View of a Microwave Oven");
frame.setSize(400, 250);
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}

}
}

Java Graphics

  • You can draw graphics on any GUI components.

Unlike the Conventional Coordinate System, Java use this Coordinate System.

The coordinate of the upper-left corner of a frame is (0,0).

The Graphics Class

Graphics class is under AWT.

You can draw strings, lines, rectangles, ovals, arcs, polygons, and polylines, using the methods in the Graphics class.

To use the class, import java.awt.Graphics

As mentioned, you can just import java.awt.* .

Each GUI Component Has its Own Coordinate System

Drawing Strings / Lines

1
2
drawString(String s, int x, int y);
drawLine(int x1, int y1, int x2, int y2);

Drawing Rectangles

1
2
drawRect(int x, int y, int w, int h);
fillRect(int x, int y, int w, int h);

Drawing Rounded Rectangles

1
2
drawRoundRect(int x, int y, int w, int h, int aw, int ah);
fillRoundRect(int x, int y, int w, int h, int aw, int ah);

Drawing Ovals

1
2
drawOval(int x, int y, int w, int h);
fillOval(int x, int y, int w, int h);

Drawing Arcs

1
2
drawArc(int x, int y, int w, int h, int angle1, int angle2);
fillArc(int x, int y, int w, int h, int angle1, int angle2);

Drawing Polygons and Polylines

1
2
3
4
int[] x = {40, 70, 60, 45, 20};
int[] y = {20, 40, 80, 45, 60};
g.drawPolygon(x, y, x.length);
g.drawPolyline(x, y, x.length);

Image Icons

Image Icon is under Swing.

Java uses the javax.swing.ImageIcon class to represent an icon.

  • An icon is a fixed-size picture; typically it is small and used to decorate components.
    • You can display image icons in labels and buttons.
  • Images are normally stored in image files.
  • To construct an image icon: new ImageIcon(filepath)
1
2
3
ImageIcon icon = new ImageIcon("image/smiley.jpg");
JLabel jlb_smiley = new JLabel(icon);
frame.getContentPane().add(jlb_smiley);

Image Class

Image class is under AWT

To display an image in a flexible size, you need to use java.awt.Image class.

  • An image can be created from an image icon using the getImage() method as follows :
1
Image image = imageIcon.getImage();

Using a label as an area for displaying images is simple and convenient, but you don’t have much control over how the image is displayed.

  • A more flexible way to display images is to use the drawImage method of the Graphics class on a panel.

Note To paint something we first need a surface(canvas) where to paint on.

In the same way a canvas needs a frame to hold it, our JPanel will be framed in a window made by the JFrame class.

Full example of Graphic class

SwingPaintDemo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
import java.awt.Color;
import java.awt.Graphics;

public class SwingPaintDemo {
public static void main(String[] args) {

JFrame frame = new JFrame("Swing Paint Demo");
frame.add(new MyPanel()); //Check MyPanel.java
frame.setSize(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

MyPanel.java

  • The paintComponent method is where all of your painting code should be placed.
  • It is true that this method will be invoked when it is time to paint, but painting actually begins higher up the class heirarchy, with the paint method (defined by java.awt.Component.)
  • This method will be executed by the painting subsystem whenever your component needs to be rendered. Its signature is: public void paint(Graphics g)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyPanel extends JPanel {
public MyPanel() {
setBorder(new LineBorder(Color.RED, 5));
}
//where all of your custom painting takes place
public void paintComponent(Graphics g) {
//passes the graphics context off to the component's UI delegate,
//which paints the panel's background.
super.paintComponent(g);
// Draw Text
g.drawString("This is my custom Panel!", 10, 20);
g.setColor(Color.RED);
g.fillOval(10, 30, 30, 30);
g.drawOval(10, 80, 30, 30);
g.fillRect(60, 30, 30, 30);
g.drawRect(60, 80, 30, 30);
}
}

For all practical purposes, paintComponent will be the only method that you will ever need to override.

Output:

Some Concept Questions

Association, Composition and Aggregation in Java

What is best to describe the relationship between a container and a Swing GUI object in the container?

Composition

a Swing GUI object in the container is a part of container

a Swing GUI object is in the container

  • In composition, both the entities are dependent on each other.

What is best to describe the relationship between a container and a layout manager?

Aggregation

Container has a layout manager

  • It is a unidirectional association i.e. a one way relationship.

What is best to describe the relationship between Component and Color?

Association

What is best to describe the relationship between Component and Font?

Association

What is best to describe the relationship between JComponent and JButton?

Inheritance

Given a Graphics object g, to draw a line from the upper left corner to the bottom right corner, you use ________.

g.drawLine(0, 0, getWidth(), getHeight())

Suppose a button jbt is placed in a frame, the coordinate of the button within the content pane of the frame is ________.

(jbt.getX(), jbt.getY())

To draw graphics, it is better to declare a class that extends ________ and override the paintComponent method.

JPanel

You should override the ________ method to draw things on a Swing component.

paintComponent()

Given a Graphics object g, to draw a polygon to connect points (3, 3), (4, 10), (10, 20), (2, 100), you use ________.

g.drawPolygon(new int[ ]{3, 4, 10, 2}, new int[ ]{3, 10, 20, 100}, 4)

Given a Graphics object g, to draw a filled oval with width 20 and height 30 centered at (50, 50), you use ________.

g.fillOval(40, 35, 20, 30)

Given a Graphics object g, to draw a filled arc with radius 20 centered at (50, 50) and start angle 0 and spanning angle 90, you use ________.

g.fillArc(30, 30, 40, 40, 0, 90)

To create a JPanel of the BorderLayout, use ________.

JPanel p = new JPanel(new BorderLayout());

Analyze the following code.

1
2
3
4
5
6
7
8
9
10
11
12
13
import java.awt.*;
import javax.swing.*;

public class GuiTest2{
public static void main(String[] args){
JFrame frame = new JFrame("My Frame");
frame.add(new JButton("OK"));
frame.add(new JButton("Cancel"));
frame.setSize(200,200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

Only button Cancel is shown.

To create an image icon for a file in c:\book\image\icon, use ________.

new ImageIcon(ʺc:\\book\\image\\iconʺ);

Note because \ is a special character in String. we need to apply another \.