JDK1.7、JavaFx自定义日期选择器

jdk1.7版本下的javafx是不支持日期选择器的,而可用的日期选择器DatePicker是从jdk1.8才开始引入的,并且只有jdk1.8才有新的时间类型。 所以自定义的日期选择器是jdk1.7版本下javafx的唯一出路。 下面是自定义javaFx日期选择器的代码:

/**
* <p>
*     自定义的时间控件选择器
* <p>
*/
public class MyDatePicker implements Form{
   Calendar c = Calendar.getInstance();
   int year = c.get(Calendar.YEAR);
   int month = c.get(Calendar.MONTH)+1;
   int date = c.get(Calendar.DATE);
   int hour = c.get(Calendar.HOUR_OF_DAY);
   int minute = c.get(Calendar.MINUTE);
   int second = c.get(Calendar.SECOND);
   HBox timeCombobox;
   ComboBox<String> hourCombobox;
   ComboBox<String> minuteCombobox;
   ComboBox<String> secondCombobox;

   /** 是否带有分秒 */
   Boolean withSecond;

   /** 是否是第一次进入 */
   Boolean isFirstComing;

   /** 日期选择器框 */
   FlowPane datePick;

   /** 显示时间文本框 */
   public TextField timeField;

   /** 年标签 */
   Label yearLabel;

   /** 月标签 */
   Label monthLabel;

   double x,y;

   public MyDatePicker(Boolean withSecond) {
       this.withSecond = withSecond;
       // 设置第一次进入
       this.isFirstComing = true;
       // 创建输入框
       timeField = new TextField();
       // 创建日期选择
       datePick = new FlowPane();
       // 年
       yearLabel = new Label(String.valueOf(year));
       // 月
       monthLabel = new Label(timeFilter(month));
  }

   /**
    * 时间月份过滤
    * @param val 数字
    * @return 字符串
    */
   private String timeFilter(int val){
       return val < 10 ? "0" + val : String.valueOf(val);
  }

   /**
    * 获取日期控件
    * @return 节点
    */
   public HBox getDateTimeTool(){
       HBox hBox = new HBox();
       timeField.setEditable(false);
       timeField.setPrefHeight(30);
       timeField.setPrefWidth(250);
       timeField.setStyle("-fx-border-radius: 20;-fx-background-radius: 20;");

       // 选择日期按钮
       Button btn = new Button("", FxImageUtil.createImage(25, "/static/image/date-bg.png"));
       btn.setStyle("-fx-background-color:transparent;-fx-cursor:hand;-fx-background-position:center;");
       btn.setOnMouseClicked(new EventHandler<MouseEvent>() {
           @Override
           public void handle(MouseEvent oa) {
               x = oa.getScreenX() - oa.getX();
               y = oa.getScreenY() - oa.getY();
               showDatePicker();
          }
      });

       Button btnCancel = new Button("", FxImageUtil.createImage(20, "/static/image/forbidden.png"));
       String cancelStyle = ("-fx-translate-x:-30;-fx-translate-y:1;-fx-opacity:1;")+
               "-fx-background-color:transparent;-fx-pref-width:22;-fx-cursor:hand;" +
               "-fx-background-repeat:no-repeat;-fx-background-position:center;";
       btnCancel.setStyle(cancelStyle);
       btnCancel.setOnMouseClicked(new EventHandler<MouseEvent>() {
           @Override
           public void handle(MouseEvent oa) {
               setCalendarTime();
               timeField.clear();
          }
      });

       StackPane stackPane = new StackPane();
       stackPane.setAlignment(Pos.CENTER_RIGHT);
       // 第一层为:textField
       stackPane.getChildren().add(timeField);
       // 第二层为:清除按钮
       stackPane.getChildren().add(btnCancel);
       // 第三层为:日期弹框按钮
       stackPane.getChildren().add(btn);

       hBox.getChildren().addAll(stackPane);
       return hBox;
  }

   /**
    * 初始化当前日期时间
    */
   public void setCalendarTime(){
       //可以对每个时间域单独修改
       Calendar calendar = Calendar.getInstance();
       year = calendar.get(Calendar.YEAR);
       month = calendar.get(Calendar.MONTH)+1;
       date = calendar.get(Calendar.DATE);
       hour = calendar.get(Calendar.HOUR_OF_DAY);
       minute = calendar.get(Calendar.MINUTE);
       second = calendar.get(Calendar.SECOND);
  }

