附送我自定义的日期格式化工具类:
import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; /** * @author zhaoyong * @Date 2021/2/4 * @Description 时间处理工具类 */ public class DateUtils { public final static String DATE_FORMAT_DAY = "yyyy-MM-dd"; public final static String DATE_FORMAT_SECOND = "yyyy-MM-dd HH:mm:ss"; public final static String DATE_FORMAT_SECOND_SINGLE = "yyyy-MM-dd HH:mm:ss"; public final static String DATE_FULL_STRING = "yyyyMMddHHmmssSSS"; public final static String DATE_FULL_14 = "yyyyMMddHHmmss"; public final static String DATE_FULL_DAY_8 = "yyyyMMdd"; private final static int[] DATE_UNIT_ARR = new int[]{Calendar.MILLISECOND, Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY, Calendar.DATE, Calendar.MONTH, Calendar.YEAR}; public static Calendar calendar = null; public static DateFormat dateFormat = null; public static Date date = null; /** * 将日期转为 字符串 * * @param date * @param format * @return */ public static String dateToString(Date date, String format) { if (date == null) { return null; } return new SimpleDateFormat(format).format(date); } /** * 将日期转换为 字符串(转换的时间按照当前登录用户的时区) * * @param date * @param format * @param timeZone * @return */ public static String dateToString(Date date, String format, String timeZone) { if (date == null) { return null; } //1、格式化日期 return getTimeZoneSimpleDateFormat(format, timeZone).format(date); } /** * 获取当前登录用户的 日期格式化对象 * * @param timeZone * @param format * @return */ private static SimpleDateFormat getTimeZoneSimpleDateFormat(String format, String timeZone) { //1、获取对应时区的格式化器 SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format); simpleDateFormat.setTimeZone(TimeZone.getTimeZone(timeZone)); return simpleDateFormat; } /** * 获取当天初始时间 * * @param date 时间 * @return 初始时间 (yyyy-MM-dd 00:00:00) */ public static Date getInitialTime(Date date) { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd 00:00:00"); String dateStr = dateFormat.format(date); try { return dateFormat.parse(dateStr); } catch (ParseException e) { e.printStackTrace(); } return null; } public static String date2Str(Date date) { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return dateFormat.format(date); } /** * 计算两个时间间隔多少秒 * * @param startDate * @param endDate * @return */ public static Long intervalTime(Date startDate, Date endDate) { long a = endDate.getTime(); long b = startDate.getTime(); Long c = ((a - b) / 1000); return c; } /** * 检测一个日期是否在 小时之内,支持跨天的小时 * * @param time * @param startDate * @param endDate * @return */ public static boolean checkDateIn(Date time, Date startDate, Date endDate) { if (startDate == null || endDate == null || time == null) { return true; } return time.before(endDate) && time.after(startDate); } /** * 检测一个日期是否在 时分秒 之内,支持跨天的小时 * * @param time * @param startHms * @param endHms * @return */ /** * 功能描述:格式化日期 * * @param dateStr 字符型日期:YYYY/MM/DD 格式 * @return Date 日期 */ public static Date parseDate(String dateStr) { return parseDate(dateStr, "yyyy-MM-dd"); } /** * 功能描述:格式化日期 * * @param dateStr 字符型日期 * @param format 格式 * @return Date 日期 */ public static Date parseDate(String dateStr, String format) { try { dateFormat = new SimpleDateFormat(format); String dt = dateStr.replaceAll("-", "/"); if ((!dt.equals("")) && (dt.length() < format.length())) { dt += format.substring(dt.length()).replaceAll("[YyMmDdHhSs]", "0"); } date = (Date) dateFormat.parse(dt); } catch (Exception e) { e.printStackTrace(); return null; } return date; } public static Date strParseDateDay(String date) throws ParseException { //获取的值为"19570323" //1、定义转换格式 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); //SimpleDateFormat formatter2 = new SimpleDateFormat("yyyyMMdd"); //2、调用formatter2.parse(),将"19570323"转化为date类型 输出为:Sat Mar 23 00:00:00 GMT+08:00 1957 Date parseDate = formatter.parse(date); return parseDate; } public static Date strParseDate(String date,String dateFormat) { Date parseDate =null; SimpleDateFormat formatter = new SimpleDateFormat(dateFormat); try { parseDate=formatter.parse(date); }catch (Exception e){ e.printStackTrace(); } return parseDate; } /** * 日期型字符串转换成标准日期格式字符串 * @param date * @param srcDateFormat * @param destDateFormat * @return */ public static String strParseToDateStr(String date,String srcDateFormat,String destDateFormat) { String resultStr =null; Date parseDate =null; SimpleDateFormat formatter = new SimpleDateFormat(srcDateFormat); try { parseDate=formatter.parse(date); resultStr= DateUtils.dateToString(parseDate,destDateFormat); }catch (Exception e){ e.printStackTrace(); } return resultStr; } public static String yyyyMMddHHmmssToStandard(String dateStr) { Date parseDate =null; String standStrForDate =null; try { parseDate= DateUtils.strParseDate(dateStr,DateUtils.DATE_FULL_14); standStrForDate= DateUtils.dateToString(parseDate,DATE_FORMAT_SECOND); }catch (Exception e){ e.printStackTrace(); } return standStrForDate; } public static String yyyyMMddToStandard(String dateStr) { Date parseDate =null; String standStrForDate = null; try { parseDate= DateUtils.strParseDate(dateStr,DateUtils.DATE_FULL_DAY_8); standStrForDate= DateUtils.dateToString(parseDate,DATE_FORMAT_SECOND); }catch (Exception e){ e.printStackTrace(); } return standStrForDate; } public static List<String> getRecent7Days() { //获取近7天的日期 如 2021-05-16 List<String> sevenDays = new ArrayList<String>(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); Calendar c = null; for (int i=0;i<7;i++){ c=Calendar.getInstance(); c.add(Calendar.DAY_OF_MONTH, - i); sevenDays.add(simpleDateFormat.format(c.getTime())); } Collections.reverse(sevenDays); return sevenDays; } /* public static void main(String args[]){ //System.out.println(DateUtils.dateToString(new Date(),DateUtils.DATE_FULL_STRING)); //Date date = DateUtils.strParseDate("20210326170206",DateUtils.DATE_FULL_14); //System.out.println(DateUtils.dateToString(date,DATE_FORMAT_SECOND)); //System.out.println(DateUtils.yyyyMMddToStandard("20211031")); Date loadGoodsTime = new Date(); long loadGoodsTimeLong = loadGoodsTime.getTime(); long min = 1000*60*20;//最小20分钟 long max = 1000*60*40;//最大40分钟 long longBounded = RandomUtils.nextLong(min, max);//最小20分钟,最大40分钟 long startDrivingTime=loadGoodsTimeLong+longBounded; Date startDrivingTimeApp = new Date(startDrivingTime);//发车时间 System.out.println(DateUtils.dateToString(startDrivingTimeApp,DateUtils.DATE_FORMAT_SECOND)); }*/ }
——————————————————
JavaFX中的DatePicker控件提供了从给定日历中选择某一天的功能
在JDK8中引入的日期和时间API允许你对日期和时间数据进行各种操作,包括根据不同时区设置日历和本地时间。
在日期和时间API中的基础包是java.time。它提供了如下类来定义基于国际标准化组织(ISO)历法的日历系统中的时间。
· Clock ——时钟类可以指定一个时区,它可以获得当前的时刻、日期和时间
· Duration ——表示一段时间
· Instant ——表示在时间轴上的一个瞬间
· LocalDate——在ISO-8601日历系统中的一个不带时区的日期
· LocalDateTime ——在ISO-8601日历系统中的一个不带时区的日期和时间
· LocalTime ——在ISO-8601日历系统中的一个不带时区的时间
· MonthDay ——在ISO-8601日历系统中的一个月份中的日期
· OffsetDateTime ——在ISO-8601日历系统中的一个日期和时间,它加入了格林威治/UTC 时间偏移量
· OffsetTime ——在ISO-8601日历系统中的一个时间,它加入了格林威治/UTC 时间偏移量
· Period – 以天为单位的一段时间
· Year ——在ISO-8601日历系统中的一年
· YearMonth ——在ISO-8601日历系统中的一年中的月份
· ZonedDateTime ——在ISO-8601日历系统中的一个带有时区的日期和时间
· ZoneId ——表示一个时区ID
· ZoneOffset —— 表示与格林威治/UTC时间的时区偏移量
如果希望获得更多相关的功能和代码样例信息,可以参考Java教程中对日期和时间API的讲解
javaFX默认没有时间选择控件可以引入第三方jar包实现(jfxtras.jar)
import javafx.application.Application; import javafx.event.ActionEvent; import javafx.geometry.HPos; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; import javafx.stage.Stage; import jfxtras.scene.control.LocalDateTimeTextField; import java.time.LocalDate; public class DatePickerSample extends Application { private Stage stage; private DatePicker checkInDatePicker;//日期控件 LocalDateTimeTextField localDateTimeTextField = new LocalDateTimeTextField();//日期+时间控件 private Menu menu = new Menu("系统"); private MenuItem item = new MenuItem("退出"); private MenuBar menuBar = new MenuBar(); public static void main(String[] args) { //Locale.setDefault(Locale.CHINA); launch(args); } @Override public void start(Stage stage) { this.stage = stage; stage.setTitle("DatePickerSample"); initUI();//自定义初始化UI组件 stage.show();//展现舞台场景 } private void initUI() { VBox vbox = new VBox(20);//创建垂直盒子布局器对象 vbox.setStyle("-fx-padding: 10;");//垂直盒子布局对象添加样式 Scene scene = new Scene(vbox, 400, 400);//场景挂载垂直盒子布局对象 stage.setScene(scene);//舞台挂载场景 menuBar.getMenus().add(menu);//MenuBar上面添加Menu对象 menu.getItems().add(item);//Menu对象上面添加MenuItem类型对象 item.setOnAction((ActionEvent e) -> {//MenuItem类型对象上添加交互事件处理机制 System.exit(0);//退出系统 }); checkInDatePicker = new DatePicker(LocalDate.now());//创建一个日期控件对象 GridPane gridPane = new GridPane();//创建一个格子布局器对象 gridPane.setHgap(10);//设置格子布局器对象的水平布局间隙 gridPane.setVgap(10);//设置格子布局器对象的垂直布局间隙 Label checkInlabel = new Label("Check-In Date:");//创建一个标签文本对象 gridPane.add(checkInlabel, 0, 0);//格子布局器对象上第一行第一列添加标签对象 GridPane.setHalignment(checkInlabel, HPos.LEFT);//格子布局器对象设置水平对齐方式 gridPane.add(checkInDatePicker, 0, 1);//格子布局器第二行第一列添加日期选择器组件 gridPane.add(localDateTimeTextField, 0, 2);//格子布局器第三行第一列添加日期时间选择器组件 vbox.getChildren().add(menuBar);//盒子布局器上添加menuBar菜单栏组件 vbox.getChildren().add(gridPane); } }
注意日期信息域在初始时为空,不过这种默认行为是可以改变的。在进行日期选择前你可以指定在日期信息域中要显示的日期。可以通过DatePicker的构造方法或者通过调用从ComboBox类继承而来的setValue方法来设置value属性的值
3 4 5 6 7 8 9 10 | //在类的构造方法中设置指定日期 checkInDatePicker = new DatePicker(LocalDate.of(1998, 10, 8)); //通过setValue方法来设置指定日期checkInDatePicker.setValue(LocalDate.of(1998, 10, 8)); //设置日历中最小的可用日期 checkInDatePicker.setValue(LocalDate.MIN); //设置日历中最大的可用日期 checkInDatePicker.setValue(LocalDate.MAX); //设置当前日期 checkInDatePicker.setValue(LocalDate.now()); |
一旦初始值被设置了,那当你编译并运行程序后,它将会显示在日期信息域
import javafx.application.Application; import javafx.event.ActionEvent; import javafx.geometry.HPos; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; import javafx.scene.text.Text; import javafx.stage.Stage; import jfxtras.scene.control.LocalDateTimeTextField; import java.time.LocalDate; public class DatePickerSample extends Application { private Stage stage; private DatePicker checkInDatePicker;//日期控件 LocalDateTimeTextField localDateTimeTextField = new LocalDateTimeTextField();//日期+时间控件 private Menu menu = new Menu("系统"); private MenuItem item = new MenuItem("退出"); private MenuItem itemDisplay = new MenuItem("显示所选时间"); private MenuBar menuBar = new MenuBar(); private Text textDisplay = new Text(); public static void main(String[] args) { //Locale.setDefault(Locale.CHINA); launch(args); } @Override public void start(Stage stage) { this.stage = stage; stage.setTitle("DatePickerSample"); initUI();//自定义初始化UI组件 stage.show();//展现舞台场景 } private void initUI() { VBox vbox = new VBox(20);//创建垂直盒子布局器对象 vbox.setStyle("-fx-padding: 10;");//垂直盒子布局对象添加样式 Scene scene = new Scene(vbox, 400, 400);//场景挂载垂直盒子布局对象 stage.setScene(scene);//舞台挂载场景 menuBar.getMenus().add(menu);//MenuBar上面添加Menu对象 menu.getItems().addAll(item, itemDisplay);//Menu对象上面添加MenuItem类型对象 item.setOnAction((ActionEvent e) -> {//MenuItem类型对象上添加交互事件处理机制 System.exit(0);//退出系统 }); itemDisplay.setOnAction((ActionEvent e) -> { String textContent = DateUtils.strParseToDateStr(localDateTimeTextField.getText(), DateUtils.DATE_FORMAT_SECOND_SINGLE, DateUtils.DATE_FORMAT_SECOND); textDisplay.setText(textContent); }); checkInDatePicker = new DatePicker(LocalDate.now());//创建一个日期控件对象 //设置日历中最小的可用日期 checkInDatePicker.setValue(LocalDate.MIN); //设置日历中最大的可用日期 checkInDatePicker.setValue(LocalDate.MAX); //设置当前日期 checkInDatePicker.setValue(LocalDate.now()); GridPane gridPane = new GridPane();//创建一个格子布局器对象 gridPane.setHgap(10);//设置格子布局器对象的水平布局间隙 gridPane.setVgap(10);//设置格子布局器对象的垂直布局间隙 Label checkInlabel = new Label("请选择日期:");//创建一个标签文本对象 gridPane.add(checkInlabel, 0, 0);//格子布局器对象上第一行第一列添加标签对象 GridPane.setHalignment(checkInlabel, HPos.LEFT);//格子布局器对象设置水平对齐方式 gridPane.add(checkInDatePicker, 0, 1);//格子布局器第二行第一列添加日期选择器组件 gridPane.add(localDateTimeTextField, 0, 2);//格子布局器第三行第一列添加日期时间选择器组件 gridPane.add(textDisplay, 0, 3);//格子布局器第四行第一列添加文本显示组件 vbox.getChildren().add(menuBar);//盒子布局器上添加menuBar菜单栏组件 vbox.getChildren().add(gridPane);//盒子布局对象上添加表格布局器对象 } }
__________________________________________________________
默认时间为当前时间:
import javafx.application.Application; import javafx.event.ActionEvent; import javafx.geometry.HPos; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; import javafx.scene.text.Text; import javafx.stage.Stage; import jfxtras.scene.control.LocalDateTimeTextField; import java.time.LocalDate; import java.time.LocalDateTime; public class DatePickerSample extends Application { private Stage stage; private DatePicker checkInDatePicker;//日期控件 LocalDateTimeTextField localDateTimeTextField = new LocalDateTimeTextField(LocalDateTime.now());//日期+时间控件 private Menu menu = new Menu("系统"); private MenuItem item = new MenuItem("退出"); private MenuItem itemDisplay = new MenuItem("显示所选时间"); private MenuBar menuBar = new MenuBar(); private Text textDisplay = new Text(); public static void main(String[] args) { //Locale.setDefault(Locale.CHINA); launch(args); } @Override public void start(Stage stage) { this.stage = stage; stage.setTitle("DatePickerSample"); initUI();//自定义初始化UI组件 stage.show();//展现舞台场景 } private void initUI() { VBox vbox = new VBox(20);//创建垂直盒子布局器对象 vbox.setStyle("-fx-padding: 10;");//垂直盒子布局对象添加样式 Scene scene = new Scene(vbox, 400, 400);//场景挂载垂直盒子布局对象 stage.setScene(scene);//舞台挂载场景 menuBar.getMenus().add(menu);//MenuBar上面添加Menu对象 menu.getItems().addAll(item, itemDisplay);//Menu对象上面添加MenuItem类型对象 item.setOnAction((ActionEvent e) -> {//MenuItem类型对象上添加交互事件处理机制 System.exit(0);//退出系统 }); itemDisplay.setOnAction((ActionEvent e) -> { String textContent = DateUtils.strParseToDateStr(localDateTimeTextField.getText(), DateUtils.DATE_FORMAT_SECOND_SINGLE, DateUtils.DATE_FORMAT_SECOND); textDisplay.setText(textContent); }); checkInDatePicker = new DatePicker(LocalDate.now());//创建一个日期控件对象 //设置日历中最小的可用日期 checkInDatePicker.setValue(LocalDate.MIN); //设置日历中最大的可用日期 checkInDatePicker.setValue(LocalDate.MAX); //设置当前日期 checkInDatePicker.setValue(LocalDate.now()); GridPane gridPane = new GridPane();//创建一个格子布局器对象 gridPane.setHgap(10);//设置格子布局器对象的水平布局间隙 gridPane.setVgap(10);//设置格子布局器对象的垂直布局间隙 Label checkInlabel = new Label("请选择日期:");//创建一个标签文本对象 gridPane.add(checkInlabel, 0, 0);//格子布局器对象上第一行第一列添加标签对象 GridPane.setHalignment(checkInlabel, HPos.LEFT);//格子布局器对象设置水平对齐方式 gridPane.add(checkInDatePicker, 0, 1);//格子布局器第二行第一列添加日期选择器组件 gridPane.add(localDateTimeTextField, 0, 2);//格子布局器第三行第一列添加日期时间选择器组件 gridPane.add(textDisplay, 0, 3);//格子布局器第四行第一列添加文本显示组件 vbox.getChildren().add(menuBar);//盒子布局器上添加menuBar菜单栏组件 vbox.getChildren().add(gridPane);//盒子布局对象上添加表格布局器对象 } }
在默认情况下,在日期信息域中的日期会按系统本地和ISO日历系统的格式来展示。因此选择的日期将会按这样的格式显示:mm/dd/yyyy。一般情况下你不需要修改默认格式,如果需要进行修改则可以使用DatePicker类的converter属性和setConverter方法来设置日期的可选格式。如果将converter的值设置为null则会恢复默认的日期格式。
创建一个converter来将日期格式转换为:yyyy-MM-dd。当用户在日期信息域输入一个日期时,它会把输入的文本转换成格式化后的LocalDate类型的对象。同时它也能把在日历中选择的日期所对应LocalDate对象转换为在日期信息域中显示的格式化文本
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.HPos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import jfxtras.scene.control.LocalDateTimeTextField;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class DatePickerSample extends Application {
private Stage stage;
private final String pattern = "yyyy-MM-dd ";//日期格式类型样板串
private DatePicker checkInDatePicker;//日期控件
LocalDateTimeTextField localDateTimeTextField = new LocalDateTimeTextField(LocalDateTime.now());//日期+时间控件
private Menu menu = new Menu("系统");
private MenuItem item = new MenuItem("退出");
private MenuItem itemDisplay = new MenuItem("显示所选时间");
private MenuBar menuBar = new MenuBar();
private Text textDisplay = new Text();
public static void main(String[] args) {
Locale.setDefault(Locale.CHINA);
launch(args);
}
@Override
public void start(Stage stage) {
this.stage = stage;
stage.setTitle("DatePickerSample");
initUI();//自定义初始化UI组件
stage.show();//展现舞台场景
}
private void initUI() {
VBox vbox = new VBox(20);//创建垂直盒子布局器对象
vbox.setStyle("-fx-padding: 10;");//垂直盒子布局对象添加样式
Scene scene = new Scene(vbox, 400, 400);//场景挂载垂直盒子布局对象
stage.setScene(scene);//舞台挂载场景
menuBar.getMenus().add(menu);//MenuBar上面添加Menu对象
menu.getItems().addAll(item, itemDisplay);//Menu对象上面添加MenuItem类型对象
item.setOnAction((ActionEvent e) -> {//MenuItem类型对象上添加交互事件处理机制
System.exit(0);//退出系统
});
itemDisplay.setOnAction((ActionEvent e) -> {//Menu
String textContent = DateUtils.strParseToDateStr(localDateTimeTextField.getText(), DateUtils.DATE_FORMAT_SECOND_SINGLE, DateUtils.DATE_FORMAT_SECOND);
textDisplay.setText(textContent);
});
// checkInDatePicker = new DatePicker(LocalDate.now());//创建一个日期控件对象
checkInDatePicker = new DatePicker();//创建一个日期控件对象
//设置日历中最小的可用日期
// checkInDatePicker.setValue(LocalDate.MIN);
//设置日历中最大的可用日期
//checkInDatePicker.setValue(LocalDate.MAX);
//设置当前日期
checkInDatePicker.setValue(LocalDate.now());
checkInDatePicker.setShowWeekNumbers(true);//显示第几周
StringConverter converter = new StringConverter<LocalDate>() {//创建一个字符串格式转换器
DateTimeFormatter dateFormatter =
DateTimeFormatter.ofPattern(pattern);//根据字符串样板样例模式创建一个日期格式化器
@Override
public String toString(LocalDate date) {
if (date != null) {
return dateFormatter.format(date);//利用格式化足迹将日期格式化成一个字符串
} else {
return "";
}
}
@Override
public LocalDate fromString(String string) {
if (string != null && !string.isEmpty()) {
return LocalDate.parse(string, dateFormatter);//利用格式化足迹将一个日期字符串格式化成一个本地日期
} else {
return null;
}
}
};
checkInDatePicker.setConverter(converter);//给日期选择控件绑定一个格式转换器组件
checkInDatePicker.setPromptText(pattern.toLowerCase());//设置默认提示文本(日期选择控件为空的时候设置默认提示文本)
GridPane gridPane = new GridPane();//创建一个格子布局器对象
gridPane.setHgap(10);//设置格子布局器对象的水平布局间隙
gridPane.setVgap(10);//设置格子布局器对象的垂直布局间隙
Label checkInlabel = new Label("请选择日期:");//创建一个标签文本对象
gridPane.add(checkInlabel, 0, 0);//格子布局器对象上第一行第一列添加标签对象
GridPane.setHalignment(checkInlabel, HPos.LEFT);//格子布局器对象设置水平对齐方式
gridPane.add(checkInDatePicker, 0, 1);//格子布局器第二行第一列添加日期选择器组件
gridPane.add(localDateTimeTextField, 0, 2);//格子布局器第三行第一列添加日期时间选择器组件
gridPane.add(textDisplay, 0, 3);//格子布局器第四行第一列添加文本显示组件
vbox.getChildren().add(menuBar);//盒子布局器上添加menuBar菜单栏组件
vbox.getChildren().add(gridPane);//盒子布局对象上添加表格布局器对象
}
}
——————————————————————
除了进行日期转换之外,为了告诉用户输入所需要的日期格式,日期信息域设置了提示信息。展示了应用了日期格式转换器的DatePicker的两种状态。在图中提示信息和被选择的日期都以新格式进行显示
带有格式转换器和提示文本信息的DatePicker
你也可以修改日历元素中任何一个单元或多个单元的默认外观并设置特定的行为。为了完成这个任务,我们可以考虑这样一个真实的用例:在进行酒店前台登记时选择入住和离店日期。创建了一个带有两个DatePicker的典型用户界面
————————————————————
自定义一个日期选择效果:
checkOutDatePicker创建了一个日期CellFactory工厂类型,它会将checkInDatePicker所选择的日期及其之前的日期单元格都禁用
dayCellFactory会应用到checkOutDatePicker之上,它在一个DateCell项上调用了setDisable和setStyle方法,以此来避免日期被选择并且将它们变成粉红色
知道了如何创建日期Cell Factory,你可以扩展checkOutDatePicker的默认行为并且为日期单元格的选择提供扩展功能
import java.time.LocalDate; import java.util.Locale; import javafx.application.Application; import javafx.geometry.HPos; import javafx.scene.Scene; import javafx.scene.control.DateCell; import javafx.scene.control.DatePicker; import javafx.scene.control.Label; import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; import javafx.stage.Stage; import javafx.util.Callback; public class DatePickerTest3 extends Application { private Stage stage;//舞台对象的定义 private DatePicker checkInDatePicker;//日期选择器的定义 private DatePicker checkOutDatePicker;//日期选择器的定义 public static void main(String[] args) { Locale.setDefault(Locale.US);//设置默认日期时区为美国 launch(args); } @Override public void start(Stage stage) { this.stage = stage;//创建舞台为启动时候的默认传进来的舞台对象 stage.setTitle("DatePicker例子 ");//设置舞台标题 initUI();//自定义初始化UI组件对象的方法 stage.show();//舞台展现 } private void initUI() { VBox vbox = new VBox(20);//垂直盒子布局对象的创建 vbox.setStyle("-fx-padding: 10;");//设置布局盒子样式属性 Scene scene = new Scene(vbox, 400, 400);//创建场景对象,上面挂载vbox类型对象作为根节点 stage.setScene(scene);//舞台上设置场景 checkInDatePicker = new DatePicker();//创建日期组件 checkOutDatePicker = new DatePicker();//创建日期组件 checkInDatePicker.setValue(LocalDate.now());//设置日期初始值 final Callback<DatePicker, DateCell> dayCellFactory =//创建一个日期选择单元格工厂对象 new Callback<DatePicker, DateCell>() {//设置对应选择单元格的回调方法 @Override public DateCell call(final DatePicker datePicker) {//当调用一个日期单元格的时候 return new DateCell() { @Override public void updateItem(LocalDate item, boolean empty) {//更新日期选项的事件处理回调函数 super.updateItem(item, empty);//更新选中单元格 if (item.isBefore( checkInDatePicker.getValue().plusDays(1)) )//判断如果选择的日期在checkInDatePicker.getValue()取值之前,则禁用选择项,并将之前日期选择项的颜色设置为红色 { setDisable(true);//禁用相关选择项 setStyle("-fx-background-color: #ffc0cb;");//设置背景色样式 } } }; } }; checkOutDatePicker.setDayCellFactory(dayCellFactory);//为日期控件设置选择单元格工厂对象 checkOutDatePicker.setValue(checkInDatePicker.getValue().plusDays(1));//设置第二个日期选择对象所选值为第一个日期选择对象选值的后一天选项 GridPane gridPane = new GridPane();//创建一个表格布局面板 gridPane.setHgap(10);//设置被布局对象之间的水平间距 gridPane.setVgap(10);//设置被布局对象之间的垂直间距 Label checkInlabel = new Label("选择起始日期:"); gridPane.add(checkInlabel, 0, 0);//表格布局面板第一行第一列添加文本标签对象 GridPane.setHalignment(checkInlabel, HPos.LEFT);//设置文本标签对象在表格布局面板中的对齐方式 gridPane.add(checkInDatePicker, 0, 1);;//表格布局面板第二行第一列添加日期选择对象 Label checkOutlabel = new Label("选择截止日期:");//创建文本标签 gridPane.add(checkOutlabel, 0, 2);//表格布局面板第三行第一列添加文本标签对象 GridPane.setHalignment(checkOutlabel, HPos.LEFT);//设置表格布局对象的对齐方式为向左对齐 gridPane.add(checkOutDatePicker, 0, 3);//表格布局对象第四行第一列添加日期选择器 vbox.getChildren().add(gridPane);//垂直盒子对象上添加表格布局器对象 } }
——————————————————————————————
再来一个案例:
checkInDatePicker中选择日期与当前日期单元中的日期之间的间隔。计算结果会在日期单元的提示信息框(Tooltip)中显示
提示时间间隔:
import java.time.LocalDate;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Locale;
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.scene.Scene;
import javafx.scene.control.DateCell;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;
public class DatePickerTest9 extends Application {
private Stage stage;
private DatePicker checkInDatePicker;
private DatePicker checkOutDatePicker;
public static void main(String[] args) {
Locale.setDefault(Locale.US);
launch(args);
}
@Override
public void start(Stage stage) {
this.stage = stage;
stage.setTitle("DatePickerSample ");
initUI();
stage.show();
}
private void initUI() {
VBox vbox = new VBox(20);
vbox.setStyle("-fx-padding: 10;");
Scene scene = new Scene(vbox, 400, 400);
stage.setScene(scene);
checkInDatePicker = new DatePicker();
checkOutDatePicker = new DatePicker();
checkInDatePicker.setValue(LocalDate.now());
final Callback<DatePicker, DateCell> dayCellFactory =
new Callback<DatePicker, DateCell>() {
@Override
public DateCell call(final DatePicker datePicker) {
return new DateCell() {
@Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if (item.isBefore(
checkInDatePicker.getValue().plusDays(1))
) {
setDisable(true);
setStyle("-fx-background-color: #ffc0cb;");
}
long p = ChronoUnit.DAYS.between(
checkInDatePicker.getValue(), item
);//返回当前选择日期和初始化起始选择日期之间的天数
setTooltip(new Tooltip(//设置自定义提示框内容
"你打算 " + p + " 天")
);
}
};
}
};
checkOutDatePicker.setDayCellFactory(dayCellFactory);
checkOutDatePicker.setValue(checkInDatePicker.getValue().plusDays(1));
GridPane gridPane = new GridPane();
gridPane.setHgap(10);
gridPane.setVgap(10);
Label checkInlabel = new Label("Check-In Date:");
gridPane.add(checkInlabel, 0, 0);
GridPane.setHalignment(checkInlabel, HPos.LEFT);
gridPane.add(checkInDatePicker, 0, 1);
Label checkOutlabel = new Label("Check-Out Date:");
gridPane.add(checkOutlabel, 0, 2);
GridPane.setHalignment(checkOutlabel, HPos.LEFT);
gridPane.add(checkOutDatePicker, 0, 3);
vbox.getChildren().add(gridPane);
}
}