For GUI-building, here are some of the more important "standard" components:
Each component can generate events and therefore has an
associated event-listener.
In the sequel, we will learn how to create some of these
components and handle events related to them.
In-Class Exercise 11.1:
Download this file,
compile and execute it. It should produce a form. Try to identify
which of the above components are being used. Below, we will learn
to build this form step-by-step.
(Also comes with additional features, such as "selection").
(Radio-buttons).
The program above used a CardLayout to place a number
of panels on behind another.
As a first step in constructing the form, we will do the
following:
As usual, we will create a frame and use it as follows:
We will place the code for creating the top panel (instructions),
centerpanel (questions) and bottom panel (buttons) in the
constructor.
But because the questions are large (a lot of code), we will
call methods to handle individual questions.
Here is the constructor:
Note:
Here is the complete source:
(source file)
Note:
When executed, the result looks like this:
In-Class Exercise 11.2:
Improve the font of each label in the four questions.
For Question 1, the user needs to enter of the numbers 1,2,3 or 4.
To allow a simple one-line input from the user, a TextField
is best.
Here is the code for Question1:
(source file)
When executed, Question 1 looks like this:
Note:
When the user needs to select one or more items from
a known set of items, a collection of Checkbox's is
convenient:
Here is the code for Question 2:
(source file)
Note:
Suppose we want to allow only one Checkbox in a
collection to be selected.
This can be achieved by associating a CheckboxGroup
instance with the group of Checkbox's.
For example, in Question 3:
(source file)
Note:
Here is the result (the checkbox button looks different - a diamond):
For Question 4, we want a drop-down list:
Such lists are implemented using a Choice instance:
(source file)
Note:
Now the four questions are done. A few more observations:
In-Class Exercise 11.3
(Solution):
In this exercise, you are to use a List instead
of a Choice in Question 4 of the above survey.
Download this template and add
code to the method fourth_question() to support
a List.
Note that a List uses an ItemListener.
Often, a panel or some other widget is too large to fit the
window.
AWT provides a ScrollPane which lets you place the
large widget inside, and has scrollbars to allow scanning of
the whole widget.
Let us take the four questions in the above survey, place them
all on one panel, and put the panel inside a ScrollPane.
Here is the desired effect:
To implement these changes
Note:
We will next design a simple form with a few text fields
that will have the following features:
In-Class Exercise 11.4:
First, familiarize yourself with the form by downloading
the file Form.java,
compiling and executing it. In particular, fill out the form,
"submit" it and look at the properties file it creates in
the same directory. Also observe the following features:
a file dialog, a popup menu.
We will design the form in stages, starting with a simple
form that writes to a properties file.
As a first step, we will do the following:
Here is the code:
(source file)
Note:
Next, we will embellish the form in the following ways:
Rather than display the whole
source file,
we will show pieces of it:
Note:
In-Class Exercise 11.5
(Solution):
In this exercise, you will use the following
template to add a "Help"
menu to the menubar:
Next, we will allow the user to name a file using a file dialog:
Again, we will only show parts of the whole
source file:
Note:
Thus far, we have not handled errors gracefully.
For example, if the filename was incorrect, we killed
the program:
Next, we will bring up a simple dialog box with an "OK" button
to indicate the error.
This code is added to the load() method:
(source file)
Note:
In-Class Exercise 11.6
(Solution):
In this exercise, use your code from Ex.11.5 or, if that
was not completed, the following template
to add a dialog for the "About" option in the "Help" menu.
Typically, "About" displays copyright information.
Finally, we will add a simple popup menu with two items:
Here are the relevant parts of the
source file:
Note:
In this section, we will learn how to create individual scrollbars
using the time-honored example of setting a red-green-blue
combination with scrollbars:
Here is the code:
(source file)
Note:
Next, we will look at an example of handling keyboard events:
We will modify the scrollbar example in the following ways:
Here are the relevant parts of the
source file:
Note:
In-Class Exercise 11.7
(Solution):
Download the following template
and add the following functionality to the above scrollbar program:
the user should be able to use the UP and DOWN arrows to
cycle between the colors (scrollbars). The only code you need
to add is in the keyPressed() method.
(Later, we will place the actual questions in here).
class NewFrame extends Frame {
// Constructor.
public NewFrame (int width, int height)
{
}
// ... other stuff ...
}
public class Survey {
public static void main (String[] argv)
{
NewFrame nf = new NewFrame (500, 300);
}
}
class NewFrame extends Frame {
// Data.
Panel centerpanel; // For the questions.
CardLayout card; // For the centerpanel.
// Constructor.
public NewFrame (int width, int height)
{
this.setTitle ("Snoot Club Membership Test");
this.setResizable (true);
this.setBackground (Color.cyan);
this.setSize (width, height);
// this.setLayout (new BorderLayout());
// First, the instruction line at the top.
Label L = new Label ("Are you elitist enough for our exclusive club?"
+ " Fill out the form and find out");
L.setFont (new Font ("Serif", Font.BOLD | Font.ITALIC, 15));
L.setForeground (Color.blue);
this.add (L, BorderLayout.NORTH);
// Next, a panel of four buttons at the bottom.
// The four buttons: quit, submit, next-question, previous-question.
Panel bottom_panel = get_bottom_panel ();
this.add (bottom_panel, BorderLayout.SOUTH);
// Now, the center panel with the questions.
centerpanel = new Panel ();
// Set the layout to a CardLayout.
card = new CardLayout ();
centerpanel.setLayout (card);
// Each question will be created in a separate method as
// a panel. Note that the cardlayout requires a label as
// second parameter.
Panel p = first_question ();
centerpanel.add (p, "1");
p = second_question ();
centerpanel.add (p, "2");
p = third_question ();
centerpanel.add (p, "3");
p = fourth_question ();
centerpanel.add (p, "4");
// Now add the centerpanel to the frame.
this.add (centerpanel, BorderLayout.CENTER);
// Finally, show the frame.
this.setVisible (true);
}
// No-parameter constructor.
public NewFrame ()
{
this (500, 300);
}
Panel get_bottom_panel ()
{
// Create and place buttons into a panel.
}
}
(Alternatively, you can use the setText() method
of Label).
(Placing a \n in the string doesn't create a new line).
L.setAlignment (Label.RIGHT);
Panel bottom_panel = get_bottom_panel ();
this.add (bottom_panel, BorderLayout.SOUTH);
Panel p = first_question ();
centerpanel.add (p, "1");
card = new CardLayout ();
centerpanel.setLayout (card);
centerpanel.setLayout (new CardLayout());
centerpanel.add (p, "1");
import java.awt.*;
import java.awt.event.*;
class NewFrame extends Frame {
// Data.
Panel centerpanel; // For the questions.
CardLayout card; // For the centerpanel.
// Constructor.
public NewFrame (int width, int height)
{
this.setTitle ("Snoot Club Membership Test");
this.setResizable (true);
this.setBackground (Color.cyan);
this.setSize (width, height);
// this.setLayout (new BorderLayout());
// First, the instruction line at the top.
Label L = new Label ("Are you elitist enough \nfor our exclusive club?"
+ " Fill out the form and find out");
L.setFont (new Font ("Serif", Font.BOLD | Font.ITALIC, 15));
L.setForeground (Color.blue);
this.add (L, BorderLayout.NORTH);
// Next, a panel of four buttons at the bottom.
// The four buttons: quit, submit, next-question, previous-question.
Panel bottom_panel = get_bottom_panel ();
this.add (bottom_panel, BorderLayout.SOUTH);
// Now, the center panel with the questions.
centerpanel = new Panel ();
// Set the layout to a CardLayout.
card = new CardLayout ();
centerpanel.setLayout (card);
// Each question will be created in a separate method as
// a panel. Note that the cardlayout requires a label as
// second parameter.
Panel p = first_question ();
centerpanel.add (p, "1");
p = second_question ();
centerpanel.add (p, "2");
p = third_question ();
centerpanel.add (p, "3");
p = fourth_question ();
centerpanel.add (p, "4");
// Now add the centerpanel to the frame.
this.add (centerpanel, BorderLayout.CENTER);
// Finally, show the frame.
this.setVisible (true);
}
// No-parameter constructor.
public NewFrame ()
{
this (500, 300);
}
Panel get_bottom_panel ()
{
// Create a panel into which we will place buttons.
Panel bottom_panel = new Panel ();
// A "previous-question" button.
Button backward = new Button ("Previous question");
backward.setBackground (Color.green);
backward.setFont (new Font ("Serif", Font.PLAIN | Font.BOLD, 15));
backward.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
// Go back in the card layout.
card.previous (centerpanel);
}
}
);
bottom_panel.add (backward);
// A forward button.
Button forward = new Button ("Next question");
forward.setBackground (Color.green);
forward.setFont (new Font ("Serif", Font.PLAIN | Font.BOLD, 15));
forward.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
// Go forward in the card layout.
card.next (centerpanel);
}
}
);
bottom_panel.add (forward);
// A submit button.
Button submit = new Button ("Submit");
submit.setBackground (Color.green);
submit.setFont (new Font ("Serif", Font.PLAIN | Font.BOLD, 15));
submit.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
// Perform submit task.
compute_result();
}
}
);
bottom_panel.add (submit);
Button quitb = new Button ("Quit");
quitb.setBackground (Color.red);
quitb.setFont (new Font ("Serif", Font.PLAIN | Font.BOLD, 15));
quitb.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
System.exit (0);
}
}
);
bottom_panel.add (quitb);
return bottom_panel;
}
// This method will handle the panel for the first question.
Panel first_question ()
{
// We will package everything into a panel and return the panel.
Panel subpanel = new Panel ();
// For now, we'll just create a label.
Label L1 = new Label ("Question 1:");
subpanel.add (L1);
return subpanel;
}
// Second question.
Panel second_question ()
{
Panel subpanel = new Panel ();
Label L1 = new Label ("Question 2:");
subpanel.add (L1);
return subpanel;
}
// Third question.
Panel third_question ()
{
Panel subpanel = new Panel ();
Label L1 = new Label ("Question 3:");
subpanel.add (L1);
return subpanel;
}
// Fourth question.
Panel fourth_question ()
{
Panel subpanel = new Panel ();
Label L1 = new Label ("Question 4:");
subpanel.add (L1);
return subpanel;
}
// This method is called after submit is pressed.
void compute_result ()
{
// To be filled in ...
}
}
public class Survey0 {
public static void main (String[] argv)
{
NewFrame nf = new NewFrame (500, 300);
}
}
Panel get_bottom_panel ()
{
// Create a panel into which we will place buttons.
Panel bottom_panel = new Panel ();
// ... create the buttons ...
return bottom_panel;
}
quitb.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
System.exit (0);
}
}
);
public void actionPerformed (ActionEvent a)
{
// Perform submit task.
compute_result();
}
public void actionPerformed (ActionEvent a)
{
// Go back in the card layout.
card.previous (centerpanel);
}
public void actionPerformed (ActionEvent a)
{
// Go forward in the card layout.
card.next (centerpanel);
}
Panel first_question ()
{
// We will package everything into a panel and return the panel.
Panel subpanel = new Panel ();
// For now, we'll just create a label.
Label L1 = new Label ("Question 1:");
subpanel.add (L1);
return subpanel;
}
Using a TextField for user input (Question 1)
// This method will handle the panel for the first question.
TextField tf; // Used in question 1.
double q1_score = 0; // Score on question 1.
Panel first_question ()
{
// We will package everything into a panel and return the panel.
Panel subpanel = new Panel ();
// We will place things in a single column, so
// a GridLayout with one column is appropriate.
subpanel.setLayout (new GridLayout (8,1));
Label L1 = new Label ("Question 1:");
L1.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L1);
Label L2 = new Label (" Select a vacation destination");
L2.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L2);
Label L3 = new Label (" 1. Baltimore");
L3.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L3);
Label L4 = new Label (" 2. Disneyland");
L4.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L4);
Label L5 = new Label (" 3. Grand Canyon");
L5.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L5);
Label L6 = new Label (" 4. French Riviera");
L6.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L6);
Label L7 = new Label ("Enter 1,2,3 or 4 below:");
L7.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L7);
// Here's the textfield to get user-input.
tf = new TextField ();
tf.addTextListener (
new TextListener () {
// This interface has only one method.
public void textValueChanged (TextEvent t)
{
String q1_string = tf.getText();
if (q1_string.equals ("2"))
q1_score = 2;
else if (q1_string.equals ("3"))
q1_score = 3;
else if (q1_string.equals ("4"))
q1_score = 4;
else
q1_score = 1;
}
}
);
subpanel.add (tf);
return subpanel;
}
Label L5 = new Label (" 3. Grand Canyon");
L5.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L5);
tf.addTextListener (
new TextListener () {
// This interface has only one method.
public void textValueChanged (TextEvent t)
{
String q1_string = tf.getText();
if (q1_string.equals ("2"))
q1_score = 2;
else if (q1_string.equals ("3"))
q1_score = 3;
else if (q1_string.equals ("4"))
q1_score = 4;
else
q1_score = 1;
}
}
);
Here:
(Typically, the echo character used is a "*").
Using Checkbox's for user input (Question 2)
(Here, two items have been selected - the first and the third).
// For the second question, a collection of checkboxes
// will be used. More than one selection can be made.
// A listener is required for each checkbox. The state
// of each checkbox is recorded.
boolean // Store selections for this question.
q2_option1,
q2_option2,
q2_option3,
q2_option4;
int q2_score; // Score on question 2.
Panel second_question ()
{
Panel subpanel = new Panel ();
subpanel.setLayout (new GridLayout (7,1));
Label L1 = new Label ("Question 2:");
L1.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L1);
Label L2 = new Label (" Select ONE OR MORE things that ");
L2.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L2);
Label L3 = new Label (" you put into your lunch sandwich");
L3.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L3);
// Initialize the selections to false.
q2_option1 = q2_option2 = q2_option3 = q2_option4 = false;
// First checkbox.
Checkbox c1 = new Checkbox ("Ham, beef or turkey");
c1.addItemListener (
new ItemListener () {
public void itemStateChanged (ItemEvent i)
{
Checkbox c = (Checkbox) i.getSource();
q2_option1 = c.getState();
}
}
);
subpanel.add (c1);
// Second checkbox.
Checkbox c2 = new Checkbox ("Cheese");
c2.addItemListener (
new ItemListener () {
// This is where we will react to a change in checkbox.
public void itemStateChanged (ItemEvent i)
{
Checkbox c = (Checkbox) i.getSource();
q2_option2 = c.getState();
}
}
);
subpanel.add (c2);
// Third checkbox.
Checkbox c3 = new Checkbox ("Sun-dried Arugula leaves");
c3.addItemListener (
new ItemListener () {
public void itemStateChanged (ItemEvent i)
{
Checkbox c = (Checkbox) i.getSource();
q2_option3 = c.getState();
}
}
);
subpanel.add (c3);
// Fourth checkbox.
Checkbox c4 = new Checkbox ("Lemon-enhanced smoked Siberian caviar");
c4.addItemListener (
new ItemListener () {
public void itemStateChanged (ItemEvent i)
{
Checkbox c = (Checkbox) i.getSource();
q2_option4 = c.getState();
}
}
);
subpanel.add (c4);
return subpanel;
}
Checkbox c = (Checkbox) i.getSource();
q2_option1 = c.getState();
q2_option1 = c1.getState();
(Since c1 is a local variable and not on the heap).
Using a CheckboxGroup to force only one selection (Question 3)
// The third question allows only one among four choices
// to be selected. We will use checkboxes, but also use
// an associated CheckboxGroup to enforce only one selection.
int q3_score = 0;
Panel third_question ()
{
Panel subpanel = new Panel ();
subpanel.setLayout (new GridLayout (6,1));
Label L1 = new Label ("Question 3:");
L1.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L1);
Label L2 = new Label (" And which mustard do you use?");
L2.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L2);
// First, create the CheckboxGroup instance.
// This instance will be passed to each Checkbox.
CheckboxGroup cgroup = new CheckboxGroup();
// First checkbox.
Checkbox c1 = new Checkbox ("Who cares?", cgroup, true);
c1.addItemListener (
new ItemListener () {
public void itemStateChanged (ItemEvent i)
{
Checkbox c = (Checkbox) i.getSource();
if (c.getState()) q3_score = 1;
}
}
);
subpanel.add (c1);
// Second checkbox.
Checkbox c2 = new Checkbox ("Safeway Brand", cgroup, false);
c2.addItemListener (
new ItemListener () {
public void itemStateChanged (ItemEvent i)
{
Checkbox c = (Checkbox) i.getSource();
if (c.getState()) q3_score = 2;
}
}
);
subpanel.add (c2);
// Third checkbox.
Checkbox c3 = new Checkbox ("Fleishman's", cgroup, false);
c3.addItemListener (
new ItemListener () {
public void itemStateChanged (ItemEvent i)
{
Checkbox c = (Checkbox) i.getSource();
if (c.getState()) q3_score = 3;
}
}
);
subpanel.add (c3);
// Fourth checkbox.
Checkbox c4 = new Checkbox ("Grey Poupon", cgroup, false);
c4.addItemListener (
new ItemListener () {
public void itemStateChanged (ItemEvent i)
{
Checkbox c = (Checkbox) i.getSource();
if (c.getState()) q3_score = 4;
}
}
);
subpanel.add (c4);
return subpanel;
}
CheckboxGroup cgroup = new CheckboxGroup();
Checkbox c1 = new Checkbox ("Who cares?", cgroup, true);
Here, the last boolean indicates the initial state (only
one can be true).
Using a drop-down Choice-list (Question 4)
// For the fourth question we will use a drop-down Choice.
double q4_score = 0;
Choice q4_choice;
Panel fourth_question ()
{
Panel subpanel = new Panel ();
subpanel.setLayout (new GridLayout (3,1));
Label L1 = new Label ("Question 4:");
L1.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L1);
Label L2 = new Label (" Your movie preference, among these:");
L2.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L2);
// Create a Choice widget.
q4_choice = new Choice ();
q4_choice.add ("Lethal Weapon IV");
q4_choice.add ("Titanic");
q4_choice.add ("Saving Private Ryan");
q4_choice.add ("Le Art Movie avec subtitles");
q4_score = 1;
q4_choice.addItemListener (
new ItemListener () {
public void itemStateChanged (ItemEvent e)
{
q4_score = 1 + q4_choice.getSelectedIndex();
System.out.println ("Choice: " + q4_choice.getSelectedIndex());
}
}
);
subpanel.add (q4_choice);
return subpanel;
}
(Thus, the questions are removed).
void compute_result ()
{
// Clear the center panel.
centerpanel.removeAll();
// Display a wait-cursor.
this.setCursor (new Cursor(Cursor.WAIT_CURSOR));
// Create a new panel to display in the center.
Panel subpanel = new Panel (new GridLayout (5,1));
// ... compute scores etc.
// Now add the new subpanel.
centerpanel.add (subpanel, "5");
// Need to mark the centerpanel as "altered"
centerpanel.invalidate();
// Go back to original cursor.
this.setCursor (new Cursor(Cursor.DEFAULT_CURSOR));
// Everything "invalid" (e.g., the centerpanel above)
// is now re-computed.
this.validate();
}
Using a ScrollPane to display large panels
Here is the code in the constructor:
(source file)
// Now the center panel.
centerpanel = new Panel ();
centerpanel.setLayout (new GridLayout (4,1));
centerpanel.add (first_question ());
centerpanel.add (second_question());
centerpanel.add (third_question());
centerpanel.add (fourth_question());
// Next, the scrollpane.
sc = new ScrollPane ();
sc.add (centerpanel);
// Add the scrollpane to the frame.
this.add (sc, BorderLayout.CENTER);
Designing a form with a menubar and dialog
Step 1 in creating the form: writing to a file.
import java.awt.*;
import java.awt.event.*;
import java.util.*; // For "Properties".
import java.io.*; // For file I/O.
class NewFrame extends Frame {
// Data.
Panel centerpanel; // For the questions.
ScrollPane sc; // For placing the centerpanel.
TextField lastname_tf; // To get the lastname.
String lastname;
TextField firstname_tf; // Firstname.
String firstname;
TextField networth_tf; // Net worth
String networth;
TextArea address_ta; // Address (TextArea)
String address;
// Constructor.
public NewFrame (int width, int height)
{
this.setTitle ("Snoot Club Membership Form");
this.setResizable (true);
this.setBackground (Color.white);
this.setSize (width, height);
// this.setLayout (new BorderLayout());
// First, a welcome message:
Label L = new Label ("Please fill out the following form:");
L.setFont (new Font ("Serif", Font.BOLD | Font.ITALIC, 15));
L.setForeground (Color.blue);
this.add (L, BorderLayout.NORTH);
// Now the center panel.
centerpanel = new Panel ();
centerpanel.setLayout (new GridLayout (4,1));
// Each of the methods first_name() etc
// will return a panel.
centerpanel.add (first_name ());
centerpanel.add (last_name ());
centerpanel.add (net_worth ());
centerpanel.add (address ());
// Next, a scrollpane for the form.
sc = new ScrollPane ();
sc.add (centerpanel);
this.add (sc, BorderLayout.CENTER);
// Next, a panel of two buttons at the bottom.
Panel bottom_panel = new Panel ();
// A submit button.
Button submit = new Button ("Submit");
submit.setBackground (Color.green);
submit.setFont (new Font ("Serif", Font.PLAIN | Font.BOLD, 15));
submit.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
// Perform submit task.
submit ();
}
}
);
bottom_panel.add (submit);
Button quitb = new Button ("Quit");
quitb.setBackground (Color.red);
quitb.setFont (new Font ("Serif", Font.PLAIN | Font.BOLD, 15));
quitb.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
System.exit (0);
}
}
);
bottom_panel.add (quitb);
// Now add the panel to the frame.
this.add (bottom_panel, BorderLayout.SOUTH);
// Finally, show the frame.
this.setVisible (true);
}
// Read in the first name.
Panel first_name ()
{
Panel subpanel = new Panel ();
Label L = new Label ("First Name");
L.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L);
firstname_tf = new TextField (20);
firstname_tf.setForeground (Color.blue);
firstname_tf.addTextListener (
new TextListener () {
public void textValueChanged (TextEvent t)
{
// Store in the string "firstname".
firstname = firstname_tf.getText();
}
}
);
subpanel.add (firstname_tf);
return subpanel;
}
// Get last name.
Panel last_name ()
{
Panel subpanel = new Panel ();
Label L = new Label ("Last Name");
L.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L);
lastname_tf = new TextField (20);
lastname_tf.setForeground (Color.blue);
lastname_tf.addTextListener (
new TextListener () {
public void textValueChanged (TextEvent t)
{
lastname = lastname_tf.getText();
}
}
);
subpanel.add (lastname_tf);
return subpanel;
}
// Get net worth.
Panel net_worth ()
{
Panel subpanel = new Panel ();
Label L = new Label ("Net worth (in millions)");
L.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L);
networth_tf = new TextField (10);
networth_tf.setForeground (Color.blue);
networth_tf.addTextListener (
new TextListener () {
public void textValueChanged (TextEvent t)
{
networth = networth_tf.getText();
}
}
);
subpanel.add (networth_tf);
return subpanel;
}
// Get address via a TextArea.
Panel address ()
{
Panel subpanel = new Panel ();
Label L = new Label ("Address");
L.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L);
// Default size: 4 lines, 30 chars wide.
address_ta = new TextArea (4, 30);
address_ta.setForeground (Color.blue);
address_ta.addTextListener (
new TextListener () {
public void textValueChanged (TextEvent t)
{
address = address_ta.getText();
}
}
);
subpanel.add (address_ta);
return subpanel;
}
// Process data when ready.
void submit ()
{
// Create a file by concatenating firstname and lastname.
String filename = firstname + lastname;
if (filename.length() == 0) return;
// We will use a "Properties" instance to store data.
Properties p = new Properties ();
p.put ("firstname", firstname);
p.put ("lastname", lastname);
p.put ("networth", networth);
p.put ("address", address);
// Use the "save" feature of the Properties instance.
try {
FileOutputStream f = new FileOutputStream (filename);
p.save (f, "Member information");
}
catch (IOException e) {
System.out.println (e);
System.exit (0);
}
}
}
public class Form1 {
public static void main (String[] argv)
{
NewFrame nf = new NewFrame (500, 300);
}
}
This combination was placed in a panel.
firstname_tf.addTextListener (
new TextListener () {
public void textValueChanged (TextEvent t)
{
// Store in the string "firstname".
firstname = firstname_tf.getText();
}
}
);
Properties p = new Properties ();
p.put ("firstname", firstname);
p.put ("lastname", lastname);
p.put ("networth", networth);
p.put ("address", address);
FileOutputStream f = new FileOutputStream (filename);
p.save (f, "Member information");
Step 2 in creating the form: placing features in a menu
class NewFrame extends Frame {
// ... Data ...
MenuBar mb; // The menubar.
// Constructor.
public NewFrame (int width, int height)
{
// ...
// The menubar
mb = new MenuBar ();
// Add a "File" menu with two items.
Menu file_menu = new Menu ("File");
file_menu.add ("Load");
file_menu.add ("Quit");
file_menu.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
String item = a.getActionCommand ();
if (item.equals ("Load"))
load ();
else if (item.equals ("Quit"))
System.exit (0);
}
}
);
mb.add (file_menu);
// Add an "Action" menu with two items.
Menu action_menu = new Menu ("Action");
action_menu.add ("Submit");
action_menu.add ("Clear");
action_menu.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
String item = a.getActionCommand ();
if (item.equals ("Submit"))
submit ();
else if (item.equals ("Clear")) {
firstname = ""; firstname_tf.setText (firstname);
lastname = ""; lastname_tf.setText (lastname);
networth = ""; networth_tf.setText (networth);
address = ""; address_ta.setText (address);
}
}
}
);
mb.add (action_menu);
// Note how a menubar is added to a Frame.
this.setMenuBar (mb);
// Finally, show the frame.
this.setVisible (true);
}
// ... first_name() and other methods ...
// Loading from a file.
Properties info;
void load ()
{
// Create the filename.
String filename = firstname + lastname;
info = new Properties ();
try {
FileInputStream f = new FileInputStream (filename);
info.load (f);
// First and lastname are already entered.
networth = info.getProperty ("networth");
networth_tf.setText (networth);
address = info.getProperty ("address");
address_ta.setText (address);
}
catch (IOException e) {
System.out.println ("No such file ... fatal error");
System.exit (0);
}
}
mb = new MenuBar ();
// Add a "File" menu with two items.
Menu file_menu = new Menu ("File");
file_menu.add ("Load");
file_menu.add ("Quit");
file_menu.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
String item = a.getActionCommand ();
if (item.equals ("Load"))
load ();
else if (item.equals ("Quit"))
System.exit (0);
}
}
);
mb.add (file_menu);
// Note how a menubar is added to a Frame.
this.setMenuBar (mb);
else if (item.equals ("Clear")) {
firstname = ""; firstname_tf.setText (firstname);
lastname = ""; lastname_tf.setText (lastname);
networth = ""; networth_tf.setText (networth);
address = ""; address_ta.setText (address);
FileInputStream f = new FileInputStream (filename);
info.load (f);
// First and lastname are already entered.
networth = info.getProperty ("networth");
networth_tf.setText (networth);
address = info.getProperty ("address");
address_ta.setText (address);
(The assumption is that the firstname and lastname have been
entered).
Step 3 in creating the form: a file dialog.
class NewFrame extends Frame {
// ...
// Constructor.
public NewFrame (int width, int height)
{
// ...
// Add a "File" menu with two items.
Menu file_menu = new Menu ("File");
file_menu.add ("Load");
file_menu.add ("LoadFromFile");
file_menu.add ("Quit");
file_menu.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
String item = a.getActionCommand ();
if (item.equals ("Load"))
load ();
if (item.equals ("LoadFromFile"))
load_new ();
else if (item.equals ("Quit"))
System.exit (0);
}
}
);
mb.add (file_menu);
// ...
}
// ... other methods ...
// Load information from an existing Properties file.
Properties info;
// We will use a File instance.
void load ()
{
String dir = null;
String filename = firstname + lastname;
File file = new File (dir, filename);
load (file);
}
void load (File file)
{
info = new Properties ();
try {
FileInputStream f = new FileInputStream (file);
info.load (f);
firstname = info.getProperty ("firstname");
firstname_tf.setText (firstname);
lastname = info.getProperty ("lastname");
lastname_tf.setText (lastname);
networth = info.getProperty ("networth");
networth_tf.setText (networth);
address = info.getProperty ("address");
address_ta.setText (address);
}
catch (IOException e) {
System.out.println ("No such file ... fatal error");
System.exit (0);
}
}
// Use a file dialog.
void load_new ()
{
// Create the FileDialog instance.
FileDialog fd =
new FileDialog (this, "File to load from", FileDialog.LOAD);
// Note: need to make it visible.
fd.setVisible (true);
// When the user is done, get the info.
String dir = fd.getDirectory ();
String filename = fd.getFile ();
String fullname = dir + filename;
// Create a full filename.
File file = new File (fullname);
load (file);
}
file_menu.add ("LoadFromFile");
if (item.equals ("LoadFromFile"))
load_new ();
The only difference is that a File instance
can be passed to the constructor of FileInputStream:
FileInputStream f = new FileInputStream (file);
void load ()
{
String dir = null;
String filename = firstname + lastname;
File file = new File (dir, filename);
load (file);
}
FileDialog fd =
new FileDialog (this, "File to load from", FileDialog.LOAD);
// Note: need to make it visible.
fd.setVisible (true);
Note: the FileDialog is a top-level window and so, needs
to be made visible.
fd.setVisible (true);
// When the user is done, get the info.
String dir = fd.getDirectory ();
String filename = fd.getFile ();
String fullname = dir + filename;
Step 4 in creating the form: an error dialog.
try {
FileInputStream f = new FileInputStream (filename);
// ...
}
catch (IOException e) {
System.out.println ("No such file ... fatal error");
System.exit (0);
}
Dialog error_dialog;
void load (File file)
{
info = new Properties ();
try {
FileInputStream f = new FileInputStream (file);
info.load (f);
firstname = info.getProperty ("firstname");
firstname_tf.setText (firstname);
lastname = info.getProperty ("lastname");
lastname_tf.setText (lastname);
networth = info.getProperty ("networth");
networth_tf.setText (networth);
address = info.getProperty ("address");
address_ta.setText (address);
}
catch (IOException e) {
// Handle a file error more gracefully.
error_dialog = new Dialog (this, true);
error_dialog.setSize (200, 100);
error_dialog.setBackground (Color.yellow);
Label L = new Label ("File does not exist");
Button ok = new Button ("OK");
ok.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
error_dialog.dispose();
}
}
);
error_dialog.setLayout (new BorderLayout());
error_dialog.add (L, BorderLayout.CENTER);
error_dialog.add (ok, BorderLayout.SOUTH);
// Need to make it visible.
error_dialog.setVisible (true);
}
error_dialog = new Dialog (this, true);
Button ok = new Button ("OK");
ok.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
error_dialog.dispose();
}
}
);
error_dialog.setVisible (true);
Step 5 in creating the form: a popup menu
(Along the way, we will learn how to set the scroll position).
class NewFrame extends Frame {
// ...
PopupMenu pm; // The popup menu.
// Constructor.
public NewFrame (int width, int height)
{
// ...
// A pop-up menu
pm = new PopupMenu ();
pm.add ("Top");
pm.add ("Bottom");
pm.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
String item = a.getActionCommand ();
if (item.equals ("Top"))
top ();
else if (item.equals ("Bottom"))
bottom ();
}
}
);
// We add this to the frame.
this.add (pm);
// ...
}
// Methods like first_name() method are slightly modified:
Panel first_name ()
{
Panel subpanel = new Panel ();
Label L = new Label ("First Name");
L.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L);
// Listen for a Popup click.
L.addMouseListener (getMouseListener (L));
firstname_tf = new TextField (20);
firstname_tf.setForeground (Color.blue);
firstname_tf.addTextListener (
new TextListener () {
public void textValueChanged (TextEvent t)
{
firstname = firstname_tf.getText();
}
}
);
subpanel.add (firstname_tf);
subpanel.addMouseListener (getMouseListener(subpanel));
return subpanel;
}
// ...
// Create a Listener for popup's.
MouseListener getMouseListener (Component c)
{
class PopupMouseListener extends MouseAdapter {
Component c;
public PopupMouseListener (Component c)
{
this.c = c;
}
public void mousePressed (MouseEvent m)
{
// We need this special check.
if (m.isPopupTrigger ())
pm.show (c, m.getX(), m.getY());
// Note: this "show" method is not deprecated.
}
}
return new PopupMouseListener (c);
}
// Handle the "go to top" event.
void top ()
{
sc.setScrollPosition (0,0);
}
// Handle the "go to bottom" event.
void bottom ()
{
int height = sc.getViewportSize().height;
sc.setScrollPosition (0,height);
}
}
pm = new PopupMenu ();
pm.add ("Top");
pm.add ("Bottom");
pm.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
String item = a.getActionCommand ();
if (item.equals ("Top"))
top ();
else if (item.equals ("Bottom"))
bottom ();
}
}
);
Panel first_name ()
{
// ...
Label L = new Label ("First Name");
L.setFont (new Font ("SansSerif", Font.ITALIC, 20));
subpanel.add (L);
// Listen for a Popup click.
L.addMouseListener (getMouseListener (L));
// ...
}
MouseListener getMouseListener (Component c)
{
class PopupMouseListener extends MouseAdapter {
Component c;
public PopupMouseListener (Component c)
{
this.c = c;
}
public void mousePressed (MouseEvent m)
{
// We need this special check.
if (m.isPopupTrigger ())
pm.show (c, m.getX(), m.getY());
// Note: this "show" method is not deprecated.
}
}
return new PopupMouseListener (c);
}
pm.show (c, m.getX(), m.getY());
This method takes as parameters the component (e.g., label)
in which the menu pops up and the location.
Scrollbars
For example:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
class NewFrame extends Frame {
// Data.
Scrollbar // One scrollbar for each color.
red_bar,
blue_bar,
green_bar;
int // Intensity value for each color.
red_value = 0,
blue_value = 0,
green_value = 0;
Canvas c; // To display the mixed color.
// Constructor.
public NewFrame (int width, int height)
{
this.setTitle ("RGB combination");
this.setResizable (true);
this.setBackground (Color.cyan);
this.setSize (width, height);
// this.setLayout (new BorderLayout());
// Three scrollbars and the canvas will
// be added to a panel.
Panel p = new Panel ();
p.setLayout (new GridLayout (4,1));
// The canvas on which to display the result.
c = new Canvas ();
c.setBackground (Color.white);
p.add (c);
// A local Listener for the scrollbars.
class ColorAdjustmentListener implements AdjustmentListener {
public void adjustmentValueChanged (AdjustmentEvent a)
{
adjust ();
}
}
red_bar = new Scrollbar (Scrollbar.HORIZONTAL, 0, 10, 0, 255);
red_bar.addAdjustmentListener (new ColorAdjustmentListener());
p.add (red_bar);
green_bar = new Scrollbar (Scrollbar.HORIZONTAL, 0, 10, 0, 255);
green_bar.addAdjustmentListener (new ColorAdjustmentListener());
p.add (green_bar);
blue_bar = new Scrollbar (Scrollbar.HORIZONTAL, 0, 10, 0, 255);
blue_bar.addAdjustmentListener (new ColorAdjustmentListener());
p.add (blue_bar);
this.add (p, BorderLayout.CENTER);
// A quit button for the application.
Button quitb = new Button ("Quit");
quitb.setBackground (Color.red);
quitb.setFont (new Font ("Serif", Font.PLAIN | Font.BOLD, 15));
quitb.addActionListener (
new ActionListener () {
public void actionPerformed (ActionEvent a)
{
System.exit (0);
}
}
);
this.add (quitb, BorderLayout.SOUTH);
// Finally, show the frame.
this.setVisible (true);
}
// No-parameter constructor.
public NewFrame ()
{
this (500, 300);
}
// Create the composite color.
public void adjust ()
{
// Get the new values.
red_value = red_bar.getValue();
green_value = green_bar.getValue ();
blue_value = blue_bar.getValue ();
// Set the color in each scrollbar.
red_bar.setBackground (new Color (red_value, 0, 0));
green_bar.setBackground (new Color (0, green_value, 0));
blue_bar.setBackground (new Color (0, 0, blue_value));
// Create the composite color.
Color new_color = new Color (red_value, green_value, blue_value);
c.setBackground (new_color);
c.repaint ();
}
}
public class TestScrollbar {
public static void main (String[] argv)
{
NewFrame nf = new NewFrame (500, 300);
}
}
red_bar = new Scrollbar (Scrollbar.HORIZONTAL, 0, 10, 0, 255);
Keyboard events
class NewFrame extends Frame {
// ...
// Constructor.
public NewFrame (int width, int height)
{
// ...
// A KeyListener for the canvas.
c.addKeyListener (getKeyListener());
// A KeyListener for the red scrollbar.
red_bar.addKeyListener (getKeyListener());
// A KeyListener for the green scrollbar.
green_bar.addKeyListener (getKeyListener());
// A KeyListener for the blue scrollbar.
blue_bar.addKeyListener (getKeyListener());
// ...
}
// ...
// Create a KeyListener to be used everywhere.
KeyListener getKeyListener ()
{
return new KeyAdapter () {
public void keyPressed (KeyEvent k)
{
if (k.getKeyCode() == KeyEvent.VK_Q)
// "q" for quit.
System.exit (0);
else if (k.getKeyCode() == KeyEvent.VK_LEFT) {
// Left arrow.
red_bar.setValue (Math.max (0, red_value-10));
adjust ();
}
else if (k.getKeyCode() == KeyEvent.VK_RIGHT) {
// Right arrow.
red_bar.setValue (Math.min (255, red_value+10));
adjust ();
}
}
};
}
}
interface KeyListener extends EventListener {
public void keyPressed (KeyEvent e);
public void keyReleased (KeyEvent e);
public void keyTyped (KeyEvent e);
}