1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.  Oracle designates this
  10  * particular file as subject to the "Classpath" exception as provided
  11  * by Oracle in the LICENSE file that accompanied this code.
  12  *
  13  * This code is distributed in the hope that it will be useful, but WITHOUT
  14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16  * version 2 for more details (a copy is included in the LICENSE file that
  17  * accompanied this code).
  18  *
  19  * You should have received a copy of the GNU General Public License version
  20  * 2 along with this work; if not, write to the Free Software Foundation,
  21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  22  *
  23  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  24  * or visit www.oracle.com if you need additional information or have any
  25  * questions.
  26  */
  27 package com.sun.javatest.tool;
  28 
  29 import java.awt.Component;
  30 import java.awt.GridBagConstraints;
  31 import java.awt.GridBagLayout;
  32 import java.awt.event.ActionEvent;
  33 import java.awt.event.ActionListener;
  34 import java.util.Enumeration;
  35 import java.util.Map;
  36 import javax.swing.*;
  37 import javax.swing.plaf.basic.BasicComboBoxRenderer;
  38 
  39 /**
  40  * Preferences for the desktop itself.
  41  */
  42 class DesktopPrefsPane extends PreferencesPane {
  43     DesktopPrefsPane(Desktop desktop, UIFactory uif) {
  44         this.desktop = desktop;
  45         this.uif = uif;
  46         setHelp("ui.prefs.appearance.csh");
  47         setLayout(new GridBagLayout());
  48         GridBagConstraints c = new GridBagConstraints();
  49         c.fill = GridBagConstraints.HORIZONTAL;
  50         c.gridwidth = GridBagConstraints.REMAINDER;
  51         c.weightx = 1;
  52         c.insets.bottom= 10; // set off subsequent entries
  53 
  54         //add(createDesktopStylePanel(), c);
  55         styleGrp = new ButtonGroup();  // to avoid NPE
  56 
  57         add(createToolTipsPanel(), c);
  58         add(createShutdownPanel(), c);
  59 
  60         c.fill = GridBagConstraints.BOTH;
  61         c.weighty = 1;
  62         add(Box.createVerticalGlue(), c);
  63     }
  64 
  65     public String getText() {
  66         return uif.getI18NString("dt.prefs.name");
  67     }
  68 
  69     @Override
  70     public void load(Map<String, String> m) {
  71         String styleName = m.get(Desktop.STYLE_PREF);
  72         if (styleName == null)
  73             styleName = Desktop.styleNames[desktop.getStyle()];
  74 
  75         for (Enumeration<AbstractButton> e = styleGrp.getElements(); e.hasMoreElements(); ) {
  76             JRadioButton rb = (JRadioButton)e.nextElement();
  77             if (rb.getActionCommand().equals(styleName)) {
  78                 rb.setSelected(true);
  79                 break;
  80             }
  81         }
  82         // tooltips
  83         String tipState = m.get(Desktop.TTIP_PREF);
  84         ttipsCheck.setSelected(tipState == null || tipState.equalsIgnoreCase("true"));
  85 
  86         boolean complete = false;       // used for delay and duration code
  87 
  88         String tipDelay = m.get(Desktop.TTIP_DELAY);
  89         try {
  90             int delay = Integer.parseInt(tipDelay);
  91 
  92             if (delay == Desktop.TTIP_DELAY_NONE) {
  93                 // no delay
  94                 ttDelay.setSelectedItem(tooltipDelays[0]);
  95                 complete = true;
  96             }
  97             else {
  98                 for (int i = 1; i < ttDelay.getItemCount(); i++) {
  99                     if ( ttDelay.getItemAt(i).intValue() == delay ) {
 100                         ttDelay.setSelectedIndex(i);
 101                         i = ttDelay.getItemCount(); // stop loop
 102                         complete = true;
 103                     }
 104                 }   // for
 105 
 106             }   // if/else
 107         }
 108         catch (NumberFormatException e) {
 109             complete = false;
 110         }
 111 
 112         ttDelay.setEnabled(ttipsCheck.isSelected());
 113         ttDuration.setEnabled(ttipsCheck.isSelected());
 114 
 115         // default
 116         if (!complete)
 117                 ttDelay.setSelectedIndex(1);
 118 
 119         complete = false;
 120         String tipDuration = m.get(Desktop.TTIP_DURATION);
 121         try {
 122             int duration = Integer.parseInt(tipDuration);
 123             if (duration == Desktop.TTIP_DURATION_FOREVER) {
 124                 // forever
 125                 ttDuration.setSelectedItem(tooltipDurations[tooltipDurations.length-1]);
 126                 complete = true;
 127             }
 128             else {
 129                 for (int i = 0; i < tooltipDurations.length-1; i++) {
 130                     if (duration == tooltipDurations[i].intValue()) {
 131                         ttDuration.setSelectedItem(tooltipDurations[i]);
 132                         complete = true;
 133                         i = tooltipDurations.length;    // stop loop
 134                     }
 135                 }   // for
 136             }   // if/else
 137         }   // try
 138         catch (NumberFormatException e) {
 139             complete = false;
 140         }   // catch
 141 
 142         // default
 143         if (!complete){
 144                 ttDuration.setSelectedItem(tooltipDurations[1]);
 145             }
 146 
 147         // make it happen
 148         syncTooltipPrefs();
 149 
 150         // save on exit
 151         String saveState = m.get(Desktop.SAVE_ON_EXIT_PREF);
 152         saveCheck.setSelected(saveState == null || "true".equalsIgnoreCase(saveState)); // true (null) by default
 153         String restoreState = m.get(Desktop.RESTORE_ON_START_PREF); // false by default
 154         restoreCheck.setSelected(restoreState == null || "true".equalsIgnoreCase(restoreState));
 155     }
 156 
 157     @Override
 158     public void save(Map<String, String> m) {
 159         ButtonModel bm = styleGrp.getSelection();
 160         if (bm != null) {
 161             String styleName = bm.getActionCommand();
 162             for (int i = 0; i < Desktop.styleNames.length; i++) {
 163                 if (styleName.equals(Desktop.styleNames[i])) {
 164                     desktop.setStyle(i);
 165                     m.put(Desktop.STYLE_PREF, styleName);
 166                     break;
 167                 }
 168             }
 169         }
 170 
 171         boolean tips = ttipsCheck.isSelected();
 172         m.put(Desktop.TTIP_PREF, String.valueOf(tips));
 173         desktop.setTooltipsEnabled(tips);
 174 
 175         int delay = getTooltipDelay();
 176         m.put(Desktop.TTIP_DELAY, Integer.toString(delay));
 177         desktop.setTooltipDelay(delay);
 178 
 179         int duration = getTooltipDuration();
 180         m.put(Desktop.TTIP_DURATION, Integer.toString(duration));
 181         desktop.setTooltipDuration(duration);
 182 
 183         m.put(Desktop.SAVE_ON_EXIT_PREF, String.valueOf(saveCheck.isSelected()));
 184         desktop.setSaveOnExit(saveCheck.isSelected());
 185 
 186         m.put(Desktop.RESTORE_ON_START_PREF, String.valueOf(restoreCheck.isSelected()));
 187         desktop.setRestoreOnStart(restoreCheck.isSelected());
 188 
 189         syncTooltipPrefs();
 190     }
 191 
 192     /**
 193      * Force the GUI and the actual settings to be synchronized.
 194      */
 195     private void syncTooltipPrefs() {
 196         boolean tips = ttipsCheck.isSelected();
 197         desktop.setTooltipsEnabled(tips);
 198 
 199         int delay = getTooltipDelay();
 200         desktop.setTooltipDelay(delay);
 201 
 202         int duration = getTooltipDuration();
 203         desktop.setTooltipDuration(duration);
 204     }
 205    /* MDI/SID views are removed
 206     private Component createDesktopStylePanel() {
 207         Box p = Box.createHorizontalBox();
 208         p.setBorder(uif.createTitledBorder("dt.prefs.style"));
 209         styleGrp = new ButtonGroup();
 210         for (int i = 0; i < Desktop.styleNames.length; i++) {
 211             String styleName = Desktop.styleNames[i];
 212             String uiKey = "dt.prefs." + styleName;
 213             JRadioButton b = uif.createRadioButton(uiKey, styleGrp);
 214             b.setActionCommand(styleName);
 215             p.add(b);
 216         }
 217         p.add(Box.createHorizontalGlue());
 218 
 219         return p;
 220     }
 221     */
 222 
 223     private Component createShutdownPanel() {
 224         Box p = Box.createVerticalBox();
 225         p.setBorder(uif.createTitledBorder("dt.prefs.shutdown"));
 226 
 227     saveCheck = uif.createCheckBox("dt.prefs.saveOnExit");
 228         p.add(saveCheck);
 229 
 230         restoreCheck = uif.createCheckBox("dt.prefs.restoreOnStart");
 231         p.add(restoreCheck);
 232 
 233         p.add(Box.createVerticalGlue());
 234         return p;
 235     }
 236 
 237     private Component createToolTipsPanel() {
 238         JPanel p = uif.createPanel("dt.prefs.tt", false);
 239 
 240         p.setLayout(new GridBagLayout());
 241         GridBagConstraints c = new GridBagConstraints();
 242         c.anchor = GridBagConstraints.WEST;
 243         c.ipadx = 3;
 244         c.ipady = 5;
 245         c.fill = GridBagConstraints.VERTICAL;
 246         c.insets.left = 3;
 247         c.insets.right = 3;
 248         c.insets.top = 2;
 249         c.insets.bottom = 2;
 250 
 251         p.setBorder(uif.createTitledBorder("dt.prefs.ttips"));
 252         ttipsCheck = uif.createCheckBox("dt.prefs.ttips");
 253         // override default name
 254         uif.setAccessibleName(ttipsCheck, "dt.prefs.ttips");
 255 
 256         ttipsCheck.addActionListener(new ActionListener() {
 257                 public void actionPerformed(ActionEvent e) {
 258                     boolean state = ttipsCheck.isSelected();
 259                     ttDelay.setEnabled(state);
 260                     ttDuration.setEnabled(state);
 261                 }
 262             });
 263         c.gridwidth = GridBagConstraints.REMAINDER;
 264         c.weightx = 1;
 265         p.add(ttipsCheck, c);
 266 
 267         loadTooltipResources();
 268 
 269         JLabel l = uif.createLabel("dt.prefs.ttDelay", true);
 270 
 271         ttDelay = uif.createChoice("dt.prefs.ttDelay", l);
 272         for (int i = 0; i < tooltipDelays.length; i++)
 273             ttDelay.addItem(tooltipDelays[i]);
 274 
 275         ttDelay.setSelectedItem(tooltipDelays[0]);
 276         ttDelay.setRenderer(new TipDelayRenderer());
 277 
 278         c.gridwidth = 1;
 279         c.weightx = 0;
 280         p.add(l, c);
 281 
 282         c.gridwidth = GridBagConstraints.REMAINDER;
 283         c.weightx = 1;
 284         p.add(ttDelay, c);
 285 
 286         l = uif.createLabel("dt.prefs.ttDuration", true);
 287 
 288         ttDuration = uif.createChoice("dt.prefs.ttDuration", l);
 289         for (int i = 0; i < tooltipDurations.length; i++)
 290             ttDuration.addItem(tooltipDurations[i]);
 291 
 292         ttDuration.setRenderer(new TipDurationRenderer());
 293         // nominate a reasonable choice
 294         ttDuration.setSelectedItem(tooltipDurations[
 295                 Math.max(tooltipDurations.length-2, 0)]);
 296 
 297         c.gridwidth = 1;
 298         c.weightx = 0;
 299         p.add(l, c);
 300 
 301         c.gridwidth = GridBagConstraints.REMAINDER;
 302         c.weightx = 1;
 303         p.add(ttDuration, c);
 304 
 305         return p;
 306     }
 307 
 308     private void loadTooltipResources() {
 309         tooltipDurations = new Integer[] { new Integer(1000),
 310                                            new Integer(2000),
 311                                            new Integer(3000),
 312                                            new Integer(5000),
 313                                            new Integer(10000),
 314                                            new Integer(15000),
 315                                            new Integer(-1) };
 316 
 317         tooltipDelays = new Integer[] { new Integer(0),
 318                                         new Integer(1000),
 319                                         new Integer(2000),
 320                                         new Integer(3000),
 321                                         new Integer(5000),
 322                                         new Integer(10000) };
 323     }
 324 
 325     /**
 326      * How long before a tooltip should be shown, as known by the GUI.
 327      * @return Zero for no delay, otherwise a delay in milliseconds.
 328      */
 329     private int getTooltipDelay() {
 330         Integer value = (Integer)(ttDelay.getSelectedItem());
 331         return value.intValue();
 332     }
 333 
 334     /**
 335      * How long tooltips should be shown, as known by the GUI.
 336      * @return <code>Desktop.TTIP_DURATION_FOREVER</code>, otherwise a duration in
 337      *         milliseconds.
 338      */
 339     private int getTooltipDuration() {
 340         int value = ((Integer) (ttDuration.getSelectedItem())).intValue();
 341         return (value < 0 ? Desktop.TTIP_DURATION_FOREVER : value);
 342     }
 343 
 344     private Desktop desktop;
 345     private UIFactory uif;
 346     private ButtonGroup styleGrp;
 347     private JCheckBox ttipsCheck;
 348     private JComboBox<Integer> ttDelay;
 349     private JComboBox<Integer> ttDuration;
 350     private JCheckBox saveCheck;
 351     private JCheckBox restoreCheck;
 352 
 353     private Integer[] tooltipDurations;
 354     private Integer[] tooltipDelays;
 355 
 356     // cache localized strings because renderers tend to run a lot
 357     private static String TIP_SHOW_FOREVER;
 358 
 359     private class TipDelayRenderer extends BasicComboBoxRenderer {
 360         @Override
 361         public Component getListCellRendererComponent(JList list,
 362                                               Object value,
 363                                               int index,
 364                                               boolean isSelected,
 365                                               boolean cellHasFocus) {
 366             Object theVal;
 367             if (value instanceof Integer) {
 368                 int val = ((Integer)value).intValue();
 369                 // convert to seconds and create localized text
 370                 theVal = uif.getI18NString("dt.prefs.ttDelay", new Integer(val/1000));
 371             }
 372             else {
 373                 theVal = value;
 374             }
 375 
 376             return super.getListCellRendererComponent(
 377                 list, theVal, index, isSelected, cellHasFocus);
 378         }
 379     }
 380 
 381     private class TipDurationRenderer extends BasicComboBoxRenderer {
 382         TipDurationRenderer() {
 383             synchronized (DesktopPrefsPane.this) {
 384                 if (TIP_SHOW_FOREVER  == null)
 385                     TIP_SHOW_FOREVER =
 386                         uif.getI18NString("dt.prefs.ttDuration.forev");
 387             }
 388         }
 389 
 390         @Override
 391         public Component getListCellRendererComponent(JList list,
 392                                               Object value,
 393                                               int index,
 394                                               boolean isSelected,
 395                                               boolean cellHasFocus) {
 396             Object theVal;
 397             if (value instanceof Integer) {
 398                 int val = ((Integer)value).intValue();
 399                 if (val > 0) {
 400                     // convert to seconds and create localized text
 401                     theVal = uif.getI18NString("dt.prefs.ttDuration.sec",
 402                                 new Integer(val/1000));
 403                 }
 404                 else
 405                     theVal = TIP_SHOW_FOREVER;
 406             }
 407             else {
 408                 theVal = value;
 409             }
 410 
 411             return super.getListCellRendererComponent(
 412                 list, theVal, index, isSelected, cellHasFocus);
 413         }
 414     }
 415 }