/*
* TimeSelector.java - Copyright(c) 2014 Joe Pasqua
* Provided under the MIT License. See the LICENSE file for details.
* Created: Oct 19, 2014
*/
package org.noroomattheinn.fxextensions;
import java.util.Calendar;
import javafx.beans.property.ObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.ComboBox;
import org.noroomattheinn.utils.CalTime;
/**
* A UI Helper class for dealing with time selections. Times are represented by
* three combo boxes. The first lets you select the hour (1-12), the second lets
* you picked the minute (0-55 in 5 minute increments), and the last lets you
* select AM or PM.
*
* @author Joe Pasqua <joe at NoRoomAtTheInn dot org>
*/
public class TimeSelector {
final private ComboBox<String> hour;
final private ComboBox<String> min;
final private ComboBox<String> amPM;
private ObjectProperty<CalTime> prop;
/*==============================================================================
* ------- -------
* ------- Public Interface To This Class -------
* ------- -------
*============================================================================*/
/**
* Create a new instance given the underlying combo boxes.
* @param hour A combo box representing the hour
* @param min A combo box representing the minute
* @param amPM A combo box representing AM or PM
*/
public TimeSelector(ComboBox<String> hour, ComboBox<String> min, ComboBox<String> amPM) {
this.hour = hour; this.min = min; this.amPM = amPM;
}
/**
* Bind this TimeSelector bidirectionally to a property containing a CalTime.
* If the property changes then the UI will be updated to reflect that.
* If the UI changes, the property will be updated.
*
* @param prop
*/
public void bind(ObjectProperty<CalTime> prop) {
this.prop = prop;
this.hour.valueProperty().addListener(updateValue);
this.min.valueProperty().addListener(updateValue);
this.amPM.valueProperty().addListener(updateValue);
set(prop.get());
prop.addListener(new ChangeListener<CalTime>() {
@Override public void changed(ObservableValue ov, CalTime t, CalTime t1) {
set(t1); } });
}
/**
* Enable or disable the controls
* @param enable If true, enable. If false, disable
*/
public void enable(boolean enable) {
hour.setDisable(!enable);
min.setDisable(!enable);
amPM.setDisable(!enable);
}
/**
* Return the time as a composite integer
* @return An integer of the form: hhmm where hh is in the range 0-23
*/
public int getHoursAndMinutes() {
int h = Integer.valueOf(hour.getValue());
int m = Integer.valueOf(min.getValue());
if (amPM.getValue().equals("PM")) {
if (h != 12)
h = (h + 12) % 24;
} else { // It's AM
if (h == 12)
h = 0;
}
return h * 100 + m;
}
/**
* Update the selection given
* @param hhmm An integer representing a composite time of the form hhmm
* where hh is in the range 0-23
*/
public void setHoursAndMinutes(int hhmm) {
int hours = hhmm / 100;
int minutes = hhmm % 100;
minutes = (minutes/5) * 5;
boolean isPM = (hours >= 12);
if (hours == 0) {
hours = 12;
}
if (isPM && !(hours == 12))
hours -= 12;
hour.getSelectionModel().select(String.format("%02d", hours));
min.getSelectionModel().select(String.format("%02d", minutes));
amPM.getSelectionModel().select(isPM ? "PM" : "AM");
}
/*------------------------------------------------------------------------------
*
* Private Utility Methods
*
*----------------------------------------------------------------------------*/
private void set(CalTime c) {
hour.setValue(twoDigitString(c.get(Calendar.HOUR)));
min.setValue(twoDigitString((c.get(Calendar.MINUTE)/5)*5));
amPM.setValue(c.get(Calendar.AM_PM) == Calendar.AM ? "AM" : "PM");
}
private String twoDigitString(int val) { return String.format("%02d", val); };
private ChangeListener<String> updateValue = new ChangeListener<String>() {
@Override public void changed(
ObservableValue<? extends String> ov, String t, String t1) {
if (prop == null) return;
prop.set(new CalTime(hour.getValue(), min.getValue(), amPM.getValue()));
}
};
}