1 /* 2 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. 3 * All rights reserved. Use is subject to license terms. 4 * 5 * This file is available and licensed under the following license: 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the distribution. 16 * - Neither the name of Oracle Corporation nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package ensemble.samples.controls.datepicker; 33 34 import java.time.LocalDate; 35 import java.util.Iterator; 36 import java.util.Locale; 37 import javafx.application.Application; 38 import javafx.beans.value.ChangeListener; 39 import javafx.beans.value.ObservableValue; 40 import javafx.collections.FXCollections; 41 import javafx.collections.ObservableList; 42 import javafx.event.ActionEvent; 43 import javafx.event.EventHandler; 44 import javafx.geometry.Pos; 45 import javafx.scene.Parent; 46 import javafx.scene.Scene; 47 import javafx.scene.control.CheckMenuItem; 48 import javafx.scene.control.DateCell; 49 import javafx.scene.control.DatePicker; 50 import javafx.scene.control.Menu; 51 import javafx.scene.control.MenuBar; 52 import javafx.scene.control.MenuItem; 53 import javafx.scene.control.RadioMenuItem; 54 import javafx.scene.control.Toggle; 55 import javafx.scene.control.ToggleGroup; 56 import javafx.scene.control.Tooltip; 57 import javafx.scene.layout.HBox; 58 import javafx.scene.layout.VBox; 59 import javafx.scene.text.Text; 60 import javafx.stage.Stage; 61 import javafx.util.Callback; 62 63 64 /** 65 * A sample that demonstrates the DatePicker. There is an option to switch 66 * locales and see how DatePicker control picks it up. 67 * 68 * @sampleName DatePicker 69 * @preview preview.png 70 * @see javafx.scene.control.DateCell 71 * @see javafx.scene.control.DatePicker 72 */ 73 public class DatePickerApp extends Application { 74 75 private final static ObservableList<String> locales = FXCollections.observableArrayList(); 76 private DatePicker datePicker; 77 private MenuBar datePickerMenuBar; 78 private final LocalDate today = LocalDate.now(); 79 private final LocalDate tomorrow = today.plusDays(1); 80 private Locale originalLocale; 81 private HBox hbox; 82 static { 83 locales.addAll(new String[]{ 84 "en-US", 85 "ar-SA", 86 "en-GB", 87 "cs-CZ", 88 "el-GR", 89 "he-IL", 90 "hi-IN", 91 "ja-JP", 92 "ja-JP-u-ca-japanese", 93 "ru-RU", 94 "sv-SE", 95 "th-TH", 96 "th-TH-u-ca-buddhist", 97 "th-TH-u-ca-buddhist-nu-thai", 98 "zh-CN", 99 "en-US-u-ca-islamic-umalqura", 100 "ar-SA-u-ca-islamic-umalqura", 101 "en-u-ca-japanese-nu-thai" 102 }); 103 } 104 105 public Parent createContent() { 106 Text datePickerText = new Text("Date:"); 107 108 hbox = new HBox(18); 109 hbox.setAlignment(Pos.CENTER); 110 hbox.getChildren().add(datePickerText); 111 112 datePicker = createDatePicker(); 113 114 VBox vbox = new VBox(22); 115 vbox.getChildren().addAll(datePickerMenuBar, hbox); 116 vbox.setPrefSize(300, 200); 117 vbox.setMinSize(VBox.USE_PREF_SIZE, VBox.USE_PREF_SIZE); 118 return vbox; 119 } 120 121 private DatePicker createDatePicker() { 122 hbox.getChildren().remove(datePicker); 123 LocalDate value = null; 124 if (datePicker != null) { 125 value = datePicker.getValue(); 126 } 127 DatePicker picker = new DatePicker(); 128 // day cell factory 129 final Callback<DatePicker, DateCell> dayCellFactory = new Callback<DatePicker, DateCell>() { 130 @Override 131 public DateCell call(final DatePicker datePicker) { 132 return new DateCell() { 133 @Override 134 public void updateItem(LocalDate item, boolean empty) { 135 super.updateItem(item, empty); 136 if (item.isBefore(today)) { 137 setStyle("-fx-background-color: #8099ff;"); 138 } else { 139 if (item.equals(tomorrow)) { 140 setTooltip(new Tooltip("Tomorrow is important")); 141 } 142 } 143 } 144 }; 145 } 146 }; 147 //Create the menubar to experiment with the DatePicker 148 datePickerMenuBar = createMenuBar(dayCellFactory); 149 // Listen for DatePicker actions 150 picker.setOnAction((ActionEvent t) -> { 151 LocalDate isoDate = picker.getValue(); 152 if ((isoDate != null) && (!isoDate.equals(LocalDate.now()))) { 153 for (Menu menu : datePickerMenuBar.getMenus()) { 154 if (menu.getText().equals("Options for Locale")) { 155 for (MenuItem menuItem : menu.getItems()) { 156 if (menuItem.getText().equals("Set date to today")) { 157 if ((menuItem instanceof CheckMenuItem) && ((CheckMenuItem) menuItem).isSelected()) { 158 ((CheckMenuItem) menuItem).setSelected(false); 159 } 160 } 161 } 162 } 163 } 164 } 165 }); 166 hbox.getChildren().add(picker); 167 if (value != null) { 168 picker.setValue(value); 169 } 170 return picker; 171 } 172 173 private MenuBar createMenuBar(final Callback<DatePicker, DateCell> dayCellFac) { 174 final MenuBar menuBar = new MenuBar(); 175 final ToggleGroup localeToggleGroup = new ToggleGroup(); 176 // Locales 177 Menu localeMenu = new Menu("Locales"); 178 Iterator<String> localeIterator = locales.iterator(); 179 while (localeIterator.hasNext()) { 180 RadioMenuItem localeMenuItem = new RadioMenuItem(localeIterator.next()); 181 localeMenuItem.setToggleGroup(localeToggleGroup); 182 localeMenu.getItems().add(localeMenuItem); 183 } 184 185 Menu optionsMenu = new Menu("Options for Locale"); 186 //Style DatePicker with cell factory 187 // XXX - localize 188 final String MSG = "Use cell factory to color past days and add tooltip to tomorrow"; 189 final CheckMenuItem cellFactoryMenuItem = new CheckMenuItem(MSG); 190 optionsMenu.getItems().add(cellFactoryMenuItem); 191 cellFactoryMenuItem.setOnAction((ActionEvent t) -> { 192 if (cellFactoryMenuItem.isSelected()) { 193 datePicker.setDayCellFactory(dayCellFac); 194 } else { 195 datePicker.setDayCellFactory(null); 196 } 197 }); 198 199 //Set date to today 200 final CheckMenuItem todayMenuItem = new CheckMenuItem("Set date to today"); 201 optionsMenu.getItems().add(todayMenuItem); 202 todayMenuItem.setOnAction((ActionEvent t) -> { 203 if (todayMenuItem.isSelected()) { 204 datePicker.setValue(today); 205 } 206 }); 207 208 //Set date to today 209 final CheckMenuItem showWeekNumMenuItem = new CheckMenuItem("Show week numbers"); 210 optionsMenu.getItems().add(showWeekNumMenuItem); 211 showWeekNumMenuItem.setOnAction((ActionEvent t) -> { 212 datePicker.setShowWeekNumbers(showWeekNumMenuItem.isSelected()); 213 }); 214 215 localeToggleGroup.selectedToggleProperty().addListener((ObservableValue<? extends Toggle> ov, 216 Toggle oldToggle, Toggle newToggle) -> { 217 if (localeToggleGroup.getSelectedToggle() != null) { 218 String selectedLocale = ((RadioMenuItem) localeToggleGroup.getSelectedToggle()).getText(); 219 Locale locale = Locale.forLanguageTag(selectedLocale.replace('_', '-')); 220 Locale.setDefault(locale); 221 datePicker = createDatePicker(); 222 datePicker.setShowWeekNumbers(showWeekNumMenuItem.isSelected()); 223 } 224 }); 225 226 menuBar.getMenus().addAll(localeMenu, optionsMenu); 227 return menuBar; 228 } 229 230 public void play() { 231 originalLocale = Locale.getDefault(); 232 } 233 234 @Override 235 public void stop() { 236 Locale.setDefault(originalLocale); 237 } 238 239 @Override 240 public void start(Stage primaryStage) throws Exception { 241 primaryStage.setScene(new Scene(createContent())); 242 primaryStage.show(); 243 play(); 244 } 245 246 /** 247 * Java main for when running without JavaFX launcher 248 * @param args command line arguments 249 */ 250 public static void main(String[] args) { 251 launch(args); 252 } 253 }