SpinnerSimpleDateModel

Here is the code for a JSpinnerModel that handles Date objects in simple format (e.g. ‘dd/MM/yyyy’). It extends a SpinnerDateModel so most of the code is based on that class. This class assumes that values are separated by a slash (/). The reason why I created this was based on a client’s requirement where I could only display the date in simple format and select the calendar using a JSpinner:

/**
 * A SpinnerSimpleDateModel for sequences of formatted Dates.
 * in simple format(e.g. "dd/MM/yyyy")
 *
 * @author William Mora
 * @version 1.0
 */
public class SpinnerSimpleDateModel extends SpinnerDateModel {

    private Comparable start, end;
    private Date value;
    private int calendarField;
    private SimpleDateFormat dateFormat;

    private boolean calendarFieldOK(int calendarField) {
        switch (calendarField) {
            case Calendar.DATE:
            case Calendar.YEAR:
            case Calendar.MONTH:
                return true;
            default:
                return false;
        }
    }

    /**
     * Creates an instance of SpinnerSimpleDateModel
     *
     * @param value         Initial date for the model
     * @param start         Minimum date for the model
     * @param end           Maximum date for the model
     * @param calendarField The interval desired for next and previous values.
     *                      The options are:
     *                      Calendar.DATE - Day of the month
     *                      Calendar.MONTH - Month
     *                      Calendar.YEAR - Year
     * @param dateFormat    A format specified by an instance of SimpleDateFormat
     */
    public SpinnerSimpleDateModel(Date value, Comparable start, Comparable end, int calendarField, SimpleDateFormat dateFormat) {
        this.dateFormat = dateFormat;
        if (value == null) {
            throw new IllegalArgumentException("value is null");
        }
        if (!calendarFieldOK(calendarField)) {
            throw new IllegalArgumentException("invalid calendarField");
        }
        if ( !(((start == null) || (start.compareTo(value) & lt;=0))&&
        ((end == null) || (end.compareTo(value) & gt;=0)))){
            throw new IllegalArgumentException("(start <= value <= end) is false");
        }
        this.value = value;
        this.start = start;
        this.end = end;
        this.calendarField = calendarField;
    }

    @Override
    public void setStart(Comparable start) {
        if ((start == null) ? (this.start != null) : !start.equals(this.start)) {
            this.start = start;
            fireStateChanged();
        }
    }

    @Override
    public void setEnd(Comparable end) {
        if ((end == null) ? (this.end != null) : !end.equals(this.end)) {
            this.end = end;
            fireStateChanged();
        }
    }

    @Override
    public void setCalendarField(int calendarField) {
        if (!calendarFieldOK(calendarField)) {
            throw new IllegalArgumentException("invalid calendarField");
        }
        if (calendarField != this.calendarField) {
            this.calendarField = calendarField;
            fireStateChanged();
        }
    }

    @Override
    public Comparable getEnd() {
        return end;
    }

    @Override
    public Object getNextValue() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(value);
        cal.add(calendarField, 1);
        Date next = cal.getTime();
        return (end == null) || (end.compareTo(next) & gt;=0)?next:
        null;
    }

    @Override
    public Object getPreviousValue() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(value);
        cal.add(calendarField, -1);
        Date prev = cal.getTime();
        return ((start == null) || (start.compareTo((prev)) <= 0)) ? prev : null;
    }

    @Override
    public Object getValue() {
        return value;
    }

    @Override
    public void setValue(Object value) {
        if (value == null) {
            throw new NullPointerException("Date is null!");
        } else {
            if ((value instanceof String) && ((String) value).matches("[0-9]+[/][0-9]+[/][0-9]+")) {
                String date = ((String) value);
                int day = Integer.parseInt(date.substring(0, 2));
                int month = Integer.parseInt(date.substring(3, 5));
                int year = Integer.parseInt(date.substring(6));
                Calendar cal = Calendar.getInstance();
                //Month-1 because is zero-based
                cal.set(year, month - 1, day);
                this.value = cal.getTime();
            }
            if (value instanceof Date) {
                if (!dateFormat.format((Date) value).equals(dateFormat.format(this.value))) {
                    String temp = dateFormat.format((Date) value);
                    this.setValue(temp);
                    fireStateChanged();
                }
            }
        }

    }
}

Now the model can be used for any JSpinner. To create an instance for this class, the following will work:

SpinnerSimpleDateModel spinnerModel = new SpinnerSimpleDateModel(new Date(), null, null, Calendar.DATE, new SimpleDateFormat("dd/MM/yyyy"));

Then, set the editor of the JSpinner object to show the same format specified for the SpinnerSimpleDateModel object like the following:

JSpinner spinner1 = new javax.swing.JSpinner();
spinner1.setModel(spinnerModel);
spinner1.setEditor(new javax.swing.JSpinner.DateEditor(spinner1, "dd/MM/yyyy"));

Hope someone finds this useful. An advantage of this is to manipulate date formats as you wish regardless of the OS or region.

Advertisements

Software developer. Currently working at MercadoLibre.com and other personal projects.

Posted in Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Error: Please make sure the Twitter account is public.

%d bloggers like this: