1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * ident        "%Z%%M% %I%     %E% SMI"
  24  *
  25  * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
  26  * All rights reserved.
  27  */
  28 
  29     import java.awt.*;
  30     import java.awt.event.*;
  31     import java.text.NumberFormat;
  32     import java.util.ResourceBundle;
  33     import java.util.MissingResourceException;
  34 
  35     /**
  36      * This creates a modal dialog box that lets the user enter a duration of
  37      * time in seconds/minutes/hours/days/weeks/months/years.
  38      */
  39     public class DurationHelper extends Dialog {
  40 
  41         private boolean save;
  42 
  43         private Frame parent;
  44 
  45         private Choice unit;
  46         private TextField value;
  47         private Label  total;
  48 
  49         private Button ok;
  50         private Button cancel;
  51         private Button help;
  52         private Button compute;
  53 
  54         private HelpDialog hd = null;
  55 
  56         // For I18N
  57             private static ResourceBundle rb =
  58             ResourceBundle.getBundle("GuiResource" /* NOI18N */);
  59             private static ResourceBundle hrb =
  60             ResourceBundle.getBundle("HelpData" /* NOI18N */);
  61 
  62         private static String[] units = { getString("Seconds"),
  63                                         getString("Minutes"),
  64                                         getString("Hours"),
  65                                         getString("Days"),
  66                                         getString("Weeks"),
  67                                         getString("Months"),
  68                                         getString("Years")      };
  69         private static int[] unitMultipliers = {1, 60, 60*60, 60*60*24,
  70                                                 60*60*24*7, 60*60*24*30,
  71                                                 60*60*24*365    };
  72         private static NumberFormat nf = NumberFormat.getInstance();
  73         private static Toolkit toolkit = Toolkit.getDefaultToolkit();
  74 
  75         /**
  76          * Constructor for DurationHelper.
  77          * @param parent the parent Frame to whom input will be blocked
  78          * while this dialog box is begin shown(modal behaviour).
  79          */
  80     public DurationHelper(Frame parent,  Color background, Color foreground) {
  81                 super(parent, getString("SEAM Duration Helper"), true);
  82 
  83                 this.parent = parent;
  84 
  85                 setLayout(new GridBagLayout());
  86                 addLabels();
  87                 addFields(background, foreground);
  88                 addButtons();
  89                 setSize(350, 150);
  90                 setResizable(false);
  91                 addWindowListener(new DHWindowListener());
  92     }
  93 
  94     /**
  95      * Adds all the labels.
  96      */
  97     private void addLabels() {
  98         GridBagConstraints gbc = new GridBagConstraints();
  99         gbc.weightx = gbc.weighty = 1;
 100         add(new Label(getString("Unit")), gbc);
 101         add(new Label(getString("Value")), gbc);
 102 
 103         gbc.gridx = 3;
 104         gbc.gridy = 0;
 105         add(new Label(getString("Seconds")), gbc);
 106     }
 107 
 108     /**
 109      * Initializes the strings for the units.
 110      */
 111     private void initUnits() {
 112         unit = new Choice();
 113         for (int i = 0; i < units.length; i++)
 114             unit.add(units[i]);
 115         unit.select(getString("Hours"));
 116         unit.addItemListener(new ItemListener() {
 117                 public void itemStateChanged(ItemEvent e) {
 118                         DurationHelper.this.checkErrorAndSetTotal();
 119                 }
 120         });
 121     }
 122 
 123     /**
 124      * Adds all the fields
 125      */
 126     private void addFields(Color background, Color foreground) {
 127         GridBagConstraints gbc = new GridBagConstraints();
 128         gbc.weightx =  gbc.weighty = 1;
 129         initUnits();
 130         value = new TextField();
 131         value.setBackground(background);
 132         value.setForeground(foreground);
 133         value.setColumns(10);
 134 
 135         // TBD: make total large enough to hold the largest int
 136         total = new Label("             " /* NO18N */,
 137                             Label.RIGHT);
 138         gbc.gridx = 0;
 139         gbc.gridy = 1;
 140         add(unit, gbc);
 141         gbc.gridx = 1;
 142         add(value, gbc);
 143         gbc.gridx = 3;
 144         add(total, gbc);
 145 
 146         value.addActionListener(new ActionListener() {
 147                 public void actionPerformed(ActionEvent e) {
 148                         DurationHelper.this.durationHelperClose(true);
 149                 }
 150         });
 151     }
 152 
 153     /**
 154      * Adds all the buttons.
 155      */
 156     private void addButtons() {
 157 
 158         GridBagConstraints gbc = new GridBagConstraints();
 159         gbc.weightx =  gbc.weighty = 1;
 160 
 161         gbc.gridwidth = GridBagConstraints.REMAINDER;
 162         gbc.fill = GridBagConstraints.BOTH;
 163         gbc.gridx = 0;
 164         gbc.gridy = 2;
 165         gbc.insets = new Insets(0, 10, 0, 10);
 166         add(new LineSeparator(), gbc);
 167         gbc.insets = new Insets(0, 0, 0, 0);
 168 
 169         Panel p = new Panel();
 170         p.setLayout(new GridBagLayout());
 171         ok = new Button(getString("OK"));
 172         cancel =  new Button(getString("Cancel"));
 173         help = new Button(getString("Help"));
 174         gbc = new GridBagConstraints();
 175         gbc.weightx =  gbc.weighty = 1;
 176         p.add(ok, gbc);
 177         p.add(cancel, gbc);
 178         p.add(help, gbc);
 179 
 180         ActionListener bl = new ButtonListener();
 181         ok.addActionListener(bl);
 182         cancel.addActionListener(bl);
 183         help.addActionListener(bl);
 184 
 185         gbc.gridy = 3;
 186         gbc.gridwidth = GridBagConstraints.REMAINDER;
 187         gbc.fill = GridBagConstraints.HORIZONTAL;
 188         add(p, gbc);
 189 
 190         gbc = new GridBagConstraints();
 191         gbc.gridx = 2;
 192         gbc.gridy = 1;
 193         compute = new Button(getString("="));
 194         add(compute, gbc);
 195         compute.addActionListener(bl);
 196 
 197     }
 198 
 199     /**
 200      * Updates the label called total.
 201      * @return false if the text entry in the value
 202      * field is not parseable, true otherwise.
 203      */
 204     private boolean checkErrorAndSetTotal() {
 205         try {
 206             String noSpaces = value.getText().trim();
 207             value.setText(noSpaces);
 208             Long l = Long.valueOf(noSpaces);
 209             total.setText(nf.format(l.longValue() *
 210                 unitMultipliers[unit.getSelectedIndex()]));
 211         } catch (NumberFormatException e) {
 212           value.requestFocus();
 213           value.selectAll();
 214           toolkit.beep();
 215           return false;
 216         }
 217 
 218         return true;
 219     }
 220 
 221     /**
 222      * Hides the duration helper.
 223      * @param save true if the user wants to save the current value in
 224      * the dialog box, false if it is to be discarded. This is decided
 225      * based on whether the user clicked on the "Ok" button or the
 226      * "Cancel" button. Choosing the window close menu is equivalent to
 227      *  clicking on "Cancel."
 228      */
 229     private void durationHelperClose(boolean save) {
 230         if (save == true) {
 231             if (!checkErrorAndSetTotal())
 232                 return;
 233         }
 234         this.save = save;
 235         setVisible(false);
 236     }
 237 
 238     /**
 239      * Determine whether or not the user wanted to save the value in
 240      * this Dialog box. The user indicates this by clicking on the Ok
 241      * button to save it and on the Cancel button to discard it. Using the
 242      * window close menu responds the same way as cancel. 
 243      * @return true if the user wanted to use this value,
 244      * false if it is to be discarded.
 245      */
 246     public boolean isSaved() {
 247         return save;
 248     }
 249 
 250     /**
 251      * The string representation of the contents of this dialog box.
 252      * @return a String with the total number of seconds entered.
 253      */
 254     public String toString() {
 255         return total.getText();
 256     }
 257 
 258     // * **********************************************
 259     //   I N N E R    C L A S S E S   F O L L O W
 260     // * **********************************************
 261 
 262     /**
 263      * Listener for closing the dialog box through the window close
 264      * menu.
 265      */
 266     private class DHWindowListener extends WindowAdapter {
 267         public  void windowClosing(WindowEvent e) {
 268                 durationHelperClose(false);
 269         }
 270     }
 271 
 272     /**
 273      * Listener for all the buttons.
 274      * The listener is shared for the sake
 275      * of reducing the number of overall listeners.
 276      */
 277     private class ButtonListener implements ActionListener {
 278         public void actionPerformed(ActionEvent e) {
 279             if (e.getSource() == ok) {
 280                 DurationHelper.this.durationHelperClose(true);
 281             } else if (e.getSource() == cancel) {
 282                 DurationHelper.this.durationHelperClose(false);
 283             } else if (e.getSource() == help) {
 284                 if (hd != null)
 285                     hd.show();
 286                 else {
 287                     hd = new HelpDialog(DurationHelper. this.parent,
 288                         getString("Help for entering time duration"),
 289                                     false, 5, 45);
 290                     hd.setVisible(true);
 291                     hd.setText(getString(hrb, "DurationHelperHelp"));
 292                 }
 293             } else if (e.getSource() == compute) {
 294                 checkErrorAndSetTotal();
 295             }
 296         }
 297     }
 298 
 299     /**
 300      * Call rb.getString(), but catch exception
 301      * and return English
 302      * key so that small spelling errors don't cripple the GUI
 303      *
 304      */
 305     private static final String getString(String key) {
 306         return (getString(rb, key));
 307     }
 308 
 309     private static final String getString(ResourceBundle rb, String key) {
 310         try {
 311             String res = rb.getString(key);
 312             return res;
 313         } catch (MissingResourceException e) {
 314                 System.out.println("Missing resource "+key+", using English.");
 315                 return key;
 316         }
 317     }
 318 
 319     /*
 320      * A main method to test this class.
 321      */
 322     /*
 323     public static void main(String args[]) {
 324         Frame f = new Frame("Test DurationHelper");
 325         f.setVisible(true); // for help dialog to use this as parent
 326         DurationHelper dh = new DurationHelper(f, Color.white, Color.black);
 327         dh.setVisible(true);
 328         System.out.println("Save is " + dh.save);
 329     }
 330           */
 331 }