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