Intro to Computer Science II
description
Transcript of Intro to Computer Science II
1
Intro to Computer Science II
Chapter 10Graphical Interface Design
Graphical applications and applets
2BGA
Three kinds of Java programs
Console Applications Console window used for all input from the user
(Scanner) and output (System.out). GUI Applications
Graphical interface, keyboard, and mouse are used for user input and output goes to windows.
GUI Applet Special kind of Java program that can be run by
a web browser instead of command line interpreter
3BGA
Structure of GUI application
// import statements go herepublic 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 }
4BGA
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); }}
5BGA
Top level GUI components
JFrame put frame around a window that has a title
bar with a title, minimimze, maximize, close buttons
Window (content pane) The inside of a frame on which other GUI
components can be placed Components that can interact with user:
JLabel, JButton, JTextField, JTextArea, etc
6BGA
Steps for creating a GUI
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.
7BGA
This is a windowThis is the window frame
This is the titleThis is the title bar
400 by 300
book-project/chapter10/simple
8BGA
GUI Example
JLabelJTextField
JTextArea
JButton
JScrollPane
9BGA
Greeting1 Application (1)
Before entering a name
After entering a name and pressing enter key
JLabel JTextField (input)
JTextField (output)
10BGA
Greeting1 class (1)
Choose the GUI components 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
11BGA
Greeting1 class design
import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;
public class Greeting1 extends JFrame implements ActionListener{ // data fields
public Greeting1() {...}
public void actionPerformed(ActionEvent e) {...}}
this methodimplements
ActionListener
12BGA
Declaring GUI components
private JLabel prompt;private JTextField input;private JTextField output;
these areinstance data
fields
13BGA
Creating GUI components
prompt = new JLabel("Enter your name and press enter");input = new JTextField(20);output = new JTextField(20);
output.setEditable(false);
these statements go in the
constructor
approximatewidth in chars
no typing allowedin the output field
14BGA
Choosing a layout manager
A layout manager is an object that knows how to position the GUI components on the window
FlowLayout put as many components on a line as will fit, then go
to the next line (like word wrap in a word processor) BorderLayout
will use it later. It is the default layout for a JFrame GridLayout
will use it later
15BGA
Resizing with FlowLayout
Default frame before resize by user
Frame after resize using FlowLayout manager
Now frame is not wideenough to have morethan one componenton a line
16BGA
Adding GUI components to frame
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(prompt);cp.add(input);cp.add(output);
components are added to content pane of a frame, notdirectly to the frame itself
specify the layout manager
add components to the content pane
17BGA
Event-driven programming
GUI programming 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
18BGA
Events and Event Handlers
EventOccurs
Button clickhandler method
Enter keyhandler method
Mouse clickhandler method
Mouse draghandler method
19BGA
Adding Event Listeners
Event handlerobject
Event handlerobject
Event handlerobject
GUI Component
Listener list
20BGA
Event handling in Greeting1
input.addActionListener(this);
Add an action listener to the input text field
our class will contain the event
handler
public void actionPerformed(ActionEvent e){ // statements to process action events go here}
this is the event
handler contains information about the event
21BGA
Greeting1 processing code
public void actionPerformed(ActionEvent e){ String name = input.getText(); output.setText("Hello " + name);}
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
22BGA
Greeting1 class (1)
import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;
public class Greeting1 extends JFrame implements ActionListener{ private JLabel prompt; private JTextField input; private JTextField output;
See /book-project/chapter10/simple
23BGA
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); }
24BGA
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
25BGA
Using a JButton
When you press enter now nothing
happens
click the Done button to
display the greeting
26BGA
Greeting2 class (1)
import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;
public class Greeting2 extends JFrame implements ActionListener{ private JLabel prompt; private JTextField input; private JTextField output; private JButton done;
See /book-project/chapter10/simple
private JButton done;
27BGA
Greeting2 class (2) public Greeting2() { setTitle("Greeting2 (button event)"); prompt = new JLabel("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(done); cp.add(output); done.addActionListener(this); setSize(450,100); }
done = new JButton("Done");
cp.add(done);
done.addActionListener(this);
28BGA
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
29BGA
Enter key and button press
We could have written the Greeting2 class so that either the enter key or button press displays the greetinginput.addActionListener(this);done.addActionListener(this);
In either case the actionPerformed method will be called.
30BGA
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: using getSource() method of the
ActionEvent object to determine which event occured
using inner classes, one for each event type
31BGA
Exit button example
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.
32BGA
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}
33BGA
Enter key and exit button
display greeting when enter key is
pressed
Exit program whenexit button is
clicked
34BGA
Greeting3 class (1)
import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;
public class Greeting3 extends JFrame implements ActionListener{ private JLabel prompt; private JTextField input; private JTextField output; private JButton exit;
See /book-project/chapter10/simple
private JButton exit;
35BGA
Greeting3 class (2) public Greeting3() { prompt = new JLabel("Enter name ..."); 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); cp.add(exit); input.addActionListener(this);
setSize(450,100); }
exit = new JButton("Exit");
cp.add(exit);
exit.addActionListener(this);
36BGA
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
37BGA
Inner classes
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)
38BGA
EnterKeyHandler
public class EnterKeyHandler implements ActionListener{ public void actionPerformed(ActionEvent e) { String name = input.getText(); output.setText("Hello " + name); }}
Instead of
we now use
input.addActionListener(this);
input.addActionListener(new EnterKeyHandler());
inner classcan accessthe data of
the enclosing
class
39BGA
ExitButtonHandler
public class ExitButtonHandler implements ActionListener{ public void actionPerformed(ActionEvent e) { System.exit(0); }}
Instead of
we now use
exit.addActionListener(this);
exit.addActionListener(new ExitButtonHandler());
40BGA
Greeting4
Instead of
we now use
public class Greeting4 extends JFrame implements ActionListener{ ...}
public class Greeting4 extends JFrame{ ...}
since the inner classes now implement the ActionListener interface.
41BGA
Greeting4 class (1)
import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;
public class Greeting4 extends JFrame { private JLabel prompt; private JTextField input; private JTextField output; private JButton exit;
See /book-project/chapter10/simple
42BGA
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()); exit.addActionListener(new ExitButtonHander()); setSize(450,100); }
input.addActionListener(new EnterKeyHandler());exit.addActionListener(new ExitButtonHandler());
43BGA
Greeting4 class (3)
public class EnterKeyHandler implements ActionListener { public void actionPerformed(ActionEvent e) { String name = input.getText(); output.setText("Hello " + name); } }
public class ExitButtonHandler implements ActionListener { public void actionPerformed(ActionEvent e) { System.exit(0); } }
inner classes
44BGA
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
45BGA
Numeric text fields (1)
The methods for getting and setting text only work for strings: public String getText() public void setText()
To work with numeric values use "" + 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
46BGA
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));
47BGA
Temperature Conversion
double tc = Double.parseDouble(input.getText().trim());double tf = (9.0 / 5.0) * tc + 32.0;output.setText("" + tf);
48BGA
Temperature class (1)
import java.awt.*;import java.awt.event.*;import javax.swing.*;import 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);
49BGA
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
50BGA
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
51BGA
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));
52BGA
Investment application
prompt1
prompt2
rateField
amountField
calculate
output
JScrollPaneobject
we will use
GridLayout here
53BGA
Financial mathematics
nr
af12
12001
future
value
initialamoun
t
annual rate %
divide by 12*100 to get monthly rate as a fraction
numberof
monthly interest periods
in n years
54BGA
Investment class (1)
import java.text.NumberFormat;import java.awt.*;import java.awt.event.*;import javax.swing.*;import 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
55BGA
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
56BGA
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
57BGA
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.
58BGA
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"); } }
59BGA
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(); } }
60BGA
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
61BGA
Smart input text field
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
62BGA
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
63BGA
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 int getInt() {...} public long getLong() {...} public float getFloat() {...} public double getDouble() {...} public String getString() {...} // includes trim}
64BGA
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); }
65BGA
InputJTextField class (2)
public int getInt() { try { return Integer.parseInt(getText().trim()); } catch (NumberFormatException e) { setText("0"); return 0; } }
66BGA
InputJTextField class (3)
public long getLong() { try { return Long.parseLong(getText().trim()); } catch (NumberFormatException e) { setText("0"); return 0; } }
67BGA
InputJTextField class (4)
public float getFloat() { try { return Float.parseFloat(getText().trim()); } catch (NumberFormatException e) { setText("0"); return 0; } }
68BGA
InputJTextField class (5)
public float getDouble() { try { return Double.parseDouble(getText().trim()); } catch (NumberFormatException e) { setText("0"); return 0; } }
69BGA
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
70BGA
LoanRepayment table GUI
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
71BGA
LoanRepayment GUI
loanAmountField
yearsField
paymentsPerYearField
annualRateField
output
loan repaymenttable as onebig string
72BGA
doCalculations method
This method can be called by the actionPerformed method andalso in constructor to produce table for the default parameterspublic 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());}
73BGA
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));
74BGA
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;
75BGA
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);
76BGA
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));
77BGA
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());
78BGA
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()); }
79BGA
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
80BGA
Creating a JAR file
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.
81BGA
Unit conversion application
GridLayout is
used here
82BGA
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
83BGA
Connecting buttons to events
for (int i = 0; i < buttonNames.length; i++){ JButton b = new JButton(buttonNames[i]); b.addActionListener(new JButtonHandler(i)); p.add(b);}
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
We only need one JButtonHandler class. It has an indexthat distinguishes one button from another
84BGA
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)); }}
85BGA
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
86BGA
Conversions class (2)
private String[] buttonNames = { "in to cm", "cm to in", "ft to cm", "cm to ft", "mi to km", "km to mi", "gal to l", "l to gal", "lb to gm", "gm to lb", "oz to gm", "gm to 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 };
87BGA
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);
88BGA
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);
89BGA
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);
90BGA
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); }}
91BGA
ActionListener interface
public interface ActionListener extends EventListener{ public void actionPerformed(ActionEvent e);}
The ActionListener interface like all listener interfaces extends the EventListener interface:
The EventListener interface has no methods. It acts like a placeholder from which all listener interfaces extendpublic interface EventListener{
}
92BGA
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);}
93BGA
Average mark calculator
Problem: Assume each student in a class has marks for several tests and repeat the following for several students 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!
94BGA
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 studentsEND WHILE
95BGA
GUI design
pressing entercopies mark
to output area
clicking button terminates entryfor that student, computes average and displays it
96BGA
GUI events (Enter key)
Enter key is clicked for next mark in the text field: 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
97BGA
GUI events (Button)
"Calculate average" button is clicked 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
98BGA
MarkAverageGUI (1)
Declare the data fields
private JLabel prompt;private InputJTextField makrField;private JButton calculate;private JTextArea output;
private double sumMarks = 0.0;private int numMarks = 0;
99BGA
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 colsoutput.setEditable(false);
100BGA
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);
Container cp = getContentPane();cp.setLayout(new FlowLayout());cp.add(p);cp.add(new JScrollPane(output));pack();
use JPanel as a
container
instead of setSize
101BGA
MarkAverageGUI (4)
Now add action listeners to the text field and the buttonmarkField.addActionListener( new NextMarkFieldHandler());
calculate.addActionListener( new CalculateButtonHandler());
initialize variables (end of constructor)
initialize(); // see later
102BGA
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(); }}
103BGA
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");}
104BGA
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();}
105BGA
Random Triangles
JPanel using GraphicsFra
me class from Chapter
5
Number of triangles is entered as a command line argument: seeChapter 9
106BGA
Random Triangles GUI
RandomTriangles
JPanel
ControlPanel isalso a JPanel
BorderLayout is used with graphics in center and control panel in south
107BGA
BorderLayout
South
EastWest
North
Center expands to fill
remaining space
108BGA
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; }
109BGA
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() );
110BGA
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
111BGA
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(); }}
112BGA
Control panel design
JButtonInputJTextField
JLabel
JPanel with a grid layout
JPanel with a flow layout
Our own customcomponent witha listener (button)
113BGA
ControlPanel (1)
import java.awt.*;import java.awt.event.*;import java.awt.geom.*;import javax.swing.*;import javax.swing.event.*;
public class ControlPanel extends JPanel{ private JButton button; private JLabel prompt; private InputJTextField inputField;
114BGA
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); }
ControlPanel is a JPanel
115BGA
ControlPanel (3)
public void addActionListener(ActionListener a) { button.addActionListener(a); }
We implement the addActionListener method simply byadding it to the button
Return the value in the input field of the control panel
public int getValue() { return inputField.getInt(); }}
116BGA
RandomTrianglesGUI (1)
import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;
public class RandomTrianglesGUI extends JFrame{ private ControlPanel controlPanel; private RandomTriangles trianglePanel;
Note that we have only two components now and both ofthem are JPanel objects.
117BGA
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); }
118BGA
RandomTrianglesGUI (3)
public class ControlPanelHandler implements ActionListener { public void actionPerformed(ActionEvent e) { trianglePanel.setNumTriangles( controlPanel.getValue()); trianglePanel.repaint(); } }
transfer value from
control panel to the triangle panel
tell graphics system
to repaint thetriangle panel
119BGA
RandomTrianglesGUI (4)
public static void main(String[] args) { JFrame f = new RandomTrianglesGUI(); f.setVisible(true); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }}
120BGA
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 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.
121BGA
Applet template
import java.awt.*;import java.awt.event.*;import java.awt.geom.*;import 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}
122BGA
Applet life cycle
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.
123BGA
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
124BGA
RGB color applet (1)
Running as an applet in the appletviewer
controlpanel
colorpanel
125BGA
RGB color applet (2)
Running as an applet in a browser
126BGA
RGB color applet (3)
Running as a GUI application
127BGA
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 java RGBColorApplet
Running as an applet in the appletviewer appletviewer RGBColorApplet.html
128BGA
RGBColorApplet (1)
import java.awt.*;import java.awt.event.*;import java.awt.geom.*;import 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;
129BGA
RGBColorApplet (2a)
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"; }
Try to get parameters from applet tag. If no parameter ispresent null is returned and we use a default value
130BGA
RGBColorApplet (2b)
catch (NullPointerException e) { redValue = "125"; greenValue = "205"; blueValue = "125"; }
The try block is necessary since we also want to run thisapplet as an application for which getParameter is undefined
131BGA
RGBColorApplet (3)
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);
put red label and text field in paneland set panel's background color
132BGA
RGBColorApplet (4)
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);
put green label and text field in paneland set panel's background color
133BGA
RGBColorApplet (5)
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);
put blue label and text field in paneland set panel's background color
colorButton = new JButton("Color");
134BGA
RGBColorApplet (6)
controlPanel = new JPanel(); controlPanel.setLayout(new FlowLayout()); controlPanel.add(pRed); controlPanel.add(pGreen); controlPanel.add(pBlue); controlPanel.add(colorButton);
construct control panel and add color panels to it
135BGA
RGBColorApplet (7)
colorPanel = new JPanel(); Container cp = getContentPane(); cp.setLayout(new BorderLayout()); cp.add(controlPanel, "North"); cp.add(colorPanel, "Center");
construct color panel and add the panels to applet
add actionlistener and set the initial color of the color panel colorButton.addActionListener( new ColorButtonHandler(); changeColor();
136BGA
RGBColorApplet (8)
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); }
put a 1 pixel border around the appletapplets use
paint instead of paintComponent
137BGA
RGBColorApplet (9)
public class ColorButtonHandler implements ActionListener { public void actionPerformed(ActionEvent e) { changeColor(); } }
Define the handler to process the color button click
138BGA
RGBColorApplet (10)
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(); }
Change the color of the color panel(called by color button handler)
repaint is necessary to tell the event manager to request an update of the components to reflect the new background
color(calls paintComponent)
139BGA
RGBColorApplet (11)
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
To run as an application
140BGA
Running applets from BlueJ
Right click on the applet class Select Run Applet from the menu to obtain
a dialog box 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)
141BGA
Running applets with Eclipse
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
142BGA
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></body></html>
BlueJ generatesthis file for us
Java variable names and
values
book-project/chapter10/applets
143BGA
Launching an application
click the button to run
the RandomTriangl
esGUI application
144BGA
ApplicationLauncher (1)
import java.awt.*;import java.awt.event.*;import java.awt.geom.*;import javax.swing.*;
public class ApplicationLauncher extends JApplet implements ActionListener{ JFrame f; JButton launchButton;
Launching an application from a button in a web page.The applet is just a button.
145BGA
ApplicationLauncher (2)
public void init() { f = null; launchButton = new JButton("Launch application"); Container cp = getContentPane(); cp.setLayout(new BorderLayout()); cp.add(launchButton, "Center"); launchButton.addActionListener(this); }
Iniitialize the applet
146BGA
ApplicationLauncher (3)
public void destroy() { if (f != null) f.dispose(); }
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.
147BGA
ApplicationLauncher (4)
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
Now implement the actionPerformed method to create or destroy the application depending on its state