Presentation is loading. Please wait.

Presentation is loading. Please wait.

Peter Andreae Computer Science Victoria University of Wellington Copyright: Peter Andreae, Victoria University of Wellington Raw GUIs, ArrayLists Inheritance.

Similar presentations


Presentation on theme: "Peter Andreae Computer Science Victoria University of Wellington Copyright: Peter Andreae, Victoria University of Wellington Raw GUIs, ArrayLists Inheritance."— Presentation transcript:

1 Peter Andreae Computer Science Victoria University of Wellington Copyright: Peter Andreae, Victoria University of Wellington Raw GUIs, ArrayLists Inheritance COMP 102 #31 2011 T1

2 © Peter Andreae COMP 102 31:2 Outline "Raw" Gui's ArrayLists Inheritance BouncingShape with an Interface class BouncingShape with inheritance Administrivia: Thursday’s lecture will talk about the exam

3 © Peter Andreae COMP 102 31:3 MiniDraw: test classes Rectangle.java, Oval.java, Dot.java all have a test classes. You can run the main method in these classes to test your code for the class before you use it from MiniDraw. This is a kind of "unit test", which is very helpful for large programs. The test methods provided are not exhaustive, and passing the test method does not guarantee that your code is right!

4 © Peter Andreae COMP 102 31:4 Making a GUI without the UI Text input and output: use System.out and a Scanner around System.in: connected to the terminal window (or standard output and input) use print, println, etc next, nextInt, etc, but no ask… Scanner inpSc = new Scanner(System.in); System.out.print("Enter age and name: "); int age = inpSc.nextInt(); String name = inpSc.next();

