Graphical User Interface (GUI) and Object-Oriented Design (OOD)
Graphical User Interface (GUI) and Object-Oriented Design (OOD)
An important
method
An important
method
Two Ways to Create a Frame
• First way (the way we will use):
– Declare and instantiate an object of type JFrame
– Use various methods to manipulate window
import javax.swing.*;
} //end class
So why use a constant? In spite of the relatively lengthy coding required here, it is much
easier to determine what the programmer is trying to accomplish.
This is a very common and useful way of using constants. Be sure to get used to it. You
should be comfortable if you see constants used in this manner, and you should start
using them this way in your own programs when applicable.
public class DrawWindow
{
public static void main(String[] args)
{
JFrame frame = new JFrame("Rectangle Calculator");
frame.setSize(400, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
} //end main()
} //end class
Note how the window displayed here has a symmetric look to it. There seems to be two
columns and five rows. When designing a GUI, the layout is your responsibility.
There are several layouts that are built-in the Swing packages. The particular layout you
see here is called a “grid layout”. There are several different layouts you can choose
from.
You should typically declare your preferred layout for every container (e.g. for every
content pane) in your GUI.
If you do not specify a layout, then Java often (though not always) defaults to a layout
called ‘Border Layout’.
Some containers default to other kinds of layouts.
Methods Provided by the class Container
So: There are two important methods that you will want to invoke
for ALL of your Container objects (such as content panes):
• ‘add’ (to add things like buttons, text fields, labels)
• ‘setLayout’ (to define the layout)
Layout contd
• As is so common in Java, even abstract concepts such as layouts are
represented by classes/objects!
• In other words, to establish a grid layout (mentioned earlier) in your content
pane, you will need to instantiate a grid layout object. Told you there were going to
be all kinds of weird objects!
• So, to set the layout for a Container object (e.g. to set the layout of our frame),
the Container class provides the method: ‘setLayout’. We have to pass as an
argument to the method, an object of type GridLayout. Here is the code
You will soon notice, that in most of our programs, we will never need to refer to
this GridLayout object again. Therefore, having the reference ‘gl’ is simply not
necessary. Yet we sill DO need to pass a GridLayout object to the setLayout
method. We can do the following:
frame.setLayout( new GridLayout(5,2) );
Our code so far:
bn = new JButton("NORTH");
frame.add(BorderLayout.NORTH, bn);
bs = new JButton("SOUTH");
frame.add(BorderLayout.SOUTH, bs);
be = new JButton("EAST");
frame.add(BorderLayout.EAST, be);
bw = new JButton("WEST");
frame.add(BorderLayout.WEST, bw);
bc = new JButton("CENTER");
frame.add(BorderLayout.CENTER, bc);
Several Layout Managers are Available
• In addition to GridLayout and BorderLayout, there are several
other layout managers that come packaged with Java.
• Examples are FlowLayout, BoxLayout, GridBagLayout, etc, etc
– Look up the interface ‘LayoutManager’ in the API. See under ‘All Known
Implementing Classes’
• I encourage you to look into them a little bit on your own and
experiment.
Labels (using class JLabel)
class JLabel (see API here)
Even something as simple as a label is represented by an object. As seen in the
previous slide, we need labels to prompt the user to enter the length and the width.
We also needs labels to refer to the results: “Area”, “Perimeter”. So, we will need
to instantiate 4 label objects.
At this point, the most important state attribute that interests us for a label is the ‘text’
field (ie. a String)
* The second parameter in the constructor is for the alignment. If you look at the API,
you’ll see that the second parameter should be an int. The constant RIGHT (a static
constant in the SwingConstants class) simply holds the integer ‘4’. However, using
the SwingConstants makes things more clear (although admittedly, that may not seem
to be the case at the moment).
Adding JLabels: Use the same the ‘add()’ method:
frame.add(lengthL);
frame.add(widthL);
frame.add(areaL);
frame.add(perimeterL);
FYI: When working with a layout manager such as GridLayout, components are added left to right,
one row at a time. However, this may not be apparent until you fill all of the cells in the table.
class JLabel (partial constructor list from the API)
Our code so far:
public static void main(String[] args)
{
JFrame frame = new JFrame("Rectangle Calculator");
frame.setSize(400, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.add(lengthL);
frame.add(widthL);
frame.add(areaL);
frame.add(perimeterL);
} //end main()
class JTextField
A text field is that familiar window such as from web pages where
you type in information such as your name and address.
The naming convention we will use and that I want you to use is to
add the suffix ‘TF’ to the end of your text-field identifiers. e.g. widthTF
One important attribute for a text field is the columns (how long the
field should be). This value is the maximum number of characters
that can be entered in the text field.
• The ’10’ in the constructor initializes the text field to a maximum of 10 characters.
• The next step is to add these text-field components to our content pane.
JTextField lengthTF, widthTF, areaTF, perimeterTF;
lengthTF = new JTextField(10);
widthTF = new JTextField(10);
areaTF = new JTextField(10);
perimeterTF = new JTextField(10);
frame.add(lengthL);
frame.add(lengthTF);
frame.add(widthL);
frame.add(widthTF);
frame.add(areaL);
frame.add(areaTF);
frame.add(perimeterL);
frame.add(perimeterTF);
Note the order in which the compnents have been added to the layout
class JButton
Here is the code that generates the buttons, followed by the code to
add all the various components to the content pane. Note the order in
which the components are added. Recall that when adding
components to a GridLayout, the components are added from left to
right, row by row.
JButton calculateB, exitB;
calculateB = new JButton("Calculate");
exitB = new JButton("Exit");
frame.add(lengthL);
frame.add(lengthTF);
frame.add(widthL);
frame.add(widthTF);
frame.add(areaL);
frame.add(areaTF);
frame.add(perimeterL);
frame.add(perimeterTF);
frame.add(calculateB);
frame.add(exitB);
Recap
• What we’ve done:
– We created a Window/Frame (by instantiating the JFrame
class)
– We set up a layout manager (in this case, a GridLayout) for
our frame by invoking the setLayout() from the
Container class
– We created several components for our GUI such as labels,
text fields, buttons
– We added the various components to our container
frame.add(lengthL);
frame.add(lengthTF);
frame.add(widthL);
Then click on the buttons frame.add(widthTF);
frame.add(areaL);
place. frame.add(calculateB);
frame.add(exitB);
frame.setVisible(true);
} //end main()
} //end class RectangleCalculator
So we have a pretty picture….
Big Deal – it’s not like it does anything!
What Now???
The “Monkey See, Monkey Do” Teaching Model
GUI components can generate all kinds of different events. For example, a button
can generate an event by being clicked. A text field can generate an event when
the ‘Enter’ key is pressed. More on this later.
We will spend the remainder of this lecture learning about the steps involved in
writing the code that ‘’handles’ the events.
** Overview of steps in Event Handling **
2. Write code that connects the event you want to react to (e.g. the
‘Calculate’ button in the rectangle calculator) with the class from
step #1.
• This step is referred to as ‘registering the event handler’.
1. Creating the Handler Class
We begin by writing a particular kind of class called an ActionListener. This class
has two noteworthy features:
1.It “implements an interface”. For now, all you need to know is that you must add
the words ‘implements ActionListener’ after the class declaration.
2.It contains a method called ‘actionPerformed’. The code that responds to the
event will be contained inside this method.
Here is a basic example of a handler class that could be connected to a button somewhere in
our GUI:
When naming a handler class, we usually append the word ‘Handler’ at the end.
2. Registering the EventHandler:
GUI components such as buttons, text fields, and others, all have a
method called ‘addActionListener’. This method takes one
argument of type ActionListener. The class we created just
previously definitely qualifies as an ActionListener class.
I realize this may be a bit confusing right now, but reread the slides
a few times, then look at some examples. Then come back to these
descriptions. Repeat as needed and it will begin making more sense.
Where do we put the handler class?
The handler class can and often does exist as its own file. Even if
you have multiple different handler classes, say, for multiple
different buttons, you could have separate classes, each of which
exists as a separate source code file.
frame.setVisible(true);
} //end method go()
} //end class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
frame.setVisible(true);
} //end method go() In this version, the ButtonHandler class is explicitly instantiated. The
reference ‘b’ is then passed to the addActionListener method. However,
private class ButtonHandler implements ActionListener { doing so ir probably not necessary since we don’t anticipate any need to use
public void actionPerformed(ActionEvent ae) { the ButtonHandler reference in the future. We might as well simply pass
System.out.println("The button was clicked!");
the instantiation to the addActionListener method and not bother with
} //end method actionPerformed()
} //end ButtonHandler nested (inner) class declaring a reference as we did in the previous slide.
} //end class
Another Example:
• The requirements:
– Draw the window shown here
– When the user enters a number in either text field and then presses enter,
the corresponding conversion should show up in the opposite text field.
TempConversion: What do we need?
The Display:
• A window
• A container (so we can access the content pane)
• 2 labels
• 2 text fields
• 2 handlers (one for the celcius field, one for the farenheit field)
• A layout manager (maybe not since the GUI has only one row. If no layout is
specified, adding components simply places them one next to the other.)
The Event:
• When the user types something in a field and presses enter, the event should
retrieve that value, do the conversion, then display the answer in the other text
field.
Using the ActionEvent reference (optional)
• The ActionEvent reference that you see as a parameter in the
actionPerformed method is instantiated by Java when an event is triggered.
This object is then passed by Java to the actionPerformed method.
• This reference encapsulates all kinds of information about the event.
• For now, the piece of information you may find most useful comes from the
method getSource(). THis method tells you exactly which component
generated the event.
• getSource() returns a reference to the object that generated the event.
Example: Let’s say a button called calculateB generated the event. In that
case the statement
e.getSource() == calculateB
would return ‘true’.
See TwoButtonsActionEvent.java on class page. Note how we only use one
handler class, yet inside that class we can use the ActionEvent reference to
determine which object generated the event.