Review Continued
Download
Report
Transcript Review Continued
Creating a GUI Class
An example of class design using
inheritance and interfaces
GUI as an Example of I&P
The JFrame class
components and layout
inheriting from JFrame
The ActionListener interface
adding an action listener
Our Goal
Program opens up a window like this:
What can we do with it?
can enter numbers into the
first and second number boxes
can click the “Calculate” button
to put their sum into the result box
can click the “Done” button to end the program
The JFrame Class
javax.swing.JFrame is a window class
constructor takes window title
need to set its size & make it visible
» otherwise it’s tiny and invisible
JFrame win = new JFrame(“An Empty Window”);
win.setSize(300, 200);
win.setVisible(true);
Window Components
Want to add stuff to the window
labels, text fields, buttons
win.add(new JLabel(“Hello!”), BorderLayout.NORTH);
win.add(new JTextField(), BorderLayout.CENTER);
win.add(new JButton(“OK”), BorderLayout.SOUTH);
» there are other ways to lay out the window
Window Operations
Resizing: JFrame handles this
but don’t really need it, so we could get rid of it
Entering #s: JTextBox handles this
tho’ it will accept non-numbers….
Clicking buttons: JButtons “flash”
just do a tiny bit of colour change
nothing else happens!
we will need to do something about that!
Plan
Extend the class JFrame
BE the window!
» have a main method that just opens the window
Have constructor set everything up
add all the labels/fields/buttons and set them up
make sure someone is listening to the buttons
» has to be someone who knows how!
» sounds like an interface….
New Window Classes
Create a class that extends JFrame
class is another window class
public class AdderWindow extends JFrame { … }
Use constructor to add labels, buttons, etc.
laid out in a 5x2 grid
this.setLayout(new GridLayout(5, 2));
three fields, two buttons, and
four labels
Instance Variables
Window needs to track its pieces
except for the labels – they do nothing
private JTextBox firstNumberBox;
private JTextBox secondNumberBox;
private JTextBox resultBox;
private JButton calculateButton;
private JButton doneButton;
Window Constructor Tasks
Constructor:
calls parent constructor: super(“Adding Numbers”);
sets the size and layout: setSize(…); setLayout(…);
creates and adds the required elements
firstNumberBox = new JTextField();
…
this.add(new JLabel(“First number:”));
this.add(firstNumberBox);
…
(also need to “activate” the window–later )
Program to Open the Window
Create a variable for the AdderWindow
AdderWindow d;
Create and save the AdderWindow object
d = new AdderWindow();
Make it visible
d.setVisible(true);
Or we can just create it and make it visible:
(new AdderWindow()).setVisible(true);
Our Window (Inactive)
Here’s our window
not quite the same as what I showed you
Doesn’t do anything
Getting Some Action
Our buttons do nothing
» well, they change colour a bit when they’re clicked
want them to do something
Button needs to tell someone it was clicked
that someone needs to listen for the click
it needs to know how to listen for a click
The ActionListener interface
“I can listen for events (including clicks)”
The ActionListener Interface
Knows how to listen for an event
event sent using actionPerformed method
Create a new class (“AL”) that implements
the ActionListener interface
public class AL implements ActionListener {
public void actionPerformed(ActionEvent e) { … }
}
objects of type AL can listen for clicks
» and should know what to do when they get them
Adding ActionListeners
Need to tell the button who’s listening
then button can send messages to listeners
» recall: “sending a message” = “calling a method”
the addActionListener method
ActionListener al = new AL();
calculateButton.addActionListener(al);
click calculateButton al’s actionPerformed
method gets called
Problem
Needs to know how to respond to the click
needs to get/put numbers from/in text fields
needs to have access to those fields
those fields are private to our window class
So?
can add getters/setters in AdderWindow…
or we can make the window into the listener!
» no need to make a separate class AL!
Listening to Own Components
Have window implement ActionListener
public class AdderWindow extends JFrame
implements ActionListener { … }
» important: extends first, implements after
Add code to constructor
doneButton.addActionListener(this);
calculateButton.addActionListener(this);
» says “this window is listening to you”
» remember: “this” is Java for “me” / “I” / “my”
window must now implement actionPerformed
The actionPerformed Method
Argument has information about the event
including its “source”: which button it was
» choose action based on button clicked
public void actionPerformed(ActionEvent e) {
Object clicked = e.getSource();
if (clicked == doneButton) {
System.exit(0);
// end program
} else if (clicked == calculateButton) {
addTheNumbers(); // private method
}
}
Adding the Numbers
Private method to add and report result
use getText and Integer.parseInt to read #s
use setText and Integer.toString to show result
private void addTheNumbers() {
int n1, n2;
n1 = Integer.parseInt(firstNumberBox.getText());
n2 = Integer.parseInt(secondNumberBox.getText());
resultBox.setText(Integer.toString(n1 + n2));
}
When Things Go Wrong
What could go wrong in AdderWindow?
user might put non-numbers into the boxes
what happens then?
» “Calculate” button seems to do nothing
» (but there are error messages in output window)
what should happen then?
» maybe set result field to “Error”?
how can we get that to happen?
» let’s look at that error message….
The Error Messages
Look at the error messages:
java.lang.NumberFormatException: For input string: "ten"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:589)
at java.lang.Long.parseLong(Long.java:631)
at AdderDialog.addTheNumbers(AdderDialog.java:81)
at AdderDialog.actionPerformed(AdderDialog.java:73)
…
“java.lang.NumberFormatException”
» there was a problem with the format of the numbers
at … AdderDialog.java:81
» line 81 of your program
Exceptions
Objects that represent problems in program
problems that the program itself might be able
to do something about
Throw and Catch
method with problem throws the exception
» Integer.parseInt threw a NumberFormatException
method that can deal with it will catch it
» addTheNumbers can deal with it…
» …so it needs to be ready to catch it
Getting Ready to Catch
Tell Java you can deal with the exception
a “catch block” (catch has a parameter)
catch (WhatKindOfException e) { … }
» body of catch says what to do for that exception
But need to warn Java it might happen
a “try block” (comes before the catch block)
try { … }
» must include the command the exception was
thrown from
Dealing with the Problem
Try to add the numbers; catch the exception
private void addTheNumbers() {
int n1, n2;
try {
n1 = Integer.parseInt(firstNumberBox.getText());
n2 = Integer.parseInt(secondNumberBox.getText());
resultBox.setText(Integer.toString(n1 + n2));
} catch (NumberFormatException nfe) {
resultBox.setText(“ERROR”);
}
}
» no exception: numbers get added up
» exception: result gets set to “ERROR”
Try-Catch Control
Try block contains the code we want to do
but might throw an exception we can deal with
Catch block has code to deal with problem
says what kind of problem it deals with
» e.g. NumberFormatException
If try block works, catch block gets skipped
If exception happens, jump to catch block
remainder of try block gets skipped
If There’s No Problem
Both numbers are OK
try {
n1 = Integer.parseInt(firstNumberBox.getText());
n2 = Integer.parseInt(secondNumberBox.getText());
resultBox.setText(Integer.toString(n1 + n2));
} catch (NumberFormatException nfe) {
// skipped
resultBox.setText(“ERROR”);
}
n1
First number:
100
100
?
n2
Second number:
200
Result:
300
200
?
But If There Is a Problem
Suppose second number is bad
try {
n1 = Integer.parseInt(firstNumberBox.getText());
n2 = Integer.parseInt(secondNumberBox.getText());
resultBox.setText(Integer.toString(n1 + n2));
// skipped!
} catch (NumberFormatException nfe) {
resultBox.setText(“ERROR”);
}
n1
First number:
100
100
?
n2
Second number:
2oo
Result:
ERROR
?
Input Exceptions
Exceptions may happen in reading as well
user enters word where number expected
» InputMismatchException
file runs out of data early
» NoSuchElementException
Can deal with these as well
but don’t need to
Input Exceptions
Read numbers from file
» may be words in file; may be too few numbers
for (int i = 0; i < N; ++i) {
try {
arr[i] = in.nextInt();
} catch (InputMismatchException ime) {
arr[i] = -1; // indicates bad input
in.next();
// skip bad input
} catch (NoSuchElementException nse) {
break;
// no sense trying to read any more!
}
}
Multiple Catch Blocks
Can have as many catch blocks as you like
each for a different kind of exception
Catch order may be important
some exception classes inherit from others
» InputMismatchExcn is a NoSuchElementExcn
» if you ask for an int, and the next thing is a word,
then there’s no such thing as what you asked for
must put more specific exceptions first
» IME must come before NSEE
Never Catch Exception
Exception is most general exception class
if have catch(Exception e), it must come last
it’ll catch any exception
But DON’T CATCH IT!
what could you possibly do that would deal
with every possible kind of problem?
The throws Clause
If your code may throw a checked exception
and your method doesn’t deal with it, then
you need to tell Java you won’t deal with it
» that’s what being “checked” means
add throws clause to method header
private static Scanner open(String name)
throws FileNotFoundException {
return new Scanner(new File(name));
}
Questions