8

Building interfaces

This chapter demonstrates how to use Java Swing components to create a graphical program interface.

Creating a window

Adding push buttons

Adding labels

Adding text fields

Adding item selectors

Adding radio buttons

Arranging components

Changing appearance

Summary

Creating a window

Programs can provide a graphical user interface (GUI) using the “Swing” components of the Java library. The javax.swing package contains classes to create a variety of components using the style of the native operating system. These can be made available to a program by including the initial statement import javax.swing.*;.

A class must be created to represent the GUI to which components can be added to build the interface. This is easily achieved by declaring it a subclass of Swing’s JFrame class using the extends keyword – thereby inheriting attributes and behaviors that allow the user to move, resize, and close the window.

image

Remember the letter x in javax.swing by thinking of JAVA eXtra.

The class constructor should include statements to set these minimum requirements:

The title of the window – specified as a String argument to the inherited super() method of the JFrame class.

The size of the window – specified as width and height in pixels as arguments to its setSize() method.

What to do when the user closes the window – specified as a constant argument to its setDefaultCloseOperation() method.

Display the window – specified as a Boolean argument to its setVisible() method.

Additionally, the constructor can add a JPanel container component to the window, in which smaller components can be added, using the inherited add() method of the JFrame class.

By default, a JPanel container employs a FlowLayout layout manager that lays out components in left-to-right lines, wrapping at the right edge of the window.

The steps opposite describe how to create a basic window containing a JPanel container with a FlowLayout layout manager. This window is featured in subsequent examples in this book that demonstrate how to add various components to the JPanel container.

image

Layout managers are described in more detail here .

imageStart a new program that imports all Swing components

import javax.swing.* ;

image

Window.java

imageCreate a subclass of the JFrame class named “Window” containing the standard main method

class Window extends JFrame

{

public static void main ( String[] args ) {      }

}

imageBefore the main method, create a JPanel container object

JPanel pnl = new JPanel( ) ;

imageNext, insert this constructor method to specify window requirements and to add the JPanel object to the JFrame

public Window()

{

super( “Swing Window” ) ;

setSize( 500 , 200 ) ;

setDefaultCloseOperation( EXIT_ON_CLOSE ) ;

add( pnl ) ;

setVisible( true ) ;

}

imageCreate an instance of the Window class by inserting this line into the main method

Window gui = new Window() ;

imageSave the program as Window.java then compile and run the program to see the basic window appear

image

image

image

The EXIT_ON_CLOSE operation is a constant member of the JFrame class. It exits the program when the window gets closed.

image

Notice how the add() method is used here to add the JPanel object to the JFrame window.

Adding push buttons

The Swing JButton class creates a push-button component that can be added to a graphical interface. This lets the user interact with the program by clicking on a button to perform an action.

The JButton object is created with the new keyword, and its constructor takes a String argument specifying text to be displayed on that button.

Images can appear on buttons too. An ImageIcon object must first be created to represent the image, specifying the image file name as the argument to its constructor. Typically, the image will be located alongside the program but the argument can include the path for images outside the local directory.

image

Details of how to create event-handler methods to respond to user actions, such as a button click, can be found in the next chapter.

Specify the name of the ImageIcon object as the argument to the JButton constructor to display that image on the button, or specify a String and ImageIcon as its two arguments to display both text and the image.

imageEdit a copy of Window.java from here , changing the class name in the declaration, the constructor, and the instance statement from “Window” to “Buttons”

image

Buttons.java

imageBefore the Buttons() constructor, create two ImageIcon objects

ImageIcon tick = new ImageIcon( “Tick.png” ) ;

ImageIcon cross = new ImageIcon( “Cross.png” ) ;

imageNext, create three JButton objects to display text, an image, and both text and an image respectively

JButton btn = new JButton( “Click Me” ) ;

JButton tickBtn = new JButton( tick ) ;

JButton crossBtn = new JButton( “STOP” , cross ) ;

imageInside the Buttons() constructor, insert three statements to add the JButton components to the JPanel container

pnl.add( btn ) ;

pnl.add( tickBtn ) ;

pnl.add( crossBtn ) ;

imageSave the program as Buttons.java then compile and run the program to see push buttons appear in the window

image

The JPanel object has an add() method – to add components to that panel.

image

image

image

Details of how to create a Java Archive (JAR) can be found here .

The buttons respond graphically when they are clicked, but will not perform an action until the program provides an event-handler method to respond to each click event.

Where the program is intended for deployment in a single Java archive (JAR), image resources must be loaded by a ClassLoader object before creating the ImageIcon objects to represent them.

