intro to swing
DESCRIPTION
Intro to SWING. The Shape Object Painting Shapes Frames and Panels Composite Shapes Rotation Animation Window wrap-around. A Long Long Time Ago…. - PowerPoint PPT PresentationTRANSCRIPT
© 2006 Pearson EducationIntro to Graphics 1 of 42
Intro to SWING
• The Shape Object
• Painting Shapes
• Frames and Panels
• Composite Shapes
• Rotation
• Animation
• Window wrap-around
© 2006 Pearson EducationIntro to Graphics 2 of 42
• 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…
A Long Long Time Ago…
© 2006 Pearson EducationIntro to Graphics 3 of 42
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?
© 2006 Pearson EducationIntro to Graphics 4 of 42
• 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
RectangularShape
SizeLocation
© 2006 Pearson EducationIntro to Graphics 5 of 42
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
© 2006 Pearson EducationIntro to Graphics 6 of 42
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)
(40, 40)
Pixel Art
shape
bounding box
location of shape
X
Y
X
© 2006 Pearson EducationIntro to Graphics 7 of 42
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();
© 2006 Pearson EducationIntro to Graphics 8 of 42
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); }
© 2006 Pearson EducationIntro to Graphics 9 of 42
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;
}
© 2006 Pearson EducationIntro to Graphics 10 of 42
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)
Red Green Blue
(255, 0, 0) = (0, 255, 0) = (0, 0, 255) =(200, 0, 200)=
new java.awt.Color(239, 174, 45, 200)
Alpha Value
java.awt.Color.orangejava.awt.Color.green
java.awt.Color.gray
© 2006 Pearson EducationIntro to Graphics 11 of 42
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
}
© 2006 Pearson EducationIntro to Graphics 12 of 42
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!
© 2006 Pearson EducationIntro to Graphics 13 of 42
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 ColorShape paints itself, it…
– sets the color of 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);
© 2006 Pearson EducationIntro to Graphics 14 of 42
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
© 2006 Pearson EducationIntro to Graphics 15 of 42
Frames
• Most Swing applications start with a Frame– it’s actually called a javax.swing.JFrame
• J is for Java
Mac OS X FrameMicrosoft Windows Frame
Fvwm (Sunlab) Frame
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…
© 2006 Pearson EducationIntro to Graphics 16 of 42
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
sub-panels
© 2006 Pearson EducationIntro to Graphics 17 of 42
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
© 2006 Pearson EducationIntro to Graphics 18 of 42
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 }
© 2006 Pearson EducationIntro to Graphics 19 of 42
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 brush for you
• Let’s clarify with a little animation…
© 2006 Pearson EducationIntro to Graphics 20 of 42
Repaint!
?
Someone
JPanel
paintComponent( g) { super.paintComponent(g); Graphics2D brush = (Graphics2D) g; _rectangle.paint(brush);}
Graphics
paint( brush) { brush.setColor(_borderColor); brush.draw(_shape); brush.setColor(_fillColor); brush.fill(_shape);}
Graphics2D
repaint() (In JPanel)
(In Shape)
© 2006 Pearson EducationIntro to Graphics 21 of 42
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 Panelthis.setPreferredSize(
new java.awt.Dimension(500, 500));
© 2006 Pearson EducationIntro to Graphics 22 of 42
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!
© 2006 Pearson EducationIntro to Graphics 23 of 42
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);
}}
_rtEye
_ltEye
_face
© 2006 Pearson EducationIntro to Graphics 24 of 42
• 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
Rotation
Final Product
No rotation
45˚ Rotation
© 2006 Pearson EducationIntro to Graphics 25 of 42
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());
© 2006 Pearson EducationIntro to Graphics 26 of 42
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());}
}
© 2006 Pearson EducationIntro to Graphics 27 of 42
• 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); }}
Evil Alien
_ltEye.setRotation(-33); _rtEye.setRotation(33);
© 2006 Pearson EducationIntro to Graphics 28 of 42
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
© 2006 Pearson EducationIntro to Graphics 29 of 42
• 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
Event Model
© 2006 Pearson EducationIntro to Graphics 30 of 42
Event Model Continued
• Four-part process:
1) stimulus
2) object response
3) communication method
4) subscribing mechanism
Java mechanisms:1) event
2) actionPerformed
3) ActionEvent classevent record – record of what happened during stimulus
4) ActionListener
data-only object; Contains information about stimulus (e.g., location of mouse click)
the listening object’s (ActionListener’s) reaction to a stimulus
How are the responding object and stimulus connected?
classes implementing this interface can listen for a specific kind of event
listening object’s method; called in response to stimulus
button press, timer tick, etc.breaks flow of control
© 2006 Pearson EducationIntro to Graphics 31 of 42
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…
© 2006 Pearson EducationIntro to Graphics 32 of 42
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
moves 3 pixels right
and 2 pixels down
© 2006 Pearson EducationIntro to Graphics 33 of 42
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!
© 2006 Pearson EducationIntro to Graphics 34 of 42
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();
}
}
Motion Example
© 2006 Pearson EducationIntro to Graphics 35 of 42
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();
}
}
}
ActionEvent is ignored in this case
approximate milliseconds between ticks
create a new instance of a MyMoveListener, defined below
© 2006 Pearson EducationIntro to Graphics 36 of 42
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
© 2006 Pearson EducationIntro to Graphics 37 of 42
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
© 2006 Pearson EducationIntro to Graphics 38 of 42
Modular Arithmetic
• If a 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!!
© 2006 Pearson EducationIntro to Graphics 39 of 42
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
© 2006 Pearson EducationIntro to Graphics 40 of 42
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!
© 2006 Pearson EducationIntro to Graphics 41 of 42