CSC 224 Lecture Notes


Week 3: Interfaces & Inner Classes and Graphics Programming



Questions on the Homework? Anything? [1/25]
Let's take the quiz... [2/25]
How do we do multiple inheritance in Java? [3/25]
Interfaces [4/22]
Why interfaces [5/22]
Subinterfaces [6/22]
Abstract classes vs.interfaces [7/22]
Comparable interface of Java.lang [8/22]
Java is strongly typed [9/22]
EmployeeSortTest.java [10/22]
ActionListner interface of java.awt.event [11/22]
Getting in touch with your Inner Class [12/22]
InnerClassTest.java [13/22]
GUI [14/22]
javax.swing.JFrame [15/22]
javax.swing.JFrame extends java.awt.Frame [16/22]
javax.swing.JFrame is the great-great grand daughter of java.awt.Component [17/22]
CenteredFrameTest.java [18/22]
ContentPanes and Panels [19/22]
Inheritance [20/22]
A school spireted example [21/22]
Exam Next Week [22/22]

Questions on the Homework? Anything? [1/22]




Let's take the quiz... [2/22]


Then we'll go over it.


How do we do multiple inheritance in Java? [3/22]


-We now know that inheritance can be helpful
-Some OO languages allows a class to inherit from more than one unrelated class
-In C++ you can have as much inheritance as you care to debug.
-Only single inheritance in Java, we use Interfaces to accomplish the same goals.


Interfaces [4/22]


public interface Driveable { //can't be private, why? boolean MUSTBELICENSED = true; // implicitly static and final static final boolean DANGEROUS = true; // recommended for clarity boolean startEngine(); //implicitly public void stopEngine(); float accelerate(float acc); // you may or may not use the abstract keyword. either is fine, I don't. abstract boolean turn(Direction dir); }

Why interfaces [5/22]



Subinterfaces [6/22]


We subclass classes, so what do you think we can do with interfaces? If we create an interface that extends another interface then that is a subinterface.