Specifying the resource file name or path to the getResource() method of a ClassLoader returns a URL, which can be used as the argument to the ImageIcon constructor. The java.net package provides a useful URL class to which these may first be assigned.

imageBefore the Buttons() constructor, create a ClassLoader object

ClassLoader ldr = this.getClass().getClassLoader() ;

imageLoad the URLs of the image resources

java.net.URL tickURL = ldr.getResource( “Tick.png” ) ;

java.net.URL crossURL = ldr.getResource( “Cross.png” ) ;

imageEdit the ImageIcon() constructors in Step 2 opposite to use URLs

ImageIcon tick = new ImageIcon( tickURL ) ;

ImageIcon cross = new ImageIcon( crossURL ) ;

imageSave the changes then recompile and re-run the program – it will run as before but can now be deployed in a JAR

image

Notice how the getClass() method and this keyword are used here to reference this class object.

Adding labels

The Swing JLabel class creates a label component that can be added to a graphical interface. This can be used to display non-interactive text or image, or both text and an image.

The JLabel object is created with the new keyword, and its constructor takes a String argument specifying text to be displayed on that label, or the name of an ImageIcon object representing an image to display. It can also take three arguments to specify text, image, and horizontal alignment as a JLabel constant value. For example, JLabel( “text”, img, JLabel.CENTER ) aligns centrally.

Where a JLabel object contains both text and an image, the relative position of the text can be determined by specifying a JLabel constant as the argument to setVerticalPosition() and setHorizontalPosition() methods of the JLabel object.

Additionally, a JLabel object can be made to display a ToolTip when the cursor hovers over, by specifying a text String as the argument to that object’s setToolTipText() method.

imageEdit a copy of Window.java from here , changing the class name in the declaration, the constructor, and the instance statement from “Window” to “Labels”

image

Labels.java

imageBefore the Labels() constructor, create an ImageIcon object

ImageIcon duke = new ImageIcon( “Duke.png” ) ;

imageNext, create three JLabel objects to display an image, text, and both text and an image respectively

JLabel lbl1 = new JLabel( duke ) ;

JLabel lbl2 = new JLabel( “Duke is the friendly mascot of Java technology.” ) ;

JLabel lbl3 = new JLabel( “Duke” , duke , JLabel.CENTER ) ;

imageInside the Labels() constructor, insert this statement to create a ToolTip for the first label

lbl1.setToolTipText( “Duke - the Java Mascot” ) ;

imageAdd these two statements to align the text centrally below the third label

lbl3.setHorizontalTextPosition( JLabel.CENTER ) ;

lbl3.setVerticalTextPosition( JLabel.BOTTOM ) ;

imageNow, add three statements to add the JLabel components to the JPanel container

pnl.add( lbl1 ) ;

pnl.add( lbl2 ) ;

pnl.add( lbl3 ) ;

imageSave the program as Labels.java then compile and run the program, placing the cursor over the first label

image

image

image

JLabel alignment constants include LEFT, CENTER, RIGHT, TOP and BOTTOM.

Where the program is intended for deployment in a single Java archive (JAR), the image resource must be loaded by a ClassLoader object before creating the ImageIcon object to represent it.

Specifying the resource file name or path to the getResource() method of a ClassLoader returns a URL, which can be used as the argument to the ImageIcon constructor.

imageBefore the Labels() constructor, create a ClassLoader object

ClassLoader ldr = this.getClass().getClassLoader() ;

imageEdit the ImageIcon() constructor in Step 2 opposite to load the URL of the image resource using the ClassLoader object

ImageIcon duke = new ImageIcon( ldr.getResource( “Duke.png” ) ) ;

imageSave the changes, then recompile and re-run the program – it will run as before, but can now be deployed in a JAR

image

Details of how to create a Java Archive (JAR) can be found here .

Adding text fields

The Swing JTextField class creates a single-line text field component that can be added to a graphical interface. This can be used to display editable text, and allows the user to enter text to interact with the program.

The JTextField object is created with the new keyword, and its constructor can take a String argument specifying default text to be displayed in that field. In this case, the component will be sized to accommodate the length of the String. Alternatively, the argument may be a numeric value to specify the text field size. The constructor can also take two arguments, specifying both default text and the text field size.

image

Use the JPasswordField class instead of the JTextField class where input characters are needed to be not visible.

