7. Using a JMonth Component - Expert Features

This section discusses features of a JMonth component that are rarely used but which may help fine-tune it in various contexts. All these features are managed by a month model and a week model.

7.1. Concepts: About Month Models

A MonthModel is used to configure basic properties of a month from the calendar. Such a model is not something that you will use very often, it is more for internal API use. The properties are:

  • Displayed month (month and year)

  • Names of the months (short: Jan, Feb, etc or long: January, February, etc)

The com.standbysoft.component.date.swing package provides a DefaultMonthModel that is the model used by default in all JMonth components. For extra functionality it is recommended that you extend the default model. Generally, this extra functionality is related to custom month names which is explained below.

7.2. Listening for Changes on Month Model

Listening for changes on the month model may be interesting when the displayed month changes. The following line of code registers an instance of MyMonthModelListener as a listener on the month's month model:

month.addMonthModelListener(new MyMonthModelListener());

Here's the implementation of MyMonthModelListener:

class MyMonthModelListener extends MonthModelAdapter {
  public void monthChanged(MonthModelEvent evt) {
    //your action here
  }
}

It extends MonthModelAdapter because we do not need to provide an implementation for all the methods of the interface.

7.3. Implementing a Month Model

As we said above, DefaultMonthModel is the default implementation for a MonthModel. It is not an exhaustive implementation and that is why you might want to create your own month model in certain circumstances.

For instance, the default model lets you specify the names of the months using a format (SHORT or LONG) and a locale. It won't let you set an array with the names of these months. To do that you can extend it and override getMonthNames to return the names that you see fit. The following lines show a custom month model that returns the month names in Latin:

/**
 * A month model with month names in Latin.
 */
public class LatinMonthModel extends DefaultMonthModel {
  /**
   * The month names in Latin.
   */
  private String[] names = {"Ianuarius", "Februarius", "Martius", "Aprilis", "Maius", "Iunius", "Iulius", "Augustus", "September", "October", "November", "December"};

  public String[] getMonthNames() {
    return names;
  }
}

7.4. Change the Displayed Month

As explained in the previous section, a month model let's you configure the month displayed by the JMonth that uses it. You can change it using directly the month model or using JMonth's wrapper methods. The following lines of code show how you can do that:

//use the component's API directly
month.setMonth(Calendar.JANUARY);
month.setYear(2004);

//use the component's supporting month model
month.getMonthModel().setMonth(Calendar.JANUARY);
month.getMonthModel().setYear(2004);

By displayed month we mean both the month of the year (January, February, etc) and the year. You might want to specify the displayed month by using the API to make it easier for the user. For instance, if the user must return an object in two months from today just scroll the month from the API instead of putting this burden on the user.

7.5. Enabling Week Selections

By week selections we mean the possibility to select a week and/or a day of week, Tuesday for instance. These selections are handled by the WeekModel which is discussed below.

As a user, selecting a week means clicking on its number. Selecting a day of week means clicking on its label. But for a JMonth this is possible only if these operations are enabled. The following code shows how you can enable a JMonth component to select a day of week or a week when their labels are clicked:

JMonth month = new JMonth();

//enable day of week selection. when a dow label is clicked, the respective day is selected
month.setDowSelectionAllowed(true);

//enable week selection. when a week label is clicked, the respective day is selected
month.setWeekSelectionAllowed(true);

//when set to TRUE, the selected week and day of week are highlighted to appear selected
month.putClientProperty("JMonth.isWeekLabelsHighlighted", Boolean.TRUE);

The How to Configure UI Delegates API section explains why we use client properties to configure the components.

7.6. Concepts: About Week Models

Just as a MonthModel, a WeekModel is something that you as developer will rarely use. But it is there for all those finely week-related adjustments that you would want to make. Such a model is represented by the WeekModel interface which handles week settings that are needed by a JMonth component. These settings are:

  • First day of week

  • Names of the days of week (Sunday, Monday, etc)

  • Selected day of week

  • Selected week of year

A JMonth selects a day of week or a week when their labels are clicked. The names are used to paint the labels for the days of week and the first day of week is used to determine when the week starts.

The com.standbysoft.component.date.swing package provides a DefaultWeekModel that is the week model used by default in all JMonth components. For extra functionality it is recommended that you extend the default model. Generally, this extra functionality is related to custom days names which is explained below.

7.7. Listening for Changes on Week Model

Listening for changes on the week model may be interesting when the selection of the week day or week changes.

The WeekDemo program uses a week model listener to display a message when the selected day of week or week changes. The following line of code registers an instance of MyWeekModelListener as a listener on the month's week model:

month.addWeekModelListener(new MyWeekModelListener());

Here's the implementation of MyWeekModelListener:

class MyWeekModelListener extends WeekModelAdapter {
  private JTextArea messageArea;

  private JMonth month;

  public MyWeekModelListener(JTextArea messageArea, JMonth month) {
    this.messageArea = messageArea;
    this.month = month;
  }

  public void selectedDowChanged(WeekModelEvent evt) {
    messageArea.append("New selected dow: " + month.getWeekModel().getSelectedDow() + "\n");
  }

  public void selectedWeekChanged(WeekModelEvent evt) {
    messageArea.append("New selected week: " + month.getWeekModel().getSelectedWeek() + "/" + month.getWeekModel().getSelectedYear() + "\n");
  }
}

It extends WeekModelAdapter because we do not need to provide an implementation for all the methods of the interface.

7.8. Implementing a Week Model

As we said above, DefaultWeekModel is the default implementation for a WeekModel. It is not an exhaustive implementation and that is why you might want to create your own week model in certain circumstances.

For instance, the default model lets you specify the names of the week days using a format (SHORT or LONG) and a locale. It won't let you set an array with the names of these days. To do that you can extend it and override getDowNames to return the names that you see fit. Click here to see a custom week model that returns the week days names in Latin.

Another reason for creating your own model might be to modify the selection behavior. A JMonth component uses its week model to select a week when its number is clicked. In some application if the same number is clicked twice that might be interpreted as a deselection. But this is not JMonth's problem.

To obtain this behavior you might extend the default model so that when the same week is selected twice, it should be interpreted as a deselection. Click here to see a custom week model that toggles the selection of week or week days.

7.9. Specify when the Week Starts

As explained in the previous section, a week model let's you configure the first day of week of a JMonth. You can change it using the week model or using the JMonth's wrapper method. The following lines of code show how you can do that:

//use the component's API directly
month.setDowFirst(Calendar.MONDAY);

//use the component's supporting week model
month.getWeekModel().setDowFirst(Calendar.MONDAY);

The first day of week is one of the things that change when a new locale is chosen. But sometimes, this change may not be what you want, so we have added the possibility of explicitly specify this property.

7.10. Using ISO week numbers

The ISO 8601 standard defines the numeric representations of date and time which includes information on how the weeks are numbered. The standard defines the week 01 of a year as the first week that has the Thursday in this year, which is equivalent to the week that contains the fourth day of January. In other words, the first week of a new year is the week that has the majority of its days in the new year.

By default, a JMonth component displays its week numbers using the default java.util.Calendar information. But this might not be enough for people accustomed with the ISO format. The following lines of code show how you can configure a JMonth to use this format:

DefaultWeekModel model = new DefaultWeekModel();
model.setWeekNumberISOFormatEnabled(true);

month.setWeekModel(model);

Setting the weekNumberISOFormatEnabled to true, makes sure the minimal days in the first week is 4. It does not change the first day of week to Monday. If you are using a locale like France for instance, then the first day of week is automatically set to Monday.