   /**
    * 显示日期选择框
    */
   private void showDatePicker() {
       // 初始化日期
       initializationTime();

       final Stage stage = new Stage();
       // 设置弹框为APPLICATION_MODAL模式
       stage.initModality(Modality.APPLICATION_MODAL);
       //隐藏默认标题栏
       stage.initStyle(StageStyle.TRANSPARENT);
       VBox vBox = new VBox();
       vBox.setId("layout");
       vBox.setStyle("-fx-background-color:transparent;");

       //日期(年月日)主体
       VBox main = new VBox();
       createMain(stage, main);
       vBox.getChildren().add(main);

       Scene scene = new Scene(vBox, 365, 600);
       scene.getStylesheets().add(Objects.requireNonNull(
               GuiApplication.class.getResource("/static/css/datePicker.css")).toExternalForm());
       stage.setScene(scene);
       stage.setX(x+(withSecond?15:25));
       stage.setY(y-(withSecond?10:15));
       stage.showAndWait();
  }

   /**
    * 创建主要窗体
    * @param stage 窗体
    * @param main 主控件
    */
   private void createMain(final Stage stage, VBox main) {
       //时间box
       HBox timeLabelBox = new HBox();
       timeLabelBox.setStyle("-fx-border-width: 0 0 1 0;-fx-border-color: rgb(180, 180, 180);");
       Label label = new Label("日期选择");
       HBox.setMargin(label, new Insets(5, 0, 0, 5));
       timeLabelBox.getChildren().add(label);

       //日期头部拖动
       DragUtil.addDragListener(stage, timeLabelBox);

       //年月选择
       HBox yearMonthBox = new HBox();
       yearMonthBox.setId("yearMonthBox");
       VBox.setMargin(yearMonthBox, new Insets(20, 0, 0, 0));
       yearMonthBox.setAlignment(Pos.CENTER);
       setYearMonthContent(yearMonthBox);

       //星期
       FlowPane flowPane = new FlowPane();
       flowPane.setId("weekBox");
       VBox.setMargin(flowPane, new Insets(20, 0, 0, 0));
       for (String weekItem : MenuConstant.WEEK_ITEMS) {
           Label weekLabel = new Label(weekItem);
           weekLabel.setPrefWidth(50);
           weekLabel.setPrefHeight(50);
           weekLabel.setAlignment(Pos.CENTER);
           flowPane.getChildren().add(weekLabel);
      }

       //日期选择
       datePick.setId("datePick");
       VBox.setMargin(datePick, new Insets(20, 0, 0, 0));
       setDatePickContent();

       //时间(时分秒)主体
       VBox downMain = new VBox();
       if(withSecond) {
           setDownMain(downMain);
      }
       VBox.setMargin(downMain, new Insets(20, 0, 0, 0));

       HBox hBox = setBtn(stage);
       VBox.setMargin(hBox, new Insets(20, 0, 0, 0));

       main.getChildren().addAll(timeLabelBox, yearMonthBox, flowPane, datePick, downMain, hBox);
  }

