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 read a file line by line using Java NIO?

The java.nio.file.Files.lines() method is a Java NIO method used to read the contents of a file line by line. The code snippet will read the file from the specified filePath and print each line to the console. The Files.lines() method returns a Stream of strings, and we use Stream’s forEach method to print each line.

Note that we are using a try-with-resources statement which will automatically close the stream after we are done with it, it’s a good practice to always close streams to free-up system resources.

Here’s a basic example of how you can use it.

package org.kodejava.io;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;
import java.util.stream.Stream;

public class ReadFile {
    public static void main(String[] args) {
        // replace with your file path
        String filePath = "/Users/wayan/lipsum.txt";

        // read file into stream, try-with-resources
        try (Stream<String> stream = Files.lines(Paths.get(filePath))) {

            stream.map(String::trim)
                    .forEach(System.out::println);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

The Files.lines() method, along with other Java I/O and NIO methods, provide several important benefits and features:

  1. Memory Efficiency: This method reads the file line by line lazily, which means it doesn’t load the entire content of the file into memory. This is particularly useful when dealing with large files that could potentially exhaust system memory.
  2. Stream API Integration: The method returns a Stream<String>, it can naturally integrate with Java Stream API. This allows you to take advantage of powerful functions provided by Stream API such as filtering, mapping, reduction, etc., to process the file data effectively.
  3. Readability: Using Files.lines() with a try-with-resources construct results in more compact and readable code compared to older methods such as BufferedReader. The try-with-resources statement ensures that each resource is closed at the end of the statement, which can simplify cleanup code and avoid resource leaks.
  4. Exceptions Handling: I/O operations can generally throw IOException which are checked Exceptions in Java. Using Files.lines() within a try-with-resources statement ensures that any underlying resources are closed properly, even in the event of an Exception.
  5. Parallel Processing: Since Files.lines() method returns a Stream<String>, you can convert this stream into a parallel stream if you want to process the file with multithreading.

Remember, like with many programming choices, whether to use Files.lines() or another method depends on the specific needs and constraints of your project.

How do I get the number of processors available to the JVM?

The Runtime.getRuntime().availableProcessors() method returns the maximum number of processors available to the Java virtual machine, the value will never be smaller than one. Knowing the number of available processor you can use it for example to limit the number of thread in your application when you are writing a multi-thread code.

package org.kodejava.lang;

public class NumberProcessorExample {
    public static void main(String[] args) {
        final int processors = Runtime.getRuntime().availableProcessors();
        System.out.println("Number of processors = " + processors);
    }
}

Running the code snippet give you something like:

Number of processors = 8

How do I create a generic class in Java?

In this example you will learn how to create a generic class in Java. In some previous post in this blog you might have read how to use generic for working with Java collection API such as List, Set and Map. Now it is time to learn to create a simple generic class.

As an example in this post will create a class called GenericMachine and we can plug different type of engine into this machine that will be use by the machine to operate. For this demo we will create two engine type, a DieselEngine and a JetEngine. So let’s see how the classes are implemented in generic.

package org.kodejava.generics;

public class GenericMachine<T> {
    private final T engine;

    public GenericMachine(T engine) {
        this.engine = engine;
    }

    public static void main(String[] args) {
        // Creates a generic machine with diesel engine.
        GenericMachine<DieselEngine> machine = new GenericMachine<>(new DieselEngine());
        machine.start();

        // Creates another generic machine with jet engine.
        GenericMachine<JetEngine> anotherMachine = new GenericMachine<>(new JetEngine());
        anotherMachine.start();
    }

    private void start() {
        System.out.println("This machine running on: " + engine);
    }
}

Now, for the two engine class we will only create an empty class so that the GenericMachine class can be compiled successfully. And here are the engine classes:

package org.kodejava.generics;

public class DieselEngine {
}
package org.kodejava.generics;

public class JetEngine {
}

The <T> in the class declaration tell that we want the GenericMachine class to have type parameter. We also use the T type parameter at the class constructor to pass the engine.

How do I set the time of java.util.Date instance to 00:00:00?

The following code snippet shows you how to remove time information from the java.util.Date object. The static method removeTime() in the code snippet below will take a Date object as parameter and will return a new Date object where the hour, minute, second and millisecond information hasbeen reset to zero. To do this, we use the java.util.Calendar. To remove time information, we set the calendar fields of Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND and Calendar.MILLISECOND to zero.

package org.kodejava.util;

import java.util.Calendar;
import java.util.Date;

public class DateRemoveTime {
    public static void main(String[] args) {
        System.out.println("Now = " + removeTime(new Date()));
    }

    private static Date removeTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }
}

The result of the code snippet above is:

Now = Sat Nov 20 00:00:00 CST 2021

In the above code:

  1. An instance of Calendar is created using Calendar.getInstance().
  2. We set the Calendar time using setTime() method and pass the date object.
  3. The time fields (HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND) are set to zero. Calendar.HOUR_OF_DAY is used for 24-hour clock.
  4. The resulting Calendar instances time value is printed which should now represent the start of the day.