Basic drawing
In this part of the Java 2D tutorial, we will do some basic drawing.
Points
The most simple graphics primitive is point. It is a single dot on the window. Interestingly, there is no method to draw a point in Java 2D. (Or I could not find it.) To draw a point, I used a drawLine() method. I used one point twice.
package points;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import javax.swing.JPanel;
import javax.swing.JFrame;
import java.util.Random;
public class Points extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.blue);
Dimension size = getSize();
Insets insets = getInsets();
int w = size.width - insets.left - insets.right;
int h = size.height - insets.top - insets.bottom;
Random r = new Random();
for (int i=0; i<1000; i++) {
int x = Math.abs(r.nextInt()) % w;
int y = Math.abs(r.nextInt()) % h;
g2d.drawLine(x, y, x, y);
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Points");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Points());
frame.setSize(250, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
One point is difficult to observe. Why not paint 1000 of them? In our example, we do so. We draw 1000 blue points on the panel.
g2d.setColor(Color.blue);
We will paint our points in blue color.
Dimension size = getSize(); Insets insets = getInsets();
The size of the window includes borders and titlebar. We don't paint there.
int w = size.width - insets.left - insets.right; int h = size.height - insets.top - insets.bottom;
Here we calculate the area, where we will effectively paint our points.
Random r = new Random(); int x = Math.abs(r.nextInt()) % w; int y = Math.abs(r.nextInt()) % h;
We get a random number in range of the size of area, that we computed above.
g2d.drawLine(x, y, x, y);
Here we draw the point. As I already said, we use a drawLine() method. We specify the same point twice.
Lines
A line is a simple graphics primitive. To draw a line, we use the drawLine() method.
package com.zetcode;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Lines extends JFrame {
int coords[][];
int count;
public Lines() {
initUI();
}
public final void initUI() {
coords = new int[100][2];
count = 0;
JPanel panel = new JPanel();
panel.setLayout(null);
setTitle("Lines");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300, 200);
setLocationRelativeTo(null);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent event) {
if (event.getButton() == MouseEvent.BUTTON1) {
int x = event.getX();
int y = event.getY();
coords[count][0] = x;
coords[count][1] = y;
count++;
}
if (event.getButton() == MouseEvent.BUTTON3) {
drawLines();
count = 0;
}
}
});
}
public void drawLines() {
Graphics g = this.getGraphics();
Graphics2D g2d = (Graphics2D) g;
int w = getWidth();
int h = getHeight();
RenderingHints rh =
new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
rh.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHints(rh);
g2d.clearRect(0, 0, w, h);
for (int i = 0; i < count - 1; i++) {
for (int j = 0; j < count - 1; j++) {
g2d.drawLine(coords[i][0], coords[i][1],
coords[j][0], coords[j][1]);
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Lines lns = new Lines();
lns.setVisible(true);
}
});
}
}
In our example, we will draw a lot of lines. Click a lot on the panel with the left mouse button. After that, click with a right button. Each of the dots where you clicked will be connected with other dots. This way we create a complex structure.
BasicStroke
The BasicStroke class defines a basic set of rendering attributes for the outlines of graphics primitives. These rendering attributes include width, end caps, line joins, miter limit and dash attributes.
import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BasicStrokes extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
float[] dash1 = { 2f, 0f, 2f };
float[] dash2 = { 1f, 1f, 1f };
float[] dash3 = { 4f, 0f, 2f };
float[] dash4 = { 4f, 4f, 1f };
g2d.drawLine(20, 40, 250, 40);
BasicStroke bs1 = new BasicStroke(1, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND, 1.0f, dash1, 2f );
BasicStroke bs2 = new BasicStroke(1, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND, 1.0f, dash2, 2f );
BasicStroke bs3 = new BasicStroke(1, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND, 1.0f, dash3, 2f );
BasicStroke bs4 = new BasicStroke(1, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND, 1.0f, dash4, 2f );
g2d.setStroke(bs1);
g2d.drawLine(20, 80, 250, 80);
g2d.setStroke(bs2);
g2d.drawLine(20, 120, 250, 120);
g2d.setStroke(bs3);
g2d.drawLine(20, 160, 250, 160);
g2d.setStroke(bs4);
g2d.drawLine(20, 200, 250, 200);
}
public static void main(String[] args) {
JFrame frame = new JFrame("BasicStroke");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new BasicStroke());
frame.setSize(280, 270);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
In this example, we show various types of dashes. A dash attribute is a pattern, which is created by mixing opaque and transparent sections.
float[] dash1 = { 2f, 0f, 2f };
float[] dash2 = { 1f, 1f, 1f };
float[] dash3 = { 4f, 0f, 2f };
float[] dash4 = { 4f, 4f, 1f };
Here we define four different dash patterns.
BasicStroke bs1 = new BasicStroke(1, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND, 1.0f, dash1, 2f );
Construction of a typical BasicStroke object.
g2d.setStroke(bs1);
We use the setStroke() method to apply the BasicStroke to the current graphics context.
g2d.drawLine(20, 80, 250, 80);
Finally, we draw the line.
Caps
Caps are decorations applied to the ends of unclosed subpaths and dash segments. There are three different end caps in Java 2D. CAP_BUTT, CAP_ROUND, and CAP_SQUARE.
package com.zetcode.caps;
import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Caps extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
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(8, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_BEVEL);
g2d.setStroke(bs1);
g2d.drawLine(20, 30, 250, 30);
BasicStroke bs2 = new BasicStroke(8, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_BEVEL);
g2d.setStroke(bs2);
g2d.drawLine(20, 80, 250, 80);
BasicStroke bs3 = new BasicStroke(8, BasicStroke.CAP_SQUARE,
BasicStroke.JOIN_BEVEL);
g2d.setStroke(bs3);
g2d.drawLine(20, 130, 250, 130);
BasicStroke bs4 = new BasicStroke();
g2d.setStroke(bs4);
g2d.drawLine(20, 20, 20, 140);
g2d.drawLine(250, 20, 250, 140);
g2d.drawLine(254, 20, 254, 140);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Caps");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Caps());
frame.setSize(300, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
In our example, we show all three types of end caps.
g2d.drawLine(20, 20, 20, 140); g2d.drawLine(250, 20, 250, 140); g2d.drawLine(254, 20, 254, 140);
We draw three vertical lines to explain the differences among the end caps. Lines with CAP_ROUND and CAP_SQUARE are bigger than the line with CAP_BUT. Exactly how much bigger depends on the line size. In our case a line is 8px thick. Lines are bigger by 8px, 4px on the left and 4px on the right. It is clear from the picture.
Joins
Line joins are decorations applied at the intersection of two path segments and at the intersection of the endpoints of a subpath. There are three decorations are. JOIN_BEVEL, JOIN_MITER, and JOIN_ROUND.
package com.zetcode.joins;
import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Joins extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
BasicStroke bs1 = new BasicStroke(8, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_BEVEL);
g2d.setStroke(bs1);
g2d.drawRect(15, 15, 80, 50);
BasicStroke bs2 = new BasicStroke(8, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_MITER);
g2d.setStroke(bs2);
g2d.drawRect(125, 15, 80, 50);
BasicStroke bs3 = new BasicStroke(8, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND);
g2d.setStroke(bs3);
g2d.drawRect(235, 15, 80, 50);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Joins");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Joins());
frame.setSize(340, 110);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
This code example show three different line joins in action.
BasicStroke bs1 = new BasicStroke(8, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_BEVEL);
g2d.setStroke(bs1);
g2d.drawRect(15, 15, 80, 50);
Here we create a rectangle with a JOIN_BEVEL join.
In this part of the Java 2D tutorial, we did some basic drawing.