A multiple-line text field can be created with the JTextArea class, whose constructor takes two numerical arguments specifying its number of lines and its width. Alternatively, three arguments can be supplied specifying default text, line number, and width. Text can be made to wrap at word endings within this field by specifying true as the argument to the setLineWrap() method and setWrapStyleWord() method of the JTextArea object.

Where text entered into a JTextArea component exceeds its initial size, the component will expand to accommodate the text. To make the component a fixed size with scrolling capability, it can be placed in a JScrollPane container. This is created with the new keyword, and takes the name of the JTextArea as its argument.

Scroll bars will, by default, only appear when the field contains text that exceeds its initial size – but they can be made to appear constantly by specifying a JScrollPane constant as the argument to the snappily-named setVerticalScrollBarPolicy() or setHorizontalScrollBarPolicy() methods of the JScrollPane object. For example, to always display a vertical scrollbar use the JScrollPane.VERTICAL_SCROLLBAR_ALWAYS constant as the argument.

imageEdit a copy of Window.java from here , changing the class name in the declaration, the constructor, and the instance statement from “Window” to “TextFields”

image

TextFields.java

imageBefore the TextFields() constructor, create two JTextField objects

JTextField txt1 = new JTextField( 38 ) ;

JTextField txt2 = new JTextField( “Default Text” , 38 ) ;

imageCreate a JTextArea object five lines high

JTextArea txtArea = new JTextArea( 5 , 37 ) ;

imageAdd a JScrollPane object – to contain the JTextArea created in Step 3, above

JScrollPane pane = new JScrollPane( txtArea ) ;

imageIn the TextFields() constructor method, insert statements to enable the JTextArea object to wrap at word endings

txtArea.setLineWrap( true ) ;

txtArea.setWrapStyleWord( true ) ;

imageInsert a statement to always display a vertical scrollbar for the JTextArea object

pane.setVerticalScrollBarPolicy ( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS ) ;

imageInsert two statements to add the JTextField components to the JPanel container

pnl.add( txt1 ) ;

pnl.add( txt2 ) ;

imageInsert another statement to add the JScrollPane container, (containing the JTextArea field) to the JPanel container

pnl.add( pane ) ;

imageSave the program as TextFields.java then compile and run the program, entering some text into the text area

image

image

image

A JTextArea component has no scrolling ability unless it is contained within a JScrollPane component.

Adding item selectors

The Swing JCheckBox class creates a checkbox component that can be added to a graphical interface. This can be used to allow the user to select or deselect individual items in a program.

The JCheckBox object is created with the new keyword, and its constructor takes a String argument specifying text to be displayed alongside that checkbox. It can also take a second true argument to make the checkbox be selected by default.

A choice of items can be offered by the JComboBox class that creates a drop-down list from which the user can select any single item. This object is created with the new keyword, and its constructor typically takes the name of a String array as its argument. Each element in the array provides an item for selection in the drop-down list. Similarly, a choice of items can be offered by the JList class that creates a fixed-size list from which the user can select one or more items. It is created with the new keyword, and its constructor also takes an array as its argument, with each element providing an item for selection. As both JList and JComboBox are “Collections” they must specify the generic type they may contain when they get created, such as <String>.

imageEdit a copy of Window.java from here , changing the class name in the declaration, the constructor, and the instance statement from “Window” to “Items”

image

Items.java

imageBefore the Items() constructor, create a String array of items for selection

String[] toppings = { “Pepperoni” , “Mushroom” , “Ham” , “Tomato” } ;

imageNext, create four JCheckBox objects to present each array item for selection – with one selected by default

JCheckBox chk1 = new JCheckBox( toppings[0] ) ;

JCheckBox chk2 = new JCheckBox( toppings[1] , true ) ;

JCheckBox chk3 = new JCheckBox( toppings[2] ) ;

JCheckBox chk4 = new JCheckBox( toppings[3] ) ;

imageAdd a second String array of items for selection

String[] styles = { “Deep Dish” , “Gourmet Style” , “Thin & Crispy” } ;

imageCreate a JComboBox object to present each item in the second array for selection

JComboBox<String> box1 = new JComboBox<String>( styles ) ;

imageAdd a JList object to present each item in the first array for selection from a list

JList<String> lst1 = new JList<String>( toppings ) ;

imageIn the Items() constructor method, insert statements to add each JCheckBox component to the JPanel container

pnl.add( chk1 ) ;

pnl.add( chk2 ) ;

pnl.add( chk3 ) ;

pnl.add( chk4 ) ;

imageInsert statements to make a default selection and to add the JComboBox component to the JPanel container

box1.setSelectedIndex( 0 ) ;

pnl.add( box1 ) ;

