How do I write a simple analog clock using Java 2D?

Here is a simple Java code for an analog clock using Java 2D features in Swing.

Please adjust the code according to your needs. This code will create a new JFrame and continually update it every second with the current time.

package org.kodejava.swing;

import javax.swing.*;
import java.awt.*;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class AnalogClock extends JPanel {

    public AnalogClock() {
        setPreferredSize(new Dimension(400, 300));
        setBackground(Color.WHITE);
        new Timer(1000, e -> repaint()).start();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        int side = Math.min(getWidth(), getHeight());
        int centerX = getWidth() / 2;
        int centerY = getHeight() / 2;

        GregorianCalendar time = new GregorianCalendar();
        int second = time.get(Calendar.SECOND);
        int minute = time.get(Calendar.MINUTE);
        int hour = time.get(Calendar.HOUR_OF_DAY);

        drawHand(g2d, side/2 - 10, second / 60.0, 0.5f, Color.RED);
        drawHand(g2d, side/2 - 20, minute / 60.0, 2.0f, Color.BLUE);
        drawHand(g2d, side/2 - 40, hour / 12.0, 4.0f, Color.BLACK);

        // Draw clock numbers and circle
        drawClockFace(g2d, centerX, centerY, side/2 - 40);
    }

    private void drawHand(Graphics2D g2d, int length, double value, float stroke, Color color) {
        double angle = Math.PI * 2 * (value - 0.25);
        int endX = (int) (getWidth() / 2 + length * Math.cos(angle));
        int endY = (int) (getHeight() / 2 + length * Math.sin(angle));

        g2d.setColor(color);
        g2d.setStroke(new BasicStroke(stroke));
        g2d.drawLine(getWidth() / 2, getHeight() / 2, endX, endY);
    }

    // Added method to draw the clock face and numbers
    private void drawClockFace(Graphics2D g2d, int centerX, int centerY, int radius) {
        g2d.setStroke(new BasicStroke(2.0f));
        g2d.setColor(Color.BLACK);
        g2d.drawOval(centerX - radius, centerY - radius, 2 * radius, 2 * radius);

        for (int i = 1; i <= 12; i++) {
            double angle = Math.PI * 2 * (i / 12.0 - 0.25);
            int dx = centerX + (int) ((radius + 20) * Math.cos(angle));
            int dy = centerY + (int) ((radius + 20) * Math.sin(angle));

            g2d.drawString(Integer.toString(i), dx, dy);
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Analog Clock");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new AnalogClock());
        frame.pack();
        frame.setVisible(true);
    }
}

In this code, each “hand” of the clock is moved by calculating its angle according to the current time. The drawHand() method takes the length of the hand, the proportion of its rotation (for an hour hand, this would be the current hour divided by 12), the stroke width to draw with, and the color to draw, then calculates the end point of the hand line and draws it from the center of the clock.

The drawClockFace(), which draws a circle using the drawOval() method (because a circle is a type of oval), and adds numbers around the edge of the circle using the drawString() method. In both cases, the position of each element is calculated based on the sine and cosine of the angle that represents each hour on the clock face.

Analog Clock

Analog Clock

Note: Swing is an old but reliable technology that allows coding of GUI elements, however, it’s no longer actively developed. If you are developing a new project, consider using JavaFX as it is more modern and actively developed.

How do I draw a vertical text in Java 2D?

To draw a text / string vertically we need to do a transform on the Graphics2D object. First, create an instance of AffineTransform and set the rotation using the setToRotation() method. And then pass this transform object into g2.setTransform() method.

package org.kodejava.awt.geom;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;

public class DrawVerticalText extends JPanel {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setTitle("Draw Vertical Text Demo");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(new DrawVerticalText());
        frame.pack();
        frame.setSize(420, 350);
        frame.setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;

        // Define rendering hint, font name, font style and font size
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setFont(new Font("Segoe Script", Font.BOLD, 22));
        g2.setColor(Color.RED);

        // Rotate 90 degree to make a vertical text
        AffineTransform at = new AffineTransform();
        at.setToRotation(Math.toRadians(90), 80, 100);
        g2.setTransform(at);
        g2.drawString("This is a vertical text", 10, 10);
    }
}

Run the snippet, and you’ll see the following screen:

Draw 2D Vertical Text

Draw 2D Vertical Text

How do I draw a string in Java 2D?

The code snippet below show you how to draw a string using Graphics2D. The drawString() method accept the string to be drawn and their x and y coordinate. Here you can also see how to set the antialiasing mode using the setRenderingHint() method.

package org.kodejava.awt.geom;

import javax.swing.*;
import java.awt.*;

public class DrawString extends JPanel {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setTitle("Draw String Demo");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(new DrawString());
        frame.pack();
        frame.setSize(420, 300);
        frame.setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;

        // Define rendering hint, font name, font style and font size
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setFont(new Font("Segoe Script", Font.BOLD + Font.ITALIC, 40));
        g2.setPaint(Color.ORANGE);

        // Draw Hello World String
        g2.drawString("Hello World!", 50, 100);
    }
}

Run the snippet, and you’ll see the following screen:

Draw 2D String

Draw 2D String

How do I create a gradient paint in Java 2D?

To change the color of a graphics shape we can use the setPaint() method. For a simple coloring we can pass the color object into this method, such as Color.RED or Color.GREEN.

If you want to paint with a gradient paint you can use the GradientPaint class. This class provides a way to fill a shape with a linear color gradient pattern. To create a gradient color pattern you can pass the following parameter to the object constructor.

  • x1: x coordinate of the first specified point in user space
  • y1: y coordinate of the first specified point in user space
  • color1: color at the first specified point
  • x2: x coordinate of the second specified point in user space
  • y2: y coordinate of the second specified point in user space
  • color2: color at the second specified point
package org.kodejava.awt.geom;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;

public class GradientPaintDemo extends JComponent {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Gradient Paint Demo");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.getContentPane().add(new GradientPaintDemo());
        frame.pack();
        frame.setSize(new Dimension(420, 350));
        frame.setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;

        GradientPaint blackToGray = new GradientPaint(50, 50, Color.BLACK,
                300, 100, Color.LIGHT_GRAY);
        g2.setPaint(blackToGray);
        g2.fill(new Rectangle2D.Double(50, 50, 300, 100));

        GradientPaint blueToBlack = new GradientPaint(0, 0, Color.BLUE,
                400, 400, Color.BLACK);
        g2.setPaint(blueToBlack);
        g2.fill(new Rectangle2D.Double(50, 160, 300, 100));
    }
}

This code snippet produce the following output:

2D Gradient Paint Demo

2D Gradient Paint Demo

How do I define stroke when drawing a shape in Java 2D?

package org.kodejava.awt.geom;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Line2D;

public class DrawStrokeDemo extends JComponent {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Draw Stroke Demo");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.getContentPane().add(new DrawStrokeDemo());
        frame.pack();
        frame.setSize(new Dimension(420, 200));
        frame.setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;

        float[] strokes = {1, 2, 3, 4, 5, 6};
        for (float stroke : strokes) {
            g2.setStroke(new BasicStroke(stroke));
            g2.draw(new Line2D.Float(50, stroke * 20, 350, stroke * 20));
        }
    }
}

This code snippet produce the following output:

Draw 2D Stroke

Draw 2D Stroke