/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * ident "%Z%%M% %I% %E% SMI" * * Copyright (c) 1999-2000 by Sun Microsystems, Inc. * All rights reserved. */ import java.awt.*; import java.awt.event.*; import java.text.*; import java.util.*; /** * This class creates a dialog box that helps the user enter date and * time with mouse clicks. The dialog box need only be created * once. The Ok and Cancel buttons merely call setVisible with an * argument of false. */ // The layout will consist of 3 panels: topPanel contains the // different labels and fields. middlePanel contains the buttons // midnight and now. bottomPanel contains the buttons ok, cancel and // help. The last two panels are separated by a LineSeparator. public class DateTimeDialog extends Dialog { private boolean save; private Frame parent; private DCPanel dateDCPanel; private DCPanel yearDCPanel; private DCPanel hourDCPanel; private DCPanel minuteDCPanel; private DCPanel secondDCPanel; private Choice month; private DCCircularTextField date; private DCCircularTextField hour; private DCCircularTextField second; private DCCircularTextField minute; private DCTextField year; private Button ok; private Button cancel; private Button help; private Button now; private Button midnight; private HelpDialog hd = null; private Panel topPanel; private Panel middlePanel; private Panel bottomPanel; private GregorianCalendar calendar = null; private static int MONTH_LEN[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; private static DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM); private static Toolkit toolkit = Toolkit.getDefaultToolkit(); // For I18N private static ResourceBundle rb = ResourceBundle.getBundle("GuiResource" /* NOI18N */); private static ResourceBundle hrb = ResourceBundle.getBundle("HelpData" /* NOI18N */); /** * Constructor that lays out the componeents and sets the different * event handlers. */ public DateTimeDialog(Frame parent, Color background, Color foreground) { super(parent, getString("SEAM Date/Time Helper"), true); this.parent = parent; setLayout(new GridBagLayout()); addLabels(); addFields(background, foreground); addDCPanels(); addButtons(); addFocusListeners(); setCurrentTime(); setSize(250, 300); setResizable(false); addWindowListener(new DCWindowListener()); // initializeFocusOnTextField(); } /** * Adds the labels only */ private void addLabels() { GridBagConstraints gbc = new GridBagConstraints(); gbc.weighty = 1; topPanel = new Panel(); topPanel.setLayout(new GridBagLayout()); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.BOTH; gbc.anchor = GridBagConstraints.CENTER; gbc.gridx = 0; gbc.gridy = 0; add(topPanel, gbc); gbc.fill = GridBagConstraints.NONE; gbc.anchor = GridBagConstraints.EAST; gbc.gridx = 0; gbc.gridwidth = 1; gbc.gridy = 0; topPanel.add(new Label(getString("Month")), gbc); gbc.gridy = 1; topPanel.add(new Label(getString("Date")), gbc); gbc.gridy = 2; topPanel.add(new Label(getString("Year")), gbc); gbc.gridy = 3; topPanel.add(new Label(getString("Hour")), gbc); gbc.gridy = 4; topPanel.add(new Label(getString("Minute")), gbc); gbc.gridy = 5; topPanel.add(new Label(getString("Second")), gbc); } /** * Adds the fields that will store the month, year, date, hour, * minute and second. */ private void addFields(Color background, Color foreground) { GridBagConstraints gbc = new GridBagConstraints(); gbc.weighty = 1; month = new Choice(); initializeMonth(); date = new DCCircularTextField("1", 2); date.setMinimum(1); date.setBackground(background); date.setForeground(foreground); hour = new DCCircularTextField("00", 2); hour.setMaximum(23); hour.setBackground(background); hour.setForeground(foreground); minute = new DCCircularTextField("00", 2); minute.setBackground(background); minute.setForeground(foreground); second = new DCCircularTextField("00", 2); second.setBackground(background); second.setForeground(foreground); year = new DCTextField("2000", 4); year.setBackground(background); year.setForeground(foreground); Panel tempPanel = new Panel(); tempPanel.add(month); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.anchor = GridBagConstraints.WEST; gbc.gridx = 1; gbc.gridy = 0; topPanel.add(tempPanel, gbc); // Remaining fields are in topPanel gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridx = 1; gbc.gridy = 1; topPanel.add(date, gbc); gbc.gridy = 2; topPanel.add(year, gbc); gbc.gridy = 3; topPanel.add(hour, gbc); gbc.gridy = 4; topPanel.add(minute, gbc); gbc.gridy = 5; topPanel.add(second, gbc); } // Adds the panels with the +/- buttons for each DCField private void addDCPanels() { GridBagConstraints gbc = new GridBagConstraints(); gbc.weighty = 1; gbc.gridx = 2; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridheight = 1; gbc.fill = GridBagConstraints.NONE; dateDCPanel = new DCPanel(); yearDCPanel = new DCPanel(); hourDCPanel = new DCPanel(); minuteDCPanel = new DCPanel(); secondDCPanel = new DCPanel(); gbc.gridy = 1; topPanel.add(dateDCPanel, gbc); gbc.gridy = GridBagConstraints.RELATIVE; topPanel.add(yearDCPanel, gbc); topPanel.add(hourDCPanel, gbc); topPanel.add(minuteDCPanel, gbc); topPanel.add(secondDCPanel, gbc); dateDCPanel.setListener(date); yearDCPanel.setListener(year); hourDCPanel.setListener(hour); minuteDCPanel.setListener(minute); secondDCPanel.setListener(second); } /** * Sets the strings in the month pull-down menu. Also adds a listener * that will modify the maximum date allowed depending on the month. */ private void initializeMonth() { DateFormatSymbols dfSymbols = new DateFormatSymbols(); String[] monthStrings = dfSymbols.getMonths(); month.removeAll(); for (int i = 0; i < monthStrings.length; i++) { month.add(monthStrings[i]); } month.addItemListener(new DCMonthChangeListener()); } // Adds all the buttons private void addButtons() { GridBagConstraints gbc = new GridBagConstraints(); gbc.weighty = 1; middlePanel = new Panel(); now = new Button(getString("Now")); midnight = new Button(getString("Midnight")); middlePanel.add(midnight); middlePanel.add(now); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; gbc.gridy = 1; add(middlePanel, gbc); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridheight = 1; gbc.fill = GridBagConstraints.BOTH; gbc.gridx = 0; gbc.gridy = 2; add(new LineSeparator(), gbc); bottomPanel = new Panel(); ok = new Button(getString("OK")); cancel = new Button(getString("Cancel")); help = new Button(getString("Help")); bottomPanel.add(ok); bottomPanel.add(cancel); bottomPanel.add(help); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; gbc.gridy = 3; add(bottomPanel, gbc); DCButtonListener bl = new DCButtonListener(); ok.addActionListener(bl); cancel.addActionListener(bl); help.addActionListener(bl); now.addActionListener(bl); midnight.addActionListener(bl); } /** * Adds a listener to all the text fields so that when they go out * of focus (by tab or clicking), their values are checked for * errors. */ private void addFocusListeners() { FocusListener fl = new DCFocusListener(); date.addFocusListener(fl); year.addFocusListener(fl); hour.addFocusListener(fl); minute.addFocusListener(fl); second.addFocusListener(fl); } /** * Closes (hides) the dialog box when the user is done * @param save true if the box is being dismissed by clicking on * "ok" and the user wants to retain the modified value, false * otherwise. */ private void dateTimeDialogClose(boolean save) { if (save == true) { if (!updateFromGui()) return; } this.save = save; setVisible(false); } /** * Checks to see is all text fields contain valid values. * @return true if all are valid, false otherwise. */ private boolean updateFromGui() { return (checkErrorAndSet(date) && checkErrorAndSet(year) && checkErrorAndSet(hour) && checkErrorAndSet(minute) && checkErrorAndSet(second)); } /** * Checks the value stored as text in the field and sets its numeric * value to that if it is legitimate. * @return true if the value was legitimate and got set, false * otherwise. */ private boolean checkErrorAndSet(DCTextField tf) { int i = 0; boolean errorState = false; try { i = new Integer(tf.getText().trim()).intValue(); errorState = !tf.checkValue(i); } catch (NumberFormatException e2) { errorState = true; } if (errorState) { tf.selectAll(); toolkit.beep(); } else tf.setValue(i); return !errorState; } /** * Checks if the user requested that the value in this * DateTimeDialog be used e.g., by clicking on "Ok" instead of * "Cancel." * @return true if the user wants to save the value in the * DateTimeDialog, false otherwise. */ public boolean isSaved() { return save; } /** * Sets the date and time in fields to the current date and time. */ public void setCurrentTime() { setDate(new Date()); } /** * Sets the current date of the DateTimeDialog and updates the gui * components to reflect that. * @param date the Date to set it to. */ public void setDate(Date newDate) { calendar = new GregorianCalendar(); calendar.setTime(newDate); // update gui components now year.setValue(calendar.get(Calendar.YEAR)); month.select(calendar.get(Calendar.MONTH)); date.setValue(calendar.get(Calendar.DATE)); // Make sure the date is in the valid range for the given month fixDateField(); hour.setValue(calendar.get(Calendar.HOUR_OF_DAY)); minute.setValue(calendar.get(Calendar.MINUTE)); second.setValue(calendar.get(Calendar.SECOND)); } /** * Set the time fields to midnight, i.e., clears them. */ private void setMidnight() { hour.setValue(0); minute.setValue(0); second.setValue(0); } /** * Make sure the date does not exceed the maximum allowable value * for the currently selected month. */ private void fixDateField() { int monthIndex = month.getSelectedIndex(); int max = MONTH_LEN[monthIndex]; date.setMaximum(calendar.isLeapYear(year.getValue()) && monthIndex == 1 ? max + 1 : max); } // * ********************************************** // I N N E R C L A S S E S F O L L O W // *********************************************** /** * Listener for closing the dialog box through the window close * menu. */ private class DCWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { dateTimeDialogClose(false); } } /** * Listener for any change in the month selected through the * pull down menu */ private class DCMonthChangeListener implements ItemListener { public void itemStateChanged(ItemEvent e) { fixDateField(); } } /** * Listener for all the buttons. The listener is shared for the sake * of reducing the number of overall listeners. * TBD: I18N the help */ private class DCButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (e.getSource() == ok) { DateTimeDialog.this.dateTimeDialogClose(true); } else if (e.getSource() == cancel) { DateTimeDialog.this.dateTimeDialogClose(false); } else if (e.getSource() == now) { DateTimeDialog.this.setCurrentTime(); } else if (e.getSource() == midnight) { DateTimeDialog.this.setMidnight(); } else if (e.getSource() == help) { if (hd != null) hd.show(); else { hd = new HelpDialog(DateTimeDialog.this.parent, getString("Help for Date and Time Dialog"), false); hd.setVisible(true); hd.setText(getString(hrb, "DateTimeDialogHelp")); } } } // actionPerformed } /** * Listener for any change in focus with respect to the text * fields. When a text field is going out of focus, it detemines if the * text value in it is valid. If not, it returns focus to that text * field. */ private class DCFocusListener extends FocusAdapter { public void focusLost(FocusEvent e) { if (!checkErrorAndSet((DCTextField)e.getSource())) ((DCTextField)e.getSource()).requestFocus(); } } /** * The string representation of the dialog box. * @return a String which contians the date and time in locale * default format, but to MEDIUM length formatting style. */ public String toString() { calendar = new GregorianCalendar(year.getValue(), month.getSelectedIndex(), date.getValue(), hour.getValue(), minute.getValue(), second.getValue()); return df.format(calendar.getTime()); } /** * Call rb.getString(), but catch exception and return English * key so that small spelling errors don't cripple the GUI * */ private static final String getString(String key) { return (getString(rb, key)); } private static final String getString(ResourceBundle rb, String key) { try { String res = rb.getString(key); return res; } catch (MissingResourceException e) { System.out.println("Missing resource "+key+", using English."); return key; } } /* public static final void main(String args[]) { Frame f = new Frame(); // while (true){ DateTimeDialog d = new DateTimeDialog(f, Color.white, Color.black); d.setVisible(true); System.out.println(d.toString()); // } } */ }