001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2016 005 * Space Science and Engineering Center (SSEC) 006 * University of Wisconsin - Madison 007 * 1225 W. Dayton Street, Madison, WI 53706, USA 008 * https://www.ssec.wisc.edu/mcidas 009 * 010 * All Rights Reserved 011 * 012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 013 * some McIDAS-V source code is based on IDV and VisAD source code. 014 * 015 * McIDAS-V is free software; you can redistribute it and/or modify 016 * it under the terms of the GNU Lesser Public License as published by 017 * the Free Software Foundation; either version 3 of the License, or 018 * (at your option) any later version. 019 * 020 * McIDAS-V is distributed in the hope that it will be useful, 021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 023 * GNU Lesser Public License for more details. 024 * 025 * You should have received a copy of the GNU Lesser Public License 026 * along with this program. If not, see http://www.gnu.org/licenses. 027 */ 028 029package edu.wisc.ssec.mcidasv.ui; 030 031import java.awt.BorderLayout; 032 033import java.util.Calendar; 034import java.util.Date; 035import java.util.GregorianCalendar; 036import java.util.TimeZone; 037 038import javax.swing.JComponent; 039import javax.swing.JLabel; 040import javax.swing.JPanel; 041import javax.swing.JSpinner; 042import javax.swing.SpinnerDateModel; 043 044import com.toedter.calendar.JCalendar; 045import com.toedter.calendar.JDateChooser; 046 047import ucar.unidata.idv.IdvConstants; 048import ucar.unidata.util.GuiUtils; 049 050/** 051 * This class is just a backport of the IDV's old {@code DateTimePicker}. 052 */ 053public class JCalendarPicker extends JPanel { 054 055 /** Date chooser */ 056 private JDateChooser dateChooser; 057 058 /** SpinnerDateModel */ 059 private SpinnerDateModel timeModel; 060 061 /** JCalendar */ 062 private JCalendar jc; 063 064 /** 065 * Default constructor. Builds a {@code JCalendarPicker} with a {@code null} 066 * initial date and includes the {@literal "hour picker"}. 067 */ 068 public JCalendarPicker() { 069 this(null, null, true); 070 } 071 072 /** 073 * Creates a {@code JCalendarPicker} with a {@code null} initial date. 074 * 075 * @param includeHours Whether or not to include an hour picker. 076 */ 077 public JCalendarPicker(boolean includeHours) { 078 this(null, null, includeHours); 079 } 080 081 /** 082 * Create a {@code JCalendarPicker} with the initial date. 083 * 084 * @param date Initial date. {@code null} is allowed. 085 */ 086 public JCalendarPicker(Date date) { 087 this(date, null, true); 088 } 089 090 /** 091 * Create a {@code JCalendarPicker} with the initial date. 092 * 093 * @param date Initial date. {@code null} is allowed. 094 * @param timeZoneId Time zone identifier. If {@code null}, 095 * {@link IdvConstants#DEFAULT_TIMEZONE} is used. 096 * @param includeHours {@code true} to have an hour picker. 097 * 098 * @see TimeZone#getTimeZone(String) 099 */ 100 public JCalendarPicker(Date date, String timeZoneId, boolean includeHours) { 101 jc = new JCalendar(); 102 Calendar calendar = getCalendar(null); 103 jc.getDayChooser().setCalendar(calendar); 104 jc.setCalendar(calendar); 105 106 dateChooser = new JDateChooser(jc, new Date(), null, new JCalendarDateEditor()); 107 setLayout(new BorderLayout()); 108 109 // Create a date spinner that controls the hours 110 timeModel = new SpinnerDateModel(calendar.getTime(), null, null, 111 Calendar.HOUR_OF_DAY); 112 JSpinner spinner = new JSpinner(timeModel); 113 JSpinner.DateEditor editor = 114 new JSpinner.DateEditor(spinner, "HH:mm"); 115 spinner.setEditor(editor); 116 JComponent timeComp; 117 if (timeZoneId == null) { 118 timeZoneId = IdvConstants.DEFAULT_TIMEZONE; 119 } 120 String timeZoneLabel = ' ' + TimeZone.getTimeZone(timeZoneId).getID(); 121 if (includeHours) { 122 timeComp = GuiUtils.hbox(spinner, new JLabel(timeZoneLabel), 5); 123 } else { 124 timeComp = new JLabel(timeZoneLabel); 125 } 126 add(BorderLayout.CENTER, GuiUtils.hbox(dateChooser, timeComp)); 127 if (date != null) { 128 setDate(date); 129 } 130 } 131 132 public JDateChooser getDateChooser() { 133 return dateChooser; 134 } 135 136 /** 137 * Get the {@link Date} that has been set. 138 * 139 * @return {@code Date} that represents the user's selection. 140 */ 141 public Date getDate() { 142 Date d = dateChooser.getDate(); 143 Calendar c0 = getCalendar(d); 144 Calendar c1 = new GregorianCalendar(c0.get(Calendar.YEAR), 145 c0.get(Calendar.MONTH), 146 c0.get(Calendar.DAY_OF_MONTH)); 147 148 if (timeModel != null) { 149 Date time = timeModel.getDate(); 150 Calendar timeCal = getCalendar(time); 151 c1.set(Calendar.HOUR_OF_DAY, timeCal.get(Calendar.HOUR_OF_DAY)); 152 c1.set(Calendar.MINUTE, timeCal.get(Calendar.MINUTE)); 153 c1.set(Calendar.SECOND, timeCal.get(Calendar.SECOND)); 154 } 155 return c1.getTime(); 156 } 157 158 /** 159 * Get the calendar for this instance. 160 * 161 * @param date The date. If {@code null}, the current time in the system's 162 * default time zone will be used instead. 163 * 164 * @return {@link GregorianCalendar} associated with {@code date}. 165 */ 166 private Calendar getCalendar(Date date) { 167 Calendar calendar = new GregorianCalendar(); 168 if (date != null) { 169 calendar.setTime(date); 170 } 171 return calendar; 172 } 173 174 /** 175 * Set the {@link Date} that will be used to populate the GUI components. 176 * 177 * @param date {@code Date}. 178 */ 179 public void setDate(Date date) { 180 Calendar c = getCalendar(date); 181 dateChooser.setDate(c.getTime()); 182 timeModel.setValue(date); 183 } 184 185 /** 186 * Get the user's selection as a {@literal "YYYY-MM-DD"} string. 187 * <b>This method ignores time zones.</b> 188 * 189 * @return Selected date as a {@literal "YYYY-MM-DD"} string. 190 */ 191 public String getUserSelectedDay() { 192 Calendar selectedDay = getCalendar(dateChooser.getDate()); 193 int year = selectedDay.get(Calendar.YEAR); 194 int month = selectedDay.get(Calendar.MONTH) + 1; // zero-based 195 int day = selectedDay.get(Calendar.DAY_OF_MONTH); 196 return String.format("%d-%02d-%02d", year, month, day); 197 } 198}