1 / 41

Intro to SWING

Intro to SWING. The Shape Object Painting Shapes Frames and Panels Composite Shapes Rotation Animation Window wrap-around. A Long Long Time Ago….

zody
Download Presentation

Intro to SWING

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Intro to SWING • The Shape Object • Painting Shapes • Frames and Panels • Composite Shapes • Rotation • Animation • Window wrap-around Intro to Graphics

  2. A Long 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

  3. 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

  4. RectangularShape • Use AWT’s utility classes to store geometric information about a shape: • java.awt.geom.RectangularShape • Class is abstract - use subclasses in practice • all subclasses can be bound by a rectangular bounding box: • java.awt.geom.Rectangle2D.Double • java.awt.geom.RoundRectangle2D.Double • java.awt.geom.Ellipse2D.Double • java.awt.geom.Arc2D.Double • Define your own shape class • contains a RectangularShape for geometric data • these store Locations and Dimensions • Other instance variables provide additional data • colors, rotation angle Size Location Intro to Graphics

  5. ColorShape public abstract class ColorShape { private java.awt.geom.RectangularShape _shape; public ColorShape (java.awt.geom.RectangularShape s) { _shape = s; } //accessors/mutators and other //attributes to follow.. } • Our shape contains a RectangularShape Intro to Graphics

  6. (40, 40) Y X X bounding box location of shape shape Location/Dimension • The screen is a grid of pixels(tiny dots) • “picture elements” • 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 Y (0, 0) Pixel Art Intro to Graphics

  7. RectangularShape – Mutators/Accessors • To set location and size: _shape.setFrame(xLoc, yLoc, width, height); • use this method to initialize and reset location and size on a RectangularShape • To get geometric data: _shape.getX(); _shape.getY(); _shape.getWidth(); _shape.getHeight(); Intro to Graphics

  8. ColorShape class Accessors/Mutators • Accessors to make RectangularShape data available to external classes: public double getX(){ return _shape.getX(); } • Create mutators so external classes can change location and size independently: public void setLocation (double x, double y){ // Change only x and y, preserve the width and height _shape.setFrame(x, y, _shape.getWidth(), _shape.getHeight()); } public void setSize (double w, double h) { // Change only the width and height, preserve the x and y coordinates _shape.setFrame(_shape.getX(), _shape.getY(), w, h); } Intro to Graphics

  9. Storing Color • additional data in Instance Variables • Use accessors/mutators: public void setFillColor(java.awt.Color c){ _fillColor = c; } public java.awt.Color getFillColor(){ return _fillColor; } • Ditto for border color • Or use one method to change both fill and border color at once: public void setColor(java.awt.Color c){ _fillColor = c; _borderColor = c; } Intro to Graphics

  10. Red Green Blue Alpha Value new java.awt.Color(239, 174, 45, 200) Color • java.awt.Color stores color • RGB format • 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 • Basic colors come preset • Colors can be • specify the alpha value [0-255]… • 0 = completely transparent • new • java.awt.Color(0, 255, 0) (255, 0, 0) = (0, 255, 0) = (0, 0, 255) = (200, 0, 200)= java.awt.Color.green java.awt.Color.orange java.awt.Color.gray transparent Intro to Graphics

  11. ColorShape again! public abstract class ColorShape { private java.awt.geom.RectangularShape _shape; private java.awt.Color _borderColor, _fillColor; public ColorShape (java.awt.geom.RectangularShape s) { _shape = s; // initialize attributes… this.setLocation(50, 50); this.setSize(100, 100); this.setBorderColor (java.awt.Color.black); this.setFillColor(java.awt.Color.blue); } // accessors/mutators } Intro to Graphics

  12. Painting Shapes • Now we know what our ColorShape is… • a collection of data (geometric and non-geometric) • 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

  13. Graphics • Our brush is brilliantly named a “Graphics” • thanks, Java designers! • Actually, use Graphics2D – Its more powerful subclass • Think of it as a parameterized brush • Each time ColorShapepaints itself, it… • sets the colorof the brush brush.setColor(_borderColor); • tells brush to draw outline of a geometric shape brush.draw(_shape); • sets the color of the brush brush.setColor(_fillColor); • tells brush to fill geometric shape brush.fill(_shape); Intro to Graphics

  14. ColorSubclass • ColorShape is abstract… • what should the subclass do? • ColorShape takes a RectangularShape in constructor • pass in subclass of RectangularShape • Like so… public class ColorRectangle extends ColorShape { public ColorRectangle () { super(new java.awt.geom.Rectangle2D.Double()); } } • Same for other RectangularShapes • except for Arc2D… • see book for details Intro to Graphics

  15. 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.setSize(500, 450); //size varies • this.setDefaultCloseOperation( • EXIT_ON_CLOSE); • //add code for top-level object • this.setVisible(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… Fvwm (Sunlab) Frame Microsoft Windows Frame Mac OS X Frame Intro to Graphics

  16. sub-panels Panels • JFrames hold JPanels • think of a JFrame as a window frame • think of a JPanel as a window pane • 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 Frame Panel Intro to Graphics

  17. 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: paintComponent(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 Graphics2D • the parameter of paintComponent is a Graphics Intro to Graphics

  18. Class Cast and Repaint • Only Cast to another variable type when ABSOLUTELY Necessary • Cast like so: public void method (GenericType g){ SpecificType sub = (SpecificType) g; } • Apply this pattern to get a Graphics2D public void paintComponent(Graphics g){ Graphics2D brush = (Graphics2D) g; //tell shape to paint itself } Intro to Graphics

  19. PaintComponent • Whenever you want to execute the code in paintComponent(…), call repaint() on the JPanel instead _drawingPanel.repaint(); • Java calls paintComponent(…) for you and also creates the brushfor you • Let’s clarify with a little animation… Intro to Graphics

  20. ? Someone JPanel Repaint! Graphics repaint() (In JPanel) paintComponent( g) { super.paintComponent(g); Graphics2D brush = (Graphics2D) g; _rectangle.paint(brush); } Graphics2D (In Shape) paint( brush) { brush.setColor(_borderColor); brush.draw(_shape); brush.setColor(_fillColor); brush.fill(_shape); } Intro to Graphics

  21. To the Drawing Panel! • Add a rectangle to a Drawing Panel… public class DrawingPanel extends JPanel { private ColorRectangle _rectangle; public DrawingPanel(){ super(); this.setBackground(java.awt.Color.white); _rectangle = new ColorRectangle(); } public void paintComponent (Graphics g){ super.paintComponent(g); Graphics2D brush = (Graphics2D) g; _rectangle.paint(brush); } } • Wait! Don’t forget to set the size of the Panel this.setPreferredSize( new java.awt.Dimension(500, 500)); Intro to Graphics

  22. Composite Shapes • If we make an ellipse subclass… public class ColorEllipse extends ColorShape { public ColorEllipse () { super(new java.awt.geom.Ellipse2D.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

  23. _rtEye _ltEye _face Nice Alien • Nice Alien class contains 3 ellipses… public class NiceAlien { private ColorEllipse _face, _ltEye, _rtEye; private java.awt.Color _faceColor, _eyeColor; public NiceAlien () { //initializations, set size elided… _face.setLocation(100, 100); _ltEye.setLocation(133, 120); _rtEye.setLocation(164, 120); } public void setLocation (double x, double y) { _face.setLocation(x, y); // absolute position _ltEye.setLocation(x+33, y+20); //relative “ _rtEye.setLocation(x+64, y+20); } public void paint (Graphics2D brush){ _face.paint(brush); _ltEye.paint(brush); _rtEye.paint(brush); } } Intro to Graphics

  24. Rotation • Rotating shapes is easy, but slightly counter-intuitive… • won’t rotate the java.awt.geom.RectangularShape • Instead, tell brush (Graphics2D) to rotate the canvas. • canvas automatically rotates in opposite direction • paint shape, then un-rotate No rotation 45˚ Rotation Final Product Intro to Graphics

  25. Rotation • Need to store rotation angles… • degrees are easier conceptually, but Graphics2D needs radians • write accessors/mutators in degrees, store data in radians public void setRotation (double degrees) { _rotation = degrees*Math.PI/180; } public double getRotation(){ return _rotation*180/Math.PI; } • Rotate method requires: • angle of rotation (radians) • center point of shape • subclasses of RectangularShape store center point brush.rotate(_rotation, _shape.getCenterX(), _shape.getCenterY()); Intro to Graphics

  26. Color Shape • Our new shape class can rotate… public abstract class ColorShape { private java.awt.geom.RectangularShape _shape; private java.awt.Color _borderColor, _fillColor; private double _rotation; public ColorShape (java.awt.geom.RectangularShape s) { //most of constructor elided… _rotation = 0; } public void setRotation(double degrees){ _rotation = degrees*Math.PI/180; } public double getRotation(){ return _rotation*180/Math.PI; } public void paint (Graphics2D brush){ // rotate canvas brush.rotate(_rotation, _shape.getCenterX(), _shape.getCenterY()); brush.setColor(this.getBorderColor()); brush.draw(_shape); brush.setColor(this.getFillColor()); brush.fill(_shape); // unrotate canvas brush.rotate(0-_rotation, _shape.getCenterX(), _shape.getCenterY()); } } Intro to Graphics

  27. Evil Alien • Exactly the same as Nice Alien… public class EvilAlien { private ColorEllipse _face, _ltEye, _rtEye; private java.awt.Color _faceColor, _eyeColor; public EvilAlien () { //initializations, set dimensions elided… • But rotate the eyes! _face.setLocation(100, 100); _ltEye.setLocation(133, 120); _rtEye.setLocation(164, 120); } public void setLocation (double x, double y) { _face.setLocation(x, y); _ltEye.setLocation(x+33, y+20); _rtEye.setLocation(x+64, y+20); } public void paint (Graphics2D brush){ _face.paint(brush); _ltEye.paint(brush); _rtEye.paint(brush); } } _ltEye.setRotation(-33); _rtEye.setRotation(33); Intro to Graphics

  28. 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

  29. 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

  30. Event Model Continued • Four-part process: Java mechanisms: 1) stimulus 1) event breaks flow of control button press, timer tick, etc. 2) object response 2) actionPerformed the listening object’s (ActionListener’s) reaction to a stimulus listening object’s method; called in response to stimulus 3) communication method 3) ActionEventclass event record – record of what happened during stimulus data-only object; Contains information about stimulus (e.g., location of mouse click) 4) subscribing mechanism 4) ActionListener How are the responding object and stimulus connected? classes implementing this interface can listen for a specific kind of event Intro to Graphics

  31. Animation Revisited • So, to get our aliens moving we need… • a timer • a class to listen for ticks • must implement ActionListener • must define actionPerformed(ActionEvent e) • should tell the alien to move (change location) • Can call setLocation() 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 ColorEllipse • advantages? disadvantages? • Store alien’s current location with new instance variables… Intro to Graphics

  32. moves 3 pixels right and 2 pixels down Alien Revisited public class EvilAlien { private ColorEllipse _face, _ltEye, _rtEye; private java.awt.Color _faceColor, _eyeColor; private double _alienX, _alienY; //constructor elided //accessors and mutators elided public void setLocation (double x, double y) { _face.setLocation(x, y); _ltEye.setLocation(x+33, y+20); _rtEye.setLocation(x+64, y+20); _alienX = x; _alienY = y; } public void move(double deltaX, double deltaY){ this.setLocation(_alienX+deltaX, _alienY+deltaY); } } • Make the same additions to NiceAlien Intro to Graphics

  33. The Design • There are many ways to setup the stimulus-response mechanisms for animation. This is our way: • The basic plan: • Create a Timer class with its own ActionListener “inner class” • Have our DrawingPanel contain this Timer • On each tick of the Timer, tell the DrawingPanel • DrawingPanel decides what should move, and then repaints itself • Let’s see what this looks like in code! Intro to Graphics

  34. Motion Example public class DrawingPanel extends JPanel { private NiceAlien _alien1; private EvilAlien _alien2; private MyTimer _timer; public DrawingPanel (){ //part of constructor elided _timer = new MyTimer(this); _timer.start(); } /* * move is called by ActionListener’s * actionPerformed method. */ public void move() { _alien1.move(3, 2); _alien2.move(4, 5); //moves “faster” this.repaint(); } } Intro to Graphics

  35. Motion Example (Continued) public class MyTimer extends javax.swing.Timer { private DrawingPanel _drawingPanel; public MyTimer(DrawingPanel panel) { super(100, new MyMoveListener()); _drawingPanel = panel; } /** * Private inner class, can only be used inside of * MyTimer. This is standard for listener classes in * Java. */ private class MyMoveListener implements java.awt.event.ActionListener { // This class does not need a constructor // More on this in section public void actionPerformed( java.awt.event.ActionEvent e) { _drawingPanel.move(); } } } approximate milliseconds between ticks create a new instance of aMyMoveListener, defined below ActionEvent is ignored in this case Intro to Graphics

  36. Design Tradeoff • Why not have aliens implement ActionListener 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

  37. 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 setLocation() • wrap() recalculates shape’s location to fall within the bounds of the JPanel Intro to Graphics

  38. Modular Arithmetic • Ifa shape is… • on a drawing panel of size 400x400 • of size 20x30 • 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

  39. Wrap-around • Aliens must know size of Drawing Panel • new instance variable; initialize in constructor public class EvilAlien { private ColorEllipse _face, _ltEye, _rtEye; private java.awt.Color _faceColor, _eyeColor; private double _alienX, _alienY; private int _dpWidth, _dpHeight; public EvilAlien(int dpWidth, int dpHeight) { _dpWidth = dpWidth; _dpHeight = dpHeight; //rest of constructor elided } public void setLocation(double x, double y) { double newX = (x + _dpWidth) % _dpWidth; double newY = (y + _dpHeight) % _dpHeight; _face.setLocation(newX, newY);_ltEye.setLocation(newX+33, newY+20); _rtEye.setLocation(newX+64, newY+20); _alienX = newX; _alienY = newY; } } • 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 getSize() on the JPanel Intro to Graphics

  40. Wrapping up! • You now have everything you need to produce graphics: • Shape superclass • contains all necessary information • non-geometric: instance variables • geometric: rectangularShape subclass • paints itself • with a Graphics2D 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

  41. Intro to Graphics

More Related