Graphics lecture

The basics

 

JPanel - do you remember this, what is it?

JPanels can draw, actually any Component can paint.

Has a repaint(Graphics g) method

Whenever the JPanel needs to draw the repaint method is called

When would that be?

You can cause the JPanel to repaint by calling JPanel.paintComponent().

 

The Graphics class, g, is your handle to drawing, you call its methods to draw something.

Drawings are made by using primitives: Line, Rectangle, Oval, Arc, Polygon, String

and setting the graphics rendering properties/graphics environment: Color, Font

 

Example method calls:

Primitives:

drawLine(int x1, int y1, int x2, int y2)

drawRect(int x, int y, int width, int height)

drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)

drawOval(int x, int y, int width, int height)

drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)

 

drawPolyline(int[] xPoints, int[] yPoints, int nPoints)

drawPolygon(int[] xPoints, int[] yPoints, int nPoints)

 

drawString(String str, int x, int y)

drawChars(char[] data, int offset, int length, int x, int y)

 

then there are fill versions, but there are no fillString()

 

Set rendering properties before you draw or fill:

            setColor(Color c)

setFont(Font font)

 

Coordinates:

Before you think that you know everything we should talk about origins

 x & y

x horizontal positive right

y vertical positive down <-

 

units are pixel

 

The component origin is upper left corner.

 

Painting

 

If you have a hierarchy of components in your JFrame then you should use

paintComponent(Graphics g), in other words your component overwrites the method:

 

protected void paintComponent(Graphics g){

super.paintComponent(g);

// now you have a Graphics, g, to paint with.

// Call the graphics methods.

}

 

Drawing order is last drawn on top.

 

 

Other paint methods:

 

void

paint(Graphics g)
          Invoked by Swing to draw components.

protected  void

paintBorder(Graphics g)
          Paints the component's border.

protected  void

paintChildren(Graphics g)
          Paints this component's children.

protected  void

paintComponent(Graphics g)
          Calls the UI delegate's paint method, if the UI delegate is non-null.

 void

paintImmediately(int x, int y, int w, int h)
          Paints the specified region in this component and all of its descendants that overlap the region, immediately.

 void

paintImmediately(Rectangle r)
          Paints the specified region now.

 

 


More topics:

 

Font

GraphicsEnvironment.getLocalGraphicsEnvironment - to get available fonts

getAllFonts method returns an array that contains Font

 

Java 2D™ defines the following five logical font families:

Dialog, DialogInput, Monospaced, Serif, SansSerif

Dialog is the default font

 

Font font = new Font("Dialog", Font.PLAIN, 12);

 

 

 

Font geometry - get from FontMetrics

 

FontMetrics metrics = graphics.getFontMetrics(font);

 

Ascent line

Base line

Descent line

This figure shows hot to measure text by using font metrics

 

Height = leading + Ascent + Descent

 

The standard leading, or interline spacing, is the logical amount of space to be reserved between the descent of one line of text and the ascent of the next line. The height metric is calculated to include this extra space.

 

get from FontMetrics, which you get from the graphics class:

 

FontMetrics metrics = graphics.getFontMetrics(font);

 

 

getAscent(), getLeading(), charWidth(char), charsWidth(char[], int, int)

 

Images

drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer)

 

ImageObsever is the component that will paint the image. So normally you give the Image to the Component that will draw it and use this for the ImageObserver.

 

The easiest way to create an Image.

Assume that you have a GIF, PNG, JPEG, BMP file of the image

(You made it using drawing software or you found the image.)

 

Use ImageIcon to read the file

ImageIcon(String filename)
          Creates an ImageIcon from the specified file.

ImageIcon(String filename, String description)
          Creates an ImageIcon from the specified file.

ImageIcon(URL location)
          Creates an ImageIcon from the specified URL.

 

Use ImageIcon to make the Image myImage = myImageIcon.getImage()

         

ImageIcon can be stretched but Image cannot.


More Material in Graphics2D

http://download-llnw.oracle.com/javase/tutorial/2d/

 

Graphics has only translate(int x, int y) to transform your drawings.

 

Graphics2D has access to AffineTransformations:

A 2D affine transform that performs a linear mapping from 2D coordinates to other 2D coordinates that preserves the "straightness" and "parallelness" of lines. Affine transformations can be constructed using sequences of translations, scales, flips, rotations, and shears.  The real reason for affine transformation is because they can be implemented using matrices.

 

Graphics has only setColor(), setXORMode(Color) which alternates pixels between the current color and a specified XOR color. 

 

Graphics2D has access to Paint interfaces that define how color patterns can be generated:

PaintContext, Color, GradientPaint, TexturePaint

 

Graphics only has only drawing on top for combining primitives.

 

Graphics2D has access to Shape and Area interfaces. Area allows you to subtract, intersect and add Areas to get more complex Areas and Shapes.

 

 

Graphics only draws Images

 

Graphics2D can draw BufferedImages

BufferedImages allows accessing parts of the image, Raster and the ColorModel

 

 

Examples:

1. Painting - MyGraphicsExample

MyFrame - getContentPane = DravingPanel

DrawingPanel

 

g.setColor(bg);

      g.fillRect(0, 0, panelW, panelH);

 

.... // need draw the background color first

 

Rectangle sb = fm.getStringBounds(title, g).getBounds();

int textHAbove=sb.height; // relative to base line

      int textHBelow=-sb.y; // relative to base line

      int textY = panelH-margin-textHBelow; //note y for drawString is base line

      int textW = sb.width;

int textX = (panelW-textW)/2;

 

.... // The above is very messy

 

g.setColor(fg);

      g.drawLine(pivotX, pivotY, bulbCX, bulbCY);

      g.fillOval(pivotX-pivotD/2, pivotY-pivotD/2, pivotD, pivotD);

      g.drawString(title,textX,textY);

      g.setColor(organge); // for some variation

g.fillOval(bulbCX-bulbD/2,bulbCY-bulbD/2,bulbD,bulbD);

 

2. Components - MyGraphicsExampleWithComponents

MyFrame - the same as with previous example

DrawingPanel

 

title.set(new Point((panelW-title.width())/2,

                  panelH-margin-title.height())

      );

     

      // set the pendulum

            pendulum.set(new Point(panelW/2, margin),0,

                  Math.min( panelW-2*margin,

            panelH-title.height()-3*margin-pendulum.bulbDiameter()/2)

      );

 

      // The above cleans up DrawingPanel

 

 

      // paint

      pendulum.repaint();

      title.repaint();

 

Pendulum is a JComponent

has Bulb a JComponent

and the string has angle Theta

 

 

      public void paintComponent(Graphics g){

            setBounds(this.getParent().getBounds()); // need properly locate children components.

            // Calculate bulb center

            Point bulbC = new Point(

                        pivot.x +                                                               (int)Math.rint(length*Math.sin(theta)),

                        pivot.y + (int)Math.rint(length*Math.cos(theta))

                        );

            bulb.set(bulbC);

            // draw line

            g.setColor(lineColor);

      g.drawLine(pivot.x, pivot.y, bulbC.x, bulbC.y);

      g.fillOval(pivot.x-pivotD/2, pivot.y-pivotD/2, pivotD, pivotD);

 

      bulb.repaint();

      }

 

Bulb is a JComponent

has a Point, diameter, and color

 

public void paintComponent(Graphics g){

            g.setColor(color);

            g.fillOval(0, 0, diameter, diameter);

      }