1 /* 2 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.javafx.scene.control.skin; 27 28 import java.time.LocalDate; 29 import java.time.DateTimeException; 30 import java.time.YearMonth; 31 import java.time.format.DecimalStyle; 32 import java.time.chrono.Chronology; 33 import java.time.chrono.HijrahChronology; 34 import java.time.chrono.HijrahDate; 35 import java.time.chrono.IsoChronology; 36 import java.util.Locale; 37 38 import static java.time.temporal.ChronoField.*; 39 40 import javafx.geometry.Pos; 41 import javafx.scene.control.DatePicker; 42 import javafx.scene.control.DateCell; 43 import javafx.scene.control.Label; 44 import javafx.scene.layout.BorderPane; 45 import javafx.scene.text.Text; 46 47 /** 48 * Extends DatePickerContent to add a secondary calendar, allowing the 49 * ISO and Islamic calendars to be displayed simultaneously. The 50 * secondary month, day, and year values are displayed as a colored 51 * overlay, offset from the primary values. 52 * 53 * If the current DatePicker Chronology is HijrahChronology, then sets 54 * the content's primary Chronology to be IsoChronology, and sets 55 * HijrahChronology as the secondary. 56 */ 57 class DatePickerHijrahContent extends DatePickerContent { 58 private Label hijrahMonthYearLabel; 59 60 DatePickerHijrahContent(final DatePicker datePicker) { 61 super(datePicker); 62 } 63 64 /** 65 * The primary chronology for display. This is overridden because 66 * DatePickerHijrahContent uses ISO as primary and Hijrah as a 67 * secondary chronology. 68 */ 69 @Override protected Chronology getPrimaryChronology() { 70 return IsoChronology.INSTANCE; 71 } 72 73 @Override protected BorderPane createMonthYearPane() { 74 BorderPane monthYearPane = super.createMonthYearPane(); 75 76 hijrahMonthYearLabel = new Label(); 77 hijrahMonthYearLabel.getStyleClass().add("secondary-label"); 78 monthYearPane.setBottom(hijrahMonthYearLabel); 79 BorderPane.setAlignment(hijrahMonthYearLabel, Pos.CENTER); 80 81 return monthYearPane; 82 } 83 84 85 @Override protected void updateMonthYearPane() { 86 super.updateMonthYearPane(); 87 88 Locale locale = getLocale(); 89 HijrahChronology chrono = HijrahChronology.INSTANCE; 90 long firstMonth = -1; 91 long firstYear = -1; 92 String firstMonthStr = null; 93 String firstYearStr = null; 94 String hijrahStr = null; 95 YearMonth displayedYearMonth = displayedYearMonthProperty().get(); 96 97 for (DateCell dayCell : dayCells) { 98 LocalDate date = dayCellDate(dayCell); 99 100 // Display Hijra month names only for current ISO month. 101 if (!displayedYearMonth.equals(YearMonth.from(date))) { 102 continue; 103 } 104 105 try { 106 HijrahDate cDate = chrono.date(date); 107 long month = cDate.getLong(MONTH_OF_YEAR); 108 long year = cDate.getLong(YEAR); 109 110 if (hijrahStr == null || month != firstMonth) { 111 String monthStr = monthFormatter.withLocale(locale) 112 .withChronology(chrono) 113 .withDecimalStyle(DecimalStyle.of(locale)) 114 .format(cDate); 115 String yearStr = yearFormatter.withLocale(locale) 116 .withChronology(chrono) 117 .withDecimalStyle(DecimalStyle.of(locale)) 118 .format(cDate); 119 if (hijrahStr == null) { 120 firstMonth = month; 121 firstYear = year; 122 firstMonthStr = monthStr; 123 firstYearStr = yearStr; 124 hijrahStr = firstMonthStr + " " + firstYearStr; 125 } else { 126 if (year > firstYear) { 127 hijrahStr = firstMonthStr + " " + firstYearStr + " - " + monthStr + " " + yearStr; 128 } else { 129 hijrahStr = firstMonthStr + " - " + monthStr + " " + firstYearStr; 130 } 131 break; 132 } 133 } 134 } catch (DateTimeException ex) { 135 // Date is out of range, ignore. 136 137 //System.err.println(dayCellDate(dayCell) + " " + ex); 138 } 139 } 140 141 hijrahMonthYearLabel.setText(hijrahStr); 142 } 143 144 @Override protected void createDayCells() { 145 super.createDayCells(); 146 147 for (DateCell dayCell : dayCells) { 148 Text secondaryText = new Text(); 149 dayCell.getProperties().put("DateCell.secondaryText", secondaryText); 150 } 151 } 152 153 @Override void updateDayCells() { 154 super.updateDayCells(); 155 156 Locale locale = getLocale(); 157 HijrahChronology chrono = HijrahChronology.INSTANCE; 158 159 int majorityMonth = -1; 160 int visibleDaysInMajorityMonth = -1; 161 int curMonth = -1; 162 int visibleDaysInCurMonth = 0; 163 164 for (DateCell dayCell : dayCells) { 165 Text secondaryText = (Text)dayCell.getProperties().get("DateCell.secondaryText"); 166 dayCell.getStyleClass().add("hijrah-day-cell"); 167 secondaryText.getStyleClass().setAll("text", "secondary-text"); 168 169 try { 170 HijrahDate cDate = chrono.date(dayCellDate(dayCell)); 171 // long month = cDate.getLong(MONTH_OF_YEAR); 172 173 String hijrahStr = 174 dayCellFormatter.withLocale(locale) 175 .withChronology(chrono) 176 .withDecimalStyle(DecimalStyle.of(locale)) 177 .format(cDate); 178 179 secondaryText.setText(hijrahStr); 180 dayCell.requestLayout(); 181 } catch (DateTimeException ex) { 182 // Date is out of range. 183 // System.err.println(dayCellDate(dayCell) + " " + ex); 184 secondaryText.setText(" "); 185 dayCell.setDisable(true); 186 } 187 188 // if (month == curMonth) { 189 // visibleDaysInCurMonth++; 190 // } else { 191 // curMonth = month; 192 // visibleDaysInCurMonth = 1; 193 // } 194 // if (visibleDaysInCurMonth > visibleDaysInMajorityMonth) { 195 // majorityMonth = month; 196 // visibleDaysInMajorityMonth = visibleDaysInCurMonth; 197 // } 198 } 199 200 // boolean seenMajorityMonth = false; 201 // for (DateCell dayCell : dayCells) { 202 // HijrahDate cDate = chrono.date(dayCellDate(dayCell)); 203 // int month = cDate.get(MONTH_OF_YEAR); 204 // Text secondaryText = (Text)dayCell.getProperties().get("DateCell.secondaryText"); 205 206 // if (month == majorityMonth) { 207 // seenMajorityMonth = true; 208 // secondaryText.getStyleClass().add("current-month"); 209 // } else { 210 // secondaryText.getStyleClass().add(seenMajorityMonth ? "next-month" : "previous-month"); 211 // } 212 // } 213 } 214 }