modules/controls/src/main/java/javafx/scene/control/skin/DatePickerSkin.java

Print this page
rev 9240 : 8076423: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization

@@ -21,38 +21,76 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
 
-package com.sun.javafx.scene.control.skin;
+package javafx.scene.control.skin;
 
 import java.time.LocalDate;
 import java.time.YearMonth;
 import java.time.chrono.HijrahChronology;
-import java.time.format.DateTimeParseException;
 
+import com.sun.javafx.scene.control.DatePickerContent;
+import com.sun.javafx.scene.control.DatePickerHijrahContent;
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.behavior.ComboBoxBaseBehavior;
 import javafx.beans.InvalidationListener;
 import javafx.beans.Observable;
 import javafx.event.ActionEvent;
 import javafx.geometry.Insets;
 import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.Control;
 import javafx.scene.control.DatePicker;
 import javafx.scene.control.TextField;
 import javafx.util.StringConverter;
 
 import com.sun.javafx.scene.control.behavior.DatePickerBehavior;
 
+/**
+ * Default skin implementation for the {@link DatePicker} control.
+ *
+ * @see DatePicker
+ * @since 9
+ */
 public class DatePickerSkin extends ComboBoxPopupControl<LocalDate> {
 
-    private DatePicker datePicker;
+    /***************************************************************************
+     *                                                                         *
+     * Private fields                                                          *
+     *                                                                         *
+     **************************************************************************/
+
+    private final DatePicker datePicker;
     private TextField displayNode;
     private DatePickerContent datePickerContent;
 
-    public DatePickerSkin(final DatePicker datePicker) {
-        super(datePicker, new DatePickerBehavior(datePicker));
+    private final DatePickerBehavior behavior;
+
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Constructors                                                            *
+     *                                                                         *
+     **************************************************************************/
+
+    /**
+     * Creates a new DatePickerSkin instance, installing the necessary child
+     * nodes into the Control {@link Control#getChildren() children} list, as
+     * well as the necessary input mappings for handling key, mouse, etc events.
+     *
+     * @param control The control that this skin should be installed onto.
+     */
+    public DatePickerSkin(final DatePicker control) {
+        super(control);
+
+        this.datePicker = control;
 
-        this.datePicker = datePicker;
+        // install default input map for the control
+        this.behavior = new DatePickerBehavior(control);
+//        control.setInputMap(behavior.getInputMap());
 
         // The "arrow" is actually a rectangular svg icon resembling a calendar.
         // Round the size of the icon to whole integers to get sharp edges.
         arrow.paddingProperty().addListener(new InvalidationListener() {
             // This boolean protects against unwanted recursion.

@@ -69,17 +107,68 @@
                     }
                 }
             }
         });
 
-        registerChangeListener(datePicker.chronologyProperty(), "CHRONOLOGY");
-        registerChangeListener(datePicker.converterProperty(), "CONVERTER");
-        registerChangeListener(datePicker.dayCellFactoryProperty(), "DAY_CELL_FACTORY");
-        registerChangeListener(datePicker.showWeekNumbersProperty(), "SHOW_WEEK_NUMBERS");
-        registerChangeListener(datePicker.valueProperty(), "VALUE");
+        registerChangeListener(control.chronologyProperty(), e -> {
+            updateDisplayNode();
+            datePickerContent = null;
+            popup = null;
+        });
+        registerChangeListener(control.converterProperty(), e -> updateDisplayNode());
+        registerChangeListener(control.dayCellFactoryProperty(), e -> {
+            updateDisplayNode();
+            datePickerContent = null;
+            popup = null;
+        });
+        registerChangeListener(control.showWeekNumbersProperty(), e -> {
+            if (datePickerContent != null) {
+                datePickerContent.updateGrid();
+                datePickerContent.updateWeeknumberDateCells();
+            }
+        });
+        registerChangeListener(control.valueProperty(), e -> {
+            updateDisplayNode();
+            if (datePickerContent != null) {
+                LocalDate date = control.getValue();
+                datePickerContent.displayedYearMonthProperty().set((date != null) ? YearMonth.from(date) : YearMonth.now());
+                datePickerContent.updateValues();
+            }
+            control.fireEvent(new ActionEvent());
+        });
+        registerChangeListener(control.showingProperty(), e -> {
+            if (control.isShowing()) {
+                if (datePickerContent != null) {
+                    LocalDate date = control.getValue();
+                    datePickerContent.displayedYearMonthProperty().set((date != null) ? YearMonth.from(date) : YearMonth.now());
+                    datePickerContent.updateValues();
+                }
+                show();
+            } else {
+                hide();
+            }
+        });
+    }
+
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Public API                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    /** {@inheritDoc} */
+    @Override public void dispose() {
+        super.dispose();
+
+        if (behavior != null) {
+            behavior.dispose();
+        }
     }
 
