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]
- We need to finish the slides from last weeks lecture
- Let's go over the homeworks.
- Then let's go over everything we've covered in the reading and the notes thus far
- Ask any questions you want
- We can spend as much time as you need
- I have a short class planned because I want to get everybody up to speed
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]
- an interface is simply a list of methods with no bodies
- similar to an abstract class where every method is abstract, and every field is final static
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]
- having your class
implement
an interface is like a promise that your class will support the listed methods
- Other classes may insist that you
implement
certain interfaces
- The
Arrays
class will only sort objects that implement the Comparable
interface... more on that later
- Interfaces define abilities, so rather than extending an interface you
implement
an interface. Since a car is driveable an automobile class might implement
a driveable interface.
class Automobile implements Driveable {
public boolean startEngine() {
if (notTooCold) {
engineRunning = true;
}
return engineRunning;
}
public void stopEngine() {
engineRunning = false;
}
public float accelerate(float acc) {
// ..
}
public boolean turn(Direction dir) {
// ..
}
}
- Another possible use of interfaces is as a holder of predefined values.
- By placing initialized variables within the interface, you can bestow those values on a class by having the class implement the interface.
- Unlike class inheritance, a class can
implement
multiple interfaces
- A Car class might want to implement Drivable; but also Comparable, and more...
- You can declare a variable of an interface type!
- If you code to the interface you can change the implementation w/o changing the code that uses the methods
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
- models an abstract concept
- contains real methods
- contains abstract methods
- contains any type of variable
- to use we must extend it
- may be extended by other abstract classes
Interface
- models a behavior or set of attributes
- contains only abstract methods
- contains only static final variables
- to use we must implement it
- may be extended by other interfaces
Both
- classes which extend or implement must override all methods
Comparable
interface of Java.lang [8/22]
public interface Comparable{
int compareTo(Object other);
}
- The
java.util.Arrays
has a sort()
method that will sort an array of objects; but only if every object in the array implements Comparable
!
- In order to sort you must be able to compare, implementing this interface guarantees that the sort method of the
Arrays
class can execute this kind of command: int x = obj1.compareTo(obj2);
- x will be greater than zero if obj1 is greater than obj2, less than zero if the reverse, or zero if equal
- Why not provide the
compareTo()
method without implementing the Comparable
interface?
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]
- An inner class is a class defined inside another class, Why?
- An object of the inner class can access the private data of the outer class
- Inner classes can be hidden from other classes in the same package
- Helpful when writing event-driven programs (more next week)
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]
- GUI (Graphical User Interface)
javax.swing
is the current standard for Java, don't mind the 'x'
- Swing is much richer than the original Java GUI libraries
- It is also more portable, adapts to the native platform
- Plus it's a little easier to code in
- Be careful, many of the methods used are inherited from the superclasses of Swing
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]
-
java.awt.Frame.setIconImage()
- Sets an icon to associate your frame with
java.awt.Frame.setTitle()
- Lets you title your frame
javax.swing.JFrame is the great-great granddaughter of java.awt.Component
[17/22]
-
java.awt.Component.setLocation(x, y)
- Where your component, including frames, will be on the screen
java.awt.Component.setBounds(x, y, width, height)
- Where and how big (in pixels) on the screen
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
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