Object-Oriented Programming in Java -- Graphical User Interface (GUI) and Exception Handling

Graphical User Interface (GUI)

GUI built from window gadgets ("widgets") to provide visual interface that contains buttons, labels, text fields, check boxes, etc.

import java.awt.* add (widget);

add () is Container method that adds widget to applet

Label

Label = area where uneditable text displayed on single line

Label() creates empty label Label( String s) // label string Label( String s, // label string int align) // alignment align must be Label.LEFT (default), Label.CENTER, or Label.RIGHT String getText() returns label string void setText( String s) // label string void setAlignment( int align) // alignment

examples:

Label over, name, id; String whatSay; over = new Label(); name = new Label ("What is Your Name?"); id = new Label ("Enter ID", Label.RIGHT); add(over); add(name); add(id); whatSay = name.getText(); over.setText(whatSay); id.setAlignment(Label.LEFT);

Button

Button = clickable component to trigger action (button event)

text on face of button called "button label"

Button() creates button with no label Button( String s) // button label String getLabel() returns button label void setLabel( String s) // button label void addActionListener( ActionListener l) listener l must have actionPerformed() to receive action events from this button String getActionCommand() used in actionPerformed, returns label of button pressed Object getSource() used in actionPerformed, returns name of button pressed

examples:

Button press, click; String whatSay; press = new Button(); press.addActionListener(this); click = new Button("Click Here"); click.addActionListener(this); add(press); add(click); whatSay = click.getLabel(); press.setLabel(whatSay);

TextField

TextField = input, output, interaction

input followed by enter key generates action event

event listener can be registered for TextField

TextField( int cols) creates text field TextField( String s) text field large enough to display string TextField( String s, int cols) void setEchoChar( char c) character to echo, like * in password fields void setEditable( boolean b) true is editable false is not editable void setText( String s) puts this string in TextField String getText() returns string in TextField String getActionCommand() used in actionPerformed, returns string in TextField

examples:

TextField entry = new TextField (25); TextField address = new TextField ("125 Mulberry Lane"); TextField newaddr = new TextField ("125 Mulberry Lane", 40); entry.setEchoChar('*'); address.setEditable(false); entry.getText() is character string currently there

Choice

Choice = drop-down list

Choice() creates empty choice menu void addItem( String s) adds s to choice menu String getSelectedItem() returns selected item int getSelectedIndex() returns selected index void addItemListener( ItemListener l) listener l must have itemStateChanged() or actionPerformed() to receive item events from this choice menu

example:

Choice c = new Choice(); c.addItem("This"); c.addItem("is"); c.addItem("a"); c.addItem("Choice"); c.addItem("Menu"); suppose "Choice" selected: c.getSelectedItem() is "Choice" c.getSelectedIndex() is 3

Checkbox

Checkbox = box that is either selected or not

Checkbox( String s) // checkbox label void addItemListener( ItemListener l) adds listener l to receive item events from this checkbox boolean getState() used in listener, determines if this checkbox is on or off CheckboxGroup() used to make "radio" buttons Checkbox( String s, CheckboxGroup c, boolean state) true is checked false is not checked

examples:

Checkbox cb = new Checkbox ("Hey I am a Checkbox!"); cb.getState() is true if checked CheckboxGroup cbg = new CheckboxGroup(); Checkbox cb1 = new Checkbox("we",cbg,true); Checkbox cb2 = new Checkbox("are",cbg,false); Checkbox cb3 = new Checkbox("a",cbg,false); Checkbox cb4 = new Checkbox("CheckboxGroup",cbg,false); cb3.getState() is true if checked

List

List = collection of items

Click once to select item

Double-click to generate action

List( int rows) void addItem( String s) adds s to list String getSelectedItem() returns selected item int getSelectedIndex() returns selected index void addItemListener( ItemListener l) listener l must have itemStateChanged() or actionPerformed() to receive item events (click) from this list void addActionListener( ActionListener l) listener l must have actionPerformed() to receive action events (double click) from list