+    /** {@inheritDoc} */
     @Override public Node getPopupContent() {
         if (datePickerContent == null) {
             if (datePicker.getChronology() instanceof HijrahChronology) {
                 datePickerContent = new DatePickerHijrahContent(datePicker);
             } else {

@@ -88,80 +177,36 @@
         }
 
         return datePickerContent;
     }
 
+    /** {@inheritDoc} */
     @Override protected double computeMinWidth(double height,
                                                double topInset, double rightInset,
                                                double bottomInset, double leftInset) {
         return 50;
     }
 
-    @Override protected void focusLost() {
-        // do nothing
-    }
-
-
+    /** {@inheritDoc} */
     @Override public void show() {
         super.show();
         datePickerContent.clearFocus();
     }
 
-    @Override protected void handleControlPropertyChanged(String p) {
-
-        if ("CHRONOLOGY".equals(p) ||
-            "DAY_CELL_FACTORY".equals(p)) {
-
-            updateDisplayNode();
-//             if (datePickerContent != null) {
-//                 datePickerContent.refresh();
-//             }
-            datePickerContent = null;
-            popup = null;
-        } else if ("CONVERTER".equals(p)) {
-            updateDisplayNode();
-        } else if ("EDITOR".equals(p)) {
-            getEditableInputNode();
-        } else if ("SHOWING".equals(p)) {
-            if (datePicker.isShowing()) {
-                if (datePickerContent != null) {
-                    LocalDate date = datePicker.getValue();
-                    datePickerContent.displayedYearMonthProperty().set((date != null) ? YearMonth.from(date) : YearMonth.now());
-                    datePickerContent.updateValues();
-                }
-                show();
-            } else {
-                hide();
-            }
-        } else if ("SHOW_WEEK_NUMBERS".equals(p)) {
-            if (datePickerContent != null) {
-                datePickerContent.updateGrid();
-                datePickerContent.updateWeeknumberDateCells();
-            }
-        } else if ("VALUE".equals(p)) {
-            updateDisplayNode();
-            if (datePickerContent != null) {
-                LocalDate date = datePicker.getValue();
-                datePickerContent.displayedYearMonthProperty().set((date != null) ? YearMonth.from(date) : YearMonth.now());
-                datePickerContent.updateValues();
-            }
-            datePicker.fireEvent(new ActionEvent());
-        } else {
-            super.handleControlPropertyChanged(p);
-        }
-    }
-
+    /** {@inheritDoc} */
     @Override protected TextField getEditor() {
         // Use getSkinnable() here because this method is called from
         // the super constructor before datePicker is initialized.
         return ((DatePicker)getSkinnable()).getEditor();
     }
 
+    /** {@inheritDoc} */
     @Override protected StringConverter<LocalDate> getConverter() {
         return ((DatePicker)getSkinnable()).getConverter();
     }
 
+    /** {@inheritDoc} */
     @Override public Node getDisplayNode() {
         if (displayNode == null) {
             displayNode = getEditableInputNode();
             displayNode.getStyleClass().add("date-picker-display-node");
             updateDisplayNode();

@@ -169,13 +214,23 @@
         displayNode.setEditable(datePicker.isEditable());
 
         return displayNode;
     }
 
-    public void syncWithAutoUpdate() {
-        if (!getPopup().isShowing() && datePicker.isShowing()) {
-            // Popup was dismissed. Maybe user clicked outside or typed ESCAPE.
-            // Make sure DatePicker button is in sync.
-            datePicker.hide();
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Private implementation                                                  *
+     *                                                                         *
+     **************************************************************************/
+
+    /** {@inheritDoc} */
+    @Override void focusLost() {
+        // do nothing
         }
+
+    /** {@inheritDoc} */
+    @Override ComboBoxBaseBehavior getBehavior() {
+        return behavior;
     }
 }