   /**
    * 设置年月调整按钮框
    * @param yearMonthBox 年月调整按钮框
    */
   private void setYearMonthContent(HBox yearMonthBox){
       Button yearLeftArrow = new Button("", FxImageUtil.createImage(20, "/static/image/yearLeftArrow.png"));
       yearLeftArrow.setStyle("-fx-background-color: transparent;-fx-background-position:center;-fx-background-repeat:no-repeat;-fx-background-size:50%;");
       yearLeftArrow.setOnAction(new EventHandler<ActionEvent>() {
           @Override
           public void handle(ActionEvent oa) {
               //年减一
               year = Integer.parseInt(yearLabel.getText()) - 1;
               yearLabel.setText(String.valueOf(year));
               setDatePickContent();
          }
      });

       Button yearRightArrow = new Button("", FxImageUtil.createImage(20, "/static/image/yearRightArrow.png"));
       yearRightArrow.setStyle("-fx-background-size:50%;-fx-background-position:center;-fx-background-repeat:no-repeat;-fx-background-color: transparent;");
       yearRightArrow.setOnAction(new EventHandler<ActionEvent>() {
           @Override
           public void handle(ActionEvent oa) {
               //年加一
               year = Integer.parseInt(yearLabel.getText()) + 1;
               yearLabel.setText(String.valueOf(year));
               setDatePickContent();
          }
      });

       Button monthLeftArrow = new Button("", FxImageUtil.createImage(20, "/static/image/monthLeftArrow.png"));
       monthLeftArrow.setStyle("-fx-background-size:80%;-fx-background-position:center;-fx-background-repeat:no-repeat;-fx-background-color: transparent;");
       monthLeftArrow.setOnAction(new EventHandler<ActionEvent>() {
           @Override
           public void handle(ActionEvent oa) {
               month = getMonth(Integer.parseInt(monthLabel.getText()) - 1);
               //月减一
               monthLabel.setText(timeFilter(month));
               setDatePickContent();
          }
      });

       Button monthRightArrow = new Button("", FxImageUtil.createImage(20, "/static/image/monthRightArrow.png"));
       monthRightArrow.setStyle("-fx-background-size:80%;-fx-background-position:center;-fx-background-repeat:no-repeat;-fx-background-color: transparent;");
       monthRightArrow.setOnAction(new EventHandler<ActionEvent>() {
           @Override
           public void handle(ActionEvent oa) {
               //月加一
               month = getMonth(Integer.parseInt(monthLabel.getText()) + 1);
               monthLabel.setText(timeFilter(month));
               setDatePickContent();
          }
      });

       HBox yearAndMonth = new HBox();
       yearAndMonth.getChildren().addAll(yearLabel, new Label("年"), monthLabel, new Label("月"));

       yearMonthBox.getChildren().addAll(yearLeftArrow, monthLeftArrow, yearAndMonth, monthRightArrow, yearRightArrow);
  }

   /**
    * 获取月份
    * @param val 月份数字
    * @return 月份
    */
   public static int getMonth(int val){
       if(val > 12) {
           return 1;
      } else if(val <  1) {
           return 12;
      }else {
           return val;
      }
  }

   /**
    * 填充日期时间
    */
   private void setDatePickContent(){
       datePick.getChildren().clear();
       datePick.setPrefWrapLength(350);
       final List<Button> btnList = new ArrayList<>();
       //当月总天数
       int monthDays = getDaysOfMonth(month);
       //前一个月总天数
       int lastMonthDays = getDaysOfMonth(month - 1);

       //判断当月第一天是星期几, curDay为多少则前一个月所在当前的天数就为多少 getWeekNumber(monthDays)最后一天是星期几
       int curDay = getWeekNumber(1);

       // 6-getWeekNumber(monthDays) 就为下个月有几天在当前日历
       int lastDay = 6 - getWeekNumber(monthDays);

       List<Integer> allDayList = new ArrayList<>();

       for(int i = (curDay-1); i>-1; i--){
           //加入上个月在本日历的几天
           allDayList.add(lastMonthDays - i);
      }
       for(int i=1; i<=monthDays; i++){
           //加入本月的日历
           allDayList.add(i);
      }
       for(int i=1;i<=lastDay;i++){
           //加入下个月的几天
           allDayList.add(i);
      }

       int size = allDayList.size();
       int subDate = (size-lastDay-1);
       c.setTime(new Date());
       int realYear = c.get(Calendar.YEAR);
       int realMonth = c.get(Calendar.MONTH)+1;
       for (int i = 0; i < size; i++) {
           final int k = allDayList.get(i);
           final Button btn = new Button(String.valueOf(k));
           btn.setPrefWidth(50);
           btn.setPrefHeight(50);
           if(year==realYear && month==realMonth && k==date) {
               btn.setStyle(HOVERED_BUTTON_STYLE);
          }
           if(i>=curDay && i<= subDate){
               btn.setOnMouseEntered(new EventHandler<MouseEvent>() {
                   @Override
                   public void handle(MouseEvent e) {
                       btn.setStyle(HOVERED_BUTTON_STYLE);
                  }
              });
               btn.setOnMouseExited(new EventHandler<MouseEvent>() {
                   @Override
                   public void handle(MouseEvent e) {
                       btn.setStyle(NORMAL_BUTTON_STYLE);
                  }
              });
               btnList.add(btn);
               btn.setOnAction(new EventHandler<ActionEvent>() {
                   @Override
                   public void handle(ActionEvent oa) {
                       for (Button b : btnList) {
                           b.setStyle(NORMAL_BUTTON_STYLE);
                      }
                       btn.setOnMouseEntered(null);
                       btn.setOnMouseExited(null);
                       btn.setStyle(HOVERED_BUTTON_STYLE);
                       date = k;
                       //设置当前选择日期的时间
                       setCurrentDateTime();
                       System.out.println("点击了日期:" + date);
                  }
              });
          }else{
               btn.setDisable(true);
               btn.setStyle("-fx-background-color: #F4F4F4;");
          }
           datePick.getChildren().add(btn);
      }
  }