imageNow, insert a statement to add the JList component to the JPanel container

pnl.add( lst1 ) ;

imageSave the program as Items.java then compile and run the program, selecting items from the lists

image

image

image

Only one item can be selected from a JComboBox component – multiple items can be selected from a JList component.

image

Details of how to create event-handler methods to respond to user actions, such as an item selection, can be found in Chapter 9.

Adding radio buttons

The Swing JRadioButton class creates a radio button component that can be added to a graphical interface. This can be used to allow the user to select an item from a group of radio buttons.

The JRadioButton object is created with the new keyword, and its constructor takes a String argument specifying text to be displayed alongside that radio button. It can also take a second true argument to make a radio button be selected by default.

A ButtonGroup object logically groups a number of radio buttons so that only one button in that group can be selected at any time. Each radio button is added to the ButtonGroup object by specifying its name as the argument to the group’s add() method.

imageEdit a copy of Window.java from here , changing the class name in the declaration, the constructor, and the instance statement from “Window” to “Radios”

image

Radios.java

imageBefore the Radios() constructor, create three JRadioButton objects – with one selected by default

JRadioButton rad1 = new JRadioButton( “Red” , true ) ;

JRadioButton rad2 = new JRadioButton( “Rosé” ) ;

JRadioButton rad3 = new JRadioButton( “White” ) ;

imageNext, create a ButtonGroup object with which to group the radio buttons

ButtonGroup wines = new ButtonGroup() ;

imageIn the Radios() constructor method, insert statements to add each JRadioButton component to the JButtonGroup

wines.add( rad1 ) ;

wines.add( rad2 ) ;

wines.add( rad3 ) ;

imageInsert statements to add the JRadioButton components to the JPanel container

pnl.add( rad1 ) ;

pnl.add( rad2 ) ;

pnl.add( rad3 ) ;

imageSave the program as Radios.java then compile and run the program, selecting any one radio button after the default

image

The ButtonGroup object only groups the buttons logically, not physically.

image

image

image

Details of how to create event-handler methods to respond to user actions can be found in the next chapter.

The examples on the previous pages have demonstrated the most common Swing components – JButton, JLabel, JTextField, JCheckBox, JComboBox, JList and JRadioButton. There are many more specialized components available in the javax.swing package, whose details can be found in the Java documentation. For example, the JSlider, JProgressBar, and JMenuBar components below:

image

image

image

image

Try using the Java documentation to add a JSlider component to the Radios program – see here for details on how to use the documentation.

Arranging components

The java.awt package (Abstract Window Toolkit) contains a number of layout manager classes that can be used to place components in a container in different ways.

A layout manager object is created using the new keyword, and can then be specified as the argument to a JPanel constructor to have the panel use that layout. When components get added to the panel they will be placed according to the rules of the specified layout manager.

Layout Manager:

Rules:

BorderLayout

Places North, South, East, West and Center (the content pane default)

BoxLayout

Places in a single row or column

CardLayout

Places different components in a specified area at different times

FlowLayout

Places left to right in a wrapping line (the JPanel default)

GridBagLayout

Places in a grid of cells, allowing components to span cells

GridLayout

Places in a grid of rows and columns

GroupLayout

Places horizontally and vertically

SpringLayout

Places by relative spacing

The top level JFrame object has a “content pane” container that places components using the BorderLayout layout manager by default. This can be used to place up to five JPanel containers, which may each use their default FlowLayout layout manager, or any of the layout managers in the table above. Using a variety of layout managers accommodates most layout requirements.

The content pane can be represented by a java.awt.Container object, whose add() method can specify the position and name of a component to be placed within the content pane.

image

You can find further details of each layout manager in the java.awt section of the Java documentation.

imageEdit a copy of Window.java from here , changing the class declaration, constructor, and instance from “Window” to “Layout”, then add a statement at the start of the program to import the functionality of the java.awt package

import java.awt.* ;

image

Layout.java

imageBefore the Layout() constructor, create a Container object representing the JFrame content pane container

Container contentPane = getContentPane() ;

imageCreate a second JPanel object using a GridLayout layout manager in a 2 x 2 grid

JPanel grid = new JPanel( new GridLayout( 2 , 2 ) ) ;

imageIn the Layout() constructor method, insert statements adding JButton components to both JPanel objects

pnl.add( new JButton( “Yes” ) ) ;

pnl.add( new JButton( “No” ) ) ;

pnl.add( new JButton( “Cancel” ) ) ;

grid.add( new JButton( “1” ) ) ;