example:

List l = new List(3); l.addItem("This"); l.addItem("is"); l.addItem("a"); l.addItem("Scrolling"); l.addItem("List"); add(l); l.addActionListener(this); l.addItemListener(this);

Layout Managers

All components that can contain other components have a LayoutManager

setLayout(Layout Manager);

usually appears in init()

FlowLayout

FlowLayout is default

arranges components in rows left-to-right top-to-bottom

each component is its natural size

Each row is centered

Five pixels between components and between rows

layout can be changed by call to validate();

similar to repaint();

setLayout(new FlowLayout()); setLayout (new FlowLayout(int alignment); alignment may be FlowLayout.LEFT, FlowLayout.RIGHT, or FlowLayout.CENTER (default) setLayout(new FlowLayout (int alignment, int hGap, int vGap);

BorderLayout

BorderLayout divides window into North, South, East, West, Center sections

North, South -- component resized to full window width

East, West -- component resized to remaining window height

Center -- component resized to remaining space

setLayout(new BorderLayout()); setLayout(new BorderLayout (int hGap, int vGap)); gap size defaults are zero add(section, component); add("South", balButton);

GridLayout

GridLayout divides window into equal-sized rectangles of rows and columns

arranges components in rectangles left-to-right top-to-bottom

components resized to fit into rectangles

setLayout(new GridLayout (int rows, int cols));

Panels

Panel = container

Applet can have several panels

Panel() creates new panel using default layout manager Panel(LayoutManager) Creates new panel with specified layout manager

example:

setLayout(new BorderLayout()); Panel p1 = new Panel(); p1.setLayout(new GridLayout(2,2)); Panel p2 = new Panel(FlowLayout()); p1.add(button1); p1.add(button2); p1.add(button3); p1.add(button4); p2.add(textarea1); p2.add(label1); p2.add(textfield1); add("South",p1); add("Center",p2);

Background, Foreground Colors

Default background and foreground colors of applet usually white and black. Can change them with:

setForeground(Color c); setForeground(Color.red); setBackground(Color c); setBackground(Color.black);

Can also use setForeground and setBackground for any Components -- Panel, Label, Button, TextField, Choice, Checkbox, List

press.setForeground(Color.yellow); press.setBackground(Color.blue);

Event Listening and Event Handling

GUIs are event-driven

Events generated when user interacts with GUI (clicking button, changing text field, moving mouse, etc.)

import java.awt.event.*

Must register event listener and implement event handler

(1) In applet

import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class MyButton extends Applet implements ActionListener { public Button pushMe; public String whatEver = new String ("Press the button above..."); public void init() { pushMe = new Button("Press Here"); pushMe.addActionListener(this); add(pushMe); } public void paint(Graphics g) { g.drawString(whatEver,5,55); whatEver = "Thank you very much!"; } public void actionPerformed ( ActionEvent e ) { repaint(); } }

(2) In separate class

import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class MyButtons extends Applet { public Button pushMe; public String whatEver = new String ("Press the button above..."); public void init() { pushMe = new Button( "Press Here" ); pushMe.addActionListener( new ButtonRepaint(this)); add(pushMe); } public void paint(Graphics g) { g.drawString(whatEver,5,55); whatEver = "Thank you very much!"; } } class ButtonRepaint implements ActionListener { Applet applet; public ButtonRepaint( Applet a ) { applet = a; } public void actionPerformed ( ActionEvent e ) { applet.repaint(); } }

Mouse Events

public class Squeaky extends Applet implements MouseListener, MouseMotionListener

MouseListener:

void mouseClicked (MouseEvent e) when mouse button clicked

MouseMotionListener:

void mouseMoved (MouseEvent e) when mouse button moved void mouseDragged (MouseEvent e) when mouse button pressed and mouse moved

Exception Handling

Java Exception Handling nearly identical to C++

Many errors can be handled at point they occur

But some cannot and good programming practice is to isolate error handling from rest of code

Common standard exceptions -- input item in wrong format, incorrect subscript, overflow, division by zero, ....

Java has Exception class (in java.lang). Almost all exceptions are subclasses of Exception.

Exceptions are "thrown" when error occurs

Exceptions are "caught" when there is an Exception Handler for that exception

Exception Handler is block of Java code

Exceptions may be thrown, but might never be caught. What happens then?

Application: Default Exception Handler runs. Program terminates.

Applet: Default Exception Handler runs. Block where error occurred dies, Applet lives on.

Try and Catch Blocks

try { block of code that might generate exceptions, can include calls to other methods that might generate exceptions } catch (1st type of exception) { exception handler code } catch (2nd type of exception) { exception handler code } catch (3rd type of exception) { exception handler code } ...

When exception thrown, program leaves try block and searches catch blocks (IN ORDER) for appropriate exception handler

Any Exception Handler for exception class or any of its superclasses will work

After chosen Exception Handler executes, program resumes following last catch block

If no exceptions thrown in try block, all catch blocks skipped, program continues following last catch block

Standard Exceptions

You can write Exception Handler for any Java Standard Exception

These are usually thrown by run-time system

Integer class contains method:

int parseInt(String s) Returns: the integer represented by the argument. Throws: NumberFormatException if the string does not contain a parseable integer.

Example:

try { ... number=Integer.parseInt (input.getText()); ... } catch (NumberFormatException numfo) { message="You have not entered a valid integer number"; repaint(); }

Create Your Own Exception Class

These are thrown by your program

Make your own exceptions subclasses of existing Exceptions ... so that they are "Throwable"

public class TooSmallException extends ArithmeticException { public TooSmallException() { message="All input values must be greater than zero"; } } try { ... if (number<0) throw new TooSmallException(); ... } catch (TooSmallException tse) { repaint(); }

Java compiler helps with catch blocks

Cannot catch same exception in two different catch blocks in same set

Cannot catch superclass exception before subclass exception. For example, catch block for ArithmeticException must be after catch block for TooSmallException.

"Throwing Up"

A method can detect an exception but have no Exception Handler for it.

In that case it can throw the exception up to the method that called it.

This "throwing up" can continue through several call levels until an appropriate Exception Handler is found or it is determined that there are none. In the latter case, Default Exception Handler runs.

public void drawPie() throws ArithmeticException, TooSmallException { sum=number[0]+number[1] +number[2]+number[3]; if (sum==0) throw new ArithmeticException(); if (sum<0) throw new TooSmallException(); washOut(); .... }

If washOut() throws but does not handle an exception, then drawPie() must either handle that exception or list it in its throw list

Java requires each method to "catch or declare"

A Simple Applet Without Exception Handling

The applet above creates a Pie chart based on integer inputs:

import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class Pie extends Applet implements ActionListener { Label inputlabel; TextField input1, input2, input3, input4; Button b1; int number[], percent[]; int sum, counter; public void init() { sum=0; counter=0; number=new int[4]; percent=new int[4]; inputlabel= new Label("Enter four integers:"); input1=new TextField(5); input2=new TextField(5); input3=new TextField(5); input4=new TextField(5); b1=new Button("Draw Piechart"); add(inputlabel); add(input1); add(input2); add(input3); add(input4); add(b1); b1.addActionListener(this); } public void actionPerformed (ActionEvent e) { number[0]=Integer.parseInt (input1.getText()); number[1]=Integer.parseInt (input2.getText()); number[2]=Integer.parseInt (input3.getText()); number[3]=Integer.parseInt (input4.getText()); sum=number[0]+number[1] +number[2]+number[3]; percent[0]=number[0]*360/sum; percent[1]=number[1]*360/sum; percent[2]=number[2]*360/sum; percent[3]=360-percent[0] -percent[1]-percent[2]; repaint(); } public void paint(Graphics g) { g.setColor(Color.red); g.fillArc (40,60,200,200,0,percent[0]); g.setColor(Color.green); g.fillArc(40,60,200,200, percent[0], percent[1]); g.setColor(Color.blue); g.fillArc(40,60,200,200, percent[0]+percent[1], percent[2]); g.setColor(Color.yellow); g.fillArc(40,60,200,200, percent[0]+percent[1]+percent[2], percent[3]); } }

But, the applet Pie above does not handle any problems?

(1) Bad Integers in TextFields -- actionPerformed() dies, applet lives on

(2) All 4 numbers are zero -- sum is zero and actionPerformed() dies when divide by sum, applet lives on

(3) Tiny Slices -- When any slice is <5%, pie looks lousy

A Better Applet WITH Exception Handling

Handle all three problems as exceptions

import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class EHPie extends Applet implements ActionListener { Label inputlabel; TextField input1, input2, input3, input4; Button b1; String message; int number[], percent[]; int sum, counter; public void init() { sum=0; counter=0; number=new int[4]; percent=new int[4]; inputlabel= new Label("Enter four integers:"); input1=new TextField(5); input2=new TextField(5); input3=new TextField(5); input4=new TextField(5); b1=new Button("Draw Piechart"); add(inputlabel); add(input1); add(input2); add(input3); add(input4); add(b1); b1.addActionListener(this); } public void actionPerformed (ActionEvent e) { try { number[0]=Integer.parseInt (input1.getText()); number[1]=Integer.parseInt (input2.getText()); number[2]=Integer.parseInt (input3.getText()); number[3]=Integer.parseInt (input4.getText()); drawPie(); } catch (NumberFormatException numfo) { message="Make sure all four above are integers!"; redPie(); } catch (TooSmallException tse) { redPie(); } catch (ArithmeticException ae) { message="Arithmetic failure! Try again!!"; redPie(); } } public void redPie() { percent[0]=360; percent[1]=0; percent[2]=0; percent[3]=0; repaint(); } public void drawPie() throws ArithmeticException, TooSmallException { int i; message=""; sum=number[0]+number[1] +number[2]+number[3]; if (sum==0) throw new ArithmeticException(); percent[0]=number[0]*360/sum; percent[1]=number[1]*360/sum; percent[2]=number[2]*360/sum; percent[3]=360-percent[0] -percent[1]-percent[2]; for (i=0;i<4;i++) { if (percent[i]<18) throw new TooSmallException(); } repaint(); } public void paint(Graphics g) { g.drawString(message, 10, 50); g.setColor(Color.red); g.fillArc (40,60,200,200,0,percent[0]); g.setColor(Color.green); g.fillArc(40,60,200,200, percent[0], percent[1]); g.setColor(Color.blue); g.fillArc(40,60,200,200, percent[0]+percent[1], percent[2]); g.setColor(Color.yellow); g.fillArc(40,60,200,200, percent[0]+percent[1]+percent[2], percent[3]); } public class TooSmallException extends ArithmeticException { public TooSmallException() { message="At least one wedge is less than 5%"; } } }

(1) Bad Integers in TextFields -- NumberFormatException: message and redPie (looks like stop sign)

(2) All 4 numbers are zero -- ANY ArithmeticException: message and redPie

(3) Tiny Slices -- TooSmallException: message and redPie

Why Bother with Exception Handling?

Q: Why do Exception Handling by throwing and catching instead of just doing it right where it occurs?

A1: With reuseable software, the point "where it occurs" may be in a package program that is inaccessible.

A2: You may want to do different things depending upon the situation.

For example, in university housing software, BadStudentIDException may occur in locateStudent() method.

Case 1 -- Terminate applet and report IP Node Number to University Police.

Case 2 -- Suggest 2-3 Student IDs closest to one given.

Case 3 -- Offer to find student by name rather than Student ID.

(This material last modified