   String currentDateTime;

   /**
    * 设置时间日期
    */
   private void setCurrentDateTime(){
       if(isFirstComing){
           isFirstComing = false;
           currentDateTime = year +"-"+ timeFilter(month)+"-"+timeFilter(date);
           if(withSecond){
               currentDateTime = currentDateTime+" "+timeFilter(hour)+":"+timeFilter(minute)+":"+timeFilter(second);
          }
           return;
      }
       currentDateTime = year +"-"+ timeFilter(month)+"-"+timeFilter(date);
       if(withSecond && hourCombobox!=null && hourCombobox.getValue()!=null){
           currentDateTime = currentDateTime+" "+ hourCombobox.getValue() +":"+ minuteCombobox.getValue()
                   +":"+ secondCombobox.getValue();
      }else{
           System.out.println("你选择的日期是:"+currentDateTime);
           timeField.setText(currentDateTime);
      }
  }

   /**
    * 获取某月中天数
    * @param curMonth 月份
    * @return 某月中天数
    */
   private int getDaysOfMonth(Integer curMonth) {
       Date dateTime = new Date(curMonth == 0 ? (year - 1) : year, curMonth==0 ? (12) : curMonth,0);
       return dateTime.getDate();
  }

   /**
    * 获取某一天是星期几
    * @param day 天数
    * @return 某天是星期几
    */
   private int getWeekNumber(int day){
       Date dateTime = new Date(year, month - 1, day);
       c.setTime(dateTime);
       int dayOfWeek = c.get(Calendar.DAY_OF_WEEK)-2;
       return dayOfWeek < 0 ? 6 : dayOfWeek;
  }

   /**
    * 初始化日期
    */
   private void initializationTime() {
       try {
           //初始化当前日期时间
           String timeValStr = timeField.getText().trim();
           if (timeValStr.length() > 0) {
               Date dateTime;
               if(withSecond){
                   dateTime = DateUtils.YMD_HMS_FORMAT.parse(timeValStr);
              }else {
                   dateTime = DateUtils.YMD_FORMAT.parse(timeValStr);
              }
               c.setTime(dateTime);
          } else {
               setCalendarTime();
          }
      }catch (ParseException e) {
           AlertUtil.alertTime("警告", "初始化日期错误!");
      }
  }

   public void setDownMain(VBox downMain){
       downMain.setStyle("-fx-min-height: 150;-fx-max-height: 150;-fx-min-width:350;-fx-max-width:350;-fx-alignment: center;");

       HBox emptyBox1 = new HBox();
       emptyBox1.setStyle("-fx-min-height: 5;-fx-max-height: 5;-fx-min-width:330;-fx-max-width:330;-fx-border-style: hidden hidden solid hidden;-fx-border-color:#EBEBEB; ");
       //时间box
       HBox timeLabelBox = new HBox();
       timeLabelBox.setStyle("-fx-min-height: 40;-fx-max-height: 40;-fx-min-width:350;-fx-alignment: CENTER_LEFT;-fx-padding: 10; ");
       timeLabelBox.getChildren().add(new Label("时间"));
       //时间选择combobox
       timeCombobox = new HBox();
       timeCombobox.setStyle("-fx-min-height: 30;-fx-max-height: 30;-fx-min-width:350;-fx-alignment: center;");
       setComboBox();
       HBox emptyBox2 = new HBox();
       emptyBox2.setStyle("-fx-min-height: 35;-fx-max-height: 35;-fx-min-width:350;");
       downMain.getChildren().addAll(emptyBox1,timeLabelBox,timeCombobox,emptyBox2);
  }

