eu.schudt.javafx.controls.calendar.MonthView Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tiwulfx Show documentation
Show all versions of tiwulfx Show documentation
TiwulFX provides JavaFX custom components specially designed to work with java POJO object.
package eu.schudt.javafx.controls.calendar;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import java.text.DateFormat;
import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.Date;
/**
* Responsible for displaying the days of a month.
*
* @author Christian Schudt
*/
final class MonthView extends DatePane {
private static final String CSS_CALENDAR_MONTH_VIEW = "calendar-month-view";
private static final String CSS_CALENDAR_DAY_CURRENT_MONTH = "calendar-cell-current-month";
private static final String CSS_CALENDAR_DAY_OTHER_MONTH = "calendar-cell-other-month";
private static final String CSS_CALENDAR_TODAY = "calendar-cell-today";
private static final String CSS_CALENDAR_WEEKDAYS = "calendar-weekdays";
private static final String CSS_CALENDAR_WEEK_NUMBER = "calendar-week-number";
/**
* The number of days per week.
* I don't know if there is a culture with more or less than seven days per week, but theoretically {@link Calendar} allows it.
* This variable will correspond to the number of columns.
*/
private int numberOfDaysPerWeek;
/**
* Constructs the month view.
*
* @param calendarView The calendar view.
*/
public MonthView(final CalendarView calendarView) {
super(calendarView);
getStyleClass().add(CSS_CALENDAR_MONTH_VIEW);
// When the locale changed, update the weeks to the new locale.
calendarView.localeProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
updateContent();
}
});
// When the disabled week days change, update the days.
calendarView.getDisabledWeekdays().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
updateDays();
}
});
// When the disabled dates change, update the days.
calendarView.controllerProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
updateDays();
}
});
// When the disabled dates change, update the days.
calendarView.showWeeksProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
getChildren().clear();
buildContent();
updateContent();
}
});
}
/**
* {@inheritDoc}
*/
@Override
public void buildContent() {
Calendar calendar = calendarView.calendarProperty().get();
// get the maximum number of days in a week for this calendar.
numberOfDaysPerWeek = calendar.getMaximum(Calendar.DAY_OF_WEEK);
// get the maximum number of days a month could have.
int maxNumberOfDaysInMonth = calendar.getMaximum(Calendar.DAY_OF_MONTH);
// assume the first row has only 1 day, then distribute the rest among the remaining weeks and add the first week.
int numberOfRows = (int) Math.ceil((maxNumberOfDaysInMonth - 1) / (double) numberOfDaysPerWeek) + 1;
// remove all controls
getChildren().clear();
int colOffset = calendarView.getShowWeeks() ? 1 : 0;
if (calendarView.getShowWeeks()) {
Label empty = new Label();
empty.setMaxWidth(Double.MAX_VALUE);
empty.getStyleClass().add(CSS_CALENDAR_WEEKDAYS);
add(empty, 0, 0);
}
// iterate through the columns
for (int i = 0; i < numberOfDaysPerWeek; i++) {
Label label = new Label();
label.getStyleClass().add(CSS_CALENDAR_WEEKDAYS);
label.setMaxWidth(Double.MAX_VALUE);
label.setAlignment(Pos.CENTER);
add(label, i + colOffset, 0);
}
// iterate through the rows
for (int rowIndex = 0; rowIndex < numberOfRows; rowIndex++) {
if (calendarView.getShowWeeks()) {
Label label = new Label();
label.setMaxWidth(Double.MAX_VALUE);
label.setMaxHeight(Double.MAX_VALUE);
label.getStyleClass().add(CSS_CALENDAR_WEEK_NUMBER);
add(label, 0, rowIndex + 1);
}
// iterate through the columns
for (int colIndex = 0; colIndex < numberOfDaysPerWeek; colIndex++) {
final Button button = new Button();
button.setMaxWidth(Double.MAX_VALUE);
button.setMaxHeight(Double.MAX_VALUE);
GridPane.setVgrow(button, Priority.ALWAYS);
GridPane.setHgrow(button, Priority.ALWAYS);
button.setOnAction(new EventHandler() {
@Override
public void handle(ActionEvent actionEvent) {
calendarView.selectedDate.set((Date) button.getUserData());
}
});
// add the button, starting at second row.
add(button, colIndex + colOffset, rowIndex + 1);
}
}
}
/**
* {@inheritDoc}
*/
@Override
protected void updateContent() {
updateDays();
updateWeekNames();
}
/**
* Updates the days.
*/
private void updateDays() {
Calendar calendar = calendarView.getCalendar();
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL, calendarView.localeProperty().get());
dateFormat.setCalendar(calendarView.getCalendar());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// Set the calendar to the first day of the current month.
calendar.set(Calendar.DAY_OF_MONTH, 1);
int month = calendar.get(Calendar.MONTH);
Date tmp = calendar.getTime();
calendar.setTime(new Date());
int todayDay = calendar.get(Calendar.DATE);
int todayMonth = calendar.get(Calendar.MONTH);
int todayYear = calendar.get(Calendar.YEAR);
calendar.setTime(tmp);
// Set the calendar to the end of the previous month.
while (calendar.getFirstDayOfWeek() != calendar.get(Calendar.DAY_OF_WEEK)) {
calendar.add(Calendar.DAY_OF_MONTH, -1);
}
// Ignore the week day row and the week number column
for (int i = numberOfDaysPerWeek + (calendarView.getShowWeeks() ? 1 : 0); i < getChildren().size(); i++) {
final Date currentDate = calendar.getTime();
if (i % (numberOfDaysPerWeek + 1) == 0 && (calendarView.getShowWeeks())) {
Label label = (Label) getChildren().get(i);
label.setText(Integer.toString(calendar.get(Calendar.WEEK_OF_YEAR)));
} else {
Button control = (Button) getChildren().get(i);
control.setText(Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)));
control.setTooltip(new Tooltip(dateFormat.format(currentDate)));
boolean disabled = calendarView.getDisabledWeekdays().contains(calendar.get(Calendar.DAY_OF_WEEK));
if (calendarView.getController()!= null) {
disabled = !calendarView.getController().isEnabled(currentDate);
}
control.setDisable(disabled);
control.getStyleClass().remove(CSS_CALENDAR_DAY_CURRENT_MONTH);
control.getStyleClass().remove(CSS_CALENDAR_DAY_OTHER_MONTH);
control.getStyleClass().remove(CSS_CALENDAR_TODAY);
if (calendar.get(Calendar.MONTH) == month) {
control.getStyleClass().add(CSS_CALENDAR_DAY_CURRENT_MONTH);
} else {
control.getStyleClass().add(CSS_CALENDAR_DAY_OTHER_MONTH);
}
if (calendar.get(Calendar.YEAR) == todayYear && calendar.get(Calendar.MONTH) == todayMonth && calendar.get(Calendar.DATE) == todayDay) {
control.getStyleClass().add(CSS_CALENDAR_TODAY);
}
control.setUserData(calendar.getTime());
calendar.add(Calendar.DATE, 1);
}
}
// Restore original date
calendar.setTime(calendarView.calendarDate.get());
}
/**
* Updates the week names, when the locale changed.
*/
private void updateWeekNames() {
DateFormatSymbols dateFormatSymbols = new DateFormatSymbols(calendarView.localeProperty().get());
String[] weekDays = dateFormatSymbols.getShortWeekdays();
// Start with 1 instead of 0, since the first element in the array is empty.
for (int i = 1; i < weekDays.length; i++) {
// Get the first character only.
String shortWeekDay;
if (weekDays[i].length() == 2)
shortWeekDay = weekDays[i].substring(0, 2); // for Russian locale
else
shortWeekDay = weekDays[i].substring(0, 3); // other
// Shift the index according to the first day of week.
int j = i - calendarView.getCalendar().getFirstDayOfWeek();
if (j < 0) {
j += weekDays.length - 1;
}
Label label = (Label) getChildren().get(j + (calendarView.getShowWeeks() ? 1 : 0));
label.setText(shortWeekDay);
}
title.set(getDateFormat("MMMM yyyy").format(calendarView.getCalendar().getTime()));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy