Transcript chapter10
Intro to Computer Science II
Chapter 10
Graphical Interface Design
Graphical applications and applets
1
Three kinds of Java programs
Console Applications
GUI Applications
Graphical interface, keyboard, and mouse are
used for user input and output goes to windows.
GUI Applet
BGA
Console window used for all input from the user
(Scanner) and output (System.out).
Special kind of Java program that can be run by
a web browser instead of command line
interpreter
2
Structure of GUI application
// import statements go here
public class ApplicationTemplate extends JFrame
implements ActionListener
{
// Declare instance variables for GUI components here
// Declare any other variables here
public ApplicationTemplate()
{ setTitle("Put your frame title here");
// Statements to create GUI components go here
// Statements to add them to frame go here
// Statements to add action listeners go here
setSize(400, 300); // size of the frame
}
BGA
3
Structure of GUI application
public void actionPerformed(ActionEvent e)
{
// statements to process events go here
}
// Construct an application and make it visible
public static void main(String[] args)
{
JFrame f = new ApplicationTemplate();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
BGA
4
Top level GUI components
JFrame
Window (content pane)
The inside of a frame on which other GUI
components can be placed
Components that can interact with user:
BGA
put frame around a window that has a title bar
with a title, minimimze, maximize, close buttons
JLabel, JButton, JTextField, JTextArea,
etc
5
Steps for creating a GUI
BGA
Construct a JFrame object
Construct components
Add components to the frame's content pane
(a container class)
Add any action listeners to the components
Add a window listener to frame if necessary
Write the event processing code associated
with each action listener.
6
This is the title bar
This is the title
This is a window
This is the window frame
400 by 300
book-project/chapter10/simple
BGA
7
GUI Example
JLabel
JTextField
JButton
JTextArea
JScrollPane
BGA
8
Greeting1 Application (1)
Before entering a name
JLabel
JTextField (input)
After entering a name and pressing enter key JTextField (output)
BGA
9
Greeting1 class (1)
Choose the GUI components
BGA
JTextField object called input to define the input
text field
JLabel object called prompt for the text defining
what the input object should contain
JTextField object called output to define a text
field in which the greeting should be displayed
When the user pressed Enter key the text
should be copied from input to output field
10
Greeting1 class design
import
import
import
import
java.awt.*;
java.awt.event.*;
javax.swing.*;
javax.swing.event.*;
public class Greeting1 extends JFrame implements
ActionListener
{
this method
// data fields
public Greeting1() {...}
implements
ActionListener
public void actionPerformed(ActionEvent e) {...}
}
BGA
11
Declaring GUI components
private JLabel prompt;
private JTextField input;
private JTextField output;
these are
instance data
fields
BGA
12
Creating GUI components
these statements go
in the constructor
prompt =
new JLabel("Enter your name and press enter");
input = new JTextField(20);
output = new JTextField(20);
output.setEditable(false);
no typing allowed
in the output field
BGA
approximate
width in chars
13
Choosing a layout manager
A layout manager is an object that knows how to
position the GUI components on the window
FlowLayout
BorderLayout
will use it later. It is the default layout for a JFrame
GridLayout
BGA
put as many components on a line as will fit, then go to
the next line (like word wrap in a word processor)
will use it later
14
Resizing with FlowLayout
Default frame before resize by user
Frame after resize using FlowLayout manager
Now frame is not wide
enough to have more
than one component
on a line
BGA
15
Adding GUI components to frame
components are added to content pane of a frame, not
directly to the frame itself
Container cp = getContentPane();
specify the layout manager
cp.setLayout(new FlowLayout());
add components to the content pane
cp.add(prompt);
cp.add(input);
cp.add(output);
BGA
16
Event-driven programming
GUI programming
BGA
decide what events we want to process. For
example, mouse movement and clicking, enter
key press, button click
Supply the appropriate method (called an event
handler) that a component can call to process
each event we are listening for
we decide what events we want to process by
adding the appropriate listeners to each
component
17
Events and Event Handlers
Button click
handler method
Enter key
handler method
Event
Occurs
Mouse click
handler method
Mouse drag
handler method
BGA
18
Adding Event Listeners
Event handler
object
GUI Component
Listener list
Event handler
object
Event handler
object
BGA
19
Event handling in Greeting1
Add an action listener to the input text field
input.addActionListener(this);
this is the
event handler
our class will contain
the event handler
contains information about
the event
public void actionPerformed(ActionEvent e)
{
// statements to process action events go here
}
BGA
20
Greeting1 processing code
When the user presses enter the text in the input field
must be obtained and copied to the output field.
JTextField objects have getText and setText
methods to do this
public void actionPerformed(ActionEvent e)
{
String name = input.getText();
output.setText("Hello " + name);
}
BGA
21
Greeting1 class (1)
See /book-project/chapter10/simple
import
import
import
import
java.awt.*;
java.awt.event.*;
javax.swing.*;
javax.swing.event.*;
public class Greeting1 extends JFrame implements
ActionListener
{
private JLabel prompt;
private JTextField input;
private JTextField output;
BGA
22
Greeting1 class (2)
public Greeting1()
{ setTitle("Greeting1 (enter key event)");
prompt =
new JLabel("Enter your name and press Enter");
input = new JTextField(20);
output = new JTextField(20);
output.setEditable(false);
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(prompt);
cp.add(input);
cp.add(output);
input.addActionListener(this);
setSize(450,100);
}
BGA
23
Greeting1 class (3)
public void actionPerformed(ActionEvent e)
{
String name = input.getText();
output.setText("Hello " + name);
}
public static void main(String[] args)
{
JFrame = new Greeting1();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
} // end of Greeting1 class
BGA
24
Using a JButton
When you press
enter now nothing
happens
BGA
click the Done
button to display
the greeting
25
Greeting2 class (1)
See /book-project/chapter10/simple
import
import
import
import
java.awt.*;
java.awt.event.*;
javax.swing.*;
javax.swing.event.*;
public class Greeting2 extends JFrame implements
ActionListener
{
private JLabel prompt;
private JTextField input;
private JTextField output;
private
private JButton
JButton done;
done;
BGA
26
Greeting2 class (2)
public Greeting2()
{ setTitle("Greeting2 (button event)");
prompt = new JLabel("Enter ...");
input = new JTextField(20);
output = new JTextField(20);
output.setEditable(false);
done = new JButton("Done");
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(prompt);
cp.add(input);
cp.add(done);
cp.add(output);
done.addActionListener(this);
setSize(450,100);
}
BGA
27
Greeting2 class (3)
public void actionPerformed(ActionEvent e)
{
String name = input.getText();
output.setText("Hello " + name);
}
public static void main(String[] args)
{
JFrame = new Greeting2();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
} // end of Greeting2 class
BGA
28
Enter key and button press
We could have written the Greeting2 class so that
either the enter key or button press displays the greeting
input.addActionListener(this);
done.addActionListener(this);
In either case the actionPerformed method will be called.
BGA
29
Multiple types of events
In previous example the two events (enter
key press and button click) are both
processed in the same way so we don't have
to distnguish them
In general each event type will be processed
in a different way:
BGA
using getSource() method of the ActionEvent
object to determine which event occured
using inner classes, one for each event type
30
Exit button example
BGA
Use enter key event to display the greeting
Use an exit button to given an alternate way
to exit the application that is equvalent to
clicking the close box
Now we need to distinguish the two events
since they are processed differently (one
displays the greeting and the other exits the
application.
31
Using getSource
input.addActionListener(this);
exit.addActionListener(this);
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == input) // enter was pressed
{
String name = input.getText();
output.setText("Hello " + name);
}
else // exit button was clicked
{
System.exit(0); // exit program
}
BGA
32
Enter key and exit button
display greeting when
enter key is pressed
Exit program when
exit button is clicked
BGA
33
Greeting3 class (1)
See /book-project/chapter10/simple
import
import
import
import
java.awt.*;
java.awt.event.*;
javax.swing.*;
javax.swing.event.*;
public class Greeting3 extends JFrame implements
ActionListener
{
private JLabel prompt;
private JTextField input;
private JTextField output;
private
private JButton
JButton exit;
exit;
BGA
34
Greeting3 class (2)
public Greeting3()
{ prompt = new JLabel("Enter name ...");
input = new JTextField(20);
output = new JTextField(20);
output.setEditable(false);
exit = new JButton("Exit");
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(prompt);
cp.add(input);
cp.add(output);
cp.add(exit);
input.addActionListener(this);
exit.addActionListener(this);
setSize(450,100);
BGA
}
35
Greeting3 class (3)
public void actionPerformed(ActionEvent e)
{ if (e.getSource() == input)
{ String name = input.getText();
output.setText("Hello " + name);
}
else System.out.exit(0);
}
public static void main(String[] args)
{ JFrame = new Greeting3();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
} // end of Greeting3 class
BGA
36
Inner classes
BGA
An inner class is declared inside a class
There are several kinds
We will consider only the kind that are normally
used to specify event handlers
Instead of implemeningt the listener interface using
"this" (our class) we can have the inner class do it
Then each event type is associated with its own
inner class
Inner classes have access to data of the
enclosing class (important)
37
EnterKeyHandler
public class EnterKeyHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String name = input.getText();
output.setText("Hello " + name);
inner class
}
can access
}
Instead of
input.addActionListener(this);
the data of
the
enclosing
class
we now use
input.addActionListener(new EnterKeyHandler());
BGA
38
ExitButtonHandler
public class ExitButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}
Instead of
exit.addActionListener(this);
we now use
exit.addActionListener(new ExitButtonHandler());
BGA
39
Greeting4
Instead of
public class Greeting4 extends JFrame
implements ActionListener
{
...
}
we now use
public class Greeting4 extends JFrame
{
...
}
since the inner classes now implement the ActionListener
interface.
BGA
40
Greeting4 class (1)
See /book-project/chapter10/simple
import
import
import
import
java.awt.*;
java.awt.event.*;
javax.swing.*;
javax.swing.event.*;
public class Greeting4 extends JFrame
{
private JLabel prompt;
private JTextField input;
private JTextField output;
private JButton exit;
BGA
41
Greeting4 class (2)
public Greeting4()
{ prompt = new JLabel("Enter name ...");
input = new JTextField(20);
output = new JTextField(20);
output.setEditable(false);
exit = new JButton("Exit");
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(prompt);
cp.add(input); cp.add(output);
cp.add(exit);
input.addActionListener(new EnterKeyHandler());
ExitButtonHander());
exit.addActionListener(new ExitButtonHandler());
setSize(450,100);
}
BGA
42
Greeting4 class (3)
public class EnterKeyHandler
implements ActionListener
{ public void actionPerformed(ActionEvent e)
{ String name = input.getText();
output.setText("Hello " + name);
}
}
inner classes
public class ExitButtonHandler
implements ActionListener
{ public void actionPerformed(ActionEvent e)
{ System.exit(0);
}
}
BGA
43
Greeting4 class (4)
public static void main(String[] args)
{ JFrame = new Greeting4();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
} // end of Greeting4 class
BGA
44
Numeric text fields (1)
The methods for getting and setting text
only work for strings:
To work with numeric values use
BGA
public String getText()
public void setText()
"" + n to convert from a number to a string
Integer.parseInt(s) to convert string s to
an int
Double.parseDouble(s) to convert string s
to a double
45
Numeric text fields (2)
Converting text field values to numeric values
int i = Integer.parseInt(input.getText().trim());
double d = Double.parseDouble(input.getText().trim());
Displaying numeric values in text fields
output.setText("" + n);
output.setText(String.valueOf(n));
BGA
46
Temperature Conversion
double tc =
Double.parseDouble(input.getText().trim());
double tf = (9.0 / 5.0) * tc + 32.0;
output.setText("" + tf);
BGA
47
Temperature class (1)
import
import
import
import
java.awt.*;
java.awt.event.*;
javax.swing.*;
javax.swing.event.*;
public class Temperature extends JFrame
{
private JLabel prompt;
private JTextField input;
private JTextField output;
public Temperature()
{
setTitle("Celsius to Fahrenheit Conversion");
setSize(325,100);
BGA
48
Temperature class (2)
prompt = new JLabel("Enter Celsius, ...");
input = new JTextField(10);
output = new JTextField(10);
output.setEditable(false);
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(prompt);
cp.add(input);
cp.add(output);
input.addActionListener(new EnterKeyHandler());
} // end constructor
BGA
49
Temperature class (3)
public class EnterKeyHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{ double tc =
Double.parseDouble(input.getText().trim());
double tf = (9.0/5.0) * tc + 32.0;
output.setText("" + tf);
}
}
public static void main(String[] args)
{ Jframe f = new Temperature();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
} // end Temperature class
BGA
50
Multi-line text fields
A JTextArea object represents a multi-line text area that
can be used for input or output
private JTextArea output;
output = new JTextArea(10, 20); // 10 rows, 20 columns
Can put a JTextArea inside a JScrollPane to allow for
automatic scrolling in either or both directions
cp.add(new JScrollPane(output));
BGA
51
Investment application
prompt1
rateField
prompt2
amountField
calculate
we will use
GridLayout
here
output
JScrollPane
object
BGA
52
Financial mathematics
annual rate %
12 n
r
f a 1
1200
future
value
BGA
initial
amount
number
of
monthly
interest
periods in
n years
divide by 12*100
to get monthly
rate as a fraction
53
Investment class (1)
import
import
import
import
import
java.text.NumberFormat;
java.awt.*;
java.awt.event.*;
javax.swing.*;
javax.swing.event.*;
public class Investment extends JFrame
{
private JLabel prompt1;
private JLabel prompt2;
private JTextField rateField;
private JTextField amountField;
private JButton calculate;
private JTextArea output;
book-project/chapter10/investment
BGA
54
Investment class (2)
public Investment()
{
setTitle("Investment"); setSize(325,320);
prompt1 = new JLabel("Enter annual rate in %");
rateField = new JTextField("12", 10);
prompt2 = new JLabel("Enter initial amount");
amountField = new JTextField("1000", 10);
calculate = new JButton("Calculate");
output = new JTextArea(10,20);
output.setEditable(false);
Note the two argument form of JTextField. The first
argument can provide a default value for the text field
BGA
55
Investment class (3)
JPanel p = new JPanel();
p.setLayout(new GridLayout(2,2));
p.add(prompt1);
p.add(rateField);
p.add(prompt2);
p.add(amountField);
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(p);
cp.add(calculate);
cp.add(new JScrollPane(output));
• A JPanel is used to organize other components
• The GridLayout object specifies 2 rows and 2 columns
• The output area is inserted into a JScrollPane object
BGA
56
Investment class (4)
calculate.addActionListener(
new CalculateButtonHandler());
doIterations();
} // end of Investment constructor
doIterations calculates and displays the current value of
the investment at the end of each year for 30 years.
BGA
57
Investment class (5)
public void doIterations()
{
NumberFormat currency =
NumberFormat.getCurrencyInstance();
double yearlyRate = Double.parseDouble(
rateField.getText().trim());
double initialAmount = Double.parseDouble(
amountField.getText().trim());
output.setText(""); // clear text area
double amount = initialAmount;
for (int year = 1; year <= 30; year++)
{
amount = futureValue(amount, yearlyRate, 1);
output.append(currency.format(amount) + "\n");
}
}
BGA
58
Investment class (6)
public static double futureValue(double amount,
double yearlyRatePercent, int years)
{ double monthlyRate = yearlyRatePercent / 1200.0;
double a =
amount * Math.pow(1.0 * monthlyRate, 12 * year);
return a;
}
public class CalculateButtonHandler implements
ActionListener
{
public void actionPerformed(ActionEvent e)
{
doIterations();
}
}
BGA
59
Investment class (7)
public static void main(String[] args)
{
JFrame f = new Investment();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
} // end of class Investment
BGA
60
Smart input text field
BGA
Use inheritance to extend the JTextArea
class to obtain a class called
InputJTextField
keep the getText and setText methods
add new methods such as getInt,
getFloat and getDouble
61
JTextField specification
public class JTextField extends JComponent
implements SwingConstants
{
public JTextField() {...}
public JTextField(String text) {...}
public JTextField(int columns) {...}
public JTextField(String text, int columns {...}
// other methods that will be inherited
}
Since we are not adding new data fields we should design our
InputJTextField class to have constructors like this
BGA
62
InputJTextField specification
public class InputJTextField extends JTextField
{
public InputJTextField() {...}
public InputJTextField(String s) {...}
public InputJTextField(int columns) {...}
public InputJTextField(String s, int columns {...}
// new methods
public
public
public
public
public
int getInt() {...}
long getLong() {...}
float getFloat() {...}
double getDouble() {...}
String getString() {...} // includes trim
}
BGA
63
InputJTextField class (1)
public class InputJTextField extends JTextField
{
public InputJTextField()
{ super();
}
public InputJTextField(String s)
{ super(s);
}
public InputJTextField(int columns)
{ super(columns);
}
public InputJTextField(String s, int columns
{ super(s, columns);
}
BGA
64
InputJTextField class (2)
public int getInt()
{
try
{
return Integer.parseInt(getText().trim());
}
catch (NumberFormatException e)
{
setText("0");
return 0;
}
}
BGA
65
InputJTextField class (3)
public long getLong()
{
try
{
return Long.parseLong(getText().trim());
}
catch (NumberFormatException e)
{
setText("0");
return 0;
}
}
BGA
66
InputJTextField class (4)
public float getFloat()
{
try
{
return Float.parseFloat(getText().trim());
}
catch (NumberFormatException e)
{
setText("0");
return 0;
}
}
BGA
67
InputJTextField class (5)
public float getDouble()
{
try
{
return Double.parseDouble(getText().trim());
}
catch (NumberFormatException e)
{
setText("0");
return 0;
}
}
BGA
68
InputJTextField class (6)
public String getString()
{
return getText().trim();
}
} // end of InputJTextField class
Now we could use following statements in Investment class
double yearlyRate = rateField.getDouble();
double initialAmount = amountField.getDouble();
book-project/chapter10/investment-2
BGA
69
LoanRepayment table GUI
BGA
We did this in Chapter 7 using console interface
The LoanRepayment class returned the table
as one big string so that it is reusable
We can now use this class without modification
in a GUI class called
LoanRepaymentTableGUI
The LoanRepaymentTable class can be used
in a doCalculations method that gets its
data from text fields
70
LoanRepayment GUI
loanAmountField
paymentsPerYearField
yearsField
annualRateField
loan repayment
table as one
big string
BGA
output
71
doCalculations method
This method can be called by the actionPerformed method and
also in constructor to produce table for the default parameters
public void doCalculations()
{
double a = loanAmountField.getDouble();
int y = yearsField.getInt();
int p = paymentsPerYearField.getInt();
double r = annualRateField.getDouble();
LoanRepaymentTable table =
new LoanRepaymentTable(a, y, p, r);
output.setText(table.toString());
}
BGA
72
Specifying fonts
We need to use a mono spaced font for the output area. This
can be done by constructing a Font object and using the
setFont method in the JTextArea class
output.setFont( new Font("Courier", Font.PLAIN, 11));
BGA
73
LoanRepaymentTableGUI (1)
package chapter10,loan_repayment;
import custom_classes.InputJTextFields;
import java.text.NumberFormat;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class LoanRepaymentTableGUI extends JFrame
{
private JLabel loanAmountLabel, yearsLabel,
paymentsPerYearLabel, annualRateLabel;
private InputJTextField loanAmountField,
yearsField, paymentsPerYearField,
annualRateField;
private JButton calculate;
private JTextArea output;
BGA
74
LoanRepaymentTableGUI (2)
public LoanRepaymetnTableGUI()
{ setTitle("Loan Repayment"); setSize(500,450);
loanAmountLabel = new JLabel("Loan amount",
JLabel.CENTER);
loanAmountField = new InputJTextField("10000",
10);
yearsLabel = new JLabel("Years", JLabel.CENTER);
yearsField = new InputJTextField("10", 5);
paymentsPerYearLabel =
new JLabel("Payments/year", JLabel.CENTER);
paymentsPerYearField = new InputJTextField(
"2", 5);
BGA
75
LoanRepaymentTableGUI (3)
annualRateLabel = new JLabel("Annual rate %",
CENTER);
annualRateField = new InputJTextField("10", 10);
calculate = new JButton("Calculate");
output = new JTextArea(20, 60);
output.setEditable(false);
output.setFont(new Font("Courier", Font.PLAIN,
11));
BGA
76
LoanRepaymentTableGUI (4)
JPanel p = new JPanel(new GridLayout(2,4));
p.add(loanAmountLabel);
p.add(loanAmountField);
p.add(yearsLabel);
p.add(yearsField);
p.add(paymentsPerYearLabel);
p.add(paymentsPerYearField);
p.add(annualRateLabel);
p.add(annualRateField);
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(p);
cp.add(calculate);
cp.add(new JScrollPane());
BGA
77
LoanRepaymentTableGUI (5)
calculate.addActionListener(
new CalculateButtonHandler());
doCalculations();
} // end constructor
public void doCalculations()
{
double a = loanAmountField.getDouble();
int y = yearsField.getInt();
int p = paymentsPerYearField.getInt();
double r = annualRateField.getDouble();
LoanRepaymentTable table =
new LoanRepaymentTable(a, y, p, r);
output.setText(table.toString());
}
BGA
78
LoanRepaymentTableGUI (6)
public class CalculateButtonHandler implements
AcionListener
{
public void actionPerformed(ActionEvent e)
{ doCalculations();
}
}
public static void main(String[] args)
{ JFrame f = new LoanRepaymentTableGUI();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
book-project/chapter10/loan_repayment
BGA
79
Creating a JAR file
BGA
The loan repayment application can be run
outside the IDE
For example, with Eclipse a jar file can be
made (similar to a zip file)
This file can be executed outside the Eclipse
environment.
80
Unit conversion application
GridLayout is
used here
BGA
81
Defining the conversions
private String[] buttonNames =
{ "in to cm", "cm to in", ..., "gm to oz"};
private double[] factor =
{ 2.54, 1/2.54, ..., 1/28.3495 };
Each button name corresponds to a conversion factor
BGA
82
Connecting buttons to events
Construct the buttons and add them to the panel. The
buttons don't need to be private data fields. The panel will
keep track of them
for (int i = 0; i < buttonNames.length; i++)
{ JButton b = new JButton(buttonNames[i]);
b.addActionListener(new JButtonHandler(i));
p.add(b);
}
We only need one JButtonHandler class. It has an index
that distinguishes one button from another
BGA
83
The button handler class
public class JButtonHandler implements ActionListener
{
private int buttonIndex;
public JButtonHandler(int index)
{
buttonIndex = index;
}
public void actionPerformed(ActionEvent e)
{
double in = input.getDouble();
double out = in * factor[buttonIndex];
output.setText(String.format("%.5f",out));
}
}
BGA
84
Conversions class (1)
package chapter10.conversions;
import custom_clases.InputJTextField;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class Conversions extends JFrame
{
private InputJTextField input;
private JTextField output;
private JLabel inputLabel;
private JLabel outputLabel;
book-project/chapter10/conversions
BGA
85
Conversions class (2)
private String[]
{ "in to cm",
"cm to ft",
"gal to l",
"gm to lb",
};
buttonNames
"cm to in",
"mi to km",
"l to gal",
"oz to gm",
=
"ft
"km
"lb
"gm
to
to
to
to
cm",
mi",
gm",
oz"
private double[] factor =
{ 2.54, 1/2.54, 30.5, 1/30.5, 1.609, 1/1.609,
3.785, 1/3.785, 453.6, 1/453.6, 28.3495,
1/28.3495
};
BGA
86
Conversions class (3)
public Conversions()
{ setTitle("Conversions Calculator");
setSize(450,150);
inputLabel = new JLabel("Input", JLabel.CENTER);
input = new InputJTextField("1", 10);
outputLabel = new JLabel("Output", JLabel.CENTER);
output = new JTextField(10);
input.setBackground(Color.blue);
input.setForeground(Color.white);
output.setBackground(Color.blue);
output.setForeground(Color.white);
BGA
87
Conversions class (4)
// determine the number of button rows
int rows = buttonNames.length / 4;
if (buttonNames.length % 4 != 0)
rows++;
JPanel p = new JPanel();
p.setLayout(new GridLayout(rows + 1, 4));
p.add(inputLabel);
p.add(input);
p.add(outputLabel);
p.add(output);
BGA
88
Conversions class (5)
for (int i = 0; i < buttonNames.length; i++)
{
JButton b = new JButton(buttonNames[i]);
b.addActionListener(new JButtonHandler(i)));
p.add(b);
}
Container cp = getContentPane();
cp.add(p);
BGA
89
Conversions class (6)
public class JButtonHandler implements ActionListener
{ private int buttonIndex;
public JButtonHandler(int index)
{ buttonIndex = index;
}
public void actionPerformed(ActionEvent e)
{ double in = input.getDouble();
double out = in * factor[buttonIndex];
output.setText(String.format("%.5",out));
}
}
public static void main(String[] args)
{ JFrame f = new Conversions();
f.setVisible(true);
f.setDefaultCloseOperations(JFrame.EXIT_ON_CLOSE);
}
}
BGA
90
ActionListener interface
The ActionListener interface like all listener interfaces
extends the EventListener interface:
public interface ActionListener extends EventListener
{
public void actionPerformed(ActionEvent e);
}
The EventListener interface has no methods. It acts like a
placeholder from which all listener interfaces extend
public interface EventListener
{
}
BGA
91
WindowListener interface
We have used setDefaultCloseOperation. For a more
general way to specify what happens we can implement the
WindowListener interface
public interface WindowListener extends EvenListener
{
public void windowClosing(WindowEvent e);
public void windowActivated(WindowEvent e);
public void windowClosed(WindowEvent e);
public void windowDeactivated(WindowEvent e);
public void windowDeiconified(WindowEvent e);
public void windowIconified(WindowEvent e);
public void windowOpened(WindowEvent e);
}
BGA
92
Average mark calculator
Problem: Assume each student in a class has
marks for several tests and repeat the
following for several students
BGA
Enter marks for a student and calculate their
average
Console (command line) application involves
a doubly nested loop
GUI version requires no loops at all!
93
Console algorithm
WHILE more students DO
sumMarks 0
numMarks 0
read mark
WHILE mark >= 0 DO
sumMarks sumMarks + mark
numMarks numMarks + 1
read mark
END WHILE
Compute and display average for this student
Ask if more students
END WHILE
BGA
94
GUI design
pressing enter
copies mark
to output area
BGA
clicking button terminates entry
for that student, computes
average and displays it
95
GUI events (Enter key)
Enter key is clicked for next mark in the text
field:
BGA
mark is added to running sum of marks
number of marks is incremented by 1
input text field is cleared for next mark entry
mark is appended to output text area
96
GUI events (Button)
"Calculate average" button is clicked
BGA
average mark is calculated using running sum
and the number of marks entered
Average marks is displayed in the output area
number of marks is set back to 0
running sum is set back to 0
input text field is cleared
97
MarkAverageGUI (1)
Declare the data fields
private
private
private
private
JLabel prompt;
InputJTextField makrField;
JButton calculate;
JTextArea output;
private double sumMarks = 0.0;
private int numMarks = 0;
BGA
98
MarkAverageGUI (2)
Construct components in constructor
prompt = new JLabel("Enter next mark", JLabel.CENTER);
markField = new InputJTextField("", 10);
calculate = new JButton("Calculate Average");
output = new JTextArea(10,15); // 10 rows 15 cols
output.setEditable(false);
BGA
99
MarkAverageGUI (3)
Lay out components using a GridLayout containing 3 rows
and 1 column for the label, input field, and button.
Then use a flow layout for this group and the text area.
JPanel p = new JPanel();
p.setLayout(new GridLayout(3,1));
p.add(prompt);
p.add(markField);
p.add(calculate);
use JPanel
as a
container
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(p);
cp.add(new JScrollPane(output));
pack();
instead of
setSize
BGA
100
MarkAverageGUI (4)
Now add action listeners to the text field and the button
markField.addActionListener(
new NextMarkFieldHandler());
calculate.addActionListener(
new CalculateButtonHandler());
initialize variables (end of constructor)
initialize(); // see later
BGA
101
MarkAverageGUI (5)
Inner classes for event handling
public class NextMarkFieldHandler implements
ActionListener
{ public void actionPerformed(ActionEvent e)
{ addMark();
}
}
public class CalculateButtonHandler implements
ActionListener
{ public void actionPerformed(ActionEvent e)
{ calculateAverage();
}
}
BGA
102
MarkAverageGUI (6)
Initialize variables
public void initialize()
{ numMarks = 0;
sumMarks = 0.0;
markField.setText("");
}
process the adding of a mark
public void addMark()
{ double mark = markField.getDouble();
sumMarks = sumMarks + mark; numMarks++;
markField.setText("");
output.append(mark + "\n");
}
BGA
103
MarkAverageGUI (7)
Process calculating average
public void calculateAverage()
{ double avg = sumMarks / numMarks;
double avg2 = Math.round(100*avg) / 100.0;
output.append(String.format("Average is %.1f\n",
avg));
initialize();
}
BGA
104
Random Triangles
JPanel using
GraphicsFrame
class from
Chapter 5
Number of
triangles is
entered as a
command line
argument: see
Chapter 9
BGA
105
Random Triangles GUI
BorderLayout is used
with graphics in
center and control
panel in south
RandomTriangles
JPanel
ControlPanel is
also a JPanel
BGA
106
BorderLayout
North
West
Center expands
to fill remaining
space
East
South
BGA
107
RandomTriangles (1)
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class RandomTriangles extends JPanel
{
private int numTriangles;
public RandomTriangles(int n)
{ setNumTriangles(n);
setBackground(Color.white);
}
public void setNumTriangles(int n)
{ numTriangles = n;
}
BGA
108
RandomTriangles (2)
public void paintComponent(Graphics g)
{
super.paintComponent(Color.white);
Graphics2D g2D = (Graphics2D) g;
g2D.setRenderingHint(...);
double w = getWidth();
double h = getHeight();
for (int k = 1; k < numTriangles; k++)
{
Triangle2D t = new Triangle2D(
w*Math.random(), h*Math.random(),
w.Math.random(), h*Math.random(),
w.Math.random(), h*Math.random() );
BGA
109
RandomTriangles (3)
Color c = new Color(
(int) (256*Math.random()),
(int) (256*Math.random()),
(int) (256*Math.random()) );
g2D.setPaint(c);
g2D.fill(t);
g2D.setPaint(Color.black);
g2D.draw(t);
} // end for
} // end paintComponent
BGA
110
RandomTriangles (4)
// For running in BlueJ. Use setNumTriangles
// to change the number of triangles
public void draw()
{ new GraphicsFrame("RandomTriangles",
this(numTriangles), 301, 201);
}
// outside BlueJ
public static void main(String[] args)
{ int n;
if (args.length == 1)
n = Integer.parseInt(args[0]);
else n = 10;
RandomTriangles tri = new RandomTriangles(n);
tri.draw();
}
}
BGA
111
Control panel design
JLabel
Our own custom
component with
a listener (button)
BGA
InputJTextField
JButton
JPanel with a grid layout
JPanel with a flow layout
112
ControlPanel (1)
import
import
import
import
import
java.awt.*;
java.awt.event.*;
java.awt.geom.*;
javax.swing.*;
javax.swing.event.*;
public class ControlPanel extends JPanel
{
private JButton button;
private JLabel prompt;
private InputJTextField inputField;
BGA
113
ControlPanel (2)
public ControlPanel(String promptString,
String buttonLabel, int value)
{
button = new JButton(buttonLabel);
prompt = new JLabel(promptString);
inputField = new InputJTextField("" + value, 5);
JPanel p = new JPanel();
p.setLayout(new GridLayout(1,2));
p.add(inputField); p.add(button);
setLayout(new FlowLayout());
add(prompt);
add(p);
}
BGA
ControlPanel is
a JPanel
114
ControlPanel (3)
We implement the addActionListener method simply by
adding it to the button
public void addActionListener(ActionListener a)
{
button.addActionListener(a);
}
Return the value in the input field of the control panel
public int getValue()
{
return inputField.getInt();
}
}
BGA
115
RandomTrianglesGUI (1)
import
import
import
import
java.awt.*;
java.awt.event.*;
javax.swing.*;
javax.swing.event.*;
public class RandomTrianglesGUI extends JFrame
{
private ControlPanel controlPanel;
private RandomTriangles trianglePanel;
Note that we have only two components now and both of
them are JPanel objects.
BGA
116
RandomTrianglesGUI (2)
public RandomTrianglesGUI()
{ setTitle("Random Triangles GUI");
controlPanel = new controlPanel(
"Number of triangles", "draw", 10);
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
cp.add("Center", trianglePanel);
cp.add("South", controlPanel);
controlPanel.addActionListener(
new ControlPanelHandler());
setSize(400,400);
}
BGA
117
RandomTrianglesGUI (3)
public class ControlPanelHandler implements
ActionListener
{
public void actionPerformed(ActionEvent e)
{
trianglePanel.setNumTriangles(
controlPanel.getValue());
trianglePanel.repaint();
}
}
tell graphics system
to repaint the
triangle panel
BGA
transfer value from
control panel to the
triangle panel
118
RandomTrianglesGUI (4)
public static void main(String[] args)
{
JFrame f = new RandomTrianglesGUI();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
BGA
119
Applets
An applet is a special GUI class that is
executed in a web browser.
Each applet on a web page is specified using
the HTML applet tag which specifies
BGA
initialization parameters, if any
name and location of the class file
width and height of applet in pixels
Applets can be run and tested with a special
program called appletviewer.
120
Applet template
import
import
import
import
java.awt.*;
java.awt.event.*;
java.awt.geom.*;
javax.swing.*;
public class MyApplet extends JApplet
{
// declare GUI components here
public void init()
{
// code to execute when applet is initialized
}
// other methods such as start, stop, destroy
}
BGA
121
Applet life cycle
BGA
page containing applet is loaded by browser
browser calls init method to make applet visible.
Code that would go in the constructor now goes in
this method
start method is called each time user loads page
containing applet.
stop method is called if browser loads another
page
destroy us called to do clean up when applet is
terminated.
122
RGB color applet
Write an applet with 3 textfields, one for
each of the reg, green, and blue values for a
color in the range 0 to 255
At the click of a button the applet's
background color changes to this color
The default color values are obtained from
the applet tag
book-project/chapter10/applets
BGA
123
RGB color applet (1)
Running as an applet in the appletviewer
control
panel
color
panel
BGA
124
RGB color applet (2)
Running as an applet in a browser
BGA
125
RGB color applet (3)
Running as a GUI application
BGA
126
Applet or application ?
In some cases you can write your applet
class so that it can be run either as a GUI
application or as an applet.
Running as an application
Running as an applet in the appletviewer
BGA
java RGBColorApplet
appletviewer RGBColorApplet.html
127
RGBColorApplet (1)
import
import
import
import
java.awt.*;
java.awt.event.*;
java.awt.geom.*;
javax.swing.*;
public class RGBColorApplet extends JApplet
{
private JLabel redLabel, greeLabel, blueLabel;
private InputJTextField redField, greenField,
blueField;
private JPanel controlPanel;
private JPanel colorPanel;
private JButton colorButton;
private String redValue, greenValue, blueValue;
BGA
128
RGBColorApplet (2a)
Try to get parameters from applet tag. If no parameter is
present null is returned and we use a default value
public void init()
{
try
{
redValue = getParameter("redValue");
greenValue = getParameter("greenValue");
blueValue = getParameter("blueValue");
if (redValue == null) redValue = "125";
if (greenValue == null) greenValue = "205";
if (blueValue == null) blueValue = "125";
}
BGA
129
RGBColorApplet (2b)
The try block is necessary since we also want to run this
applet as an application for which getParameter is undefined
catch (NullPointerException e)
{
redValue = "125";
greenValue = "205";
blueValue = "125";
}
BGA
130
RGBColorApplet (3)
put red label and text field in panel
and set panel's background color
redLabel = new JLabel("Red", JLabel.CENTER);
redLabel.setForeground(Color.black);
redField = new InputJTextField(redValue, 4);
JPanel pRed = new JPanel();
pRed.add(redLabel);
pRed.add(redField);
pRed.setBackground(Color.red);
BGA
131
RGBColorApplet (4)
put green label and text field in panel
and set panel's background color
greenLabel = new JLabel("Green", JLabel.CENTER);
greenLabel.setForeground(Color.black);
greenField = new InputJTextField(greenValue, 4);
JPanel pGreen = new JPanel();
pGreen.add(greenLabel);
pGreen.add(greenField);
pGreen.setBackground(Color.green);
BGA
132
RGBColorApplet (5)
put blue label and text field in panel
and set panel's background color
blueLabel = new JLabel("Blue", JLabel.CENTER);
blueLabel.setForeground(Color.black);
blueField = new InputJTextField(blueValue, 4);
JPanel pBlue = new JPanel();
pBlue.add(blueLabel);
pBlue.add(blueField);
pBlue.setBackground(Color.blue);
colorButton = new JButton("Color");
BGA
133
RGBColorApplet (6)
construct control panel and add color panels to it
controlPanel = new JPanel();
controlPanel.setLayout(new FlowLayout());
controlPanel.add(pRed);
controlPanel.add(pGreen);
controlPanel.add(pBlue);
controlPanel.add(colorButton);
BGA
134
RGBColorApplet (7)
construct color panel and add the panels to applet
colorPanel = new JPanel();
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
cp.add(controlPanel, "North");
cp.add(colorPanel, "Center");
add actionlistener and set the initial color of the color panel
colorButton.addActionListener(
new ColorButtonHandler();
changeColor();
BGA
135
RGBColorApplet (8)
put a 1 pixel border around the applet
applets use
paint instead of
paintComponent
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2D = (Graphics2D) g;
int xMax = getWidth() - 1;
int yMax = getHeight() - 1;
Shape border =
new Rectangle2D.Double(0, 0, xMax, yMax);
g2D.setPaint(Color.black);
g2D.draw(border);
}
BGA
136
RGBColorApplet (9)
Define the handler to process the color button click
public class ColorButtonHandler implements
ActionListener
{
public void actionPerformed(ActionEvent e)
{
changeColor();
}
}
BGA
137
RGBColorApplet (10)
Change the color of the color panel
(called by color button handler)
public void changeColor()
{
int red = redField.getInt();
int green = greenField.getInt();
int blue = blueField.getBlue();
Color c = new Color(red, green, blue);
colorPanel.setBackground(c);
repaint();
repaint is necessary to tell the
}
BGA
event manager to request an
update of the components to reflect
the new background color
(calls paintComponent)
138
RGBColorApplet (11)
To run as an application
public static void main(String[] args)
{
RGBColorApplet a = new RGBColorApplet();
a.setSize(400,150);
a.init();
JFrame f = new JFrame();
Container cp = f.getContentPane();
cp.add(a);
f.setTitle("RGB colors");
f.setSize(400,175);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}// end of RGBColorApplet
BGA
139
Running applets from BlueJ
Right click on the applet class
Select Run Applet from the menu to obtain a
dialog box
BGA
choose whether to use appletviewer or browser
set width and height of applet
set any parameter names
(For RGBColorApplet the parameter names are
redValue, greenValue, blueValue)
BlueJ creates a small HTML file with same
name as the applet class (RGBColorApplet)
140
Running applets with Eclipse
BGA
This will be discussed in class
From the Run menu select "Run…" instead
of "Run as" and configure the applet
Also configure any parameters
Applet runs using appletviewer program
Write an HTML file containing the applet tag
to run applet in web browser outside Eclipse
141
RGBColorApplet.html
<html>
<head><title>RGBColorApplet</title></head>
<body>
<h1>RGBColorApplet Applet</h1>
<hr>
<applet code="RGBColorApplet.class"
width=400 height=200 codebase="." alt="......" >
<param name = redValue value = 125>
<param name = greenValue value = 205>
<param name = blueValue value = 125>
</applet>
<hr>
Java variable names
BlueJ generates
</body>
and values
this file for us
</html>
BGA
book-project/chapter10/applets
142
Launching an application
click the button
to run the
RandomTriangles
GUI application
BGA
143
ApplicationLauncher (1)
Launching an application from a button in a web page.
The applet is just a button.
import
import
import
import
java.awt.*;
java.awt.event.*;
java.awt.geom.*;
javax.swing.*;
public class ApplicationLauncher extends JApplet
implements ActionListener
{
JFrame f;
JButton launchButton;
BGA
144
ApplicationLauncher (2)
Iniitialize the applet
public void init()
{
f = null;
launchButton =
new JButton("Launch application");
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
cp.add(launchButton, "Center");
launchButton.addActionListener(this);
}
BGA
145
ApplicationLauncher (3)
destroy method should remove the application and its frame.
This is done with the applet's dispose method: when the
applet gets destroyed we should also destroy the application
if it exits.
public void destroy()
{
if (f != null) f.dispose();
}
BGA
146
ApplicationLauncher (4)
Now implement the actionPerformed method to create or
destroy the application depending on its state
public void actionPerformed(ActionEvent e)
{ if (f == null)
{ f = new RandomTrianglesGUI();
f.setVisible(true);
launchButton.setText("Terminate application");
}
else
{ f.dispose();
f = null;
launchButton.setText("Launch application");
}
}
} // end ApplicationLauncher
BGA
147