Top Hat Question Which of the following is

  • Slides: 44
Download presentation
Top Hat Question Which of the following is the correct way to create a

Top Hat Question Which of the following is the correct way to create a private inner class that uses the Event. Handler interface? A. public class Pane. Organizer { //constructor elided private class Move. Handler extends Event. Handler() { public Move. Handler() { //code for constructor elided } public void handle(Action. Event event) { //code elided } } } B. public class Pane. Organizer { //constructor elided }Q private class Move. Handler implements Event. Handler() { public Move. Handler() { //code for constructor elided } public void handle(Action. Event event) { //code elided } } C. public class Pane. Organizer { //constructor elided private class Move. Handler implements Event. Handler()<Action. Event> { public Move. Handler() { //code for constructor elided } public void handle(Action. Event event) { //code elided } } } Andries van Dam © 2019 10/3/19 1/44

Lecture 9 Graphics Part II – Understanding Animations & Shapes Andries van Dam ©

Lecture 9 Graphics Part II – Understanding Animations & Shapes Andries van Dam © 2019 10/3/19 2/44

Outline • Animation • Layout Panes • Java FX Shapes Andries van Dam ©

Outline • Animation • Layout Panes • Java FX Shapes Andries van Dam © 2019 10/3/19 3/44

Animation – Change Over Time • Suppose we have an alien Shape we would

Animation – Change Over Time • Suppose we have an alien Shape we would like to animate (e. g. make it move across the screen) • As in film and video animation, we can create apparent motion with many small changes in position • If we move fast enough and in small enough increments, we get smooth motion • Same goes for size, orientation, shape change, etc… • How to orchestrate a sequence of incremental changes? o coordinate with a Timeline where change happens at defined instants Andries van Dam © 2019 10/3/19 4/44

Introducing Timelines (1/3) • The Timeline sequences one or more Key. Frames o a

Introducing Timelines (1/3) • The Timeline sequences one or more Key. Frames o a Key. Frame can be thought of as a singular photo o each Key. Frame lasts for its entire Duration without making any changes o when the Duration ends, the Event. Handler updates variables to affect the animation Andries van Dam © 2019 10/3/19 5/44

Introducing Timelines (2/3) Handler Time. Line Handler Key. Frame etc. Duration Andries van Dam

Introducing Timelines (2/3) Handler Time. Line Handler Key. Frame etc. Duration Andries van Dam © 2019 10/3/19 6/44

Introducing Timelines (3/3) Time. Line Handler Key. Frame Duration We can do simple animation

Introducing Timelines (3/3) Time. Line Handler Key. Frame Duration We can do simple animation using a single Key. Frame that is repeated a fixed or indefinite number of times Event. Handler is called, it makes incremental changes to time-varying variables (e. g. , (x, y) position of a shape) Andries van Dam © 2019 10/3/19 7/44

Using Java. FX Timelines (1/2) • javafx. animation. Timeline is used to sequence one

Using Java. FX Timelines (1/2) • javafx. animation. Timeline is used to sequence one or more javafx. animation. Key. Frames or run through them cyclically o each Key. Frame lasts for its entire Duration until its time interval ends and Event. Handler is called to make updates • When we instantiate a Key. Frame, we pass in o a Duration (e. g. Duration. seconds(0. 3) or Duration. millis(300)), which defines time that each Key. Frame lasts o an Event. Handler that defines what should occur upon completion of each Key. Frame • Key. Frame and Timeline work together to control the animation, but our application’s Event. Handler is what actually causes variables to change Andries van Dam © 2019 10/3/19 8/44

Using Java. FX Timelines (2/2) • We then pass our new Key. Frame into

Using Java. FX Timelines (2/2) • We then pass our new Key. Frame into Timeline • After we instantiate our Timeline, we must set its Cycle. Count property o defines number of cycles in Animation o setting cycle count to Animation. INDEFINITE will let Timeline run forever or until we explicitly stop it • In order for Timeline to work, we must then call Timeline. play(); Andries van Dam © 2019 10/3/19 9/44

Another Java. FX App: Clock • Simple example of discrete (non-smooth) animation • Specifications:

Another Java. FX App: Clock • Simple example of discrete (non-smooth) animation • Specifications: App should display current date and time, updating every second • Useful classes: o o java. util. Date javafx. util. Duration javafx. animation. Key. Frame javafx. animation. Timeline Andries van Dam © 2019 10/3/19 10/44

Process: Clock 1. Write App class that extends javafx. application. Application and implements start

Process: Clock 1. Write App class that extends javafx. application. Application and implements start (Stage) Stage 2. Write a Pane. Organizer class that instantiates the root node and returns it in a public get. Root() method. Instantiate a Label and add it as root node’s child. Factor out code for Timeline into its own method. 3. In our own setup. Timeline(), instantiate a Key. Frame passing in a Duration and an instance of Time. Handler (defined later). Then instantiate Timeline, passing in our Key. Frame, and play Timeline. Scene VBox Label 4. Write private inner Time. Handler class that implements Event. Handler — it should know about a Label and update its text on every Action. Event Andries van Dam © 2019 10/3/19 11/44

Clock: App class (1/3) *Note: Exactly the same process as in Color. Changer’s App

Clock: App class (1/3) *Note: Exactly the same process as in Color. Changer’s App [Lecture 8]* 1 a. Instantiate a Pane. Organizer and store it in the local variable organizer public class App extends Application { @Override public void start(Stage stage) { Pane. Organizer organizer = new Pane. Organizer(); } } Andries van Dam © 2019 10/3/19 12/44

Clock: App class (2/3) *Note: Exactly the same process as in Color. Changer’s App

Clock: App class (2/3) *Note: Exactly the same process as in Color. Changer’s App [Lecture 8]* 1 a. Instantiate a Pane. Organizer and store it in the local variable organizer public class App extends Application { @Override public void start(Stage stage) { Pane. Organizer organizer = new Pane. Organizer(); Scene scene = new Scene(organizer. get. Root(), 200); 1 b. Instantiate a Scene, passing in organizer. get. Root(), and desired width and height of Scene (); } } Andries van Dam © 2019 10/3/19 13/44

Clock: App class (3/3) *Note: Exactly the same process as in Color. Changer’s App

Clock: App class (3/3) *Note: Exactly the same process as in Color. Changer’s App [Lecture 8]* 1 a. Instantiate a Pane. Organizer and store it in the local variable public class App organizer @Override public void start(Stage stage) { Pane. Organizer organizer = new Pane. Organizer(); Scene scene = new Scene(organizer. get. Root(), 200); 1 b. Instantiate a Scene, passing in organizer. get. Root(), desired width and height of the Scene 1 c. Set the Scene, set the Stage’s title, and show the Stage! extends Application { stage. set. Scene(scene); stage. set. Title("Clock!"); stage. show(); } } Andries van Dam © 2019 10/3/19 14/44

Process: Clock 1. Write App class that extends javafx. application. Application and implements start(Stage)

Process: Clock 1. Write App class that extends javafx. application. Application and implements start(Stage) Stage 2. Write a Pane. Organizer class that instantiates the root node and returns it in a public get. Root() method. Instantiate a Label and add it as root node’s child. Factor out code for Timeline into its own method, which we’ll call setup. Timeline() 3. In our own setup. Timeline(), instantiate a Key. Frame passing in a Duration and an instance of Time. Handler (defined later). Then instantiate a Timeline, passing in our Key. Frame, and play the Timeline 4. Write a private inner Time. Handler class that implements Event. Handler — it should know about a Label and update its text on every Action. Event Andries van Dam © 2019 10/3/19 Scene VBox Label 15/44

Clock: Pane. Organizer Class (1/3) public class Pane. Organizer{ 2 a. In the Pane.

Clock: Pane. Organizer Class (1/3) public class Pane. Organizer{ 2 a. In the Pane. Organizer class’ private VBox _root; constructor, instantiate a root VBox private Label _label; and set it as the return value of a public Pane. Organizer(){ public get. Root() method _root = new Vbox(); _label = new Label(); _ } public VBox get. Root() { return _root; } } Andries van Dam © 2019 10/3/19 16/44

Clock: Pane. Organizer Class (2/3) 2 a. In the Pane. Organizer class’ constructor, instantiate

Clock: Pane. Organizer Class (2/3) 2 a. In the Pane. Organizer class’ constructor, instantiate a root VBox and set it as the return value of a public get. Root() method public class Pane. Organizer{ private VBox _root; private Label _label; 2 b. ); Instantiate a Label and add it to the list of the root node’s children public Pane. Organizer(){ _root = new Vbox(); _label = new Label(); _root. get. Children(). add(_label); } public VBox get. Root() { return _root; } } Andries van Dam © 2019 10/3/19 17/44

Clock: Pane. Organizer Class (3/3) 2 a. In the Pane. Organizer class’ constructor, instantiate

Clock: Pane. Organizer Class (3/3) 2 a. In the Pane. Organizer class’ constructor, instantiate a root VBox and set it as the return value of a public get. Root() method public class Pane. Organizer{ private VBox _root; private Label _label; public Pane. Organizer(){ _root = new Vbox(); _label = new Label(); _root. get. Children(). add(_label); 2 b. Instantiate a Label and add it to the list of the root node’s children 2 c. Call setup. Timeline(); this is another example of delegation to a specialized “helper method” which we’ll define next ! this. setup. Timeline(); } public VBox get. Root() { return _root; } } Andries van Dam © 2019 10/3/19 18/44

Process: Clock 1. Write an App class that extends javafx. application. Application and implements

Process: Clock 1. Write an App class that extends javafx. application. Application and implements start(Stage) Stage 2. Write a Pane. Organizer class that instantiates the root node and returns it in a public get. Root() method. Instantiate a Label and add it as the root node’s child. Factor out code for Timeline into its own method 3. In setup. Timeline(), instantiate a Key. Frame, passing in a Duration and an instance of Time. Handler (defined later). Then instantiate a Timeline, passing in our Key. Frame, and play the Timeline. Scene VBox Label 4. Write a private inner Time. Handler class that implements Event. Handler — it should know about a Label and update its text on every Action. Event Andries van Dam © 2019 10/3/19 19/44

Clock: Pane. Organizer class- setup. Timeline() (1/4) Within setup. Timeline(): 3 a. Instantiate a

Clock: Pane. Organizer class- setup. Timeline() (1/4) Within setup. Timeline(): 3 a. Instantiate a Key. Frame, which takes two parameters public class Pane. Organizer{ //other code elided public void setup. Timeline(){ Key. Frame kf = new Key. Frame( } } Andries van Dam © 2019 10/3/19 20/44

Clock: Pane. Organizer class- setup. Timeline() (1/4) Within setup. Timeline(): public class Pane. Organizer{

Clock: Pane. Organizer class- setup. Timeline() (1/4) Within setup. Timeline(): public class Pane. Organizer{ //other code elided 3 a. Instantiate a Key. Frame, which takes two parameters ○ public void setup. Timeline(){ Key. Frame kf = new Key. Frame( Duration. seconds(1), //how long want to update text of _label each second — therefore make Duration of the Key. Frame 1 second } } Andries van Dam © 2019 10/3/19 21/44

Clock: Pane. Organizer class- setup. Timeline() (1/4) Within setup. Timeline(): public class Pane. Organizer{

Clock: Pane. Organizer class- setup. Timeline() (1/4) Within setup. Timeline(): public class Pane. Organizer{ //other code elided 3 a. Instantiate a Key. Frame, which takes two parameters ○ want to update text of _label each second — therefore make Duration of the Key. Frame 1 second ○ for the Event. Handler parameter pass an instance of our Time. Handler class, to be created later Note: Java. FX automatically calls Time. Handler’s handle() method at end of Key. Frame, which in this case changes the label text, and then lets next 1 second cycle of Key. Frame start public void setup. Timeline(){ Key. Frame kf = new Key. Frame( Duration. seconds(1), //how long new Time. Handler()); //event handle } } Andries van Dam © 2019 10/3/19 22/44

Clock: Pane. Organizer class- setup. Timeline() (2/4) Within setup. Timeline(): 3 a. 3 b.

Clock: Pane. Organizer class- setup. Timeline() (2/4) Within setup. Timeline(): 3 a. 3 b. Instantiate a Key. Frame public class Pane. Organizer{ //other code elided public void setup. Timeline(){ Key. Frame kf = new Key. Frame( Duration. seconds(1), new Time. Handler()); Instantiate a Timeline, passing in our new Key. Frame Timeline timeline = new Timeline(kf); timeline. set. Cycle. Count(Animation. INDEFINITE); timeline. play(); } } Andries van Dam © 2019 10/3/19 23/44

Clock: Pane. Organizer class- setup. Timeline() (3/4) Within setup. Timeline(): 3 a. 3 b.

Clock: Pane. Organizer class- setup. Timeline() (3/4) Within setup. Timeline(): 3 a. 3 b. Instantiate a Key. Frame public class Pane. Organizer{ //other code elided public void setup. Timeline(){ Key. Frame kf = new Key. Frame( Duration. seconds(1), new Time. Handler()); Instantiate a Timeline, passing in our new Key. Frame Timeline timeline = new Timeline(kf); 3 c. timeline. set. Cycle. Count( Animation. INDEFINITE); timeline. play(); Set Cycle. Count to INDEFINITE } } Andries van Dam © 2019 10/3/19 24/44

Clock: Pane. Organizer class- setup. Timeline() (4/4) Within setup. Timeline(): 3 a. 3 b.

Clock: Pane. Organizer class- setup. Timeline() (4/4) Within setup. Timeline(): 3 a. 3 b. Instantiate a Key. Frame public class Pane. Organizer{ //other code elided public void setup. Timeline(){ Key. Frame kf = new Key. Frame( Duration. seconds(1), new Time. Handler()); Instantiate a Timeline, passing in our new Key. Frame Timeline timeline = new Timeline(kf); 3 c. timeline. set. Cycle. Count( Animation. INDEFINITE); timeline. play(); Set Cycle. Count to INDEFINITE } 3 d. Play, i. e. start Timeline } Andries van Dam © 2019 10/3/19 25/44

Process: Clock 1. Write an App class that extends javafx. application. Application and implements

Process: Clock 1. Write an App class that extends javafx. application. Application and implements start(Stage) Stage 2. Write a Pane. Organizer class that instantiates the root Node and returns it in public get. Root() method. Instantiate a Label and add it as root node’s child. Factor out code for Timeline into its own method. 3. In setup. Timeline(), instantiate a Key. Frame passing in a Duration and an instance of Time. Handler (defined later). Then instantiate a Timeline, passing in our Key. Frame, and play the Timeline. Scene VBox Label 4. Write a private inner Time. Handler class that implements Event. Handler — it should know about a Label and update its text on every Action. Event Andries van Dam © 2019 10/3/19 26/44

Clock: Time. Handler Private Inner Class (1/3) 4 a. The last step is to

Clock: Time. Handler Private Inner Class (1/3) 4 a. The last step is to create our Time. Handler and implement handle(), specifying what should occur at the end of each Key. Frame – called automatically by JFX public class Pane. Organizer{ //other code elided private class Time. Handler implements Event. Handler<Action. Event>{ public void handle(Action. Event event){ } } //end of private Time. Handler class } //end of Pane. Organizer class Andries van Dam © 2019 10/3/19 27/44

Clock: Time. Handler Private Inner Class (2/3) 4 a. 4 b. The last step

Clock: Time. Handler Private Inner Class (2/3) 4 a. 4 b. The last step is to create our Time. Handler and implement handle(), specifying what should occur at the end of each Key. Frame – called automatically by JFX public class Pane. Organizer{ //other code elided private class Time. Handler implements Event. Handler<Action. Event>{ public void handle(Action. Event event){ Date now = new Date(); java. util. Date represents a specific instant in time. Date is a representation of the time, to the nearest millisecond, at the moment the Date is instantiated } } //end of private Time. Handler class } //end of Pane. Organizer class Andries van Dam © 2019 10/3/19 28/44

Clock: Time. Handler Private Inner Class (3/3) 4 a. 4 b. 4 c. The

Clock: Time. Handler Private Inner Class (3/3) 4 a. 4 b. 4 c. The last step is to create our Time. Handler and implement handle(), specifying what should occur at the end of each Key. Frame – called automatically by JFX public class Pane. Organizer{ //other code elided private class Time. Handler implements Event. Handler<Action. Event>{ java. util. Date represents a specific instant in time. Date is a representation of the time, to the nearest millisecond, at the moment the Date is instantiated public void handle(Action. Event event){ Date now = new Date(); //to. String converts the Date into a //String with year, day, time etc. //_label instantiated in //constructor of PO _label. set. Text(now. to. String()); Because our Timeline has a Duration of 1 second, each second a new Date } will be generated, converted to a } //end of private Time. Handler class String, and set as the _label’s text. This will appropriately update _label } //end of Pane. Organizer class with correct time every second! Andries van Dam © 2019 10/3/19 29/44

The Whole App: Clock public class Pane. Organizer{ private VBox _root; private Label _label;

The Whole App: Clock public class Pane. Organizer{ private VBox _root; private Label _label; public Pane. Organizer(){ _root = new VBox(); _label = new Label(); _root. get. Children(). add(_label); this. setup. Timeline(); } //App class import javafx. stage. Stage; import javafx. scene. Scene; import javafx. application. *; // package includes Pane class and its subclasses import javafx. scene. layout. *; //package includes Label, Button classes import javafx. scene. control. *; //package includes Action. Event, Event. Handler classes import javafx. event. *; import javafx. util. Duration; import javafx. animation. Animation; import javafx. animation. Key. Frame; import javafx. animation. Timeline; import java. util. Date; public VBox get. Root() { return _root; } public void setup. Timeline(){ Key. Frame kf = new Key. Frame(Duration. seconds(1), new Time. Handler()); Timeline timeline = new Timeline(kf); timeline. set. Cycle. Count(Animation. INDEFINITE); timeline. play(); } public class App extends Application { @Override public void start(Stage stage) { Pane. Organizer organizer = new Pane. Organizer(); Scene scene = new Scene(organizer. get. Root(), 200); stage. set. Scene(scene); stage. set. Title("Clock"); stage. show(); } } private class Time. Handler implements Event. Handler<Action. Event>{ public void handle(Action. Event event){ Date now = new Date(); _label. set. Text(now. to. String()); } } } Andries van Dam © 2019 10/3/19 30/44

Layout Panes • Until now, we have been adding all our GUI components to

Layout Panes • Until now, we have been adding all our GUI components to a VBox o VBoxes lay everything out in one vertical column • What if we want to make some more interesting GUIs? • Use different types of layout panes! o VBox is just one of many Java. FX panes—there are many more options o we will introduce a few, but check out our documentation or Java. Docs for a complete list Andries van Dam © 2019 10/3/19 31/44

HBox • Similar to Vbox, but lays everything out in a horizontal row (hence

HBox • Similar to Vbox, but lays everything out in a horizontal row (hence the name) • Example: // code for setting the scene elided HBox button. Box = new HBox(); Button b 1 = new Button(“Button One”); Button b 2 = new Button(“Button Two”); Button b 3 = new Button(“Button Three”); button. Box. get. Children(). add. All(b 1, b 2, b 3); • Like VBox, we can set the amount of horizontal spacing between each child in the HBox using the set. Spacing(double) method Andries van Dam © 2019 10/3/19 32/44

Border. Pane (1/2) • Border. Pane lays out children in top, left, bottom, right

Border. Pane (1/2) • Border. Pane lays out children in top, left, bottom, right and center positions • To add things visually, use set. Left(Node), set. Center(Node), etc. o this includes an implicit call to get. Children(). add(…) • Use any type of Node—Panes (with their own children), Buttons, Labels, etc. ! Andries van Dam © 2019 10/3/19 33/44

Border. Pane (2/2) • Remember our VBox example from earlier? VBox button. Box =

Border. Pane (2/2) • Remember our VBox example from earlier? VBox button. Box = new VBox(); Button b 1 = new Button(“Top”); Button b 2 = new Button(“Middle”); Button b 3 = new Button(“Bottom”); button. Box. get. Children. add. All(b 1, b 2, b 3); button. Box. set. Spacing(8); button. Box. set. Alignment(Pos. TOP_CENTER); • We can make our VBox the center of this Border. Pane container = new Border. Pane(); container. set. Center(button. Box); • No need to use all regions—could just use a few of them Note: we didn’t have to call container. get. Children. add(button. Box), as this call is done implicitly in the set. Center() method! • Unused regions are “compressed”, e. g. could have a two-region (left/right) layout without a center Andries van Dam © 2019 10/3/19 34/44

Absolute Positioning • Until now, all layout panes we have seen have performed layout

Absolute Positioning • Until now, all layout panes we have seen have performed layout management for us o what if we want to position our GUI components freely ourselves? • Need to set component’s location to exact pixel location on screen o called absolute positioning • When would you use this? o to position shapes—stay tuned! Andries van Dam © 2019 10/3/19 35/44

Pane • Pane allows you to lay things out completely freely, like on an

Pane • Pane allows you to lay things out completely freely, like on an art canvas – DIY graphics! More control, more work ; ) • It is a concrete superclass to all more specialized layout panes seen earlier that do automatic positioning o can call methods on its children (panes, buttons, shapes, etc. ) to set location within pane ▪ for example: use set. X(double) and set. Y(double) to position a Rectangle o Pane performs no layout management, so coordinates you set determine where things appear on the screen Andries van Dam © 2019 10/3/19 36/44

Creating Custom Graphics • We’ve now introduced you to using Java. FX’s native UI

Creating Custom Graphics • We’ve now introduced you to using Java. FX’s native UI elements o ex: Label and Button • Lots of handy widgets for making your own graphical applications! • What if you want to create your own custom graphics? • This lecture: build your own graphics using the javafx. scene. shape package! Andries van Dam © 2019 10/3/19 37/44

javafx. scene. shape Package • Java. FX provides built-in classes to represent 2 D

javafx. scene. shape Package • Java. FX provides built-in classes to represent 2 D shapes, such as rectangles, ellipses, polygons, etc. • All these classes inherit from abstract class Shape, which inherits from Node o methods relating to rotation and visibility are defined in Node o methods relating to color and border are defined in Shape o other methods are implemented in the individual classes of Ellipse, Rectangle, etc. Andries van Dam © 2019 10/3/19 38/44

Shape Constructors • Rectangle(double width, double height) • Ellipse(double radius. X, double radius. Y)

Shape Constructors • Rectangle(double width, double height) • Ellipse(double radius. X, double radius. Y) • Polygon(double … points) Default position for Shape with this constructor would be (0, 0) o the “…” in the signature means that you can pass in as many points as you would like to the constructor pass in Points (even number of x and y coordinates) and Polygon will connect them for you passing points will define and position the shape of Polygon o Example: new Polygon(0, 10, 10, 5, 0) o o • Each of these Shape subclasses have multiple overloaded constructors (see Math and Making Decisions, slide 58) — check out the Java. FX documentation for more options! o for example, if you wanted to instantiate a Rectangle with a given position and size: Rectangle(double x, double y, double width, double height) Andries van Dam © 2019 10/3/19 (5, 0) (0, 10) (10, 10) 39/44

location Shapes: Setting Location • Java. FX Shapes have different behaviors (methods) for setting

location Shapes: Setting Location • Java. FX Shapes have different behaviors (methods) for setting their location within their parent’s coordinate system o Rectangle: use set. X(double) and set. Y(double) o Ellipse: use set. Center. X(double) and set. Center. Y(double) o Polygon: use set. Layout. X(double) and set. Layout. Y(double) Rectangle location • Java. FX has many different ways to set location o from our experience, these are the most straightforward ways o if you choose to use other methods, be sure you fully location understand them or you may get strange bugs! o check out our Java. FX documentation and the Javadocs for more detailed explanations! Ellipse Polygon Andries van Dam © 2019 10/3/19 40/44

Shapes: Setting Size width height • Java. FX Shapes also have different behaviors (methods)

Shapes: Setting Size width height • Java. FX Shapes also have different behaviors (methods) for altering their size o Rectangle: use set. Width(double) and set. Height(double) o Ellipse: use set. Radius. X(double) and set. Radius. Y(double) o Polygon: use set. Scale. X(double) and set. Scale. Y(double) radius. X radius. Y Ellipse scale. X scale. Y ▪ multiplies the original size in the X or Y dimension by the scale factor Rectangle • Again, this is not the only way to set size for Shapes but it is relatively painless o reminder: Java. FX documentation and Javadocs! Andries van Dam © 2019 10/3/19 Polygon 41/44

Accessors and Mutators of all Shapes final = can’t override method • Rotation: Rotation

Accessors and Mutators of all Shapes final = can’t override method • Rotation: Rotation is about the center of the Shape’s “bounding box”; i. e. , the smallest rectangle that contains the entire shape. o public final void set. Rotate(double rotate. Angle); o public final double get. Rotate(); • Visibility: o public final void set. Visible(boolean visible); o public final boolean get. Visible(); • Color: o o public final void set. Stroke(Paint value); Paint get. Stroke(); void set. Fill(Paint value); Paint get. Fill(); • Border: o public final void set. Stroke. Width(double val); o public final double get. Stroke. Width(); The stroke is the border that outlines the Shape, while the fill is the color of the interior of the Shape Generally, uses a Color, which inherits from Paint. Use predefined color constants Color. WHITE, Color. BLUE, Color. AQUA, etc. , or define your own new color by using the following syntax: Paint color = Color. color(0. 5, 0. 5); OR: Paint color = Color. rgb(100, 150, 200); To have a Shape rotate about an arbitrary center of rotation, create a Rotate instance with the degree you wish to rotate around and the x, y, z coordinates of your desired pivot point to create a new center of rotation and add it to the Shape’s get. Transforms() list (see Javadocs). Tip: Set z to 0. Andries van Dam © 2019 10/3/19 42/44

Announcements • Fruit. Ninja deadlines: o early: Friday, 10/4 at 11: 59 pm o

Announcements • Fruit. Ninja deadlines: o early: Friday, 10/4 at 11: 59 pm o on-time: Sunday, 10/6 at 11: 59 pm o late: Tuesday, 10/8 at 11: 59 pm • Section Slides released after the end of the last section Andries van Dam © 2019 10/3/19 43/44

Andries van Dam © 2019 10/3/19 44/44

Andries van Dam © 2019 10/3/19 44/44