Title: BasicStroke
Course: CPS 261: Advanced Java Concepts ~ DL & MM MASTER

Graphics2D class

For all of our drawing in cps261 we have so far restricted ourselves to the Graphics class for simplicity. However, there are more sophisticated drawing features available in the Graphics2D class which extends the Graphics class. I have a series of notes and videos to cover some of these features:

- lines which are more than just a single pixel wide
- transformations (rotations, scaling, etc.)
- blending more than one picture together
- etc.

This is the beginning of a series of notes on the Graphics2D class and its related classes. I have tried to keep each set of notes focused on a smaller topic to keep the video lengths shorter than many of the other cps261 videos.

The ideas for this set of notes and many of the examples in this area have been inspired or somewhat lifted from a web site:

http://zetcode.com

I have reworked a lot of it, but in some of the examples it is clear that I borrowed a lot of code from the above website.

BasicStroke

Graphics2D - enhanced graphics which extends the Graphics class.

In the Graphics class we are limited to specifying coordinates as integer pixels. This results in a granular look when you look at curves, or even straight lines that are on an angle.

With Graphics2D, we can specify coordinates in terms of either floating point precision or double precision locations. It is OK to specify a location as 34.5678.

Note that real devices like screen monitors really only have pixels. However, with Graphics2D pixels can be shaded in such as way as to trick our eye into thinking we have better precision than we really have. If you desire to have your graphics smoothed out to look better to the eye, you can turn on "Rendering Hints".

In the first application below we will demonstrate the effect of "Rendering Hints".

I have a lot of examples using Graphics2D, and I have sometimes turned on the Rendering Hints and sometimes left them off. Feel free to experiment with these examples to see what difference it makes for a specific program.

When using the Graphics2D class we often make a copy of it and modify the copy. Then the copy is disposed.

Graphics2D g2d = (Graphics2D) g.create();

.....

g2d.dispose();

According to documentation: A copy must be created if we change attributes other than fonts, colors, or rendering hints. In this set of notes we will be changing the BasicStroke in our copy. I'm not sure I've seen the ramifications for violating this because I have tried out programs where I didn't make a copy.

In this set of notes we are going to take a look at the effect of creating a stroke from one of the following versions of the BasicStroke constructor.

BasicStroke() - Constructs a new BasicStroke with defaults for all attributes.

BasicStroke(float width) -Constructs a solid BasicStroke with the specified line width and with default values for the cap and join styles.

BasicStroke(float width, int cap, int join) -Constructs a solid BasicStroke with the specified attributes.

Basic_Stroke_1.java


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.JFrame;

