com.calendarfx.view.WeekView Maven / Gradle / Ivy
/*
* Copyright (C) 2017 Dirk Lemmermann Software & Consulting (dlsc.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.calendarfx.view;
import com.calendarfx.util.ViewHelper;
import impl.com.calendarfx.view.WeekViewSkin;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Bounds;
import javafx.scene.control.Skin;
import javafx.util.Callback;
import org.controlsfx.control.PropertySheet;
import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.util.Objects;
import java.util.Optional;
import static java.time.temporal.ChronoField.DAY_OF_WEEK;
import static java.util.Objects.requireNonNull;
/**
* A view for showing several week days in a row, normally seven. However the
* view can be configured to show any number of days. A factory is used to
* create instances of {@link WeekDayView} on the fly as needed. Another factory
* is required for creating the child control {@link AllDayView}. The image
* below shows the appearance of this view when it is embedded inside the
* {@link DetailedWeekView}.
*
*
*
*
*/
public class WeekView extends DayViewBase {
private static final String DEFAULT_STYLE_CLASS = "week-view";
/**
* Constructs a new week view with seven days.
*/
public WeekView() {
this(7);
}
/**
* Constructs a new week view with the given number of days.
*
* @param numberOfDays the number of days (day views)
*/
public WeekView(int numberOfDays) {
getStyleClass().add(DEFAULT_STYLE_CLASS);
setWeekDayViewFactory(param -> new WeekDayView());
setNumberOfDays(numberOfDays);
dateProperty().addListener(it -> updateStartAndEndDates());
updateStartAndEndDates();
}
@Override
protected Skin> createDefaultSkin() {
return new WeekViewSkin(this);
}
@Override
public ZonedDateTime getZonedDateTimeAt(double x, double y) {
final WeekDayView view = getWeekDayViewAt(x);
if (view != null) {
return ZonedDateTime.of(ViewHelper.getLocationTime(view, y, false, true), getZoneId());
}
return super.getZonedDateTimeAt(x, y);
}
private WeekDayView getWeekDayViewAt(double x) {
for (WeekDayView view : getWeekDayViews()) {
final Bounds bounds = view.getBoundsInParent();
if (bounds.getMinX() <= x && bounds.getMaxX() >= x) {
return view;
}
}
return null;
}
private final ObservableList weekDayViews = FXCollections.observableArrayList();
/**
* A list of the {@link WeekDayView} instances that the view created via the factory.
*
* @see #setWeekDayViewFactory(Callback)
*
* @return the currently used list of week day views (please note that this list is very volatile
* and will be updated very often.
*/
public final ObservableList getWeekDayViews() {
return weekDayViews;
}
private final IntegerProperty numberOfDays = new SimpleIntegerProperty(this, "numberOfDays", 7);
/**
* Stores the number of days that will be shown by this view. This value
* will be 1 if the view is used in combination with the {@link DayView} and
* 7 if used together with the {@link DetailedWeekView}.
*
* @return the number of days shown by the view
*/
public final IntegerProperty numberOfDaysProperty() {
return numberOfDays;
}
/**
* Returns the value of {@link #numberOfDaysProperty()}.
*
* @return the number of days shown by the view
*/
public final int getNumberOfDays() {
return numberOfDaysProperty().get();
}
/**
* Sets the value of {@link #numberOfDaysProperty()}.
*
* @param number the new number of days shown by the view
*/
public final void setNumberOfDays(int number) {
if (number < 1) {
throw new IllegalArgumentException("invalid number of days, must be larger than 0 but was "
+ number);
}
numberOfDaysProperty().set(number);
}
private final BooleanProperty adjustToFirstDayOfWeek = new SimpleBooleanProperty(this, "adjustToFirstDayOfWeek", true);
/**
* A flag used to indicate that the view should always show the first day of
* the week (e.g. "Monday") at its beginning even if the
* {@link #dateProperty()} is set to another day (e.g. "Thursday").
*
* @return true if the view always shows the first day of the week
*/
public final BooleanProperty adjustToFirstDayOfWeekProperty() {
return adjustToFirstDayOfWeek;
}
/**
* Returns the value of {@link #adjustToFirstDayOfWeekProperty()}.
*
* @return true if the view always shows the first day of the week
*/
public final boolean isAdjustToFirstDayOfWeek() {
return adjustToFirstDayOfWeekProperty().get();
}
/**
* Sets the value of {@link #adjustToFirstDayOfWeekProperty()}.
*
* @param adjust if true the view will always show the first day of the week
*/
public final void setAdjustToFirstDayOfWeek(boolean adjust) {
adjustToFirstDayOfWeekProperty().set(adjust);
}
/**
* The parameter object for the week day view factory.
*
* @see #weekDayViewFactoryProperty()
*/
public static final class WeekDayParameter {
private WeekView weekView;
/**
* Constructs a new parameter object.
*
* @param weekView the week view for which the week day view will be used
*/
public WeekDayParameter(WeekView weekView) {
this.weekView = Objects.requireNonNull(weekView);
}
/**
* Returns the week view where the day view will be used.
*
* @return the week view
*/
public WeekView getWeekView() {
return weekView;
}
}
private final ObjectProperty> weekDayViewFactory = new SimpleObjectProperty<>(this, "weekDayViewFactory");
/**
* A factory used for creating instances of {@link WeekDayView} on the fly
* as required.
*
* @return the week day view factory
*/
public final ObjectProperty> weekDayViewFactoryProperty() {
return weekDayViewFactory;
}
/**
* Returns the value of {@link #weekDayViewFactoryProperty()}.
*
* @return the week day view factory
*/
public final Callback getWeekDayViewFactory() {
return weekDayViewFactoryProperty().get();
}
/**
* Sets the value of {@link #weekDayViewFactoryProperty()}.
*
* @param factory the new factory
*/
public final void setWeekDayViewFactory(Callback factory) {
requireNonNull(factory);
weekDayViewFactoryProperty().set(factory);
}
private void updateStartAndEndDates() {
LocalDate date = calculateStartDate();
startDate.set(date);
endDate.set(date.plusDays(getNumberOfDays() - 1));
}
private LocalDate calculateStartDate() {
LocalDate startDate = getDate();
if (isAdjustToFirstDayOfWeek()) {
LocalDate newStartDate = startDate.with(DAY_OF_WEEK, getFirstDayOfWeek().getValue());
if (newStartDate.isAfter(startDate)) {
startDate = newStartDate.minusWeeks(1);
} else {
startDate = newStartDate;
}
}
return startDate;
}
private final ReadOnlyObjectWrapper startDate = new ReadOnlyObjectWrapper<>(this, "startDate");
/**
* The earliest date shown by the view.
*
* @return the earliest date shown
*/
public final ReadOnlyObjectProperty startDateProperty() {
return startDate;
}
/**
* Returns the value of {@link #startDateProperty()}.
*
* @return the earliest date shown
*/
public final LocalDate getStartDate() {
return startDate.get();
}
private final ReadOnlyObjectWrapper endDate = new ReadOnlyObjectWrapper<>(this, "endDate");
/**
* The latest date shown by the view.
*
* @return the latest date shown
*/
public final ReadOnlyObjectProperty endDateProperty() {
return endDate;
}
/**
* Returns the value of {@link #endDateProperty()}.
*
* @return the latest date shown
*/
public final LocalDate getEndDate() {
return endDate.get();
}
private static final String WEEK_VIEW_CATEGORY = "Week View";
@Override
public ObservableList getPropertySheetItems() {
ObservableList items = super.getPropertySheetItems();
items.add(new PropertySheet.Item() {
@Override
public Optional> getObservableValue() {
return Optional.of(numberOfDaysProperty());
}
@Override
public void setValue(Object value) {
setNumberOfDays((Integer) value);
}
@Override
public Object getValue() {
return getNumberOfDays();
}
@Override
public Class> getType() {
return Integer.class;
}
@Override
public String getName() {
return "Number of Days";
}
@Override
public String getDescription() {
return "Number of Days";
}
@Override
public String getCategory() {
return WEEK_VIEW_CATEGORY;
}
});
items.add(new PropertySheet.Item() {
@Override
public Optional> getObservableValue() {
return Optional.of(adjustToFirstDayOfWeekProperty());
}
@Override
public void setValue(Object value) {
setAdjustToFirstDayOfWeek((Boolean) value);
}
@Override
public Object getValue() {
return isAdjustToFirstDayOfWeek();
}
@Override
public Class> getType() {
return Boolean.class;
}
@Override
public String getName() {
return "Adjust to first day of week";
}
@Override
public String getDescription() {
return "Adjust to first day of week";
}
@Override
public String getCategory() {
return WEEK_VIEW_CATEGORY;
}
});
items.add(new PropertySheet.Item() {
@Override
public Optional> getObservableValue() {
return Optional.of(startDateProperty());
}
@Override
public void setValue(Object value) {
}
@Override
public Object getValue() {
return getStartDate();
}
@Override
public Class> getType() {
return LocalDate.class;
}
@Override
public String getName() {
return "Start date (read-only)";
}
@Override
public String getDescription() {
return "Start date (read-only)";
}
@Override
public String getCategory() {
return WEEK_VIEW_CATEGORY;
}
});
items.add(new PropertySheet.Item() {
@Override
public Optional> getObservableValue() {
return Optional.of(endDateProperty());
}
@Override
public void setValue(Object value) {
}
@Override
public Object getValue() {
return getEndDate();
}
@Override
public Class> getType() {
return LocalDate.class;
}
@Override
public String getName() {
return "End date (read-only)";
}
@Override
public String getDescription() {
return "End date (read-only)";
}
@Override
public String getCategory() {
return WEEK_VIEW_CATEGORY;
}
});
return items;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy