CSC 314 Lecture Notes


Week 3: Interfaces & Inner Classes and Graphics Programming



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

Questions on the Homework? [1/25]




Benchmarking [2/25]



import java.util.*; public class BenchMark{ public static void main(String[] args){ final int SIZE = 1500; int[][] m1 = new int[SIZE][SIZE]; int[][] m2 = new int[SIZE][SIZE]; int[][] m3 = new int[SIZE][SIZE]; int[][] m4 = new int[SIZE][SIZE]; for (int i = 0; i< SIZE; i++){ for (int j = 0; j < SIZE; j++){ m1[i][j] = (int)(Math.random()*500); m2[i][j] = (int)(Math.random()*500); } } Date addStart = new Date(); m3 = MatrixMath.add(m1,m2,SIZE); Date addEnd = new Date(); Date mulStart = new Date(); m4 = MatrixMath.mul(m1,m2,SIZE); Date mulEnd = new Date(); System.out.println("Addition took "+(addEnd.getTime() - addStart.getTime())+" milliseconds"); System.out.println("Multiplication took "+(mulEnd.getTime() - mulStart.getTime())+" milliseconds"); MoreMatrixMath one = new MoreMatrixMath(); System.out.println("There are: " + MoreMatrixMath.howMany() + " instances"); MoreMatrixMath two = new MoreMatrixMath(); System.out.println("There are: " + MoreMatrixMath.howMany() + " instances"); } } BenchMark.java

How else did people do it?

Static methods [3/25]


public class MatrixMath{ public static int[][] add(int[][] m1, int[][] m2, int size){ int[][] m3 = new int[size][size]; for(int i = 0; i< size; i++){ for(int j = 0; j < size; j++){ m3[i][j] = m1[i][j]+m2[i][j]; } } return m3; } public static int[][] mul(int[][] m1, int[][] m2, int size){ int[][] m3 = new int[size][size]; for(int i = 0; i< size; i++){ for(int j = 0; j < size; j++){ m3[i][j] = m1[i][j]*m2[i][j]; } } return m3; } } MatrixMath.java

How else did people do it?

Static fields [4/25]


public class MoreMatrixMath extends MatrixMath{ public MoreMatrixMath(){ increment(); } private void increment(){ ++amount; } public static int howMany(){ return amount; } private static int amount = 0; } MoreMatrixMath.java

How else did people do it?

Let's run it!

Let's compare static fields/methods to instance fields/methods, remember our BankAccount class from last week?


Let's take the quiz... [5/25]


Then we'll go over it.


How do we do multiple inheritance in Java? [6/25]


-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 [7/25]


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 [8/25]



Subinterfaces [9/25]


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 [10/25]


Abstract class Interface Both

Comparable interface of Java.lang [11/25]


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

Java is strongly typed [12/25]


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 [13/25]


import java.util.*; public class EmployeeSortTest{ public static void main(String[] args) { Employee[] staff = new Employee[3]; staff[0] = new Employee("Harry Hacker", 35000); staff[1] = new Employee("Carl Cracker", 75000); staff[2] = new Employee("Tony Tester", 38000); Arrays.sort(staff); for (int i = 0; i < staff.length; i++){ Employee e = staff[i]; System.out.println("name=" + e.getName() + ",salary=" + e.getSalary()); } } } class Employee implements Comparable{ public Employee(String n, double s){ name = n; salary = s; } public String getName(){return name;} public double getSalary(){return salary;} public void raiseSalary(double byPercent){ double raise = salary * byPercent / 100; salary += raise; } public int compareTo(Object otherObject){ Employee other = (Employee)otherObject; if (salary < other.salary) return -1; if (salary > other.salary) return 1; return 0; } private String name; private double salary; } EmployeeSortTest.java

ActionListner interface of java.awt.event [14/25]


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.

class TimePrinter implements ActionListener{ public void actionPerformed(ActionEvent event){ Date now = new Date(); System.out.println("The time is " + now); } }
public class TimerTest{ public static void main(String[] args){ ActionListener listener = new TimePrinter(); Timer t = new Timer(10000, listener); t.start(); } }

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



InnerClassTest.java [16/25]


import java.awt.event.*; import java.text.*; import javax.swing.*; public class InnerClassTest{ public static void main(String[] args){ BankAccount account = new BankAccount(10000); account.accrueInterest(10); while(true){} } } class BankAccount{ public BankAccount(double initialBalance){ balance = initialBalance; } public void accrueInterest(double rate){ ActionListener adder = new InterestAdder(rate); Timer t = new Timer(2000, adder); t.start(); } private double balance; //////INNER CLASS////// private class InterestAdder implements ActionListener{ public InterestAdder(double aRate){ rate = aRate; } public void actionPerformed(ActionEvent event){ double interest = balance * rate / 100; balance += interest; System.out.println("new balance: " + balance); } private double rate; } /////END INNER CLASS////// } InnerClassTest.java

Is this a good idea??


GUI [17/25]



javax.swing.JFrame [18/25]


import javax.swing.*; public class SimpleFrameTest { public static void main(String[] args) { SimpleFrame frame = new SimpleFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // add stuff to your frame here, before showing it! frame.show(); } } class SimpleFrame extends JFrame { public SimpleFrame() { setSize(WIDTH, HEIGHT); } public static final int WIDTH = 300; public static final int HEIGHT = 200; } SimpleFrameTest.java

javax.swing.JFrame extends java.awt.Frame [19/25]





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



CenteredFrameTest.java [21/25]


import java.awt.*; import java.awt.event.*; import javax.swing.*; public class CenteredFrameTest { public static void main(String[] args) { CenteredFrame frame = new CenteredFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.show(); } } class CenteredFrame extends JFrame{ public CenteredFrame(){ Toolkit kit = Toolkit.getDefaultToolkit(); //Toolkit class gives system info Dimension screenSize = kit.getScreenSize(); int screenHeight = screenSize.height; int screenWidth = screenSize.width; // center frame in screen setSize(screenWidth / 2, screenHeight / 2); setLocation(screenWidth / 4, screenHeight / 4); // set frame icon and title Image img = kit.getImage("icon.gif"); setIconImage(img); setTitle("CenteredFrame"); } } CenteredFrameTest.java
icon.gif

ContentPanes and Panels [22/25]

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.

import javax.swing.*; import java.awt.*; public class NotHelloWorld { public static void main(String[] args) { NotHelloWorldFrame frame = new NotHelloWorldFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.show(); } } /** A frame that contains a message panel */ class NotHelloWorldFrame extends JFrame { public NotHelloWorldFrame() { setTitle("NotHelloWorld"); setSize(300, 200); // add panel to frame NotHelloWorldPanel panel = new NotHelloWorldPanel(); Container contentPane = getContentPane(); //gets this.ContentPane for this frame contentPane.add(panel); //put a panel on it } } /** A panel that displays a message. */ class NotHelloWorldPanel extends JPanel { public void paintComponent(Graphics g) //overide this method, it is called implicitly { super.paintComponent(g); //The parent class handles background color etc. g.drawString("Not a Hello, World program", 75, 100); } } NotHelloWorld.java

Graphics2D extends Graphics [23/25]


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 chapter 7 for a full description of the methods this enables you.


A school spireted example [24/25]


import java.awt.*; import java.awt.geom.*; import javax.swing.*; public class DemonDraw{ public static void main(String[] args){ DrawFrame frame = new DrawFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.show(); } } /** A frame that contains a panel with drawings */ class DrawFrame extends JFrame{ public DrawFrame(){ setTitle("DrawTest"); setSize(400, 400); DrawPanel panel = new DrawPanel(); Container contentPane = getContentPane(); contentPane.add(panel); } } /** A panel that displays rectangles and ellipses. */ class DrawPanel extends JPanel{ public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2 = (Graphics2D)g; double leftX = 100; double topY = 100; double width = 200; double height = 150; Rectangle2D rect = new Rectangle2D.Double(leftX, topY, width, height); g2.draw(rect); g2.setPaint(Color.blue); g2.fill(rect); g2.setPaint(Color.black); //chapter 7 goes over Fonts also, it's straight forward Font f= new Font("SanSerif", Font.BOLD, 20); g2.drawString("Go DePaul Blue Demons!", 130, 170); } } DemonDraw.java

Exam Next Week [25/25]


-Exam 3 Next Week
-Homework 3 Due Before Class