5 © Peter Andreae COMP 102 31:5 GUI without UI: set up window Buttons, mouse, etc: construct window, panel, buttons, etc. public class StandardInterface implements ActionListener, MouseListener{ private JFrame frame;private JTextArea textPane; private JTextField inputField; public StandardInterface(){ frame = new JFrame("Eg GUI");frame.setSize(400, 600); textPane = new JTextArea(); textPane.addMouseListener(this); frame.add(textPane, BorderLayout.CENTER); JPanel panel = new JPanel(); frame.add(panel, BorderLayout.NORTH); JButton helloButton = new JButton("Hello"); helloButton.addActionListener(this);panel.add(helloButton); panel.add(new JLabel("number to double:")); inputField = new JTextField(5);panel.add(inputField); JButton calcButton = new JButton("Double"); calcButton.addActionListener(this);panel.add(calcButton); JButton quitButton = new JButton("Quit"); quitButton.addActionListener(this);panel.add(quitButton); frame.setVisible(true); }

6 © Peter Andreae COMP 102 31:6 GUI without UI: respond to buttons ActionPerformed is passed an ActionEvent: public void actionPerformed(ActionEvent e){ if (e.getActionCommand().equals("Hello") ){ textPane.append("Hello there,\nThis is a doubling calculator"); } else if (e.getActionCommand().equals("Double") ){ if (!inputField.getText().equals("")){ doubleNums(Integer.parseInt(inputField.getText())); } else { textPane.append("\n\n******\nEnter a number first\n******\n"); } else if (e.getActionCommand().equals("Quit") ){ frame.dispose(); }

7 © Peter Andreae COMP 102 31:7 GUI without UI: respond to mouse MouseListeners have six methods, passed a MouseEvent public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) { int x =e.getX(); int y =e.getY(); textPane.setText(""); textPane.append(String.format("Mouse at (%3d,%3d)\n", x, y )); } public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {}

8 © Peter Andreae COMP 102 31:8 ArrayList Using arrays for lists of things: private static final int maxStudents = 1000; private Student[ ] students = new Student[maxStudents]; private int count = 0; What are the problems with using arrays this way? fixed size: may run out of space may waste lots of memory “just in case”. have to keep the array and the count in step hard to pass them around easy to get the count wrong can’t use the nice foreach loop: for ( Student s : students){ ……

9 © Peter Andreae COMP 102 31:9 Solution: ArrayList Part of the Java Collections framework. predefined class Stores a list of items, “list” = collection of items kept in a particular order. part of the java.util package ⇒ need import java.util.*; at head of file You can make an new ArrayList object, and put items in it Don’t have to specify its size Like an infinitely stretchable array Should specify the type of items. new syntax: “type parameters” or “generics” But, you have to call methods on it; you can’t use the […] notation. More in COMP103 on ArrayList and other Collection types

10 © Peter Andreae COMP 102 31:10 Using ArrayList: declaring List of students Array: private static final int maxStudents = 1000; private Student[ ] students = new Student[maxStudents]; private int count = 0; ArrayList: private ArrayList students = new ArrayList (); The type of values in the list is between “ ” after ArrayList. No maximum; no initial size; no explicit count Note: may not use this for MiniDraw!!

11 © Peter Andreae COMP 102 31:11 Using ArrayList: methods ArrayList has many methods! Most important: size():returns the number of items in the list add(item ):adds an item to the end of the list add(index, item ):inserts an item at index (moves later items up) set(index, item ):replaces the item at index with item contains(item ):true if the list contains an item that equals item get(index ):returns the item at position index remove(item ):removes an occurrence of item remove(index ):removes the item at position index (both move later items down) You can use the “for each” loop on an array list, as well as a for loop

12 © Peter Andreae COMP 102 31:12 Using ArrayList: using private ArrayList students = new ArrayList (); : students.add(new Student(30212345, “Jane”, “Doe”)); while (scan.hasNext()){ Student s = new Student(scan); students.add(s); } Student lastStudent = students.get(students.size()-1); System.out.println(students.get(0) + “to” + lastStudent); for (Student st : students){ System.out.println(st); } for (int i = 0; i < students.size(); i += 10){ System.out.println(students.get(i)); }

13 © Peter Andreae COMP 102 31:13 How does ArrayList work? It uses an array and a count! just as you are doing for ShapeList When the array gets full, it makes new array, double the size copies the items over from the old array throws away the old array and keeps the new one. It turns out that this is very efficient! For lists of items, use ArrayList instead of arrays. (except not in MiniDraw) COMP 103 will look at this in more detail, and other kinds of collections, and other ways of implementing collections. data: count:

14 © Peter Andreae COMP 102 31:14 Inheritance Interfaces allow a variable to contain different subtypes The interface specifies the methods that the subtypes can perform The interface does not provide any code. Inheritance = Interface PLUS shared code. specifies what the subtypes can do provides method definitions and fields that the subtype automatically reuses. Inheritance allows “Special Cases” Shape Oval Rect Triangle

15 © Peter Andreae COMP 102 31:15 Bouncing Shapes ScreenSaver Consists of a collection of shapes: Move around the screen (speeding up as they go) When hit a wall, slow down and bounce off again. Each kind of shape is animated in a different way as it goes.

16 © Peter Andreae COMP 102 31:16 Bouncing Shapes ScreenSaver Design is a bit like BalloonGame ++ ScreenSaver has a list of BShapes Each cycle, it calls step() on each shape then calls draw(canvas) Each BShape keeps track of its position At each step, moves, and changes its speed (gradually speeds up, until hits edge) Each kind of BShape also has some other state which changes on each step: BRect changes colour, BOval changes shape, Butterfly flaps BShape BOval BRect Butterfly ScreenSaver list of BShapes

17 © Peter Andreae COMP 102 31:17 Bouncing Shapes public class ScreenSaver { public static final int Top = 10, Bot = 600, Left = 10, Right = 600; : public ScreenSaver(){ // set up the user interface } public void animate(){ ArrayList shapes = new ArrayList (); shapes.add(new BRect(500, 100)); shapes.add(new BOval(100, 200)); ….. while (true){ UI.clear(false); for (BShape shape : shapes){ shape.step(); shape.draw(); } UI.display(); } Using ArrayList of BShape instead of Array of BShape & count

18 © Peter Andreae COMP 102 31:18 BShape Interface, specifying what a BShape must be able to do. public interface BShape{ public void step(); public void draw(); } BShape BOval BRect Butterfly ScreenSaver list of BShapes

19 © Peter Andreae COMP 102 31:19 BRect Must have fields for state, and constructor: public class BRect implements BShape{ private double x; // position private double y; private double dx; // step size private double dy; private int size = 20; private int red; // current colour private int green; private int blue; /** Construct a new BRect */ public BRect(double x, double y){ x = x; dx = Math.random()-0.5; y = y; dy = Math.random()-0.5; red = (int)(Math.random()*255); ….. } BShape BOval BRect Butterfly ScreenSaver list of BShapes

20 © Peter Andreae COMP 102 31:20 BRect: step and draw methods public void draw(){ UI.setColor(new Color(red, green, blue)); UI.fillRect( x, y, size, size, false); } public void step(){ // change position and check boundary x = x + dx; y = y + dy; if (x < Left){ x =Left;dx = - dx/10;dy = dy/10; } else if (x > Right){ x =Right;dx = - dx/10;dy = dy/10; } if (y < Top ){ y =.Top;dx = dx/10;dy = - dy/10; } else if (y > Bot){ y =Bot;dx = dx/10;dy = - dy/10; } //increase speed dx = dx *(1 + 0.05*Math.random()); dy = dy *(1 + 0.05*Math.random()); // change the colour red = (red+1) % 255; blue = (blue+1) % 255; green= (green+1) % 255; }

21 © Peter Andreae COMP 102 31:21 BOval Must have fields for state, and constructor: public class BOval implements BShape{ private double x;// position private double y; private double dx;// step size private double dy; private int wd; // current shape private int ht; private int shapeChange; private Colour col;// colour /** Construct a new BOval */ public BOval(double x, double y){ x = x; dx = Math.random()-0.5; ….. } Same as BRect BShape BOval BRect Butterfly ScreenSaver list of BShapes

22 © Peter Andreae COMP 102 31:22 BOval public void draw(){ UI.setColor(col); UI.fillOval( x, y, wd, ht, false); } public void step(){ // change position and check boundary x = x + dx; y = y + dy; if (x < Left){ x =Left;dx = - dx/10;dy = dy/10; } else if (x > Right){ x =Right;dx = - dx/10;dy = dy/10; } if (y < Top ){ y =.Top;dx = dx/10;dy = - dy/10; } else if (y > Bot){ y =Bot;dx = dx/10;dy = - dy/10; } //increase speed dx = dx *(1 + 0.05*Math.random()); dy = dy *(1 + 0.05*Math.random()); // change the shape wd = wd + shapeChange; ht = ht - shapeChange; if (wd <1 || ht < 1) shapeChange = - shapeChange; } Same as BRect

23 © Peter Andreae COMP 102 31:23 Duplicated Code Is a pain you have to copy and paste it Leads to errors change in one place, but not the others changing takes a long time may be hard to find all the places It would be nice to put the shared code somewhere. The movement component of step is common to all the BShapes ⇒ extract the movement bit out of step() into a move() method: put move() somewhere, just once the fields (x, y, dx, dy) are common to all the BShapes ⇒ put the fields in one place. Where?

24 © Peter Andreae COMP 102 31:24 BRect Make step() simpler: public void step(){public void step(){ move(); move(); red = (red +1) % 255; wd = wd + shapeChange; blue = (blue+1) % 255; ht = ht - shapeChange; green= (green+1) % 255; if (wd <1 || ht < 1) } shapeChange = -shapeChange; } public void move(){ // change position and check boundary x = x + dx; y = y + dy; if (x < ScreenSaver2.Left){ x =ScreenSaver2.Left;dx = - dx/10; dy = dy/10; } else if (x > ScreenSaver2.Right){ x =ScreenSaver2.Right;dx = - dx/10; dy = dy/10; } if (y < ScreenSaver2.Top ){ y =ScreenSaver2.Top;dx = dx/10;dy = - dy/10; } else if (y > ScreenSaver2.Bot){ y =ScreenSaver2.Bot;dx = dx/10;dy = - dy/10; } //increase speed dx = dx *(1 + 0.05*Math.random()); dy = dy *(1 + 0.05*Math.random()); } Still need copies of move() in every shape class

25 © Peter Andreae COMP 102 31:25 Code shared by the subtypes Put the code in BShape: public interface BShape{ private double x; private double y; private double dx; private double dy; public void step(); public void draw(); public void move(){ x = x + dx; y = y + dy; if (x < ScreenSaver2.Left){ x =ScreenSaver2.Left;dx = - dx/10; dy = dy/10; } else if (x > ScreenSaver2.Right){ x =ScreenSaver2.Right;dx = - dx/10; dy = dy/10; } if (y < ScreenSaver2.Top ){ y =ScreenSaver2.Top;dx = dx/10; dy = - dy/10; } else if (y > ScreenSaver2.Bot){ y =ScreenSaver2.Bot;dx = dx/10; dy = - dy/10; } //increase speed dx = dx *(1 + 0.05*Math.random()); dy = dy *(1 + 0.05*Math.random()); } Can’t put fields or method definitions in an interface! Can ’ t do this! Can ’ t put definitions of methods in an interface Can ’ t do this! Can ’ t put fields in an interface

26 © Peter Andreae COMP 102 31:26 Code shared by the subtypes Make BShape be a class: public class BShape{ public double x; public double y; public double dx; public double dy; public void step(); public void draw(); public void move(){ x = x + dx; y = y + dy; if (x < ScreenSaver2.Left){ x =ScreenSaver2.Left;dx = - dx/10;dy = dy/10; } else if (x > ScreenSaver2.Right){ x =ScreenSaver2.Right;dx = - dx/10;dy = dy/10; } if (y < ScreenSaver2.Top ){ y =ScreenSaver2.Top;dx = dx/10;dy = - dy/10; } else if (y > ScreenSaver2.Bot){ y =ScreenSaver2.Bot;dx = dx/10;dy = - dy/10; } //increase speed dx = dx *(1 + 0.05*Math.random()); dy = dy *(1 + 0.05*Math.random()); } Must have bodies for all methods in a class Can ’ t do this! Must have bodies for methods in a class

27 © Peter Andreae COMP 102 31:27 Code shared by the subtypes Make BShape be a class: public class BShape{ public double x; public double y; public double dx; public double dy; public void step(){ move(); } public void draw(){ } public void move(){ x = x + dx; y = y + dy; if (x < ScreenSaver2.Left){ x =ScreenSaver2.Left; dx = - dx/10;dy = dy/10; } else ….. dx = dx *(1 + 0.05*Math.random()); dy = dy *(1 + 0.05*Math.random()); } But how can BRect and BOval be BShapes? Note! Fields have to be accessible to the subclasses (protected would be better)

28 © Peter Andreae COMP 102 31:28 Inheritance Interfaces specify just types Classes specify types specify object descriptions (fields) specify object behaviour (methods) We want all three: Declare BOval and BRect (etc) to be subclasses of BShape ⇒ are of the BShape type AND ⇒ share the BShape object descriptions (fields) AND ⇒ share the BShape methods.

29 © Peter Andreae COMP 102 31:29 BRect public class BRect extends BShape{ private int size = 20; private int red; private int green; private int blue; public BRect(double x, double y){ // must have own constructor x = x; dx = Math.random()-0.5; y = y; dy = Math.random()-0.5; red = (int)(Math.random()*255); ….. } public void draw(){ UI.setColor(new Color(red, green, blue)); UI.fillRect(x, y, size, size,false); } public void step(){ move(); red = (red+1) % 255; blue = (blue+1) % 255; green= (green+1) % 255; } BRect -44 x: y: dx: dy: size: red: green: blue: inherited from BShape overrides BShape ’ s step method overrides BShape ’ s draw method

30 © Peter Andreae COMP 102 31:30 Inheritance Inheritance = Interface PLUS shared code. superclass specifies a type: can have a variable of the supertype containing a value of any of the subtypes superclass provides method definitions and fields that the subclasses automatically reuse subclasses can override superclass: provide their own definition of methods defined in the superclass Inheritance allows “Special Cases” BShape BOval BRect Butterfly

31 © Peter Andreae COMP 102 31:31 Visibility specifiers private: scope of field or method (or class...) is this class only ⇒ only methods in this class can refer to it. can apply to fields and methods (and more) good practice: non-static (ordinary) fields are almost always private methods should be private if they are “helper” methods public: scope of field or name (etc) is the whole program good practice: methods essential for using an object should be public static final fields (ie, constants) may be public if relevant to rest of program no specifier: intermediate case, scope = package protected: special case, scope = package & subclasses

32 © Peter Andreae COMP 102 31:32 Public or Private? The principle of encapsulation says “Keep it private unless it needs to be public” ⇒ less chance of errors ⇒ easier to change this module later without affecting rest of program Keep fields private except for some static final fields (ie constants) except fields accessible to subclasses: ⇒ protected Provide public “getter & setter” methods if necessary: private int size; public int getSize(){ return size; } public void setSize(int s) { size = s; } Make “external” methods public; Make “helper” methods private


Download ppt "Peter Andreae Computer Science Victoria University of Wellington Copyright: Peter Andreae, Victoria University of Wellington Raw GUIs, ArrayLists Inheritance."

Similar presentations


Ads by Google