Intro to SWING The Shape Object Painting Shapes
Intro to SWING • The Shape Object • Painting Shapes • Frames and Panels • Composite Shapes • Rotation • Animation • Window wrap-around Intro to Graphics 1 © 2006 Pearson Education
A Long Time Ago… • Sun provided the Abstract Window Toolkit (AWT), a collection of classes (java files) that make displaying graphics easy for the programmer – object-oriented – reusable and extensible – but, AWT is very complex… • for our course, relies too much on low-level processing • Sun then released Swing on top of AWT – new and improved! – easier to use and more powerful! – some AWT classes are still in use… • • java. awt. Color java. awt. Dimension java. awt. Shape and more… Intro to Graphics 2 © 2006 Pearson Education
Let’s talk about shapes • What is a Shape? – it is an Object, just like everything else in Java • So it must have attributes… – size – location – border color – fill color – rotation angle • And capabilities… – all attributes can change (mutators) – can draw itself – more to come later… • mouse interaction • animation • window wrap-around • How to keep track of the attributes? Intro to Graphics 3 © 2006 Pearson Education
Rectangular. Shape • Use AWT’s utility classes to store geometric information about a shape: – java. awt. geom. Rectangular. Shape • Class is abstract - use subclasses in practice – all subclasses can be bound by a rectangular bounding box: • • java. awt. geom. Rectangle 2 D. Double java. awt. geom. Round. Rectangle 2 D. Double java. awt. geom. Ellipse 2 D. Double java. awt. geom. Arc 2 D. Double • Define your own shape class – contains a Rectangular. Shape for geometric data • these store Locations and Dimensions Size Location – Other instance variables provide additional data • colors, rotation angle Intro to Graphics 4 © 2006 Pearson Education
Color. Shape public abstract class Color. Shape { private java. awt. geom. Rectangular. Shape _shape; public Color. Shape (java. awt. geom. Rectangular. Shape s) { _shape = s; } //accessors/mutators and other //attributes to follow. . } • Our shape contains a Rectangular. Shape Intro to Graphics 5 © 2006 Pearson Education
Location/Dimension • The screen is a grid of pixels (tiny dots) – “picture elements” X Y (40, 40) Y (0, 0) Pixel Art X • Unlike a Cartesian plane! – the origin is in the upper-left corner – the y-axis increases downward • The location of any shape is described by the upper-left corner of it’s bounding box location of shape Intro to Graphics shape 6 © 2006 Pearson Education
Rectangular. Shape – Mutators/Accessors • To set location and size: _shape. set. Frame(x. Loc, y. Loc, width, height); – use this method to initialize and reset location and size on a Rectangular. Shape • To get geometric data: _shape. get. X(); _shape. get. Y(); _shape. get. Width(); _shape. get. Height(); Intro to Graphics 7 © 2006 Pearson Education
Color. Shape class Accessors/Mutators • Accessors to make Rectangular. Shape data available to external classes: public double get. X(){ return _shape. get. X(); } • Create mutators so external classes can change location and size independently: public void set. Location (double x, double y){ // Change only x and y, preserve the width and height _shape. set. Frame(x, y, _shape. get. Width(), _shape. get. Height()); } public void set. Size (double w, double h) { // Change only the width and height, preserve the x and y coordinates _shape. set. Frame(_shape. get. X(), _shape. get. Y(), w, h); } Intro to Graphics 8 © 2006 Pearson Education
Storing Color • additional data in Instance Variables • Use accessors/mutators: public void set. Fill. Color(java. awt. Color c){ _fill. Color = c; } public java. awt. Color get. Fill. Color(){ return _fill. Color; } • Ditto for border color • Or use one method to change both fill and border color at once: public void set. Color(java. awt. Color c){ _fill. Color = c; _border. Color = c; } Intro to Graphics 9 © 2006 Pearson Education
Color • java. awt. Color stores color – RGB format new java. awt. Color(0, Red 255, 0) Green Blue • Colors are determined by concentrations of Red, Green and Blue – each is given a value between 0 -255 – how many combinations are there? • 16, 777, 216 (255, 0, 0) = (0, 255, 0) = (0, 0, 255) = (200, 0, 200)= • Basic colors come preset java. awt. Color. green java. awt. Color. orange java. awt. Color. gray • Colors can be – specify the alpha value [0 -255]… – 0 = completely transparent Alpha Value new java. awt. Color(239, 174, 45, 200) Intro to Graphics 10 © 2006 Pearson Education
Color. Shape again! public abstract class Color. Shape { private java. awt. geom. Rectangular. Shape _shape; private java. awt. Color _border. Color, _fill. Color; public Color. Shape (java. awt. geom. Rectangular. Shape s) { _shape = s; // initialize attributes… this. set. Location(50, 50); this. set. Size(100, 100); this. set. Border. Color (java. awt. Color. black); this. set. Fill. Color(java. awt. Color. blue); } // accessors/mutators } Intro to Graphics 11 © 2006 Pearson Education
Painting Shapes • Now we know what our Color. Shape is… – a collection of data (geometric and nongeometric) • How do we paint it on the screen? • Shapes will have a paint method, to paint themselves • Nothing can paint without a paintbrush! Intro to Graphics 12 © 2006 Pearson Education
Graphics • Our brush is brilliantly named a “Graphics” – thanks, Java designers! • Actually, use Graphics 2 D – Its more powerful subclass • Think of it as a parameterized brush • Each time Color. Shape paints itself, it… – sets the color of the brush. set. Color(_border. Color); – tells brush to draw outline of a geometric shape brush. draw(_shape); – sets the color of the brush. set. Color(_fill. Color); – tells brush to fill geometric shape brush. fill(_shape); Intro to Graphics 13 © 2006 Pearson Education
Color. Subclass • Color. Shape is abstract… – what should the subclass do? • Color. Shape takes a Rectangular. Shape in constructor – pass in subclass of Rectangular. Shape • Like so… public class Color. Rectangle extends Color. Shape { public Color. Rectangle () { super(new java. awt. geom. Rectangle 2 D. Double()); } } • Same for other Rectangular. Shapes – except for Arc 2 D… • see book for details Intro to Graphics 14 © 2006 Pearson Education
Frames • Most Swing applications start with a Frame – it’s actually called a javax. swing. JFrame • J is for Java public class App extends javax. swing. JFrame { public App() { super(“xterm”); this. set. Size(500, 450); //size varies this. set. Default. Close. Operation( EXIT_ON_CLOSE); //add Fvwm Microsoft Mac OS(Sunlab) XWindows Frame code for Frame top-level object Frame this. set. Visible(true); } public static void main(String[] argv) { App app = new App(); } } • When you draw graphics, you always need to draw onto some kind of container - a frame, like the one above, holds containers… Intro to Graphics 15 © 2006 Pearson Education
Panels • JFrames hold JPanels – think of a JFrame as a window frame – think of a JPanel as a window pane Frame Panel sub-panels • Panels are the canvas for your program – in Swing, they are called javax. swing. JPanels – draw graphical shapes and GUI elements on a panel – Add panels to a frame, then add shapes and GUI elements to the panels Intro to Graphics 16 © 2006 Pearson Education
Drawing Panels • Specialized panels hold specific types of objects – some hold buttons, sliders and text boxes – some hold shapes – some hold other panels • Subclass a JPanel to specialize it – we want to specialize a JPanel to hold shapes • To paint anything on any JPanel, you must partially override its special method: paint. Component(Graphics g) – remember that a Graphics is our “brush” • won’t call this method explicitly; Java does • call paint on your shape from this method – pass the brush to your shape • there’s one small complication… – you need to pass your shape a Graphics 2 D – the parameter of paint. Component is a Graphics Intro to Graphics 17 © 2006 Pearson Education
Class Cast and Repaint • Only Cast to another variable type when ABSOLUTELY Necessary • Cast like so: public void method (Generic. Type g){ Specific. Type sub = (Specific. Type) g; } • Apply this pattern to get a Graphics 2 D public void paint. Component(Graphics g){ Graphics 2 D brush = (Graphics 2 D) g; //tell shape to paint itself } Intro to Graphics 18 © 2006 Pearson Education
Paint. Component • Whenever you want to execute the code in paint. Component(…), call repaint() on the JPanel instead _drawing. Panel. repaint(); • Java calls paint. Component(…) for you and also creates the brush for you • Let’s clarify with a little animation… Intro to Graphics 19 © 2006 Pearson Education
Repaint! ? Graphics Someone repaint() (In JPanel) paint. Component( Graphics 2 Dg) { super. paint. Component(g); Graphics 2 D brush = (Graphics 2 D) g; _rectangle. paint(brush); } JPanel paint( brush) { (In Shape) brush. set. Color(_border. Color); brush. draw(_shape); brush. set. Color(_fill. Color); brush. fill(_shape); } Intro to Graphics 20 © 2006 Pearson Education
To the Drawing Panel! • Add a rectangle to a Drawing Panel… public class Drawing. Panel extends JPanel { private Color. Rectangle _rectangle; public Drawing. Panel(){ super(); this. set. Background(java. awt. Color. white); _rectangle = new Color. Rectangle(); } public void paint. Component (Graphics g){ super. paint. Component(g); Graphics 2 D brush = (Graphics 2 D) g; _rectangle. paint(brush); } } • Wait! Don’t forget to set the size of the Panel this. set. Preferred. Size( new java. awt. Dimension(500, 500)); Intro to Graphics 21 © 2006 Pearson Education
Composite Shapes • If we make an ellipse subclass… public class Color. Ellipse extends Color. Shape { public Color. Ellipse () { super(new java. awt. geom. Ellipse 2 D. Double()); } } • We can make a nice little alien: • We could make 3 ellipses…and strategically place them in a Drawing Panel – but, how to move alien? • have to change location of all 3 ellipses explicitly • Or, make Alien class… – alien class moves all 3 ellipses automatically – can change alien without changing Drawing panel – adding more aliens is easy! Intro to Graphics 22 © 2006 Pearson Education
Nice Alien • Nice Alien class contains 3 ellipses… public class Nice. Alien { private Color. Ellipse _face, _lt. Eye, _rt. Eye; private java. awt. Color _face. Color, _eye. Color; public Nice. Alien () { //initializations, set size elided… _face. set. Location(100, 100); _lt. Eye. set. Location(133, 120); _rt. Eye. set. Location(164, 120); } public void set. Location (double x, double y) { _face. set. Location(x, y); // absolute position _lt. Eye. set. Location(x+33, y+20); //relative “ _rt. Eye. set. Location(x+64, y+20); _rt. Eye } _lt. Eye public void paint (Graphics 2 D brush){ _face. paint(brush); _lt. Eye. paint(brush); _rt. Eye. paint(brush); } } Intro to Graphics _face 23 © 2006 Pearson Education
Rotation • Rotating shapes is easy, but slightly counterintuitive… – won’t rotate the java. awt. geom. Rectangular. Shape • Instead, tell brush (Graphics 2 D) to rotate the canvas. – canvas automatically rotates in opposite direction – paint shape, then un-rotate No rotation 45˚ Rotation Intro to Graphics Final Product 24 © 2006 Pearson Education
Rotation • Need to store rotation angles… – degrees are easier conceptually, but Graphics 2 D needs radians – write accessors/mutators in degrees, store data in radians public void set. Rotation (double degrees) { _rotation = degrees*Math. PI/180; } public double get. Rotation(){ return _rotation*180/Math. PI; } • Rotate method requires: – angle of rotation (radians) – center point of shape • subclasses of Rectangular. Shape store center point brush. rotate(_rotation, _shape. get. Center. X(), _shape. get. Center. Y()); Intro to Graphics 25 © 2006 Pearson Education
Color Shape • Our new shape class can rotate… public abstract class Color. Shape { private java. awt. geom. Rectangular. Shape _shape; private java. awt. Color _border. Color, _fill. Color; private double _rotation; public Color. Shape (java. awt. geom. Rectangular. Shape s) { //most of constructor elided… _rotation = 0; } public void set. Rotation(double degrees){ _rotation = degrees*Math. PI/180; } public double get. Rotation(){ return _rotation*180/Math. PI; } public void paint (Graphics 2 D brush){ // rotate canvas brush. rotate(_rotation, _shape. get. Center. X(), _shape. get. Center. Y()); brush. set. Color(this. get. Border. Color()); brush. draw(_shape); brush. set. Color(this. get. Fill. Color()); brush. fill(_shape); // unrotate canvas brush. rotate(0 -_rotation, _shape. get. Center. X(), _shape. get. Center. Y()); } } Intro to Graphics 26 © 2006 Pearson Education
Evil Alien • Exactly the same as Nice Alien… public class Evil. Alien { private Color. Ellipse _face, _lt. Eye, _rt. Eye; private java. awt. Color _face. Color, _eye. Color; public Evil. Alien () { //initializations, set dimensions elided… _face. set. Location(100, 100); _lt. Eye. set. Location(133, 120); _rt. Eye. set. Location(164, 120); } public void set. Location (double x, double y) { _face. set. Location(x, y); _lt. Eye. set. Location(x+33, y+20); _rt. Eye. set. Location(x+64, y+20); } public void paint (Graphics 2 D brush){ _face. paint(brush); _lt. Eye. paint(brush); _rt. Eye. paint(brush); } } • But rotate the eyes! _lt. Eye. set. Rotation(-33); _rt. Eye. set. Rotation(33); Intro to Graphics 27 © 2006 Pearson Education
Animation • How do we animate characters like our aliens (e. g. move across screen)? • As in film and video animation, create apparent motion with many small changes in position • If you move in fast enough increments, you get smooth motion • Same applies to size, orientation, shape change, etc… – all time-varying attributes are called “behaviors” • How to create incremental change? – we need a timer that emits “ticks” • We also need an object to listen for ticks from the timer and respond appropriatey Intro to Graphics 28 © 2006 Pearson Education
Event Model • Want object to respond to clock tick • Also want to model other types of behaviors – might want to respond to mouse click instead of timer tick • See how to use the mouse in the next lecture • Java generalizes such stimulus--response – actions, events, listeners – event gets generated by a source, which passes it to a listener – listener in turn sends a message to one or more responders Intro to Graphics 29 © 2006 Pearson Education
Event Model Continued • Four-part process: Java mechanisms: 1) stimulus 1) event button press, timer tick, etc. breaks flow of control 2) action. Performed 2) object response the listening object’s (Action. Listener’s) reaction to a stimulus listening object’s method; called in response to stimulus 3) Action. Event class 3) communication method event record – record of what happened during stimulus data-only object; Contains information about stimulus (e. g. , location of mouse click) 4) Action. Listener 4) subscribing mechanism How are the responding object and stimulus connected? Intro to Graphics classes implementing this interface can listen for a specific kind of event 30 © 2006 Pearson Education
Animation Revisited • So, to get our aliens moving we need… – a timer – a class to listen for ticks • must implement Action. Listener • must define action. Performed(Action. Event e) – should tell the alien to move (change location) • Can call set. Location() on alien at each tick – with absolute x, y values • Or, can give aliens a move() method – with relative x, y values – arbitrary movement • gives aliens added functionality, encapsulation • First, must know current location of alien – which ellipse determines location? • the face; simple in this case, but can be more complicated for a more complex shape – could make alien class subclass of Color. Ellipse • advantages? disadvantages? • Store alien’s current location with new instance variables… Intro to Graphics 31 © 2006 Pearson Education
Alien Revisited public class Evil. Alien { private Color. Ellipse _face, _lt. Eye, _rt. Eye; private java. awt. Color _face. Color, _eye. Color; private double _alien. X, _alien. Y; //constructor elided //accessors and mutators elided public void set. Location (double x, double y) { _face. set. Location(x, y); _lt. Eye. set. Location(x+33, y+20); _rt. Eye. set. Location(x+64, y+20); _alien. X = x; _alien. Y = y; } public void move(double delta. X, double delta. Y){ this. set. Location(_alien. X+delta. X, _alien. Y+delta. Y); } } moves 3 pixels right and 2 pixels down • Make the same additions to Nice. Alien Intro to Graphics 32 © 2006 Pearson Education
The Design • There are many ways to setup the stimulusresponse mechanisms for animation. This is our way: • The basic plan: – Create a Timer class with its own Action. Listener “inner class” – Have our Drawing. Panel contain this Timer – On each tick of the Timer, tell the Drawing. Panel – Drawing. Panel decides what should move, and then repaints itself – Let’s see what this looks like in code! Intro to Graphics 33 © 2006 Pearson Education
Motion Example public class Drawing. Panel extends JPanel { private Nice. Alien _alien 1; private Evil. Alien _alien 2; private My. Timer _timer; public Drawing. Panel (){ //part of constructor elided _timer = new My. Timer(this); _timer. start(); } /* * move is called by Action. Listener’s * action. Performed method. */ public void move() { _alien 1. move(3, 2); _alien 2. move(4, 5); //moves “faster” this. repaint(); } } Intro to Graphics 34 © 2006 Pearson Education
Motion Example (Continued) public class My. Timer extends javax. swing. Timer { private Drawing. Panel _drawing. Panel; approximate milliseconds between ticks public My. Timer(Drawing. Panel panel) { super(100, new My. Move. Listener()); _drawing. Panel = panel; } create a new instance of a My. Move. Listener, defined below /** * Private inner class, can only be used inside of * My. Timer. This is standard for listener classes in * Java. */ private class My. Move. Listener implements java. awt. event. Action. Listener { // This class does not need a constructor // More on this in section Action. Event is ignored in this case public void action. Performed( java. awt. event. Action. Event e) { _drawing. Panel. move(); } } } Intro to Graphics 35 © 2006 Pearson Education
Design Tradeoff • Why not have aliens implement Action. Listener instead? • Pro Alien as “Smart Object”: – each object knows how to animate itself – object is completely self-contained – encapsulation to the MAX! • Pro Container: – container can pick which aliens move – easy to repaint after you move everything – more efficient as you add more shapes Intro to Graphics 36 © 2006 Pearson Education
Window wrap-around • What happens when the aliens reach the edge of the screen? – they disappear!!! Not very interesting. • Shapes should wrap around the screen: • First, we must know when the shape passes an edge… – If so, call shape’s wrap() method • this check can occur in set. Location() – wrap() recalculates shape’s location to fall within the bounds of the JPanel Intro to Graphics 37 © 2006 Pearson Education
Modular Arithmetic • If a shape is… – on a drawing panel of size 400 x 400 – of size 20 x 30 – at location (401, 150) • Where should the new location be? – location: (1, 150) • What formula would allow us to predict where the shape should be in all cases? – HINT: use the Mod (%) Operator!! Intro to Graphics 38 © 2006 Pearson Education
Wrap-around • Aliens must know size of Drawing Panel – new instance variable; initialize in constructor public class Evil. Alien { private Color. Ellipse _face, _lt. Eye, _rt. Eye; private java. awt. Color _face. Color, _eye. Color; private double _alien. X, _alien. Y; private int _dp. Width, _dp. Height; public Evil. Alien(int dp. Width, int dp. Height) { _dp. Width = dp. Width; _dp. Height = dp. Height; //rest of constructor elided } public void set. Location(double x, double y) { double new. X = (x + _dp. Width) % _dp. Width; double new. Y = (y + _dp. Height) % _dp. Height; _face. set. Location(new. X, new. Y); _lt. Eye. set. Location(new. X+33, new. Y+20); _rt. Eye. set. Location(new. X+64, new. Y+20); _alien. X = new. X; _alien. Y = new. Y; } } • The alien’s constructor now takes two ints – how to retrieve those from drawing panel? • know the size when creating the panel • or can call get. Size() on the JPanel Intro to Graphics 39 © 2006 Pearson Education
Wrapping up! • You now have everything you need to produce graphics: – Shape superclass • contains all necessary information • • – non-geometric: instance variables – geometric: rectangular. Shape subclass paints itself – with a Graphics 2 D brush animates wraps around the screen you can subclass to make specific shapes – Drawing Panel • subclass of JPanel • can draw shapes • sits in a JFrame • User-interfaces are next! – Come back and learn • • buttons sliders layouts and more! Intro to Graphics 40 © 2006 Pearson Education
Intro to Graphics 41 © 2006 Pearson Education
- Slides: 41