 |
Graphical User Interfaces
|
Reading: The cucs
package
The cucs
GUI Class
-
Introduction
-
Many programs obtain data and display results in a Graphical User Interface
(GUI) window, rather than in a command window as in our programs so far.
-
cucs
GUI class - one way to create simple GUIs for use in programs
-
Basic terminology used when working with GUIs:
-
GUI usually has a title at the top of the window
-
Various buttons and text fields for entering and displaying
data within the window.
-
For example, window whose layout is:
-------------------------------------------------
| Greeting |
|-------------------------------------------------|
| |
| ------------------------------- |
| Name: | | |
| ------------------------------- |
| |
| ------- |
| | Hello | |
| ------- |
| |
| ------------------------------- |
| Message: | | |
| ------------------------------- |
| |
-------------------------------------------------
"Greeting" is the title. There is a button labeled "Hello", and there are text fields with labels "Name:" and "Message:".
Window
components such as buttons, text fields, and labels are sometimes called
widgets.
-
May wish to look at the
code for this example before we look at its details. If you do look
at it now, don't try to understand it, but just try to get a general feel
for it. The code is explained below. You can also download the program
and compile and execute it to get a feel for what it does.
-
So:
-
In Java a GUI window is an object, and each widget is also an object.
-
GUI window is an instance of some class, as is each of the components of
the window.
-
Much of the setting up and basic management of a window is usually done
by predefined system methods, which allows new GUIs created by a program
to have the standard "look and feel" of the underlying platform.
-
For example, the above window, if created by a Java program using the standard
classes and methods in package java.awt
and the cucs
package, would look similar on Windows and Unix platforms, but the
border and the controls for closing, resizing, etc., would be the standard
ones for that platform.
-
Using the cucs GUI class for laying out a GUI window, each window is partitioned into rows and columns of cells. The cells are designated
using integer coordinates of a rectangular coordinate system in which the upper-left cell is at coordinates (0,0), the X-axis is horizontal and
increases to the right, and the Y-axis is vertical and increases downward (not upward). For example, a window of three rows and four
columns of cells would be viewed as partitioned something like
-----------------------------------
|(0,0) | (1,0) | (2,0) |(3,0) |
|-----------------------------------|
| | | | |
| | | | |
|(0,1) | (1,1) | (2,1) |(3,1) |
| | | | |
| | | | |
| | | | |
|-----------------------------------|
|(0,2) | (1,2) | (2,2) |(3,2)|
-----------------------------------
where the coordinates of each cell are indicated in parentheses. We can add a widget to the window in any cell, and in any order. Note that
the rows can have different heights and the columns can have different widths. The height of a row is determined by the largest height of the
widgets in the row, and the width of a column is determined by the largest width of a widget in the column.
Implementing a class for a GUI window
-
To obtain the standard interface and system support functions, a GUI window
class in Java is not a new standalone class as have been the others that
we have created.
-
Instead, it builds upon an existing base class that provides the basic
support methods and adds the specific methods needed for the specific application
program.
-
The cucs
class GUI is a GUI window base class that was designed to provide
many of the housekeeping operations that can be difficult to comprehend
when first learning about GUI windows.
-
To implement a class, say Greeting, for a window such as the one
illustrated above using the cucs
GUI class, the class definition specifies that it is an extension
of the GUI class by using the syntax
class Greeting extends GUI {
. . .
}
The remainder (internals) of the class implementation are similar to those
for any class in that there will usually be instance variables and there
will be at least one constructor and one or more methods.
Implementing a constructor
-
Constructor for a GUI window puts the needed widgets into the window and
displays any initial text that is needed in the window.
-
Widgets, being objects, are instances of predefined Java classes (from
the java.awt
package). There are also some widgets defined by the cucs package.
-
The classes are:
-
Button, for buttons
-
TextField, for text fields
-
IntField, for integer (int) fields (see the cucs package)
-
DoubleField, for floating point (double) fields (see the cucs package)
-
Label for labels. (A Label object is a label on the window that is not
part of another widget. The label on a button, for example, is not a Label
object.)
-
Each widget must be created and then added to the window.
-
Creation process for a widget is similar to that used for most objects:
-
Define a variable for the object
-
Create a new object
-
Assign it as the value of the variable
For example, for the window above, we could declare
the instance variables
Label nameLabel, messageLabel; // labels Name: and Message:
TextField nameField, messageField; // text fields for the name and message
Button hello; // Hello button
With these declarations, we could create the widgets and assign them to
these variables by the code
nameLabel = new Label("Name:");
messageLabel = new Label("Message:");
nameField = new TextField("", 20);
messageField = new TextField("Enter your name and click Hello.", 40);
hello = new Button("Hello");
Note that
-
Button constructor has one parameter: the label (String) on the button.
-
the TextField constructor has two parameters: the initial string that is
displayed in the field and the size (number of characters) for the text
field widget.
-
the Label constructor has one parameter: the string that is to be displayed
as the label.
After creating the widgets, we add them to the window. Code for this is
illustrated by:
add (nameLabel, 0, 0); // to cell (0,0)
add (nameField, 1, 0); // to cell (1,0)
add (messageLabel, 0, 3);
add (messageField, 1, 3);
add (hello, 0, 1, 2, 1); // center across two columns (0-1).
These statements may look a bit strange at first until we recognize that
this is shorthand for the code
this.add (nameLabel, 0, 0); // to cell (0,0)
this.add (nameField, 1, 0); // to cell (1,0)
this.add (messageLabel, 0, 3);
this.add (messageField, 1, 3);
this.add (hello, 0, 1, 2, 1); // center across two columns (0-1).
Note that the first parameter of each add message is the widget to be added, and the second and third parameters are the X and Y coordinates
of the cell into which that widget is to be placed. Thus the name label is placed in cell (0,0), the name text field is placed in cell (1,0), etc.
Additionally, the last statement (add(hello, 0, 1, 2, 1);) illustrates that the fourth and fifth parameters, if any, specify the width and height
(in cells) of the area that the widget will occupy. (The widget is centered in this area unless otherwise specified.) Thus the hello button is to be
in row 1 and is to be centered in columns 0 and 1 (because its area is two cells wide and one cell high, and the upper left cell of its area is
(0,1)).
You can set a window title by using the setTitle method:
this.setTitle ("Greeting");
The last step that must be taken in developing the GUI constructor is to
include a showstatement, which displays all the widgets you have
added to the window
this.show ();
So what is happening here is that we are sending the add message to the
GUI window itself, and the parameters for the add messages are the widgets
to be added. Does this mean that we have to write an add method somewhere
in our GUI class? Otherwise, how will our GUI object (the window) know
how to execute the add message?
We do not have to write an add method, because it is inherited from
the cucs
GUI class. (Actually it the GUI class also inherits it from somewhere else,
but that isn't important here.) By extending the GUI class, we start with
all of the methods that are defined for GUI objects and we only have to
add the additional methods that are needed for our class. So the add method
is defined already (inherited from the GUI class).
Reacting to external events
-
Program that uses a GUI normally is organized quite differently from a
program that uses, say, standard input (keyboard) and output (command window).
-
For example, in the program for the window illustrated
above, once the window is set up and put on the screen, there is nothing
to do until the user clicks the Hello button.
-
Clicking a button is called an event in Java (and in most other
languages as well), and when a GUI is used there can be many such events.
-
For example, there might be several buttons that could be selected in any
order by a user. We might also want to detect when text is entered into
a text field without requiring a button click, or we might want to detect
when the mouse moves around in the window. All of these things are events,
and in general there is no way for a program to control what event will
happen next, unlike prompting for input from a command window, where the
next event must be that the user enters input in response to the prompt.
-
The way that events are handled in Java is that an object that wants to
be notified when certain events occur must have certain methods defined
to handle those events.
-
Using the cucs
GUI class, the method for handling a mouse click on a button that has been
added to the window is named performButtonAction.
-
So we need to include a performButtonAction method in our GUI class:
public void performButtonAction (Button b) {
. . .
}
This method needs to
-
Get the name that has been entered into the name text field.
- Display a message (in the message field) that includes the name from the name field in a "Hello" greeting.
The code to do this in the example Greeting program is
public void performButtonAction(Button b) {
messageField.setText("Hello, " + nameField.getText() + "!");
}
(The operator + is an alternate way to indicate string
concatenation. The statement in the body of the
performButtonAction method here is
equivalent to
messageField.setText("Hello, ".concat(nameField.getText()).concat("!"));
Note that the performButtonAction method is executed
each time that the Hello button is clicked. Thus the GUI can be used
to display
greetings repeatedly by changing the name and then clicking the Hello button again.
Getting the GUI started and ending the program
-
Have now seen how to:
-
set up a GUI window (in the constructor of a class that extends class GUI)
and
-
how to specify actions that are to happen when button is clicked (in the
performButtonAction method).
-
Observed that any program that uses a GUI similar to the one that we have
looked at just sits around waiting for a mouse click, at which time it
performs its performButtonAction method and goes back to waiting for another
mouse click.
-
To complete the picture, we need to learn how to create the window in the
first place, and how the user terminates the program when finished.
-
A Java application program is a class that contains a "main" method whose
heading is something like
public static void main(String[] args)
For a GUI program, the main program only has to create the GUI object and
let it start waiting for mouse clicks on its button(s). Our class in this
example is named "Greeting", so the main program here could be
public static void main(String[] args) {
new Greeting(); // Create the Greeting window.
}
This may look a bit strange at first. The program creates a new object
but doesn't assign its value to any variable. The reason is that the main
program never needs to use the Greeting object, so it has no need to have
a variable that references it.
If it gives you more of a warm fuzzy feeling, you could also code this
something like
public static void main(String[] args) {
Greeting window;
window = new Greeting(); // Create the Greeting window.
}
but there is no difference in the effect of these two main methods.
A second strange thing is that it looks as if the main program would just
create the GUI and end, thus terminating the program before the user has
a chance to interact with the GUI. When we used a similar class for a user
dialog, we sent a message to the interface (dialog) object to cause it
to start the dialog. If we followed the same approach here, then it seems
that we should do something like
public static void main(String[] args) {
Greeting window;
window = new Greeting(); // Create the Greeting window.
window.conductInteraction();
}
But this isn't done because a GUI is event-driven, just sitting around
waiting for an event to happen that sends it an action message such as
performButtonAction. A program that opens a window is not terminated by
the system until the window has been destroyed, so even though the main
method has finished executing after it creates the GUI window, the system
does not terminate the program until the window is closed (by using the
standard window control buttons).
The main method can be placed either in a separate class or in the same
class with the GUI implementation. If it is placed in the GUI class, then
the GUI program would be compiled as usual:
javac Greeting.java
and executed as usual:
java Greeting
Imports needed
The GUI class comes from the cucs
package and the widgets come from the java.awt
package. Thus both packages (or each class used from each package) must
be imported:
import cucs.*;
import java.awt.*;
You may wish to look at the
entire program now.
An additional widget
One additional widget that is an extension of a TextField widget is
a TextArea widget. A text area allows more than one row of text, and it
has both vertical and horizontal scroll bars to allow for lines that are
longer than the display area and for more lines than can be shown in the
display area. The constructor for a TextArea specifies the number of rows
and the number of characters shown on each row:
TextArea ta;
ta = new TextArea(10, 30);
The above text area will initially be empty. To add text to what is already
in the text area widget, the append message can be used:
ta.append("A line of text.\n");
ta.append(s + "\n");
The above code would add the line "A line of text." and the line that is
the value of String s to the text area. Note that a new line is started
by appending the end-of-line character ("\n") at the end of the previous
line.
Examples
-
Greeting2.java, a variation on program Greeting. It detects a
in the Name: input field to print a "Thank you" message in addition to
detecting a click on the Hello button to print a "Hello" message.
This program also detects whether a name has been entered for a click on
the Hello button.
-
GUIAdder.java
,
adds two integers
-
GUIDoubleAdder.java
,
adds two doubles
Last modified: 10/14/99