grid.add( new JButton( “2” ) ) ;

grid.add( new JButton( “3” ) ) ;

grid.add( new JButton( “4” ) ) ;

imageNow, insert statements adding both panels and a button to the content pane

contentPane.add( “North” , pnl ) ;

contentPane.add( “Center” , grid ) ;

contentPane.add( “West” , new JButton( “West” ) ) ;

imageSave the program as Layout.java then compile and run the program to see the component layout

image

image

While the FlowLayout maintains the JButton size, other layout managers expand the components to fill their layout design.

Changing appearance

The java.awt package (Abstract Window Toolkit) contains “painting” classes that can be used to color interface components. These can be made available to a program by including the initial statement import java.awt.* ; .

Included in the java.awt package is a Color class that has constants representing a few basic colors, such as Color.RED. Additionally, instances of the Color class can be created using the new keyword to represent custom colors. The constructor can take three integer arguments between zero and 255 to represent red, green, and blue (RGB) values to form the custom color.

Each component has a setBackground() method and a setForeground() method that take a Color object as their argument to paint that component with the specified color.

Note that the background of JLabel components are transparent by default, so it is recommended that their setOpaque() method should be called to set the opacity to true before they are painted.

Also in the java.awt package is a Font class that can be used to modify the font displaying text. A Font object represents a font, and its constructor can take three arguments to specify name, style and size:

The specified name should be one of the three platform-independent names “Serif ”, “SansSerif ” or “Monospaced”.

The specified style should be one of the following three
constants: Font.PLAIN, Font.BOLD or Font.ITALIC

The specified size should be an integer of the point size.

Each component has a setFont() method that takes a Font object as its argument to paint that component with the specified font.

imageEdit a copy of Window.java from here , changing the class name in the declaration, the constructor, and the instance statement from “Window” to “Custom”

image

Custom.java

imageAdd a statement at the very start of the program to import the functionality of all classes in the java.awt package

import java.awt.* ;

imageBefore the Custom() constructor, create three JLabel objects

JLabel lbl1 = new JLabel( “Custom Background” ) ;

JLabel lbl2 = new JLabel( “Custom Foreground” ) ;

JLabel lbl3 = new JLabel( “Custom Font” ) ;

imageNext, create Color, Font, and Box layout objects

Color customColor = new Color( 255 , 0 , 0 ) ;

Font customFont = new Font( “Serif” , Font.PLAIN , 64 ) ;

Box box = Box.createVerticalBox() ;

imageIn the Custom() constructor method, insert statements to color a JLabel background using a Color constant

lbl1.setOpaque( true ) ;

lbl1.setBackground( Color.YELLOW ) ;

imageInsert a statement to color a JLabel foreground using a custom Color object

lbl2.setForeground( customColor ) ;

imageInsert a statement to paint text on a JLabel component using a custom font

lbl3.setFont( customFont ) ;

imageAdd each label to the layout container

box.add( lbl1 ) ; box.add( lbl2 ) ; box.add( lbl3 ) ;

imageThen, add the layout container to the JPanel container

pnl.add( box ) ;

imageSave the program as Custom.java then compile and run the program to see the effect

image

image

In this case, the custom color is equivalent to Color.RED as the RGB value specifies the maximum red value with no green or blue.

image

A Box object is a handy lightweight container that uses BoxLayout as its layout manager. The Box object’s createVerticalBox() method individually displays its components from top to bottom.

Summary

The javax.swing package contains the Java Swing classes that are used to create GUI components.

A window is created as a top-level JFrame container.

The JFrame constructor should specify the window’s title, size, default close operation and visibility.

A JPanel container displays smaller components in a wrapping line using its default FlowLayout layout manager.

The JButton constructor can specify text and images to be displayed on a push button component.

An ImageIcon object represents an image to use in the program.

Programs that are to be deployed as a single Java archive (JAR) should use a ClassLoader object to specify an image source.

A JLabel object displays non-interactive text and image content.

Editable text can be displayed in JTextField and JTextArea fields.

A JScrollPane object provides scrollbars for a JTextArea field.

Items for selection can be displayed with JCheckBox, JComboBox and JList components.

A ButtonGroup object logically groups a number of JRadioButton components so only one can be selected.

Specific RGB colors can be represented by the Color class of the java.awt package.

The java.awt package has a Font class that can be used to create objects representing a particular font name, style, and size.

Multiple JPanel containers can be added to a JFrame container by using the Container class of the java.awt package to represent the content pane of the JFrame.

When creating a JPanel container object, its argument may optionally specify a layout manager.