presentation slides for Object-Oriented Problem Solving JAVA, JAVA, JAVA Second Edition Ralph Morelli Trinity College Hartford, CT published by Prentice Hall Java, Java, Java Object Oriented Problem Solving Chapter 10: Graphics and Drawing Objectives • Know how to use Java's drawing classes and methods. • Understand the concept of a graphics context. • Be able to design scalable drawings. • Know how to design and implement interfaces. • Be familiar with handling mouse events. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Outline • • • • • • • • • • • Introduction The Drawing Surface Graphics and Color From the Java Library: Points and Dimensions Painting and Drawing Lines and Shapes Graphing Equations Drawing Bar Charts and Pie Charts Handling Text in a Graphics Context Case Study: Interactive Drawing Object-Oriented Design: Scalable CyberPet In the Laboratory: The SelfPortrait Class Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Introduction • Chapter focus: Java's drawing, painting and mouse-handling methods • All of these elements are part of the Java's Abstract Windowing Toolkit (AWT). • Design theme: Using parameters to generalize methods. • Example: Scalable drawings -- drawings that can be easily resized. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics The Drawing Surface • In the AWT, a Canvas component is the usual drawing surface. • In Swing programs you can draw directly on the top-level windows --- JApplet, JFrame -- or on a JPanel. • JPanels are transparent by default but can be made opaque. • Subclasses of JComponent are transparent. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics The Graphics Context • Graphics Context: Each GUI component has a java.awt.Graphics object which contains the drawing methods. • The java.awt.Graphics class is abstract and cannot be instantiated. • AWT components: the Graphics object is accessed from paint() method. • Swing components: the Graphics object is accessed from paintComponent() method. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics The Drawing Surface A JPanel gives an opaque drawing surface. You must override its paintComponent() method in a subclass and set its pencolor in order to draw on it. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics A Drawing Panel import javax.swing.*; import java.awt.*; import java.awt.event.*; public class DrawingPanel extends JPanel { public void paintComponent(Graphics super.paintComponent(g); g.setColor(getForeground()); g.drawString("Hello World", 10, g.fillRect(10, 55, 80, 20); } g) { // Make opaque // Set drawing color 50); public static void main(String args[]) { JFrame frame = new JFrame("Drawing Panel"); DrawingPanel panel = new DrawingPanel(); frame.getContentPane().add(panel); frame.setSize(200, 100); frame.setVisible(true); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } // main() } // DrawingPanel Make the JPanel opaque. // Quit Swing components override paintComponent() Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Creating an Opaque Panel • Transparent JPanel (Default): Will show the color of the underlying container. • Opaque JPanel: – Call super.paintComponent() method. – Set the color to the panel’s foreground color. super.paintComponent(g); g.setColor(getForeground()); Java, Java, Java, 2E by R. Morelli // Make opaque // Set drawing color Copyright 2002. All rights reserved. Chapter 10: Graphics Graphics Color and Component Color • Each GUI component has a foreground and background color, accessible by: • The Graphics object has one color, the color it uses for drawing and painting. • Drawing refers to making a line drawing -e.g., drawX(). • Painting fills a bounded object with color -e.g., fillX(). Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics The Graphics Coordinate System • Each picture element (pixel) is represented by its x and y coordinates. • The origin is located at the components topleft corner. Unlike the Cartesian system, the origin is not in the center. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Properties of the Graphics Context • A Graphics object has an internal state that consists of several properties: Property Description Default Value Color Font Drawing mode Clip region Origin Current drawing color Current text font Controls the pixel color The drawing region The point (0,0) JComponent's foreground color JComponent's font Java, Java, Java, 2E by R. Morelli New pixels replace old pixels. The entire JComponent Top-left pixel of the JComponent Copyright 2002. All rights reserved. Chapter 10: Graphics The Graphics Class Clip region -drawing is confined to this region. Moves the origin. XORmode -- is based on pixel-wise exclusive or Background Color White Black Java, Java, Java, 2E by R. Morelli Pen Color Black Black Color of Result Black White Copyright 2002. All rights reserved. Chapter 10: Graphics The Color Class Static built-in colors. Colors are created from an RGB value: red + green + blue: Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics The Color Class (cont) public Color(int r, int g, int b); public Color(int rgb); // RGB = 65536 * R + 256 * G + B public Color(float r, float g, float b); public public public public public public public public public public public public public static static static static static static static static static static static static static final final final final final final final final final final final final final Color Color Color Color Color Color Color Color Color Color Color Color Color black; blue; cyan; darkGray; gray; green; lightGray; magenta; orange; pink; red; white; yellow; Java, Java, Java, 2E by R. Morelli // // // // // // // // 0,0,0 0,0,255 0,255,255 140,140,140 128,128,128 0,255,0 192,192,192 255,0,255 Note for grays, R=G=B // 255,0,0 // 255,255,255 // 255,255,0 Copyright 2002. All rights reserved. Chapter 10: Graphics Example: The ColorPicker Applet • Design and implement an applet that lets the user input R, G, B values and displays the resulting colors in various formats. JTextFields for input toString() output drawRect() output drawString() output Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics ColorPicker Applet: Interface Design import javax.swing.*; import java.awt.*; import java.awt.event.*; Handles the drawing. JTextFields for input public class ColorPicker extends JApplet implements ActionListener { private JTextField redIn, greenIn, blueIn; private JLabel R = new JLabel("R:"), G = new JLabel("G:"), B = new JLabel("B:"); Sets up the private JPanel controls = new JPanel(); private Canvas canvas = new Canvas(); JTextFields public void init() { initControls(); getContentPane().add(controls, "North"); getContentPane().add(canvas, "Center"); canvas.setBorder(BorderFactory.createTitledBorder( "The Color Display")); getContentPane().setBackground(Color.white); setSize(250,150); } // init() } // ColorPicker Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. BorderLayout Background color Chapter 10: Graphics ColorPicker Applet: Controls JTextFields are used private void initControls() { for control. redIn = new JTextField("128", 4); // Create 3 input textfields greenIn = new JTextField("128", 4); blueIn = new JTextField("128", 4); redIn.addActionListener(this); // Give them listeners greenIn.addActionListener(this); blueIn.addActionListener(this); controls.setLayout( new FlowLayout()); controls.setBorder(BorderFactory.createTitledBorder( "Type in values for RGB")); controls.add(R); controls.add(redIn); controls.add(G); controls.add(greenIn); controls.add(B); controls.add(blueIn); } // initControls() Painting Protocol. Whenever a container is repainted,so are all of its contained components. public void actionPerformed(ActionEvent e) { int r = Integer.parseInt(redIn.getText()); // Get user's inputs int g = Integer.parseInt(greenIn.getText()); int b = Integer.parseInt(blueIn.getText()); Reset thecolor drawing canvas.setColor(new Color(r, g, b)); // Reset the canvas's repaint(); // Repaint the applet color. } // actionPerformed() Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics The Canvas Class Derived from JPanel import javax.swing.*; import java.awt.*; public class Canvas extends JPanel { private final int HREF = 40, VREF = 55; // Reference points private final int WIDTH = 40, HEIGHT = 50; // Rectangle dimensions private final int HGAP = 70, VGAP = 60; // Spacing constants private Color color = Color.gray; Invoked automatically public void setColor(Color c) { when applet repainted. color = c; } public void paintComponent(Graphics g) { super.paintComponent(g); // Make the panel opaque g.setColor(color); // Set the pen's color g.drawString(color.toString(),HREF,VREF-15);// Draw the RGB's g.fillRect(HREF, VREF, WIDTH, HEIGHT); // Color a rectangle g.drawString("color", HREF, VREF + VGAP); g.setColor(color.brighter()); // Brighten the color g.fillRect(HREF + HGAP, VREF, WIDTH, HEIGHT); g.drawString("brighter", HREF + HGAP, VREF + VGAP); g.setColor(color.darker()); // Darken the color g.fillRect(HREF + HGAP * 2, VREF, WIDTH, HEIGHT); g.drawString("darker", HREF + HGAP * 2, VREF + VGAP); } // paintComponent() } // Canvas Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics The Repainting Protocol • When a container is repainted, it repaints all of its components. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics OOD: Reference Constants • Note how constants --- final int variables --are used in the Canvas class to simplify the layout of the drawing area: private final int HREF = 40, VREF = 55; // Reference points private final int WIDTH = 40, HEIGHT = 50; // Rectangle dimensions private final int HGAP = 70, VGAP = 60; // Spacing constants • Effective Design: Symbolic constants rather than literal values make code more general, as well as easier to develop and maintain Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics From the Java Library: Points • The java.awt.Point class represents a point the coordinate system: Public Instance Variables: For a point P you can get its coordinates with P.x and P.y. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics From the Java Library: Dimensions • The java.awt.Dimension class represents the size (width and height) of a component: Public Instance Variables: For a dimension D you can get its width and height with D.width and D.height. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Drawing Methods Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Example: The ShapeDemo Applet • Illustrates various drawing methods. • Note the use of constants import java.awt.*; to layout import javax.swing.*; class ShapeDemo extends JApplet { shapes. public public final int NFIGS = 5; // Number of shapes public final int HREF = 2; // Horizontal reference • Uses public final int VREF = 20; // Vertical reference public final int WIDTH = 40; // Width of figure paint() public final int HGT = 20; // Height of figure method. public final int HGAP = 20; // H gap between figures public final int VGAP = 20; } // ShapeDemo Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. // V gap between figures Chapter 10: Graphics Moving the Origin • Cartesian coordinates: the origin (0,0) is at center of graph where x and y axes intersect. • Graphics.translate(deltaH, deltaV) is used to move the origin • Example: To move origin from top-left corner to the center of a panel: g.translate(size.width /2, size.height /2);// Place origin at middle • deltaH, deltaV give the horizontal and vertical displacement, not the coordinates of the new origin. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Graphing Equations • A Java application to graph linear equation y = 0.5x + 25.2 and quadratic equation 4y = -x2 Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Graphing Linear Equations • Graphing a Line represented in slope-intercept form: y = mx + b • Algorithm: Draw y value for each pixel on x-axis. /** graphLine() graphs a linear equation represented in slope* intercept form: y = mx + b, where m represents the slope and * b represents the y intercept. paintComponent() */ private void graphLine(Graphics g, double m, double b) { Dimension size = this.getSize(); // Get the panel's size int hBound = size.width / 2; // Use it to set the bounds g.setColor( Color.red ); for (int x = -hBound; x <= hBound; x++) { //For each pixel on x int y = (int)(m * x + b ); y = -y; // Reverse y coordinate (Cartesian) g.drawLine(x, y, x+1, y+1); // Draw a point } } // graphLine() Called from y-axis reversed in Cartesian plane Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Graphing Quadratic Equations • Graphing a quadratic equation represented as: y = ax2 + bx + c • Algorithm: Draw y value for each pixel on x-axis. /** graphQuadratic() graphs a quadratic equation represented in the * form: y = ax^2 + bx + c. */ private void graphQuadratic(Graphics g, double a, double b, double c) { Dimension size = this.getSize(); // Get the panel's size int hBound = size.width/2; // Use it to set the bounds g.setColor(Color.red); for (int x = -hBound; x <= hBound; x++) { // For each pixel on x int y = (int)(a * x * x + b * x + c); y = -y; // Reverse y coordinate (cartesian) g.fillOval(x-1, y-1, 3, 3); // Draw a point } } // graphQuadratic() y-axis reversed in Cartesian plane Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Design: The Graph Class Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Implementation: The Graph Class The graph is proportional to JPanel size. import java.awt.*; import javax.swing.*; public class Graph extends JPanel { private final int WIDTH = 400, HEIGHT = 400; // Defaults public Graph () { setSize(WIDTH,HEIGHT); } Swing components must be cleared. public void paintComponent(Graphics g) { Dimension size = this.getSize(); g.setColor(getBackground()); // Clear the drawing area g.setClip(0, 0, size.width, size.height); g.fillRect(0, 0, size.width, size.height); // Reset clip g.setClip(20, 20, size.width - 40, size.height - 40); g.translate(size.width / 2, size.height / 2);// Relocate origin g.setColor(Color.black); drawXYAxes(g); // Draw the X and Y axes graphLine(g, 0.5, 25.2); // Graph y = 0.5x + 25.2 graphQuadratic(g, -0.125, 0, 0 ); // Graph 4y = -x^2 } // paintComponent() } // Graph Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Drawing the Axes private void drawXYAxes(Graphics g) { Dimension size = this.getSize(); int hBound = size.width / 2; int vBound = size.height / 2; int tic = size.width / 100; // Get the panel's size // Use it to set the bounds g.drawLine(-hBound,0,hBound,0); for (int k = -hBound; k <= hBound; k+=10) g.drawLine(k, tic, k, -tic); g.drawLine(0, vBound, 0, -vBound); for (int k = -vBound; k <= vBound; k+=10) g.drawLine(-tic, k, +tic, k); } // drawXYAxes() // Draw X-axis // Draw Y-axis Tic marks Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Creating the Top-Level Window Create a top-level window and add the Graph JPanel to it. public static void main(String args[]) { JFrame f = new JFrame("Graphing Window"); Graph graph = new Graph(); f.getContentPane().add(graph); f.setSize(graph.getSize().width, graph.getSize().height); f.setVisible(true); f.addWindowListener(new WindowAdapter() { // Quit public void windowClosing(WindowEvent e) { System.exit(0); } }); } // main() An anonymous inner class is used to create a WindowAdapter to handle window close events. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Drawing Bar Charts and Pie Charts • The origin must be translated twice in this graph, once for the bar chart and once for the pie chart. • The bar chart shows sales data for 5 agents over two quarters. • The pie chart shows the proportion of sales of the 5 agents for a given quarter. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics The ChartDemo Class Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Scaling the Bar Chart • The bars must be scaled to the height of the JPanel. • If the panel is 400 pixels and $10,000 is the maximum sales amount, a scale factor of 75% would let a bar of 300 pixels represent 10000. public static private final private final private final final int WIDTH = 400, HEIGHT = 300; // Initial values int NSELLERS = 5; int MAXSALES = 6000; // Max quarter sales amount double SCALE = 0.75; // % of height used for max sales int maxBar = (int)(SCALE * size.height); // Size of biggest bar int barWidth = size.width / 40; // Width of bar int hgt = (int)(maxBar * quarter1[k] / MAXSALES);// Hgt quarter1 sales g.fillRect(href, -hgt, barWidth, hgt); // Draw the bar Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics The ChartDemo Class import java.awt.*; import javax.swing.*; public class ChartDemo extends JPanel { public static final int WIDTH = 400,HEIGHT = 300;// Initial values private final int NSELLERS = 5; private final int MAXSALES = 6000; // Max quarter sales private final double SCALE = 0.75; // Scale factor private double quarter1[] = {1099.85, 2105.86, 3105.25, 987.20, 5000.45}; private double quarter2[] = {2199.85, 3105.86, 2805.25, 1500.20, 6250.95}; public ChartDemo() { setSize(WIDTH, HEIGHT); } } // ChartDemo Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Sales data stored in arrays. Chapter 10: Graphics ChartDemo.paintComponent() Proportional to panel size. Drawing methods need Graphics. Bar chart origin in lower-left corner. public void paintComponent( Graphics g ) { Dimension size = this.getSize(); g.setColor(getBackground()); g.fillRect(0, 0, size.width, size.height); // Clear panel g.translate(size.height / 20, size.height - size.height / 20); drawBarChart(g); int pieSize = Math.min(size.width, size.height) / 3; int barWidth = size.width / 40; g.translate(NSELLERS * 4 * barWidth, -pieSize); drawPieChart(g, pieSize); } // paintComponent() Pie chart origin to the right and up Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics ChartDemo.drawBarChart() Local variables. public void drawBarChart(Graphics g) { Dimension size = this.getSize(); int maxBar = (int)(SCALE * size.height); // Size of tallest bar int barWidth = size.width / 40; // Width of bars int hGap = size.width / 60; // Gap between bars g.drawLine(0, 0, NSELLERS * (2 * barWidth + hGap), 0); // x-axis Reference point for each bar. int href = 0; for (int k = 0; k < NSELLERS; k++ ) { // For each seller int hgt = (int)(maxBar * quarter1[k] / MAXSALES); // q1 sales g.setColor(Color.black); g.drawString( k+1 + "", href + 5, 13); // Label the chart g.fillRect(href, -hgt, barWidth, hgt); hgt = (int)(maxBar * quarter2[k] / MAXSALES); // H of q2 sales href += barWidth; // Move reference point g.setColor(Color.darkGray); // Use 2nd color g.fillRect(href, -hgt, barWidth, hgt); href += barWidth + hGap; // Move reference pt } // for } // drawBarChart() Draw the bar. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Drawing Arcs • The pie chart uses the fillArc() method: fillArc(int x, int y, int width, int hgt, int startAngle, int arcAngle); Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics ChartDemo.drawPieChart() Local variables. public void drawPieChart(Graphics g, int pieSize) { double sumq2 = (int)total(quarter2); // Compute total sales int rgb = 0; Color color = null; int startAngle = 0; Reference point for each segment. for (int k = 0; k < NSELLERS; k++) { // For each seller color = new Color(rgb, rgb, rgb); // For grays r = g = b g.setColor(color); rgb += 32; // Lighten the color double percent = quarter2[k] / sumq2; // Percentage sales int currAngle = (int)Math.round(360 * percent);// Scale to 360 // Draw slice g.fillArc(0, 0, pieSize, pieSize, startAngle, currAngle); startAngle += currAngle; // Advance start angle } //for } // drawPieChart() Draw the arc. For grays, same number for RGB. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Fonts and FontMetrics • Each graphics context has an associated Font and FontMetrics object, accessible by: • A FontMetrics encapsulates font data -- e.g., height and width. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics The Font Class • The Font class provides a platformindependent representation of an individual font. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics The FontMetrics Class • The FontMetrics class has methods for calculating font sizes. Get the width of a character Get the font’s height. Or the width of a string. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics The FontNames Applet • Display the system’s built-in Fonts. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Implementation: FontNames • Display the system’s built-in Fonts. import java.awt.*; import javax.swing.*; public class FontNames extends JApplet { public void paint(Graphics g) { // Get the font names available in this graphics environment GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); String[] fonts = ge.getAvailableFontFamilyNames(); // Display hello world and font's name in the first 10 fonts Fonts are inherently platform dependent. int vRef = 30; int vGap = 15; g.drawString("The first 10 fonts on this system are: ", 30, vRef); for (int k = 0; k < 10; k++) { vRef += vGap; g.setFont(new Font(fonts[k], Font.PLAIN, 12)); g.drawString("Hello World! (" + fonts[k] + ")", 30, vRef); } } // paint() } // FontNames Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Example: Centering a Line of Text • Each time you resize the applet, it picks a different font and centers “Hello World!” Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Implementation: CenterText • For any font, center a string in the window. No matter what font the system gives us ... import java.awt.*; import javax.swing.*; public class CenterText extends JApplet { // Print hello world! in center of applet public void paint(Graphics g) { String str = "Hello World!"; g.setFont(new Font("Random", Font.PLAIN, 24)); // Random font FontMetrics metrics = g.getFontMetrics(); // Get its metrics Dimension d = getSize(); // Get the applet's size // Calculate coordinates int x = (d.width - metrics.stringWidth(str)) / 2; int y = (d.height + metrics.getHeight()) / 2; g.drawString( str, x, y ); // Draw the string } // paint() } // CenterText … use its metrics to center it. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Handling Mouse Events • There are two types of mouse events: mouse events and mouse motion events, each handled by its own listener interface. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Case Study: Interactive Painting • GUI Design Click the mouse here to clear the drawing. Draw within the rectangle by dragging the mouse. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics MousePaint: Object Oriented Design Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics The MousePaint Class (partial) These interfaces must be implemented. import import import public javax.swing.*; java.awt.*; java.awt.event.*; class MousePaint extends JPanel implements MouseListener, MouseMotionListener { private static final int WIDTH = 300, HEIGHT = 300; // Initial size private static final int LEFT = 10; // Reference points private static final int TOP = 10; private static final int BORDER = 30; private static final Color backColor = Color.gray; // Background private static final Color lineColor = Color.red; // Outline color private Point mouse = new Point(); // Mouse's current location public void paintComponent (Graphics g) { } public static void main(String args[]) { JFrame f = new JFrame("Drawing Window"); MousePaint mp = new MousePaint(); f.getContentPane().add(mp); f.setSize(mp.WIDTH, mp.HEIGHT); f.setVisible(true); } } // MousePaint Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Mouse’s location. // Top-level window // Drawing panel Chapter 10: Graphics Implementing the Listener Interfaces When the mouse is moved or dragged, just record its location and repaint the frame. public void mouseDragged(MouseEvent e) { // When the mouse is dragged mouse = e.getPoint(); // get its coordinates repaint(); } public void mouseClicked(MouseEvent e) { // When mouse is clicked mouse = e.getPoint(); // get its coordinates repaint(); } // These five interface methods are not used public void mouseEntered(MouseEvent e) { } // but must be implemented public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e){ } public void mouseMoved(MouseEvent e) { } Note the trivial body. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Repainting the Frame Use the mouse’s location to decide whether to draw or clear. public void paintComponent(Graphics g) { Dimension d = getSize(); g.setColor(lineColor); g.fillRect(0, 0, LEFT, TOP); // The clearing rectangle g.drawRect(LEFT, TOP, d.width - BORDER, d.height - BORDER); g.drawString("Drag to draw; Click the red rectangle to clear.", LEFT, d.height - 5); g.setColor(Color.black); // Set drawing color // If the mouse is in drawing area, draw a dot if ((mouse.x > LEFT) && (mouse.x < LEFT + d.width - BORDER) && (mouse.y > TOP) && (mouse.y < TOP + d.height - BORDER)) g.fillRect(mouse.x, mouse.y, 3, 3); // If the mouse is in clearing rectangle, clear the drawing if ((mouse.x < LEFT) && (mouse.y < TOP)) g.clearRect(LEFT + 1, TOP + 1, d.width - BORDER - 1, d.height - BORDER - 1); } // paintComponent() Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics OOD: Scalable CyberPet • Problem Statement: Design a CyberPet that permits members of its subclasses to be drawn in a variety of ways at a wide range of scales. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics The Drawable Interface • Effective Design: Each CyberPet subclass must implement its own draw method, so use an interface to define what we mean by drawable. import java.awt.*; /** * The Drawable interface defines two * graphical objects, the draw() and */ public interface Drawable { public abstract void draw(Graphics public abstract void fill(Graphics } // Drawable Java, Java, Java, 2E by R. Morelli methods used for drawing fill() methods. g); g); Copyright 2002. All rights reserved. Chapter 10: Graphics The Scalable Interface • A single method with a double parameter suffices to scale an object. /** * The Scalable interface defines the scale() method, which * is used to resize graphical objects. */ import java.awt.*; public interface Scalable { public abstract void scale(double ratio); } //Scalable If ratio > 1.0 the object grows. If ratio < 1.0 the object shrinks. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics The DrawablePet Class public class DrawablePet extends CyberPet implements Drawable, Scalable { protected int size = 30; // Default size = vertical radius of head protected Point location; // Top left corner of head public DrawablePet(String s, int radius, Point loc) { super(s); size = radius; location = loc; } Inheritable properties. public void setLocation(Point p) { location = p; } public Point getLocation() { return location; } public void draw( Graphics g ){ g.drawOval(location.x, location.y, 4 * size, 2 * size); // Head drawFace(g, location.x + 2 * size, location.y + size); drawJointedLegs(g, location.x + 2 * size, location.y + 2 * size, size /12); } // draw() Ratio is the scale factor. public void scale( double ratio ) { size = (int) (size * ratio); } // scale() public void fill(Graphics g) { } fill() is the similar to draw() } // DrawablePet Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Drawing the Face Reference for outline of head. Reference facial features, r = size Face features are relative to a single reference point, (x,y). private void drawFace(Graphics g, int x, int y ) { // x, y is center of head g.drawOval(x, y, size, size / 2); //Mouth g.drawOval(x - size / 2, y - size / 2, size / 2, size / 3); //Eye g.drawOval(x + size / 2, y - size / 2, size / 2, size / 3); //Eye } // drawFace() Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Drawing the Legs Legs are based on a formula. private int int int int for void drawJointedLegs(Graphics g, int x, int y, int lineWidth) { x1 = x - 2 * size; x2 = x - 3 * size / 2; x3 = x + 3 * size / 2; x4 = x + 2 * size; (int j = 0; j < lineWidth; j++) { // Loop to control width of legs for (int k = 1; k <= 4; k++) { // Draw 4 left, right pairs of legs int y2 = y - (2 - k) * size / 4; int y3 = y + k * size / 4; g.drawLine(x, y, x2, y2); //Left leg g.drawLine(x2, y2, x1, y3); Leg Knee joint End of g.drawLine(x, y, x3, y2); //Right leg 1 -r/4 r/4 g.drawLine(x3, y2, x4, y3); 2 0 2r/4 } y++; // Redraw line 1 pixel off to give width 3 r/4 3r/4 } } // drawJointedLegs() 4 r/2 r Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Leg Testing the DrawablePet import java.awt.*; import javax.swing.*; public class DrawablePetApplet extends JApplet { private DrawablePet pet; public void init() { setSize(400,400); Create } a DrawablePet, then move it and scale it. public void paint(Graphics g) { pet = new DrawablePet("Spidey", 60, new Point(50,10), Color.green); pet.sleep(); pet.setLocation( new Point(50, 10 ) ); pet.draw(g); pet.fill(g); pet.scale( 0.5 ); pet.eat(); pet.setLocation( new Point(100, 200 ) ); pet.draw(g); pet.scale( 0.5 ); pet.setLocation( new Point(300, 200 ) ); pet.draw(g); } } // DrawablePetApplet.java Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics DrawablePetApplet Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Effective Design • Generality and extensibility. Objects and methods should be designed to be as general and as extensible as possible. • Interfaces versus Classes. An interface should be used to implement a set of welldefined behaviors. An abstract superclass should be used when its subclasses must all inherit some shared behavior or state. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics In the Laboratory: SelfPortrait The objectives of this lab are: • To design a portrait of yourself which uses reference points in the same way they were used in the DrawablePet example. • To define a SelfPortrait class that implements the Drawable and Scalable interfaces and draws your self-portrait. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Self Portrait Lab: Problem Statement • Design a portrait of yourself that contains at least the following elements: a head, a face with eyes, nose, and mouth, a hat, some hair, and a torso wearing a sweater with your school's letter on it. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Problem Decomposition • Classes and Interfaces Needed – SelfPortrait class: contains the implementation of the Drawable and Scalable interfaces. Draws the portrait. – Drawable interface: defined earlier. – Scalable interface: defined earlier. – PortraitApplet or PortraitFrame: main program. Creates and tests instances of SelfPortrait. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Technical Terms • • • • • • • • • ascent baseline Cartesian coordinates clip region drawing mode graphics context histogram interface mouse events Java, Java, Java, 2E by R. Morelli • • • • • • • • mouse motion events multiple inheritance origin pixel RGB value scalable slope-intercept form XOR mode Copyright 2002. All rights reserved. Chapter 10: Graphics Summary Of Important Points • Graphics context:an instance of java.awt.Graphics provides drawing methods for each GUI component. • Unlike the Cartesian system, the Java origin, (0,0), is at the top-left corner. Each pixel has an x and y-coordinate, with x coordinates increasing from left to right and y coordinates increasing from top to bottom. • Graphics Properties: origin, color, font, drawing mode, and clip region. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Summary Of Important Points (cont) • RGB value: Colors are represented as a combination of red, green, and blue. • There are 13 predefined colors in the Color class. • Symbolic constant: a final variable should be used to define values that don’t change during drawing or painting. This is an example of the generality principle. • Drawn shapes are transparent while filled shapes are colored in the current Graphics color. • Graphics methods: drawing and filling a variety of shapes, including arcs, ovals, rectangles, lines, and polygons. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Summary Of Important Points (cont) • Graphics.translate(deltaH, deltaV): moves the origin by deltaH and deltaV pixels. • Graphing Equations: The direction of the y axis is reversed in Java's coordinate system. • fillArc(): useful for creating pie charts. • Scalable drawing: define all locations and dimensions relative to some fixed reference point. • Scalability: Use parameters! Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics Summary Of Important Points (cont) • FontMetrics class: used to obtain the dimensions of the specific Fonts. • Fonts are inherently platform dependent. • For maximum portability, use default fonts. • Scalability with a frame: Make the object’s dimensions relative to the frame size. • The MouseListener handles mouse clicks and MouseMotionListener handles mouse motion, including dragging. Java, Java, Java, 2E by R. Morelli Copyright 2002. All rights reserved. Chapter 10: Graphics