Transcript Slides
Intro to SWING
• The Shape Object
• Painting Shapes
• Frames and Panels
• Composite Shapes
• Rotation
• Animation
• Window wrap-around
Intro to Graphics
1 of 42
© 2006 Pearson Education
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
2 of 42
© 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 of 42
© 2006 Pearson Education
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
Size
Location
– Other instance variables provide additional data
• colors, rotation angle
Intro to Graphics
4 of 42
© 2006 Pearson Education
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
5 of 42
© 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
bounding box
location
of shape
shape
Intro to Graphics
6 of 42
© 2006 Pearson Education
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
7 of 42
© 2006 Pearson Education
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
8 of 42
© 2006 Pearson Education
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
9 of 42
© 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 of 42
© 2006 Pearson Education
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
11 of 42
© 2006 Pearson Education
Painting Shapes
• Now we know what our ColorShape
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 of 42
© 2006 Pearson Education
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);
Intro to Graphics
13 of 42
© 2006 Pearson Education
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
14 of 42
© 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.setSize(500, 450); //size varies
this.setDefaultCloseOperation(
EXIT_ON_CLOSE);
//add
Fvwm
Microsoft
Mac
OS(Sunlab)
X Frame
code
forFrame
top-level
object
Windows
Frame
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…
Intro to Graphics
15 of 42
© 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 of 42
© 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:
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
17 of 42
© 2006 Pearson Education
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
18 of 42
© 2006 Pearson Education
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…
Intro to Graphics
19 of 42
© 2006 Pearson Education
Repaint!
?
Graphics
Someone
repaint()
(In JPanel)
paintComponent( Graphics2Dg) {
super.paintComponent(g);
Graphics2D brush =
(Graphics2D) g;
_rectangle.paint(brush);
}
JPanel
paint(
brush) { (In Shape)
brush.setColor(_borderColor);
brush.draw(_shape);
brush.setColor(_fillColor);
brush.fill(_shape);
}
Intro to Graphics
20 of 42
© 2006 Pearson Education
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
21 of 42
© 2006 Pearson Education
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
22 of 42
© 2006 Pearson Education
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);
_rtEye
}
_ltEye
public void paint (Graphics2D brush){
_face.paint(brush);
_ltEye.paint(brush);
_rtEye.paint(brush);
}
}
_face
Intro to Graphics
23 of 42
© 2006 Pearson Education
Rotation
• Rotating shapes is easy, but slightly counterintuitive…
– 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
Intro to Graphics
Final Product
24 of 42
© 2006 Pearson Education
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
25 of 42
© 2006 Pearson Education
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
26 of 42
© 2006 Pearson Education
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…
_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);
}
}
• But rotate the eyes!
_ltEye.setRotation(-33);
_rtEye.setRotation(33);
Intro to Graphics
27 of 42
© 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 of 42
© 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 of 42
© 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) actionPerformed
2) object response
the listening object’s
(ActionListener’s)
reaction to a stimulus
listening object’s method;
called in response to stimulus
3) communication method
3) ActionEvent class
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?
Intro to Graphics
classes implementing this
interface can listen for a
specific kind of event
30 of 42
© 2006 Pearson Education
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
31 of 42
© 2006 Pearson Education
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);
}
}
moves 3 pixels
right
and 2 pixels
down
• Make the same additions to NiceAlien
Intro to Graphics
32 of 42
© 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
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
33 of 42
© 2006 Pearson Education
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
34 of 42
© 2006 Pearson Education
Motion Example (Continued)
public class MyTimer extends javax.swing.Timer {
private DrawingPanel _drawingPanel;
approximate
milliseconds
between ticks
public MyTimer(DrawingPanel panel) {
super(100, new MyMoveListener());
_drawingPanel = panel;
}
create a new instance of a
MyMoveListener, defined
below
/**
* 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
ActionEvent is
ignored in this
case
public void actionPerformed(
java.awt.event.ActionEvent e) {
_drawingPanel.move();
}
}
}
Intro to Graphics
35 of 42
© 2006 Pearson Education
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
36 of 42
© 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 setLocation()
– wrap() recalculates shape’s location to fall within
the bounds of the JPanel
Intro to Graphics
37 of 42
© 2006 Pearson Education
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!!
Intro to Graphics
38 of 42
© 2006 Pearson Education
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
39 of 42
© 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: 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
40 of 42
© 2006 Pearson Education
Intro to Graphics
41 of 42
© 2006 Pearson Education