public class Basic_Stroke_1 extends JFrame{
    Basic_Stroke_1()
    {
        setSize(600, 320);
        setTitle("Basic_Stroke_1");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    public void paint(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g.create();


        BasicStroke bs16 = new BasicStroke(16);
        g2d.setStroke(bs16);
        g2d.drawString("DEFAULT", 125,225);
        g2d.drawRect(125,250,80,50);



        g2d.drawString("JOIN_BEVEL", 15, 45);
        BasicStroke bs1 = new BasicStroke(16, BasicStroke.CAP_ROUND,
                BasicStroke.JOIN_BEVEL);
        g2d.setStroke(bs1);
        g2d.drawRect(15, 70, 80, 50);

        g2d.drawString("JOIN_MITER", 125, 45);
        BasicStroke bs2 = new BasicStroke(16, BasicStroke.CAP_ROUND,
                BasicStroke.JOIN_MITER);
        g2d.setStroke(bs2);
        g2d.drawRect(125, 70, 80, 50);

        g2d.drawString("JOIN_ROUND", 235, 45);
        BasicStroke bs3 = new BasicStroke(16, BasicStroke.CAP_ROUND,
                BasicStroke.JOIN_ROUND);
        g2d.setStroke(bs3);
        g2d.drawRect(235, 70, 80, 50);
        g2d.drawString("Without any Rendering Hints" , 340, 90);

        // Compare with default Basic Stroke
        g2d.setColor(Color.red);
        BasicStroke bs_default = new BasicStroke();
        g2d.setStroke(bs_default);

        // Redraw the above Rectangles with the default BasicStroke using red
        g2d.drawRect(15, 70, 80, 50);
        g2d.drawRect(125, 70, 80, 50);
        g2d.drawRect(235, 70, 80, 50);
        g2d.drawRect(125,250,80,50);



        // Now with Rendering Hints added

        RenderingHints rh = new RenderingHints(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        rh.put(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);

        g2d.setRenderingHints(rh);

        g2d.setColor(Color.black);
        g2d.setStroke(bs1);
        g2d.drawRect(15, 140, 80, 50);

        g2d.setStroke(bs2);
        g2d.drawRect(125, 140, 80, 50);

        g2d.setStroke(bs3);
        g2d.drawRect(235, 140, 80, 50);

        g2d.drawString("Rendering Hints Used" , 340, 160);

        // Compare with default Basic Stroke
        g2d.setColor(Color.red);
        g2d.setStroke(bs_default);

        // Redraw the 3 Rectangles using the default BasicStroke in the color red
        g2d.drawRect(15, 140, 80, 50);
        g2d.drawRect(125, 140, 80, 50);
        g2d.drawRect(235, 140, 80, 50);

        g2d.dispose();
    }

    public static void main(String[] args)
    {
        Basic_Stroke_1 bs1 = new Basic_Stroke_1();
    }

}






s

Basic_Stroke_2.java



import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.JFrame;

public class Basic_Stroke_2 extends JFrame{
    Basic_Stroke_2()
    {
        setSize(600, 420);
        setTitle("Basic_Stroke_2");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    public void paint(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g.create();

        RenderingHints rh = new RenderingHints(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        rh.put(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);

        g2d.setRenderingHints(rh);

        BasicStroke bs1 = new BasicStroke(32, BasicStroke.CAP_BUTT,
                BasicStroke.JOIN_BEVEL);
        g2d.setStroke(bs1);
        g2d.drawString("CAP_BUTT", 100, 70);
        g2d.drawLine(100, 90, 450, 90);

        BasicStroke bs2 = new BasicStroke(32, BasicStroke.CAP_ROUND,
                BasicStroke.JOIN_BEVEL);
        g2d.setStroke(bs2);
        g2d.drawString("CAP_ROUND", 100, 160);
        g2d.drawLine(100, 180, 450, 180);

        BasicStroke bs3 = new BasicStroke(32, BasicStroke.CAP_SQUARE,
                BasicStroke.JOIN_BEVEL);
        g2d.setStroke(bs3);
        g2d.drawString("CAP_SQUARE", 100, 250);
        g2d.drawLine(100, 270, 450, 270);

        BasicStroke bs_default_32 = new BasicStroke(32);
        g2d.setStroke(bs_default_32);
        g2d.drawString("Default-32", 100, 340);
        g2d.drawLine(100, 360, 450, 360);

        BasicStroke bs_default = new BasicStroke();
        g2d.setStroke(bs_default);
        g2d.setColor(Color.red);

        // Redraw the above lines again with default BasicStroke in red.
        g2d.drawLine(100, 90, 450, 90);
        g2d.drawLine(100, 180, 450, 180);
        g2d.drawLine(100, 270, 450, 270);
        g2d.drawLine(100, 360, 450, 360);

        // Draw some vertical lines to show what is going on
        g2d.drawLine(100, 20, 100, 440);
        g2d.drawLine(450, 20, 450, 440);
        g2d.drawLine(466, 20, 466, 440);

        g2d.dispose();
    }

    public static void main(String[] args)
    {
        Basic_Stroke_2 bs1 = new Basic_Stroke_2();
    }

}



Last Updated: June 20, 2015 10:50 AM