    interface OffRoadDrivable extends Drivable {
      static final boolean fourWheelDrive = true;
    }

Remember that if we implement OffRoadDrivable we must be sure to override all the methods in both this interface and the Drivable interface.


Abstract classes versus interfaces [7/22]


Abstract class Interface Both

Comparable interface of Java.lang [8/22]


public interface Comparable{ int compareTo(Object other); }

Java is strongly typed [9/22]


Strong typing means that when a method call is made in Java, the compiler must check to ensure that the method actually exists. Somewhere in the sort method of the Arrays class a call is made like this:

(Comparable)a[i].compareTo((Comparable)a[j])

if the cast is allowed, the object implements Comparable, and thus the existance of the method is assured.


EmployeeSortTest.java [10/22]


1: import java.util.*; 2: 3: public class EmployeeSortTest{ 4: public static void main(String[] args) { 5: Employee[] staff = new Employee[3]; 6: staff[0] = new Employee("Harry Hacker", 35000); 7: staff[1] = new Employee("Carl Cracker", 75000); 8: staff[2] = new Employee("Tony Tester", 38000); 9: 10: Arrays.sort(staff); 11: 12: for (int i = 0; i < staff.length; i++){ 13: Employee e = staff[i]; 14: System.out.println("name=" + e.getName() 15: + ",salary=" + e.getSalary()); 16: } 17: } 18: } 19: 20: class Employee implements Comparable{ 21: public Employee(String n, double s){ 22: name = n; 23: salary = s; 24: } 25: 26: public String getName(){return name;} 27: 28: public double getSalary(){return salary;} 29: 30: public void raiseSalary(double byPercent){ 31: double raise = salary * byPercent / 100; 32: salary += raise; 33: } 34: public int compareTo(Object otherObject){ 35: Employee other = (Employee)otherObject; 36: if (salary < other.salary) return -1; 37: if (salary > other.salary) return 1; 38: return 0; 39: } 40: private String name; 41: private double salary; 42: } EmployeeSortTest.java
est.bat

ActionListner interface of java.awt.event [11/22]


public interface ActionListener{ void actionPerformed(Action event); } -Classes that implement this interface can be passed an Action object from the OS, not explicitly called within the code.

-We will cover this in much more detail next week

-For example the class javax.swing.Timer requests a class that implements this interface as part of its constructor:

Timer(int interval, ActionListener listener)

and then calls the classes actionPerformed() method whenever the OS signals that the interval in milliseconds has passed.

1: 2: import java.awt.*; 3: import java.awt.event.*; 4: import java.util.*; 5: import javax.swing.*; 6: import javax.swing.Timer; 7: // to resolve conflict with java.util.Timer 8: 9: public class TimerTest 10: { 11: public static void main(String[] args) 12: { 13: ActionListener listener = new TimePrinter(); 14: 15: // construct a timer that calls the listener 16: // once every 10 seconds 17: Timer t = new Timer(10000, listener); 18: t.start(); 19: 20: JOptionPane.showMessageDialog(null, "Quit program?"); 21: System.exit(0); 22: } 23: } 24: 25: class TimePrinter implements ActionListener 26: { 27: public void actionPerformed(ActionEvent event) 28: { 29: Date now = new Date(); 30: System.out.println("At the tone, the time is " + now); 31: Toolkit.getDefaultToolkit().beep(); 32: } 33: } TimerTest.java
tt.bat

Getting in touch with your Inner Class [12/25]



InnerClassTest.java [13/22]


1: 2: 3: import java.awt.event.*; 4: import java.text.*; 5: import javax.swing.*; 6: 7: public class InnerClassTest 8: { 9: public static void main(String[] args) 10: { 11: // construct a bank account with initial balance of $10,000 12: BankAccount account = new BankAccount(10000); 13: // start accumulating interest at 10% 14: account.start(10); 15: 16: // keep program running until user selects "Ok" 17: JOptionPane.showMessageDialog(null, "Quit program?"); 18: System.exit(0); 19: } 20: } 21: 22: class BankAccount 23: { 24: /** 25: Constructs a bank account with an initial balance 26: @param initialBalance the initial balance 27: */ 28: public BankAccount(double initialBalance) 29: { 30: balance = initialBalance; 31: } 32: 33: /** 34: Starts a simulation in which interest is added once per 35: second 36: @param rate the interest rate in percent 37: */ 38: public void start(double rate) 39: { 40: ActionListener adder = new InterestAdder(rate); 41: Timer t = new Timer(1000, adder); 42: t.start(); 43: } 44: 45: private double balance; 46: 47: /** 48: This class adds the interest to the bank account. 49: The actionPerformed method is called by the timer. 50: */ //BEGIN INNER CLASS 51: private class InterestAdder implements ActionListener 52: { 53: public InterestAdder(double aRate) 54: { 55: rate = aRate; 56: } 57: 58: public void actionPerformed(ActionEvent event) 59: { 60: // update interest 61: double interest = balance * rate / 100; 62: balance += interest; 63: 64: // print out current balance 65: NumberFormat formatter 66: = NumberFormat.getCurrencyInstance(); 67: System.out.println("balance=" 68: + formatter.format(balance)); 69: } 70: 71: private double rate; 72: }//END INNER CLASS 73: } InnerClassTest.java
ict.bat

Is this a good idea??


GUI [14/22]



javax.swing.JFrame [15/22]


1: 2: import javax.swing.*; 3: 4: public class SimpleFrameTest 5: { 6: public static void main(String[] args) 7: { 8: SimpleFrame frame = new SimpleFrame(); 9: frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 10: frame.show(); 11: } 12: } 13: 14: class SimpleFrame extends JFrame 15: { 16: public SimpleFrame() 17: { 18: setSize(WIDTH, HEIGHT); 19: } 20: 21: public static final int WIDTH = 300; 22: public static final int HEIGHT = 200; 23: } 24: SimpleFrameTest.java

javax.swing.JFrame extends java.awt.Frame [16/22]





javax.swing.JFrame is the great-great granddaughter of java.awt.Component [17/22]



CenteredFrameTest.java [18/22]


1: import java.awt.*; 2: import java.awt.event.*; 3: import javax.swing.*; 4: 5: public class CenteredFrameTest 6: { 7: public static void main(String[] args) 8: { 9: CenteredFrame frame = new CenteredFrame(); 10: frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 11: frame.show(); 12: } 13: } 14: 15: class CenteredFrame extends JFrame 16: { 17: public CenteredFrame() 18: { 19: // get screen dimensions 20: 21: Toolkit kit = Toolkit.getDefaultToolkit(); 22: Dimension screenSize = kit.getScreenSize(); 23: int screenHeight = screenSize.height; 24: int screenWidth = screenSize.width; 25: 26: // center frame in screen 27: 28: setSize(screenWidth / 2, screenHeight / 2); 29: setLocation(screenWidth / 4, screenHeight / 4); 30: 31: // set frame icon and title 32: 33: Image img = kit.getImage("icon.gif"); 34: setIconImage(img); 35: setTitle("CenteredFrame"); 36: } 37: } CenteredFrameTest.java
icon.gif

ContentPanes and Panels [19/22]


The empty part of the frames we keep drawing is the ContentPane, when we want to add more interesting things, we draw graphic images on a Panel and then place the panel onto the ContentPane.

1: import javax.swing.*; 2: import java.awt.*; 3: 4: public class NotHelloWorld 5: { 6: public static void main(String[] args) 7: { 8: NotHelloWorldFrame frame = new NotHelloWorldFrame(); 9: frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 10: frame.show(); 11: } 12: } 13: 14: /** 15: A frame that contains a message panel 16: */ 17: class NotHelloWorldFrame extends JFrame 18: { 19: public NotHelloWorldFrame() 20: { 21: setTitle("NotHelloWorld"); 22: setSize(WIDTH, HEIGHT); 23: 24: // add panel to frame 25: 26: NotHelloWorldPanel panel = new NotHelloWorldPanel(); 27: Container contentPane = getContentPane(); 28: contentPane.add(panel); 29: } 30: 31: public static final int WIDTH = 300; 32: public static final int HEIGHT = 200; 33: } 34: 35: /** 36: A panel that displays a message. 37: */ 38: class NotHelloWorldPanel extends JPanel 39: { 40: public void paintComponent(Graphics g) 41: { 42: super.paintComponent(g); 43: 44: g.drawString("Not a Hello, World program", 45: MESSAGE_X, MESSAGE_Y); 46: } 47: 48: public static final int MESSAGE_X = 75; 49: public static final int MESSAGE_Y = 100; 50: } NotHelloWorld.java
nhw.bat

Graphics2D extends Graphics [20/22]


You can cast your Graphics object, to a 2D object since methods like paintComponent automaticly receive an object of the Graphics2D class:

public void paintComponent(Graphics g){ Graphics2D g2 = (Graphics2D)g; ... } Now you have access to shapes, see the API for a full list of the methods this enables you.


A school spireted example [21/22]


1: import java.awt.*; 2: import java.awt.geom.*; 3: import javax.swing.*; 4: 5: public class DemonDraw{ 6: public static void main(String[] args){ 7: DrawFrame frame = new DrawFrame(); 8: frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 9: frame.show(); 10: } 11: } 12: 13: /** 14: A frame that contains a panel with drawings 15: */ 16: class DrawFrame extends JFrame{ 17: public DrawFrame(){ 18: setTitle("DrawTest"); 19: setSize(400, 400); 20: DrawPanel panel = new DrawPanel(); 21: Container contentPane = getContentPane(); 22: contentPane.add(panel); 23: } 24: } 25: 26: /** 27: A panel that displays rectangles and ellipses. 28: */ 29: class DrawPanel extends JPanel{ 30: public void paintComponent(Graphics g){ 31: super.paintComponent(g); 32: Graphics2D g2 = (Graphics2D)g; 33: 34: double leftX = 100; 35: double topY = 100; 36: double width = 200; 37: double height = 150; 38: 39: Rectangle2D rect = new Rectangle2D.Double(leftX, topY, 40: width, height); 41: g2.draw(rect); 42: g2.setPaint(Color.blue); 43: g2.fill(rect); 44: 45: g2.setPaint(Color.black); 46: Font f= new Font("SanSerif", Font.BOLD, 20); 47: g2.setFont(f); 48: g2.drawString("Go DePaul Blue Demons!", 130, 170); 49: } 50: } DemonDraw.java
dd.bat

Exam Next Week [22/22]


-Exam 3 Next Week
-Homework 3 Due Before Class