   private void setComboBox(){
       timeCombobox.getChildren().addAll(getCombo("时"),getCombo("分"),getCombo("秒"));
  }

   private HBox getCombo(final String text){
       HBox main = new HBox();
       main.setStyle("-fx-alignment: center;");
       main.prefWidthProperty().bind(timeCombobox.widthProperty().subtract(20).divide(3));
       main.prefHeightProperty().bind(timeCombobox.heightProperty());
       ComboBox<String> comboBox = new ComboBox<>();
       comboBox.prefWidthProperty().bind(main.widthProperty().multiply(2).divide(3));
       comboBox.prefHeightProperty().bind(main.heightProperty());
       Label label = new Label(" "+text);
       label.prefWidthProperty().bind(main.widthProperty().multiply(1).divide(3));
       label.prefHeightProperty().bind(main.heightProperty());
       comboBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {
           @Override
           public void changed(ObservableValue<? extends Number> ov, Number oldv, Number newv) {
               if ("时".equals(text) && newv.intValue() != hour) {
                   setCurrentDateTime();
              } else if ("分".equals(text) && newv.intValue() != minute) {
                   setCurrentDateTime();
              } else if ("秒".equals(text) && newv.intValue() != second) {
                   setCurrentDateTime();
              }
          }
      });
       main.getChildren().addAll(comboBox,label);

       ObservableList<String> items = FXCollections.observableArrayList();
       if("时".equals(text)){
           setRange(24,items);
           comboBox.setValue(timeFilter(hour));
           hourCombobox = comboBox;
      }else if("分".equals(text)){
           setRange(60,items);
           comboBox.setValue(timeFilter(minute));
           minuteCombobox = comboBox;
      }else if("秒".equals(text)){
           setRange(60,items);
           comboBox.setValue(timeFilter(second));
           secondCombobox = comboBox;
      }
       comboBox.setItems(items);
       return main;
  }

   private void setRange(int range, ObservableList<String> items){
       int k =0;
       while (k<range){
           if(k<10){
               items.add("0"+k);
          }else{
               items.add(String.valueOf(k));
          }
           k++;
      }
  }

   /**
    * 设置按钮
    * @param stage 窗体
    */
   private HBox setBtn(final Stage stage) {
       //取消和确认按钮box
       HBox btnBox = new HBox(20);
       btnBox.setStyle("-fx-min-height: 40;-fx-max-height: 40;-fx-min-width:350;" +
               "-fx-border-style: solid hidden hidden hidden;-fx-border-color:#EBEBEB;-fx-alignment: center;");
       Button confirmBtn = new Button("确认");
       Button cancelBtn = new Button("取消");
       HBox.setMargin(confirmBtn, new Insets(20, 0, 0, 0));
       HBox.setMargin(cancelBtn, new Insets(20, 0, 0, 0));
       confirmBtn.setId("confirmBtn");
       cancelBtn.setId("cancelBtn");
       confirmBtn.setOnAction(new EventHandler<ActionEvent>() {
           @Override
           public void handle(ActionEvent oa) {
               timeField.setText(currentDateTime);
               stage.close();
          }
      });
       cancelBtn.setOnAction(new EventHandler<ActionEvent>() {
           @Override
           public void handle(ActionEvent oa) {
               timeField.clear();
               stage.close();
          }
      });
       btnBox.getChildren().addAll(cancelBtn, confirmBtn);
       return btnBox;
  }

}

用法:

MyDatePicker myDatePicker = new MyDatePicker(true);
myDatePicker.getDateTimeTool();
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
其他源码

支付宝微信运动步数网页源码附带原始接口代码

2023-1-16 0:17:57

技术文章

JDK1.7版本下JavaFx自定义日期选择器

2023-2-28 20:59:50

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索