How do I create a simple annotation?

Metadata is a way to add some supplement information to the source code. This information is called annotation will not change how the program runs. This metadata can be used by other tools such as source code generator for instance to generate additional code at the runtime. Or it will be used by a dependency injection framework such as the Spring Framework.

The annotation can be attached to classes, methods, etc. To create an annotation we use the interface keyword and add an @ symbol in front of it. The @ symbol will tell the compiler that it is an annotation.

So now let us see the code for a simple annotation, a HelloAnnotation.

package org.kodejava.lang.annotation;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface HelloAnnotation {
    String value();

    String greetTo();
}

All annotations extend the java.lang.annotation.Annotation interface, which means that java.lang.annotation.Annotation is the super-interface of all annotations

An annotation need to have a RetentionPolicy that will be the scope of the annotation where at this point the annotation will be ignored or discarded. The values are RetentionPolicy.SOURCE, RetentionPolicy.CLASS and RetentionPolicy.RUNTIME. When no retention policy defined it will use the default retention policy which is the RetentionPolicy.CLASS.

Annotation with RetentionPolicy.SOURCE retention policy will be retained only in the source code, it is available to the compiler when it compiles the class and will be discarded after that. The RetentionPolicy.CLASS retention policy will make the annotation stored in the class file during compilation, but will not available during the runtime. And the RetentionPolicy.RUNTIME retention policy will store the annotation in the class file during compilation, and it is also available to JVM at runtime.

In the example above you also see that the HelloAnnotation have two members value() and greetTo(). Annotations only have method declaration in it with no implementation body.

How do I set mapped property value of a bean?

This example demonstrate how to use PropertyUtils.setMappedProperty() method to modify a Map typed property value of a bean. To set the property we need to pass bean instance, property name, map key and map value to PropertyUtils.setMappedProperty() method.

package org.kodejava.commons.beanutils;

import org.apache.commons.beanutils.PropertyUtils;
import org.kodejava.commons.beanutils.support.Track;
import org.kodejava.commons.beanutils.support.Record;

import java.util.HashMap;
import java.util.Map;

public class PropertySetMappedExample {

    public static void main(String[] args) {
        // Create an instance of Recording bean.
        Record record = new Record();
        record.setId(1L);
        record.setTitle("Introduction");

        // Create a map to hold record tracks.
        Map<String, Track> tracks = new HashMap<>();
        tracks.put("track-one", new Track());
        tracks.put("track-two", new Track());
        tracks.put("track-three", new Track());
        record.setMapTracks(tracks);

        try {
            // We add another tracks to the record track using
            // a PropertyUtils.setMappedProperty() method.
            PropertyUtils.setMappedProperty(record,
                    "mapTracks", "track-four", new Track());
            PropertyUtils.setMappedProperty(record,
                    "mapTracks", "track-five", new Track());
        } catch (Exception e) {
            e.printStackTrace();
        }

        tracks = record.getMapTracks();
        System.out.println("New Track Numbers: " + tracks.size());
        for (String key : tracks.keySet()) {
            System.out.println(key + " = " + tracks.get(key));
        }
    }
}

Maven Dependencies

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.4</version>
</dependency>

Maven Central

How do I set indexed property value of a bean?

In this example we show how to set the value of an indexed property. In the code below we modified the value of an array type. We’ll change the second colors of MyBean‘s colors property.

We do it in the same way as we are using the PropertyUtils.setSimpleProperty method. For indexed property we use the PropertyUtils.setIndexedProperty method and passes four arguments, they are the instance of bean to be manipulated, the indexed property name, the index to be changes and finally the new value.

package org.kodejava.commons.beanutils;

import org.apache.commons.beanutils.PropertyUtils;
import org.kodejava.commons.beanutils.support.MyBean;

import java.util.Arrays;

public class PropertySetIndexedExample {
    public static void main(String[] args) {
        String[] colors = new String[]{"red", "green", "blue"};

        MyBean myBean = new MyBean();
        myBean.setColors(colors);
        System.out.println("Colors = " + Arrays.toString(myBean.getColors()));

        try {
            PropertyUtils.setIndexedProperty(myBean, "colors", 1, "orange");
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("Colors = " + Arrays.toString(myBean.getColors()));
    }
}
package org.kodejava.commons.beanutils.support;

public class MyBean {
    private String[] colors;

    public void setColors(String[] colors) {
        this.colors = colors;
    }

    public String[] getColors() {
        return colors;
    }
}

The output of this code is:

Colors = [red, green, blue]
Colors = [red, orange, blue]

Maven Dependencies

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.4</version>
</dependency>

Maven Central

How do I set property value of a bean?

The Commons BeanUtils component provides a class called PropertyUtils that supplies method for manipulating a bean such as our Track class below. For this demo we use a Track class that have a property called id, title and duration.

To set the value of a bean we can use the PropertyUtils.setProperty() method. This method ask for the bean instance whose property value to be set, the property name and the value.

package org.kodejava.commons.beanutils;

import org.apache.commons.beanutils.PropertyUtils;
import org.kodejava.commons.beanutils.support.Track;

public class PropertySetExample {
    public static void main(String[] args) {
        Track track = new Track();
        try {
            PropertyUtils.setProperty(track, "id", 10L);
            PropertyUtils.setProperty(track, "title", "Hey Jude");
            PropertyUtils.setProperty(track, "duration", 180);
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("Track = " + track);
    }
}
package org.kodejava.commons.beanutils.support;

public class Track {
    private Long id;
    private String title;
    private Integer duration;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Integer getDuration() {
        return duration;
    }

    public void setDuration(Integer duration) {
        this.duration = duration;
    }

    @Override
    public String toString() {
        return "Track{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", duration=" + duration +
                '}';
    }
}

Some exceptions could be thrown by this method, so we need to handle the IllegalAccessException, InvocationAccessException and NoSuchMethodException. To make the code simple we will just catch it as java.lang.Exception.

These exceptions could happen if we don’t have access to the property, or the bean’s accessor throws an exception or if the method we tried to manipulate doesn’t exist.

Maven Dependencies

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.4</version>
</dependency>

Maven Central

How do I create JSpinner component with hour value?

This example shows you how to create a JSpinner that allow you to select an hour value. As the spinner model we are using the SpinnerDateModel and set the calendar field to Calendar.HOUR_OF_DAY.

To correctly display the hour value on the spinner we also change the formatter of the spinner’s text field using SimpleDateFormatter class.

package org.kodejava.swing;

import javax.swing.*;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.DateFormatter;
import java.awt.*;
import java.util.Date;
import java.util.Calendar;
import java.text.SimpleDateFormat;

public class JSpinnerHour extends JFrame {
    public JSpinnerHour() {
        initializeUI();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(
                () -> new JSpinnerHour().setVisible(true));
    }

    private void initializeUI() {
        setSize(500, 500);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        // The following spinner model will have current date as its
        // value and using hour of day as the calendar field. The start
        // and end comparable has a null values which mean it doesn't
        // have minimum or maximum value.
        SpinnerDateModel model = new SpinnerDateModel(new Date(), null,
                null, Calendar.HOUR_OF_DAY);

        JSpinner spinner = new JSpinner(model);

        // Reformat the display of our spinner to show only the hour
        // and minute information part.
        JFormattedTextField textField =
                ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField();
        DefaultFormatterFactory dff =
                (DefaultFormatterFactory) textField.getFormatterFactory();
        DateFormatter formatter = (DateFormatter) dff.getDefaultFormatter();
        formatter.setFormat(new SimpleDateFormat("hh:mm a"));

        getContentPane().add(spinner, BorderLayout.NORTH);
    }
}