Download Lecture Twelve – More on GUIs

Document related concepts
no text concepts found
Transcript
Lecture Twelve – More on GUIs
Java API
Introduction to LibraryGUI
LibraryGUI program
LibraryGUI code
LibraryGUI walkthrough
LibraryGUI layout
LibraryGUI listeners
Drill
Read Chapter 10-11
1
Java API
Following is a treatment on API – this is very
important.
Good programmers don’t just write classes –
they find classes.
They find them in an API.
When you learn to use the API effectively, it will
greatly enhance your capability as a
programmer in Java.
2
Java API
The components we introduced in previous
lessons (and the ones we will use in this lesson)
are only a portion of the many components that
are available for us to use.
We can look up other helpful components by
referencing the documentation provided on
Java’s API (application programming interface)
The most up-to-date version of Java’s API
Specification can be found at
http://java.sun.com/j2se/1.5.0/docs/api/index.html
3
Java API
This is a helpful resource for Java programmers
which allows us to look up the members
variables and methods of the classes available
for us to use. It also provides us with other
helpful information about the inheritance
structure of a class.
We will take a quick detour to show you how to
read and understand the API specification.
Open up the link to the API specification in an
internet browser and follow along. We will use
the JButton as an example component that we
want to learn more about.
4
Java API
Once you open the specification you
should see this screen.
5
Java API
On the left we have a list of classes and
above that, a list of packages
6
Java API
Since JButton is in the javax.swing package we will
choose that from the package list. This will update
the class list to only include classes from that
package
7
Java API
We will then find JButton and click it to open up it’s
specification.
8
Java API
The first thing we see is the inheritance structure for
JButton. We can see the superclasses that it
inherits from, and we are even given a list of it’s
subclasses.
9
Java API
Scrolling down a little further and we can see the list
of fields (i.e. static constants) that are defined for
JButton. We can also see the constants that are
inherited from it’s superclasses.
10
Java API
Next we are given a list of available constructors for
JButton. We typically have been using the fourth
constructor in the list which “creates a button with
text.”
11
Java API
Right after that we have a list of methods followed
by the methods inherited from superclasses. To the
left we are given the return type. To the right we
have the name of the method and its arguments.
12
Java API
We can get more information on a method by
clicking it’s link. Click the link for the setText
method (which is inherited from AbstractButton).
13
Java API
Now we are able to see the entire method header, a
description of the method (and its arguments), and
possibly a list of related methods.
14
Java API
Over time you will learn to familiarize yourself
with the API and will become more comfortable
using it.
The rest of this lesson will cover a few GUI
components and their most commonly used
methods.
If you ever want to learn more about the
capabilities of a certain component you can now
teach yourself with the API specification!
15
Introduction to LibraryGUI
The rest of this lesson is a demonstration and discussion
of a more complex GUI
It is quite long, compared to previous lessons
But – just type in the code (carefully) and get it to run,
then go through the LibraryGUI walkthrough slides. If
you find some parts difficult to understand, mark it and
move on.
You can return to this example later, after you have
developed more programming skills.
Just going through this example should help you to
make that transition from student to programmer.
16
Introduction to LibraryGUI
Back in Lesson 6 you were introduced to GUIs,
however, most of the concepts were not
thoroughly explained
You should already have a basic understanding
of:
how GUIs are constructed
how we add components to content panes
how we use layouts to organize our components
how we use listeners to handle events
This lesson is meant to dive a little deeper into
GUIs and give examples of other components,
layouts, and listeners that are available to us.
17
LibraryGUI program
In Lesson 10 we wrote objects (in the form of
classes) to emulate a library check out system.
Now, we will write a GUI for our library check out
system using some of the components and listeners
found in Chapters 10 and 11 of your book
We will modify our Book object slightly. We will call
this modified Book class Book2.java
This program will be a bit longer than previous
programs, but as always be sure to type the code in
yourself and get it working!
18
LibraryGUI code
// this class is in a file named "Book2.java"
public class Book2
{
// constant values for book type
static final String HARDCOVER = "Hardcover";
static final String PAPERBACK = "Paperback";
// private member variables
private String title;
private String author;
private String type;
private String publisher;
private String summary;
private int copyrightYear;
private boolean checkedOut;
19
LibraryGUI code
// default constructor
public Book2()
{
title = "";
author = "";
type = "";
publisher = "";
summary = "";
copyrightYear = 0;
checkedOut = false;
}
// example constructor
public Book2(String title, String author,
String type, String publisher,
String summary, int copyrightYear)
{
setBook(title, author, type, publisher, summary, copyrightYear);
}
20
LibraryGUI code
// public member functions
public void setBook(String title, String author,
String type, String publisher,
String summary, int copyrightYear)
{
this.title = title;
this.author = author;
this.type = type;
this.publisher = publisher;
this.summary = summary;
this.copyrightYear = copyrightYear;
checkedOut = false;
}
public void setTitle(String title)
{
this.title = title;
}
21
LibraryGUI code
public void setAuthor(String author)
{
this.author = author;
}
public void setType(String type)
{
this.type = type;
}
public void setPublisher(String publisher)
{
this.publisher = publisher;
}
public void setSummary(String summary)
{
this.summary = summary;
}
22
LibraryGUI code
public void setCopyright(int copyrightYear)
{
this.copyrightYear = copyrightYear;
}
public String getTitle()
{
return title;
}
public String getAuthor()
{
return author;
}
public String getType()
{
return type;
}
23
LibraryGUI code
public String getPublisher()
{
return publisher;
}
public String getSummary()
{
return summary;
}
public int getCopyright()
{
return copyrightYear;
}
public boolean getCheckedOut()
{
return checkedOut;
}
24
LibraryGUI code
public void checkOut()
{
checkedOut = true;
}
public void checkIn()
{
checkedOut = false;
}
} // end of Book2.java
25
LibraryGUI code
// this is in a file names "LibraryGUI.java"
import java.awt.*;
import java.lang.*;
import javax.swing.*;
import java.awt.event.*;
public class LibraryGUI extends JFrame implements
KeyListener, ItemListener, WindowListener
{
// declare GUI components
private JPanel selectPanel;
private JLabel selectBookLabel;
private JComboBox selectBookBox;
private JPanel bookInfoPanel;
private JLabel titleLabel;
private JTextField titleField;
private JLabel authorLabel;
private JTextField authorField;
26
LibraryGUI code
private JLabel publisherLabel;
private JTextField publisherField;
private JLabel copyrightLabel;
private JTextField copyrightField;
private JLabel summaryLabel;
private JTextArea summaryArea;
private JScrollPane summaryScroll;
private JCheckBox hardcoverCheckBox;
private JPanel checkInOutPanel;
private ButtonGroup checkGroup;
private JRadioButton checkedInButton;
private JRadioButton checkedOutButton;
// declare our book array
private Book2[] books;
// variable used to keep track of the current book
private int currentBook;
27
LibraryGUI code
// main method - simply constructs a Library GUI
public static void main(String args[])
{
LibraryGUI myGUI = new LibraryGUI();
myGUI.setVisible(true);
}
public LibraryGUI()
{
// set GUI properties
super("Library Check Out System");
setSize(400, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// create our books
books = new Book2[3];
// create book instances
for (int i = 0; i < 3; i++)
books[i] = new Book2();
28
LibraryGUI code
// set info for books
books[0].setBook("Java in Easy Steps", "Mike McGrath",
Book2.PAPERBACK, "Barnes & Noble Books",
"Easily learn how to program in Java.", 2004);
books[1].setBook("Gone With the Wind", "Margaret Mitchell",
Book2.HARDCOVER, "Scribner",
"A classic love story.", 1936);
books[2].setBook("Rainbow Six", "Tom Clancy",
Book2.PAPERBACK, "Putnam",
"Action-packed counter-terrorism thriller.",1998);
currentBook = 0;
// create our GUI components
// select panel
selectPanel = new JPanel();
selectBookLabel = new JLabel("Select Book: ");
selectBookBox = new JComboBox();
for (int i = 0; i < 3; i++)
selectBookBox.addItem(books[i].getTitle());
selectPanel.add(selectBookLabel);
selectPanel.add(selectBookBox);
29
LibraryGUI code
// book information panel
bookInfoPanel = new JPanel();
titleLabel = new JLabel("Title: ");
titleField = new JTextField(books[currentBook].getTitle(), 21);
titleField.setEnabled(false);
authorLabel = new JLabel("Author: ");
authorField = new JTextField(books[currentBook].getAuthor(), 21);
publisherLabel = new JLabel("Publisher: ");
publisherField = new JTextField(books[currentBook].getPublisher(),
21);
copyrightLabel = new JLabel("Copyright: ");
copyrightField = new
JTextField(Integer.toString(books[currentBook].getCopyright()),
21);
summaryLabel = new JLabel("Summary: ");
summaryArea = new JTextArea(books[currentBook].getSummary(), 5,
20);
summaryScroll = new JScrollPane(summaryArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
hardcoverCheckBox = new JCheckBox(Book2.HARDCOVER);
30
LibraryGUI code
GridBagLayout bookInfoLayout = new GridBagLayout();
GridBagConstraints constraints = new GridBagConstraints();
bookInfoPanel.setLayout(bookInfoLayout);
constraints.gridx = 0;
constraints.gridy = 0;
bookInfoPanel.add(titleLabel, constraints);
constraints.gridx = 1;
bookInfoPanel.add(titleField, constraints);
constraints.gridx = 0;
constraints.gridy = 1;
bookInfoPanel.add(authorLabel, constraints);
constraints.gridx = 1;
bookInfoPanel.add(authorField, constraints);
constraints.gridx = 0;
constraints.gridy = 2;
bookInfoPanel.add(publisherLabel, constraints);
constraints.gridx = 1;
bookInfoPanel.add(publisherField, constraints);
constraints.gridx = 0;
constraints.gridy = 3;
31
LibraryGUI code
bookInfoPanel.add(copyrightLabel, constraints);
constraints.gridx = 1;
bookInfoPanel.add(copyrightField, constraints);
constraints.gridx = 0;
constraints.gridy = 4;
bookInfoPanel.add(summaryLabel, constraints);
constraints.gridx = 1;
bookInfoPanel.add(summaryScroll, constraints);
constraints.gridx = 0;
constraints.gridy = 5;
bookInfoPanel.add(hardcoverCheckBox, constraints);
// check in and out panel
checkInOutPanel = new JPanel();
checkGroup = new ButtonGroup();
checkedInButton = new JRadioButton("Checked In");
checkedOutButton = new JRadioButton("Checked Out");
checkGroup.add(checkedInButton);
checkGroup.add(checkedOutButton);
checkedInButton.setSelected(true);
checkInOutPanel.add(checkedInButton);
checkInOutPanel.add(checkedOutButton);
32
LibraryGUI code
// create content container and set layout
BorderLayout layout = new BorderLayout();
Container window = getContentPane();
window.setLayout(layout);
window.add(selectPanel, BorderLayout.NORTH);
window.add(bookInfoPanel, BorderLayout.CENTER);
window.add(checkInOutPanel, BorderLayout.SOUTH);
// set listeners for GUI components
selectBookBox.addItemListener(this);
titleField.addKeyListener(this);
authorField.addKeyListener(this);
publisherField.addKeyListener(this);
copyrightField.addKeyListener(this);
summaryArea.addKeyListener(this);
hardcoverCheckBox.addItemListener(this);
checkedInButton.addItemListener(this);
checkedOutButton.addItemListener(this);
}
33
LibraryGUI code
// item listener events
public void itemStateChanged(ItemEvent e)
{
if (e.getSource() == selectBookBox)
{
currentBook = selectBookBox.getSelectedIndex();
titleField.setText(books[currentBook].getTitle());
authorField.setText(books[currentBook].getAuthor());
publisherField.setText(books[currentBook].getPublisher());
copyrightField.setText(Integer.toString(
books[currentBook].getCopyright()));
summaryArea.setText(books[currentBook].getSummary());
if (books[currentBook].getType() == Book2.HARDCOVER)
hardcoverCheckBox.setSelected(true);
else
hardcoverCheckBox.setSelected(false);
if (books[currentBook].getCheckedOut() == true)
checkedOutButton.setSelected(true);
else
checkedInButton.setSelected(true);
}
34
LibraryGUI code
else if (e.getSource() == hardcoverCheckBox)
{
if (e.getStateChange() == ItemEvent.SELECTED)
books[currentBook].setType(Book2.HARDCOVER);
else
books[currentBook].setType(Book2.PAPERBACK);
}
else if (e.getSource() == checkedInButton)
books[currentBook].checkIn();
else if (e.getSource() == checkedOutButton)
books[currentBook].checkOut();
}
// key listener events
public void keyPressed(KeyEvent e) {}
35
LibraryGUI code
public void keyReleased(KeyEvent e)
{
if (e.getSource() == titleField)
books[currentBook].setTitle(titleField.getText());
else if (e.getSource() == authorField)
books[currentBook].setAuthor(authorField.getText());
else if (e.getSource() == publisherField)
books[currentBook].setPublisher(publisherField.getText());
else if (e.getSource() == copyrightField)
{
try
{
books[currentBook].setCopyright(
Integer.parseInt(copyrightField.getText()));
}
catch (NumberFormatException ex)
{
JOptionPane.showMessageDialog(null,
"Copyright must be a numeric year!");
}
}
else if (e.getSource() == summaryArea)
books[currentBook].setSummary(summaryArea.getText());
}
36
LibraryGUI code
public void keyTyped(KeyEvent e) {}
// window listener events
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
public void windowActivated(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowDeactivated(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowOpened(WindowEvent e){}
}
37
LibraryGUI walkthrough
Get the program to compile and run and play
around with it for a bit.
We will now walk you through the code line-byline and try to explain a little bit more in depth
about why we do things the way we do.
It may be helpful to keep a copy of the code
open in another window as you follow along
All of the code in Book2.java should be familiar to
you so we will mainly concentrate on
LibraryGUI.java
38
LibraryGUI walkthrough
import java.awt.*;
import java.lang.*;
import javax.swing.*;
import java.awt.event.*;
import statements are used to add classes
from the Java API to our program so we
can use them.
After the import keyword we give it a
package name. The asterisk (*) is a
shortcut that allows us to import all the
classes in the package.
39
LibraryGUI walkthrough
import java.awt.*;
import java.lang.*;
import javax.swing.*;
import java.awt.event.*;
java.awt (abstract windowing toolkit) contains the
different layout classes that we use (GridLayout,
BorderLayout, etc) and Container classes
java.lang contains the classes we need for our
NumberFormatException
javax.swing contains the classes that are used for GUI
components (JButton, JLabel, JFrame, etc)
java.awt.event contains classes we need for our listeners
40
LibraryGUI walkthrough
public class LibraryGUI extends JFrame implements
KeyListener, ItemListener, WindowListener
{
Next we have our class header. In this header we
extends JFrame – this means that our LibraryGUI is a
subclass of JFrame and inherits its members (like
setSize(), setVisible(), etc).
implements KeyListener, ItemListener, WindowListener –
these are the interfaces that we implement. By
implementing these interfaces we are assuring the Java
compiler that our class will contain the methods needed to
handle these events (like itemStateChanged(),
keyPressed(), windowClosing(), etc).
41
LibraryGUI walkthrough
// declare GUI components
private JPanel selectPanel;
private JLabel selectBookLabel;
private JComboBox selectBookBox;
...
Now we declare all of the components we will
need to construct our GUI.
Remember that declaring components does not
actually create them. They are created when
you instantiate them (i.e. call the component’s
constructor) with the new operator
42
LibraryGUI walkthrough
// declare our book array
private Book2[] books;
// variable used to keep track of the current book
private int currentBook;
Here we declare an array to hold our
books. We also created an int to
keep track of the current index in that
array.
43
LibraryGUI walkthrough
// main method - simply constructs a Library GUI
public static void main(String args[])
{
LibraryGUI myGUI = new LibraryGUI();
myGUI.setVisible(true);
}
Our main() method simply constructs
a LibraryGUI object and then calls the
setVisible() method (which was
inherited from JFrame) so the GUI is
displayed to the screen.
44
LibraryGUI walkthrough
public LibraryGUI()
{
// set GUI properties
super("Library Check Out System");
setSize(400, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Next we enter our constructor.
The first thing we do is call super() which is a special method
that calls the superclass’ constructor (in our case, JFrame’s
constructor). If we look up JFrame’s constructor in the API
specification we see it takes a String that is used to set the
title of our window
We follow that up with a few more method calls to methods
we inherited from JFrame. One sets the size of our window.
The other specifies what the program should do if the user
closes the window.
45
LibraryGUI walkthrough
// create our books
books = new Book2[3];
// create book instances
for (int i = 0; i < 3; i++)
books[i] = new Book2();
Next we create our book array.
However, just because we created the array does not
mean we created instances for each book in the array (a
common mistake by many programmers)
To actually create a Book2 instance for each book in our
array, we must use a loop. If this step is skipped you
may find yourself getting a NullPointerException!
46
LibraryGUI walkthrough
// set info for books
books[0].setBook("Java in Easy Steps", "Mike McGrath",
Book2.PAPERBACK, "Barnes & Noble Books",
"Easily learn how to program in Java.", 2004);
books[1].setBook("Gone With the Wind", "Margaret Mitchell",
Book2.HARDCOVER, "Scribner",
"A classic love story.", 1936);
books[2].setBook("Rainbow Six", "Tom Clancy",
Book2.PAPERBACK, "Putnam",
"Action-packed counter-terrorism thriller.", 1998);
currentBook = 0;
Now that we have created a Book2 instance for each book in
our array, we can now set the information for the book by
calling the setBook() method that we wrote in our Book2
class.
We will also go ahead and initialize our index currentBook to
zero (the first book in the array).
47
LibraryGUI walkthrough
// select panel
selectPanel = new JPanel();
selectBookLabel = new JLabel("Select Book: ");
selectBookBox = new JComboBox();
for (int i = 0; i < 3; i++)
selectBookBox.addItem(books[i].getTitle());
selectPanel.add(selectBookLabel);
selectPanel.add(selectBookBox);
The next part of our process is to create the GUI
component that we declared earlier.
We start by declaring a JPanel called
selectPanel.
48
LibraryGUI walkthrough
// select panel
selectPanel = new JPanel();
selectBookLabel = new JLabel("Select Book: ");
selectBookBox = new JComboBox();
for (int i = 0; i < 3; i++)
selectBookBox.addItem(books[i].getTitle());
selectPanel.add(selectBookLabel);
selectPanel.add(selectBookBox);
JPanels are similar to JFrames except they do not contain a
window with a title bar. Instead they provide us a way to
divide our components into different groups (kind of like a
sub-container).
Dividing up components and adding them to panels makes it
easier for us to display them in a desirable way because we
can apply a separate layout to each panel (and then apply a
layout across all our panels to create our final interface).
49
LibraryGUI walkthrough
// select panel
selectPanel = new JPanel();
selectBookLabel = new JLabel("Select Book: ");
selectBookBox = new JComboBox();
for (int i = 0; i < 3; i++)
selectBookBox.addItem(books[i].getTitle());
selectPanel.add(selectBookLabel);
selectPanel.add(selectBookBox);
If we do not specify a layout for the panel then
it will default to a flow layout.
After we create our panel, we create the
components that we want to add to that panel,
in this case a label and a combo box
50
LibraryGUI walkthrough
// select panel
selectPanel = new JPanel();
selectBookLabel = new JLabel("Select Book: ");
selectBookBox = new JComboBox();
for (int i = 0; i < 3; i++)
selectBookBox.addItem(books[i].getTitle());
selectPanel.add(selectBookLabel);
selectPanel.add(selectBookBox);
JLabel’s constructor is called with a String
argument which is used to set the text of the
label.
We then call the default constructor for
JComboBox.
51
LibraryGUI walkthrough
// select panel
selectPanel = new JPanel();
selectBookLabel = new JLabel("Select Book: ");
selectBookBox = new JComboBox();
for (int i = 0; i < 3; i++)
selectBookBox.addItem(books[i].getTitle());
selectPanel.add(selectBookLabel);
selectPanel.add(selectBookBox);
After that, we call the addItem() method for our JComboBox
in a for loop. This loop is looping through our book array and
adding the title of each book to the combo box. Remember
we must call getTitle() because it is the public method that
accesses the private member variable title in our book
Finally, we add these new components to our panel.
52
LibraryGUI walkthrough
// book information panel
bookInfoPanel = new JPanel();
titleLabel = new JLabel("Title: ");
titleField = new JTextField(books[currentBook].getTitle(), 21);
titleField.setEnabled(false);
...
Next we begin work on our bookInfoPanel which consists of
various label and fields used to display the information about
our book.
Notice when we create a JTextField (like titleField) we call the
constructor with two arguments: a String for the initial
contents of the box and a length for the box.
In this case, we initialize the text to display the title of our
first book and give the box a length of 21.
53
LibraryGUI walkthrough
// book information panel
bookInfoPanel = new JPanel();
titleLabel = new JLabel("Title: ");
titleField = new JTextField(books[currentBook].getTitle(), 21);
titleField.setEnabled(false);
...
In addition, we also call the setEnabled() method of titleField.
This method allows us to enable and disable components.
By disabling the component we prevent user interaction with
it.
In this example, we don’t ever want the user to change the
title of our book so we disable the field.
54
LibraryGUI walkthrough
...
summaryLabel = new JLabel("Summary: ");
summaryArea = new
JTextArea(books[currentBook].getSummary(), 5, 20);
summaryScroll = new JScrollPane(summaryArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
...
We continue to create a series of labels and
textfields until we get to summaryArea which is a
JTextArea.
We use a three-argument constructor for JTextArea
that takes a String for initial text, an int for height,
and an int for width.
55
LibraryGUI walkthrough
...
summaryLabel = new JLabel("Summary: ");
summaryArea = new
JTextArea(books[currentBook].getSummary(), 5, 20);
summaryScroll = new JScrollPane(summaryArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
...
Since our text may extend past the extents of the text area, we
decide to put it in a scroll pane
We construct our JScrollPane by calling a constructor that takes
the component we want to add scrolling to, followed by two
constants that determine how vertical and horizontal scrollbars
need to be displayed.
For a list of constants you could provide to this constructor, see
page 111 of your book or consult the API specification for
JScrollPane
56
LibraryGUI walkthrough
...
hardcoverCheckBox = new JCheckBox(Book2.HARDCOVER);
...
The final component we create that will be added to
our book information panel is a check box that will
be checked when the book is a hardcover book.
To create a JCheckBox we call a constructor that
takes a String to specify the text for the check box.
In this case we pass it Book2.HARDCOVER which
was a String constant we specified in our class.
57
LibraryGUI walkthrough
GridBagLayout bookInfoLayout = new GridBagLayout();
GridBagConstraints constraints = new GridBagConstraints();
bookInfoPanel.setLayout(bookInfoLayout);
constraints.gridx = 0;
constraints.gridy = 0;
bookInfoPanel.add(titleLabel, constraints);
Next we create a layout for our book information panel.
We decide to use GridBagLayout, which is a layout much like
GridLayout but provides us with more flexibility and
functionality.
In addition to creating the layout, we must also create
GridBagConstraints which will be used to tell the
GridBagLayout how to layout our components.
58
LibraryGUI walkthrough
GridBagLayout bookInfoLayout = new GridBagLayout();
GridBagConstraints constraints = new GridBagConstraints();
bookInfoPanel.setLayout(bookInfoLayout);
constraints.gridx = 0;
constraints.gridy = 0;
bookInfoPanel.add(titleLabel, constraints);
We use our constraints mainly to specify a specific cell of our grid
(using gridx and gridy). There are other constraints you can set like
gridwidth and gridheight. You can consult the API specification for
more constraints.
When we add a component to our container using a GridBagLayout,
we must call our add() method with 2 arguments: the component to
add and the name of our constraints.
Since we are using the same constraints each time we add a
component, we must modify the constraint values between each
add() call.
59
LibraryGUI walkthrough
...
constraints.gridx = 0;
constraints.gridy = 4;
bookInfoPanel.add(summaryLabel, constraints);
constraints.gridx = 1;
bookInfoPanel.add(summaryScroll, constraints);
...
A final thing to note about our book information
panel is that we add summaryScroll to our panel,
not summaryArea.
Remember that we added summaryArea to
summaryScroll (by specifying it as the first
agrument in summaryScroll’s constructor), therefore
all we need to add summaryScroll to our panel.
60
LibraryGUI walkthrough
// check in and out panel
checkInOutPanel = new JPanel();
checkGroup = new ButtonGroup();
checkedInButton = new JRadioButton("Checked In");
checkedOutButton = new JRadioButton("Checked Out");
checkGroup.add(checkedInButton);
checkGroup.add(checkedOutButton);
checkedInButton.setSelected(true);
checkInOutPanel.add(checkedInButton);
checkInOutPanel.add(checkedOutButton);
Our final sub-container that we created is the
checkInOutPanel.
For this panel we want to add two radio buttons.
Before creating these buttons though, we create a
ButtonGroup.
61
LibraryGUI walkthrough
// check in and out panel
checkInOutPanel = new JPanel();
checkGroup = new ButtonGroup();
checkedInButton = new JRadioButton("Checked In");
checkedOutButton = new JRadioButton("Checked Out");
checkGroup.add(checkedInButton);
checkGroup.add(checkedOutButton);
checkedInButton.setSelected(true);
checkInOutPanel.add(checkedInButton);
checkInOutPanel.add(checkedOutButton);
We then create our JRadioButtons with a constructor that
takes a single String to specify the button’s text, and we then
add it to the ButtonGroup using the add() method.
By adding these buttons to the same group, we will only allow
one button to be selected at a time (since we don’t want a
book to be checked in AND checked out at the same time!)
62
LibraryGUI walkthrough
// check in and out panel
checkInOutPanel = new JPanel();
checkGroup = new ButtonGroup();
checkedInButton = new JRadioButton("Checked In");
checkedOutButton = new JRadioButton("Checked Out");
checkGroup.add(checkedInButton);
checkGroup.add(checkedOutButton);
checkedInButton.setSelected(true);
checkInOutPanel.add(checkedInButton);
checkInOutPanel.add(checkedOutButton);
We call the setSelected() method for checkInButton
to select it as the default selection once the GUI is
displayed.
Finally, we add the radio buttons to our panel.
63
LibraryGUI walkthrough
// create content container and set layout
BorderLayout layout = new BorderLayout();
Container window = getContentPane();
window.setLayout(layout);
window.add(selectPanel, BorderLayout.NORTH);
window.add(bookInfoPanel, BorderLayout.CENTER);
window.add(checkInOutPanel, BorderLayout.SOUTH);
Now that we have added all our components into 3
panels (selectPanel, bookInfoPanel,
checkInOutPanel) the task now is to add these
panels to our main container – our window
We decide to use a BorderLayout for this. A
BorderLayout can be used to arrange components
into 5 different sections: north, south, east, west, or
center.
64
LibraryGUI walkthrough
// create content container and set layout
BorderLayout layout = new BorderLayout();
Container window = getContentPane();
window.setLayout(layout);
window.add(selectPanel, BorderLayout.NORTH);
window.add(bookInfoPanel, BorderLayout.CENTER);
window.add(checkInOutPanel, BorderLayout.SOUTH);
We first create our layout and then create
our Container, named window.
Notice we set our window equal to the result
of the getContentPane() method (a method
inherited from JFrame). This method returns
the Container for our main frame.
65
LibraryGUI walkthrough
// create content container and set layout
BorderLayout layout = new BorderLayout();
Container window = getContentPane();
window.setLayout(layout);
window.add(selectPanel, BorderLayout.NORTH);
window.add(bookInfoPanel, BorderLayout.CENTER);
window.add(checkInOutPanel, BorderLayout.SOUTH);
After setting the layout, we then add the 3
panels to our window with the add()
method.
Like GridBagLayout, BorderLayout’s add()
method requires two arguments: the
component and a constant specifying which
area to place the component.
66
LibraryGUI layout
selectPanel located at NORTH
position in our BorderLayout
bookInfoPanel with internal
GridBagLayout located at
CENTER position in our
BorderLayout
checkInOutPanel located at
SOUTH position in our
BorderLayout
Keep in mind that understanding and using layouts is typically the
most challenging aspect of GUI programming.
Here is a visual demonstrating how we used layouts to achieve the
look of our GUI.
67
LibraryGUI listeners
// set listeners for GUI components
selectBookBox.addItemListener(this);
titleField.addKeyListener(this);
authorField.addKeyListener(this);
publisherField.addKeyListener(this);
copyrightField.addKeyListener(this);
summaryArea.addKeyListener(this);
hardcoverCheckBox.addItemListener(this);
checkedInButton.addItemListener(this);
checkedOutButton.addItemListener(this);
}
The final step in our constructor is to add listeners to our
components.
We will add KeyListeners to all of our textfields and
ItemListeners to our radio buttons, combo boxes, and
check boxes.
68
LibraryGUI listeners
All that’s left for our program from this point is to
write the methods that will be used to handle the
listener events.
In previous programs we used ActionListeners which
require an actionPerformed() method.
Even though we aren’t using ActionListeners for this
GUI, the same approach is used for ItemListener
and KeyListener.
ItemListener requires an itemStateChanged()
method while KeyListener requires a keyPressed(),
keyReleased(), and keyTyped() method.
69
LibraryGUI listeners
// item listener events
public void itemStateChanged(ItemEvent e)
{
if (e.getSource() == selectBookBox)
...
else if (e.getSource() == hardcoverCheckBox)
...
else if (e.getSource() == checkedInButton)
...
else if (e.getSource() == checkedOutButton)
...
}
We will start by looking at the itemStateChanged() method.
The thing we should realize is that we have 4 different components that
could create an ItemEvent.
Therefore, the first thing we realize we need to do is to construct a series of
if/else if statements to determine which component created the event
We can get this component by calling the ItemEvent’s getSource() method.
70
LibraryGUI listeners
if (e.getSource
() == selectBookBox)
(e.getSource()
selectBookBox)
{
currentBook = selectBookBox.getSelectedIndex();
selectBookBox.getSelectedIndex();
titleField.setText(books[currentBook].getTitle());
titleField.setText(books[currentBook].getTitle());
authorField.setText(books[currentBook].getAuthor());
authorField.setText(books[currentBook].getAuthor());
publisherField.setText(books[currentBook].getPublisher());
publisherField.setText(books[currentBook].getPublisher());
copyrightField.setText(Integer.toString(books[currentBook].getCopyright
()));
copyrightField.setText(Integer.toString(books[currentBook].getCopyright()));
summaryArea.setText(books[currentBook].getSummary());
summaryArea.setText(books[currentBook].getSummary());
if (books[currentBook].getType
() == Book2.HARDCOVER)
(books[currentBook].getType()
hardcoverCheckBox.setSelected(true);
hardcoverCheckBox.setSelected(true);
else
hardcoverCheckBox.setSelected(false);
hardcoverCheckBox.setSelected(false);
if (books[currentBook].getCheckedOut
() == true)
(books[currentBook].getCheckedOut()
checkedOutButton.setSelected(true);
checkedOutButton.setSelected(true);
else
checkedInButton.setSelected(true);
checkedInButton.setSelected(true);
}
The first case occurs when the combo box selectBookBox causes the
event.
The first thing we do in this case is determine which book was selected
by using the getSelectedIndex() method. Alternatively, we could have
used getItem() to return the actual String, but the index is better for us
in this case because we can use it as the index for our book array.
71
LibraryGUI listeners
if (e.getSource
() == selectBookBox)
(e.getSource()
selectBookBox)
{
currentBook = selectBookBox.getSelectedIndex();
selectBookBox.getSelectedIndex();
titleField.setText(books[currentBook].getTitle());
titleField.setText(books[currentBook].getTitle());
authorField.setText(books[currentBook].getAuthor());
authorField.setText(books[currentBook].getAuthor());
publisherField.setText(books[currentBook].getPublisher());
publisherField.setText(books[currentBook].getPublisher());
copyrightField.setText(Integer.toString(books[currentBook].getCopyright
()));
copyrightField.setText(Integer.toString(books[currentBook].getCopyright()));
summaryArea.setText(books[currentBook].getSummary());
summaryArea.setText(books[currentBook].getSummary());
if (books[currentBook].getType
() == Book2.HARDCOVER)
(books[currentBook].getType()
hardcoverCheckBox.setSelected(true);
hardcoverCheckBox.setSelected(true);
else
hardcoverCheckBox.setSelected(false);
hardcoverCheckBox.setSelected(false);
if (books[currentBook].getCheckedOut
() == true)
(books[currentBook].getCheckedOut()
checkedOutButton.setSelected(true);
checkedOutButton.setSelected(true);
else
checkedInButton.setSelected(true);
checkedInButton.setSelected(true);
}
We then call a series of setText() methods to update the text fields
with the information of the selected book.
Finally, we set our radio buttons and check boxes with the
setSelected() method depending on the values of the current book
72
LibraryGUI listeners
else if (e.getSource() == hardcoverCheckBox)
{
if (e.getStateChange() == ItemEvent.SELECTED)
books[currentBook].setType(Book2.HARDCOVER);
else
books[currentBook].setType(Book2.PAPERBACK);
}
The next case occurs if the hardcoverCheckBox is
selected.
In this case, we first check to see if the check box was
selected or de-selected. We use the getStateChange()
method to determine this.
If it was selected then we change the type for the
current book to Hardcover, otherwise, we change it to
Paperback.
73
LibraryGUI listeners
else if (e.getSource() == checkedInButton)
books[currentBook].checkIn();
else if (e.getSource() == checkedOutButton)
books[currentBook].checkOut();
}
Finally, if the checkInButton radio button
is selected then we call the checkIn()
method for the current book.
Likewise, we call the checkOut() method if
the checkOutButton is selected.
74
LibraryGUI listeners
The next listener we need to take care of the
KeyListener.
Since we added KeyListeners to our textfields, we
need to determine which of the 3 KeyListener
methods is best to use in the event of a textfield
change.
keyPressed() is called when a key is pressed down
keyReleased() is called when a key is de-pressed and
released
keyTyped() is called after the key has been released
We decide keyReleased() is the best time to update
our textfields so let’s take a look at that method.
75
LibraryGUI listeners
public void keyReleased(KeyEvent e)
{
if (e.getSource() == titleField)
books[currentBook].setTitle(titleField.getText());
...
Just like itemStateChanged(), we first need to
determine which textfield caused the event so we
use an if/else if structure
If the titleField is changed then we update the title
(using our setTitle() method we wrote in Book2) for
our current book. We can retrieve the new text
from our textbox by using the getText() method.
76
LibraryGUI listeners
else if (e.getSource() == copyrightField)
{
try
{
books[currentBook].setCopyright(
Integer.parseInt(copyrightField.getText()));
}
catch (NumberFormatException ex)
{
JOptionPane.showMessageDialog(null,
"Copyright must be a numeric year!");
}
}
All the other textfields essentially perform the same operations if
they cause the event.
The only one that differs slightly is copyrightField, which we put in a
try/catch block that will catch an exception when the user attempts
to enter a non-numeric value into the copyrightField.
77
LibraryGUI listeners
// window listener events
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
public void windowActivated(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowDeactivated(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowOpened(WindowEvent e){}
}
Finally, we end our program by writing the methods required for
WindowListener.
The only method we are concerned with is the windowClosing()
method.
However, we still need to write the other empty methods in order to
satisfy the listener.
78
Drill 12
Recall back to a drill from Lesson 10 where you wrote a simple
Payroll system that used Employee objects. First, extend your
Employee object to also contain members that hold an employeeID
number and a notes variable that can be used to leave notes and
special requests about the employee. Then, create a GUI for your
payroll system. You can use any combination of layouts that you
desire (it should look nice though - be creative!). Your GUI should
allow a user to select an employee from a list of employees and
update information on that employee (name, salary, notes, number
of years employed). They should also be able to change an
employee’s status (active, terminated, on leave - inactive). The
user should NOT be able to change the employee’s ID and should
NOT be allowed to enter anything other than a numeric (float)
salary.
*BONUS* - try to use a JSlider for the number of years employed.
You can find information on how to use a JSlider on page 126 of
your book OR you could consult the Java API specification (which
would be good practice :) As programmers, there are many times
when we must teach ourselves how to use certain components that
we may not have seen or used before – this is an opportunity for
you to learn to develop this important skill!
79