javafx日期控件

来源:互联网 发布:python绝技 pdf 中文 编辑:程序博客网 时间:2024/05/26 09:54

package com.taocares.naoms.client.model.common.custom.control;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;

import javafx.beans.NamedArg;
import javafx.beans.property.LongProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.control.SpinnerValueFactory;
import javafx.util.StringConverter;

public class LocalDateTimeSpinnerValueFactory extends SpinnerValueFactory{
/**
* Creates a new instance of the LocalDateSpinnerValueFactory, using the
* value returned by calling {@code LocalDate#now()} as the initial value,
* and using a stepping amount of one day.
*/
public LocalDateTimeSpinnerValueFactory() {
this(LocalDateTime.now());

}/** * Creates a new instance of the LocalDateSpinnerValueFactory, using the * provided initial value, and a stepping amount of one day. * * @param initialValue The value of the Spinner when first instantiated. */public LocalDateTimeSpinnerValueFactory(@NamedArg("initialValue") LocalDateTime initialValue) {    this(LocalDateTime.MIN, LocalDateTime.MAX, initialValue);}/** * Creates a new instance of the LocalDateSpinnerValueFactory, using the * provided initial value, and a stepping amount of one day. * * @param min The minimum allowed double value for the Spinner. * @param max The maximum allowed double value for the Spinner. * @param initialValue The value of the Spinner when first instantiated. */public LocalDateTimeSpinnerValueFactory(@NamedArg("min") LocalDateTime min,                                    @NamedArg("min") LocalDateTime max,                                    @NamedArg("initialValue") LocalDateTime initialValue) {    this(min, max, initialValue, 1, ChronoUnit.DAYS,"yyyy-MM-dd HH:mm:ss");}/** * Creates a new instance of the LocalDateSpinnerValueFactory, using the * provided min, max, and initial values, as well as the amount to step * by and {@link java.time.temporal.TemporalUnit}. * * <p>To better understand, here are a few examples: * * <ul> *     <li><strong>To step by one day from today: </strong> {@code new LocalDateSpinnerValueFactory(LocalDate.MIN, LocalDate.MAX, LocalDate.now(), 1, ChronoUnit.DAYS)}</li> *     <li><strong>To step by one month from today: </strong> {@code new LocalDateSpinnerValueFactory(LocalDate.MIN, LocalDate.MAX, LocalDate.now(), 1, ChronoUnit.MONTHS)}</li> *     <li><strong>To step by one year from today: </strong> {@code new LocalDateSpinnerValueFactory(LocalDate.MIN, LocalDate.MAX, LocalDate.now(), 1, ChronoUnit.YEARS)}</li> * </ul> * * @param min The minimum allowed double value for the Spinner. * @param max The maximum allowed double value for the Spinner. * @param initialValue The value of the Spinner when first instantiated. * @param amountToStepBy The amount to increment or decrement by, per step. * @param temporalUnit The size of each step (e.g. day, week, month, year, etc) */public LocalDateTimeSpinnerValueFactory(@NamedArg("min") LocalDateTime min,                                    @NamedArg("min") LocalDateTime max,                                    @NamedArg("initialValue") LocalDateTime initialValue,                                    @NamedArg("amountToStepBy") long amountToStepBy,                                    @NamedArg("temporalUnit") TemporalUnit temporalUnit,                                    @NamedArg("pattern") String pattern) {    setMin(min);    setMax(max);    setAmountToStepBy(amountToStepBy);    setTemporalUnit(temporalUnit);    setPattern(pattern);    setConverter(new StringConverter<LocalDateTime>() {        @Override public String toString(LocalDateTime object) {            if (object == null) {                return "";            }            DateTimeFormatter stf = DateTimeFormatter.ofPattern(getPattern());            return object.format(stf);        }        @Override public LocalDateTime fromString(String string) {            return LocalDateTime.parse(string);        }    });    valueProperty().addListener((o, oldValue, newValue) -> {        // when the value is set, we need to react to ensure it is a        // valid value (and if not, blow up appropriately)        if(newValue!=null){            if (getMin() != null && newValue.isBefore(getMin())) {                setValue(getMin());            } else if (getMax() != null && newValue.isAfter(getMax())) {                setValue(getMax());            }        }    });    setValue(initialValue != null ? initialValue : LocalDateTime.now());}/*********************************************************************** *                                                                     * * Properties                                                          * *                                                                     * **********************************************************************/// --- minprivate ObjectProperty<LocalDateTime> min = new SimpleObjectProperty<LocalDateTime>(this, "min") {    @Override protected void invalidated() {        LocalDateTime currentValue = LocalDateTimeSpinnerValueFactory.this.getValue();        if (currentValue == null) {            return;        }        final LocalDateTime newMin = get();        if (newMin.isAfter(getMax())) {            setMin(getMax());            return;        }        if (currentValue.isBefore(newMin)) {            LocalDateTimeSpinnerValueFactory.this.setValue(newMin);        }    }};public final void setMin(LocalDateTime value) {    min.set(value);}public final LocalDateTime getMin() {    return min.get();}/** * Sets the minimum allowable value for this value factory */public final ObjectProperty<LocalDateTime> minProperty() {    return min;}// --- maxprivate ObjectProperty<LocalDateTime> max = new SimpleObjectProperty<LocalDateTime>(this, "max") {    @Override protected void invalidated() {        LocalDateTime currentValue = LocalDateTimeSpinnerValueFactory.this.getValue();        if (currentValue == null) {            return;        }        final LocalDateTime newMax = get();        if (newMax.isBefore(getMin())) {            setMax(getMin());            return;        }        if (currentValue.isAfter(newMax)) {            LocalDateTimeSpinnerValueFactory.this.setValue(newMax);        }    }};public final void setMax(LocalDateTime value) {    max.set(value);}public final LocalDateTime getMax() {    return max.get();}/** * Sets the maximum allowable value for this value factory */public final ObjectProperty<LocalDateTime> maxProperty() {    return max;}// --- temporalUnitprivate ObjectProperty<TemporalUnit> temporalUnit = new SimpleObjectProperty<>(this, "temporalUnit");public final void setTemporalUnit(TemporalUnit value) {    temporalUnit.set(value);}public final TemporalUnit getTemporalUnit() {    return temporalUnit.get();}/** * The size of each step (e.g. day, week, month, year, etc). */public final ObjectProperty<TemporalUnit> temporalUnitProperty() {    return temporalUnit;}// --- amountToStepByprivate LongProperty amountToStepBy = new SimpleLongProperty(this, "amountToStepBy");public final void setAmountToStepBy(long value) {    amountToStepBy.set(value);}public final long getAmountToStepBy() {    return amountToStepBy.get();}/** * Sets the amount to increment or decrement by, per step. */public final LongProperty amountToStepByProperty() {    return amountToStepBy;}//---- patternprivate StringProperty pattern=new SimpleStringProperty(this, "pattern");public final void setPattern(String value){    pattern.setValue(value);}public final String getPattern(){    return pattern.get();}public final StringProperty patternProperty(){    return pattern;}/*********************************************************************** *                                                                     * * Overridden methods                                                  * *                                                                     * **********************************************************************//** {@inheritDoc} */@Override public void decrement(int steps) {    final LocalDateTime currentValue = getValue();    final LocalDateTime min = getMin();    if(currentValue==null){        setValue(LocalDateTime.now());        return;    }    LocalDateTime newValue = currentValue.minus(getAmountToStepBy() * steps, getTemporalUnit());    if (min != null && isWrapAround() && newValue.isBefore(min)) {        // we need to wrap around        newValue = getMax();    }    setValue(newValue);}/** {@inheritDoc} */@Override public void increment(int steps) {    final LocalDateTime currentValue = getValue();    final LocalDateTime max = getMax();    if(currentValue==null){        setValue(LocalDateTime.now());        return;    }    LocalDateTime newValue = currentValue.plus(getAmountToStepBy() * steps, getTemporalUnit());    if (max != null && isWrapAround() && newValue.isAfter(max)) {        // we need to wrap around        newValue = getMin();    }    setValue(newValue);}

}

package com.taocares.naoms.client.model.common.custom.control;

import java.time.temporal.ChronoUnit;

/**
* 时间控件 ENUM
*
* @author wxx
*
*/
public enum LocalDateTimeSpinnerCode {
YEARS(0, 4, 1, ChronoUnit.YEARS),
MONTHS(5, 7, 2, ChronoUnit.MONTHS),
DAYS(8, 10, 3, ChronoUnit.DAYS),
HOURS(11, 13, 4, ChronoUnit.HOURS),
MINUTES(14, 16, 5, ChronoUnit.MINUTES),
SECONDS(17, 19, 6, ChronoUnit.SECONDS);

private Integer start;private Integer end;private Integer index;private ChronoUnit chronoUnit;LocalDateTimeSpinnerCode(Integer start, Integer end, Integer index, ChronoUnit chronoUnit) {    this.start = start;    this.end = end;    this.index = index;    this.chronoUnit = chronoUnit;}/** * 根据Start获取对象 * * @param start * @return */public static LocalDateTimeSpinnerCode getCodeByStart(Integer start) {    for (LocalDateTimeSpinnerCode code : LocalDateTimeSpinnerCode.values()) {        if (code.getStart() <= start && code.getEnd() >= start) {            return code;        }    }    return null;}/** * 根据Index 获取对象 * @param index * @return */public static LocalDateTimeSpinnerCode getCodeByIndex(Integer index){    for (LocalDateTimeSpinnerCode code : LocalDateTimeSpinnerCode.values()) {        if (code.getIndex()==index) {            return code;        }    }    return null;}public Integer getStart() {    return start;}public Integer getEnd() {    return end;}public Integer getIndex() {    return index;}public ChronoUnit getChronoUnit() {    return chronoUnit;}

}
package com.taocares.naoms.client.model.common.custom.control;

import java.time.LocalDateTime;
import java.util.Date;

import com.taocares.naoms.client.model.common.util.LocalDateConvert;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.scene.control.IndexRange;
import javafx.scene.control.Spinner;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;

/**
* 时间控件 目前适用于yyyy-MM-dd HH:mm 格式 使用方式: new LocalDateTimeSpinner()||new
* LocalDateTimeSpinner(Date date) 存取值方式: setDate(Date date),Date
* getDate()||LocalDateTime getValue()
*
* @author wxx
* @author stone 添加监听,左右切换以及键入验证
*
*/
public class LocalDateTimeSpinner extends Spinner {
private static Integer CURRENT_INDEX = -1;
private static Integer CURRENT = 0;
private boolean isMinute = false;
LocalDateTimeSpinnerValueFactory ldtsvf = new LocalDateTimeSpinnerValueFactory();

public LocalDateTimeSpinner() {    init();}public LocalDateTimeSpinner(Date date) {    init();    setDate(date);}public void setDate(Date date) {    if (date != null) {        this.getValueFactory().setValue(LocalDateConvert.UDateToLocalDateTime(date));    } else {        this.getValueFactory().setValue(null);    }}public Date getDate() {    if (this.getValueFactory().getValue() != null) {        return LocalDateConvert.LocalDateTimeToUdate(this.getValueFactory().getValue());    }    return null;}/** * 切换调整元素 */private void switchTemporalUnit() {    TextField tf = this.getEditor();    LocalDateTimeSpinnerCode code = LocalDateTimeSpinnerCode.getCodeByIndex(CURRENT_INDEX);    if (code == null) {        IndexRange range = tf.getSelection();        code = LocalDateTimeSpinnerCode.getCodeByStart(range.getStart());    }    tf.selectRange(code.getStart(), code.getEnd());    CURRENT_INDEX = code.getIndex();    ldtsvf.setTemporalUnit(code.getChronoUnit());}/** * 双击 */private void switchTemporalUnitByDoubleClick() {    TextField tf = this.getEditor();    IndexRange range = tf.getSelection();    LocalDateTimeSpinnerCode code = LocalDateTimeSpinnerCode.getCodeByStart(range.getStart());    tf.selectRange(code.getStart(), code.getEnd());    CURRENT_INDEX = code.getIndex();    ldtsvf.setTemporalUnit(code.getChronoUnit());}/** * 若没有通过之前验证,字符串替换为0+arg0.getCharacter() * * @param code * @param arg0 */private void keyBoardingElse(LocalDateTimeSpinnerCode code, KeyEvent arg0) {    CURRENT++;    getEditor().replaceText(code.getStart(), code.getEnd(), 0 + arg0.getCharacter());}/** * 键入验证 * * @param code * @param regex * @param arg0 * @return */private boolean keyBoardingRegex(LocalDateTimeSpinnerCode code, String regex, KeyEvent arg0) {    if (getEditor().getText(code.getEnd() - 1, code.getEnd()).matches(regex)) {        CURRENT++;        getEditor().replaceText(code.getStart(), code.getEnd(),                getEditor().getText(code.getEnd() - 1, code.getEnd()) + arg0.getCharacter());        return true;    }    return false;}private void init() {    ldtsvf.setPattern("yyyy-MM-dd HH:mm");    setValueFactory(ldtsvf);    // 初始化,值为空    getValueFactory().setValue(null);    setOnKeyPressed(new EventHandler<KeyEvent>() {        @Override        public void handle(KeyEvent event) {            switch (event.getCode()) {            case LEFT:                focusLeft();                // 此处可能被其他捕获                event.consume();                break;            case RIGHT:                focusRight();                // 此处可能被其他捕获                event.consume();                break;            case DELETE:                getEditor().setText("");                setDate(null);                break;            case BACK_SPACE:                getEditor().setText("");                setDate(null);                break;            default:                break;            }        }    });    this.getEditor().setOnMouseClicked(new EventHandler<MouseEvent>() {        @Override        public void handle(MouseEvent event) {            switchTemporalUnitByDoubleClick();        }    });    valueProperty().addListener(new ChangeListener<LocalDateTime>() {        @Override        public void changed(ObservableValue<? extends LocalDateTime> observable, LocalDateTime oldValue,                LocalDateTime newValue) {            if (CURRENT == 2) {                if (!isMinute) {                    focusRight();                    CURRENT = 0;                } else {                    focusLeft();                    isMinute = false;                    CURRENT = 0;                }            } else {                switchTemporalUnit();            }        }    });    /**     * 控制键入     */    this.addEventFilter(KeyEvent.KEY_TYPED, new EventHandler<KeyEvent>() {        @Override        public void handle(KeyEvent event) {            IndexRange range = getEditor().getSelection();            LocalDateTimeSpinnerCode code = LocalDateTimeSpinnerCode.getCodeByStart(range.getStart());            if(getEditor().getText()==null){                return;            }            if (event.getCharacter().matches("[0-9]")) {                switch (code.getStart()) {                case 0:                    if(code.getEnd()<0||code.getEnd()>getEditor().getText().length()){                        break;                    }                    if (getEditor().getText(code.getEnd() - 1, code.getEnd()).matches("[0-9]")) {                        getEditor().replaceText(code.getStart() + 2, code.getEnd(),                                getEditor().getText(code.getEnd() - 1, code.getEnd()) + event.getCharacter());                    }                    break;                case 5:                    if (!keyBoardingRegex(code, "1", event)) {                        keyBoardingElse(code, event);                    }                    break;                case 8:                    if (!keyBoardingRegex(code, "[1-3]", event)) {                        keyBoardingElse(code, event);                    }                    break;                case 11:                    if (!keyBoardingRegex(code, "[1-2]", event)) {                        keyBoardingElse(code, event);                    }                    break;                case 14:                    isMinute = true;                    if (!keyBoardingRegex(code, "[1-5]", event)) {                        keyBoardingElse(code, event);                    }                    break;                }            }            setDate(LocalDateConvert.getDate(getEditor().getText(), "yyyy-MM-dd HH:mm"));        }    });    setPrefWidth(180);}public void focusLeft() {    int count = ldtsvf.getPattern().split("\\-| |:").length;    CURRENT_INDEX--;    if (CURRENT_INDEX == 0) {        CURRENT_INDEX = count;    }    switchTemporalUnit();}public void focusRight() {    int count = ldtsvf.getPattern().split("\\-| |:").length;    if (CURRENT_INDEX == count) {        CURRENT_INDEX = 0;    }    CURRENT_INDEX++;    switchTemporalUnit();}

}

0 0
原创粉丝点击