View Javadoc

1   /*
2    * JarInspector - Copyright (C) 2004 Che Inc., Rosario Argentina
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Library General Public
6    * License as published by the Free Software Foundation; either
7    * version 2 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   * Library General Public License for more details.
13   *
14   * You should have received a copy of the GNU Library General Public
15   * License along with this library; if not, write to the Free
16   * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17   */
18  
19  package inc.che.common.gui;
20  
21  // Imports
22  
23  import inc.che.common.config.Config;
24  import inc.che.common.resource.ResourceManager;
25  import inc.che.common.resource.StringResources;
26  import inc.che.common.string.StringUtil;
27  
28  import java.awt.BorderLayout;
29  import java.awt.Color;
30  import java.awt.Dimension;
31  import java.awt.FlowLayout;
32  import java.awt.Font;
33  import java.awt.GridLayout;
34  import java.awt.event.ActionEvent;
35  import java.awt.event.ActionListener;
36  import java.awt.event.WindowAdapter;
37  import java.awt.event.WindowEvent;
38  import java.io.File;
39  import java.text.ParseException;
40  import java.util.ArrayList;
41  import java.util.Enumeration;
42  import java.util.HashMap;
43  import java.util.Iterator;
44  import java.util.Locale;
45  
46  import javax.swing.BorderFactory;
47  import javax.swing.BoxLayout;
48  import javax.swing.JButton;
49  import javax.swing.JCheckBox;
50  import javax.swing.JColorChooser;
51  import javax.swing.JComboBox;
52  import javax.swing.JComponent;
53  import javax.swing.JDialog;
54  import javax.swing.JFileChooser;
55  import javax.swing.JFrame;
56  import javax.swing.JLabel;
57  import javax.swing.JOptionPane;
58  import javax.swing.JPanel;
59  import javax.swing.JTabbedPane;
60  import javax.swing.JTextField;
61  
62  import org.apache.log4j.Logger;
63  
64  /***
65   *  <b>Dialog zur Bearbeitung der Konfiguration</b>
66   * @version $Id: ConfigDialog.java,v 1.1 2005/03/06 12:56:51 stevemcmee Exp $
67   * @author <address> Steve McMee &lt;Steve@users.sourceforge.net&gt; </address>
68   */
69  
70  public class ConfigDialog extends JDialog {
71  
72      /*** CVS ID of this file */
73      public static final String CVS_ID =
74          "$Id: ConfigDialog.java,v 1.1 2005/03/06 12:56:51 stevemcmee Exp $";
75  
76      /***
77       * logger instance for this class
78       */
79  
80      private static Logger log = Logger.getLogger(ConfigDialog.class);
81      /***
82       * The ResourceManager
83       */
84      private static ResourceManager resourceManager =
85          ResourceManager.getResourceManager(StringResources.TEXT_RESOURCES);
86  
87      private Locale userLocale;
88  
89      private Locale[] availableLocales;
90  
91      protected static class PropertyGroup {
92          private String name;
93          private HashMap typeinfo = new HashMap();
94          private HashMap components = new HashMap();
95          private boolean hasRestartItem = false;
96          PropertyGroup(String name) {
97              this.name = name;
98          }
99          public void addPropertyItem(String pname, PropertyItem item) {
100             log.debug("addPropertyItem (" + pname + "," + item + ")");
101             typeinfo.put(pname, item);
102             hasRestartItem = hasRestartItem || item.needsRestart;
103             log.debug(
104                 "hasRestartItem for " + this.name + " :" + hasRestartItem);
105         }
106     }
107 
108     abstract static class PropertyComponent extends JComponent {
109         private JComponent propComp = null;
110         private JLabel label = null;
111         private String labelTxt = null;
112         PropertyComponent(String labelTxt, JComponent propComp) {
113             this.propComp = propComp;
114             //            JComponent comp = new JPanel();
115             //            comp.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
116             //            comp.add(propComp);
117             this.labelTxt = labelTxt;
118             label = new JLabel(labelTxt);
119             label.setLabelFor(propComp);
120             this.setLayout(new GridLayout(2, 1));
121             this.add(label);
122             this.add(propComp);
123         }
124         public JComponent getPropComp() {
125             return this.propComp;
126         }
127         void setNeedRestart(boolean needsRestart) {
128             label.setText(labelTxt + (needsRestart ? "   *" : ""));
129         }
130         public abstract String getValue();
131     }
132 
133     class TextPropertyComponent extends PropertyComponent {
134         TextPropertyComponent(String label, String value) {
135             super(label, new JTextField(value));
136         }
137         public String getValue() {
138             return ((JTextField) getPropComp()).getText();
139         }
140     }
141 
142     private static final class LocaleItem {
143         private Locale locale;
144         private static HashMap instances = new HashMap();
145 
146         private LocaleItem(Locale locale) {
147             this.locale = locale;
148         }
149         static LocaleItem getLocaleItem(Locale locale) {
150             if (instances.get(locale) == null) {
151                 instances.put(locale, new LocaleItem(locale));
152             }
153             return (LocaleItem) instances.get(locale);
154         }
155         public String toString() {
156             return locale.getDisplayName(resourceManager.getLocale());
157         }
158 
159     }
160 
161     private class LocalePropertyComponent extends PropertyComponent {
162         LocalePropertyComponent(String label, Locale value) {
163             super(label, new JComboBox());
164             Locale[] locales = availableLocales;
165             if (availableLocales == null) {
166                 locales = Locale.getAvailableLocales();
167             }
168             for (int i = 0; i < locales.length; i++) {
169                 ((JComboBox) getPropComp()).addItem(
170                     LocaleItem.getLocaleItem(locales[i]));
171             }
172             ((JComboBox) getPropComp()).setSelectedItem(
173                 LocaleItem.getLocaleItem(value));
174         }
175         public String getValue() {
176             return (
177                 (LocaleItem) ((JComboBox) (getPropComp())).getSelectedItem())
178                 .locale
179                 .getLanguage();
180         }
181     }
182 
183     private class BooleanPropertyComponent extends PropertyComponent {
184         BooleanPropertyComponent(String label, boolean value) {
185             super(label, new JCheckBox());
186             ((JCheckBox) getPropComp()).setSelected(value);
187         }
188         public String getValue() {
189             return String.valueOf(((JCheckBox) getPropComp()).isSelected());
190         }
191     }
192 
193     private class DirPropertyComponent extends PropertyComponent {
194         DirPropertyComponent(String label, File value) {
195             super(
196                 label,
197                 new JPairComponent(new JTextField(), new JButton("...")));
198 
199             ((JPairComponent) getPropComp()).label.setText(
200                 value.getAbsolutePath());
201             ((JPairComponent) getPropComp()).label.setToolTipText(
202                 value.getAbsolutePath());
203             (
204                 (JPairComponent) getPropComp())
205                     .button
206                     .addActionListener(new ActionListener() {
207                 public void actionPerformed(ActionEvent evt) {
208                     openFileDialog(
209                         JFileChooser.DIRECTORIES_ONLY,
210                         ((JPairComponent) getPropComp()).label);
211                 }
212             });
213 
214         }
215         public String getValue() {
216             return ((JPairComponent) getPropComp()).label.getText();
217         }
218     }
219 
220     private class FilePropertyComponent extends PropertyComponent {
221         FilePropertyComponent(String label, File value) {
222             super(
223                 label,
224                 new JPairComponent(new JTextField(), new JButton("...")));
225 
226             ((JPairComponent) getPropComp()).label.setText(
227                 value.getAbsolutePath());
228             ((JPairComponent) getPropComp()).label.setToolTipText(
229                 value.getAbsolutePath());
230             (
231                 (JPairComponent) getPropComp())
232                     .button
233                     .addActionListener(new ActionListener() {
234                 public void actionPerformed(ActionEvent evt) {
235                     openFileDialog(
236                         JFileChooser.FILES_ONLY,
237                         ((JPairComponent) getPropComp()).label);
238                 }
239             });
240 
241         }
242         public String getValue() {
243             return ((JPairComponent) getPropComp()).label.getText();
244         }
245     }
246 
247     private class ColorPropertyComponent extends PropertyComponent {
248         ColorPropertyComponent(String label, Color c) {
249             super(label, new JButton());
250             try {
251                 ((JButton) getPropComp()).setText(StringUtil.toRgbString(c));
252             } catch (ParseException ex) {
253                 // do nothing
254             }
255             ((JButton) getPropComp()).setSize(new Dimension(50, 50));
256             ((JButton) getPropComp()).setBackground(c);
257             ((JButton) getPropComp()).addActionListener(new ActionListener() {
258                 public void actionPerformed(ActionEvent evt) {
259                     openColorDialog();
260                 }
261             });
262         }
263 
264         private void openColorDialog() {
265 
266             JColorChooser chooser = new JColorChooser();
267 
268             Color returnColor =
269                 chooser.showDialog(this, "Auswahl Farbe", this.getBackground());
270             String color = null;
271             if (returnColor != null) {
272                 try {
273                     color = StringUtil.toRgbString(returnColor);
274                 } catch (ParseException ex) {
275 
276                 }
277                 ((JButton) getPropComp()).setBackground(returnColor);
278                 ((JButton) getPropComp()).setText(color);
279 
280             }
281         }
282         public String getValue() {
283             return ((JButton) getPropComp()).getText();
284         }
285     }
286 
287     private static class JPairComponent extends JPanel {
288         private JTextField label = null;
289         private JButton button = null;
290 
291         JPairComponent(JTextField label, JButton button) {
292             this.setLayout(new FlowLayout(FlowLayout.LEFT, 20, 0));
293             this.label = label;
294             this.button = button;
295             this.add(label);
296             this.add(button);
297             this.validate();
298             this.label.setEditable(false);
299         }
300 
301         String getText() {
302             return this.label.getText();
303         }
304 
305         public void setEnabled(boolean b) {
306             this.label.setEnabled(b);
307             this.button.setEnabled(b);
308         }
309 
310         public void setSize(int width, int height) {
311             super.setSize(2 * width, height); // Wichtig!!!
312             this.label.setSize(width, height);
313             this.button.setSize(button.getWidth(), height);
314         }
315     }
316 
317     protected static class PropertyItem {
318         private int type = TEXT_PROPERTY;
319         private String propName;
320         private String labelName;
321         private boolean readOnly = false;
322         private boolean needsRestart = false;
323 
324         public PropertyItem(
325             String propName,
326             String labelName,
327             int type,
328             boolean readOnly,
329             boolean needsRestart) {
330             this.type = type;
331             this.propName = propName;
332             this.labelName = labelName;
333             this.readOnly = readOnly;
334             this.needsRestart = needsRestart;
335 
336         }
337 
338         public String toString() {
339             return "PropertyItem ("
340                 + type
341                 + ","
342                 + propName
343                 + ","
344                 + labelName
345                 + ","
346                 + readOnly
347                 + ","
348                 + needsRestart
349                 + ")";
350         }
351 
352     }
353 
354     public static final int TEXT_PROPERTY = 1;
355     public static final int COLOR_PROPERTY = 2;
356     public static final int FILE_PROPERTY = 3;
357     public static final int DIR_PROPERTY = 4;
358     public static final int BOOLEAN_PROPERTY = 5;
359     public static final int LOCALE_PROPERTY = 6;
360 
361     protected Config config = null;
362 
363     private ArrayList propertyGroups = new ArrayList(5);
364     private JTabbedPane tabbedPanel = null;
365 
366     private boolean showOnlyEditable = false;
367 
368     public ConfigDialog(JFrame owner, Config config, Locale locale) {
369         super(owner);
370         resourceManager.setLocale(locale);
371         this.userLocale = locale;
372         this.config = config;
373         String parameter = null;
374 
375         this.getContentPane().setLayout(new BorderLayout(10, 0));
376         tabbedPanel = new JTabbedPane();
377 
378         this.getContentPane().add(BorderLayout.NORTH, tabbedPanel);
379         this.getContentPane().add(BorderLayout.SOUTH, createButtonPanel());
380         this.setTitle(resourceManager.getText("configdlg.title"));
381         this.setModal(true);
382 
383         this.setSize(
384             config.getIntParameter("settingsdialogframe.width"),
385             config.getIntParameter("settingsdialogframe.height"));
386         GuiUtil.center(owner, this);
387 
388         this.setDefaultCloseOperation(this.DO_NOTHING_ON_CLOSE);
389         this.addWindowListener(new WindowAdapter() {
390             public void windowClosing(WindowEvent e) {
391                 closeDialog();
392             }
393         });
394 
395     }
396 
397     protected PropertyGroup createPropertyGroup(String name) {
398         PropertyGroup propGroup = new PropertyGroup(name);
399         propertyGroups.add(propGroup);
400         return propGroup;
401     }
402 
403     protected PropertyGroup createDefaultPropertyGroup() {
404         PropertyGroup defGroup =
405             new PropertyGroup(
406                 resourceManager.getText("propgroup.default.label"));
407         propertyGroups.add(defGroup);
408         for (Enumeration cenum = config.parameters();
409             cenum.hasMoreElements();
410             ) {
411             String parameter = (String) cenum.nextElement();
412             defGroup.addPropertyItem(
413                 parameter,
414                 new PropertyItem(
415                     parameter,
416                     parameter,
417                     guessType(parameter),
418                     true,
419                     false));
420         }
421         return defGroup;
422     }
423     protected void createTabs() {
424 
425         PropertyItem item = null;
426         JComponent comp = null;
427         String propName;
428         int maxPropCount = 0;
429 
430         for (Iterator pit = propertyGroups.iterator(); pit.hasNext();) {
431             // Initialize
432             PropertyGroup propGroup = (PropertyGroup) pit.next();
433             JPanel basePanel = new JPanel(new BorderLayout(0, 0));
434             JPanel compPanel = new JPanel();
435             compPanel.setBorder(
436                 BorderFactory.createEmptyBorder(10, 10, 10, 10));
437             basePanel.add(BorderLayout.NORTH, compPanel);
438             int propCount = 0;
439             for (Iterator it = propGroup.typeinfo.keySet().iterator();
440                 it.hasNext();
441                 ) {
442                 item = (PropertyItem) propGroup.typeinfo.get(it.next());
443                 if (showOnlyEditable == false || !item.readOnly) {
444                     propCount++;
445                 }
446             }
447             compPanel.setLayout(new BoxLayout(compPanel, BoxLayout.Y_AXIS));
448 
449             for (Iterator it = propGroup.typeinfo.keySet().iterator();
450                 it.hasNext();
451                 ) {
452                 propName = (String) it.next();
453                 item = (PropertyItem) propGroup.typeinfo.get(propName);
454                 if (showOnlyEditable == false || !item.readOnly) {
455                     //labelPanel.add(new JLabel(item.labelName));
456                     comp = createTypedComponent(item);
457                     comp.setEnabled(!item.readOnly);
458                     //comp.setPreferredSize(new Dimension(comp.getWidth(), 10));
459                     propGroup.components.put(propName, comp);
460                     compPanel.add(comp);
461 
462                 }
463             }
464             log.debug(
465                 "propGroup.hasRestartItem "
466                     + propGroup.name
467                     + ": "
468                     + propGroup.hasRestartItem);
469             if (propGroup.hasRestartItem) {
470                 basePanel.add(BorderLayout.SOUTH, getRestartLabel());
471             }
472             if (maxPropCount < propCount) {
473                 maxPropCount = propCount;
474             }
475             tabbedPanel.add(propGroup.name, basePanel);
476         }
477         if (this.getHeight() == 0 && this.getWidth() == 0) {
478             this.setSize(450, maxPropCount * 30);
479         }
480     }
481 
482     private JLabel getRestartLabel() {
483         JLabel restartLabel =
484             new JLabel(resourceManager.getText("configdlg.label.restart"));
485         restartLabel.setFont(new Font(null, Font.PLAIN, 10));
486 
487         return restartLabel;
488     }
489 
490     public void showOnlyEditable(boolean pshowOnlyEditable) {
491         this.showOnlyEditable = pshowOnlyEditable;
492     }
493 
494     private JPanel createButtonPanel() {
495         JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER));
496         JButton closeButton =
497             new JButton(resourceManager.getText("configdlg.button.close"));
498         JButton storeButton =
499             new JButton(resourceManager.getText("configdlg.button.store"));
500 
501         closeButton.addActionListener(new ActionListener() {
502             public void actionPerformed(ActionEvent evt) {
503                 closeDialog();
504             }
505         });
506 
507         storeButton.addActionListener(new ActionListener() {
508             public void actionPerformed(ActionEvent evt) {
509                 storeConfig();
510             }
511         });
512         panel.add(storeButton);
513         panel.add(closeButton);
514 
515         return panel;
516     }
517     protected void closeDialog() {
518         if (isChanged()) {
519             int ret =
520                 JOptionPane.showConfirmDialog(
521                     this,
522                     resourceManager.getText("configdlg.confirm.label"),
523                     resourceManager.getText("configdlg.confirm.title"),
524                     JOptionPane.YES_NO_OPTION,
525                     JOptionPane.INFORMATION_MESSAGE);
526             if (ret == JOptionPane.NO_OPTION) {
527                 return;
528             }
529 
530         }
531         config.setIntParameter("settingsdialogframe.height", this.getHeight());
532         config.setIntParameter("settingsdialogframe.width", this.getWidth());
533         this.dispose();
534     }
535 
536     private boolean isChanged() {
537         PropertyItem item;
538         String parameter;
539         PropertyComponent comp;
540 
541         for (Iterator pit = propertyGroups.iterator(); pit.hasNext();) {
542             // Initialize
543             PropertyGroup propGroup = (PropertyGroup) pit.next();
544             for (Iterator it = propGroup.typeinfo.keySet().iterator();
545                 it.hasNext();
546                 ) {
547                 parameter = (String) it.next();
548                 item = (PropertyItem) propGroup.typeinfo.get(parameter);
549                 comp = (PropertyComponent) propGroup.components.get(parameter);
550                 if (comp != null) {
551                     if (!comp
552                         .getValue()
553                         .equals(config.getParameter(parameter))) {
554                         return true;
555                     }
556                 }
557             }
558         }
559         return false;
560     }
561 
562     private boolean needsRestart() {
563         PropertyItem item;
564         String parameter;
565         PropertyComponent comp;
566         for (Iterator pit = propertyGroups.iterator(); pit.hasNext();) {
567             // Initialize
568             PropertyGroup propGroup = (PropertyGroup) pit.next();
569             for (Iterator it = propGroup.typeinfo.keySet().iterator();
570                 it.hasNext();
571                 ) {
572                 parameter = (String) it.next();
573                 item = (PropertyItem) propGroup.typeinfo.get(parameter);
574                 comp = (PropertyComponent) propGroup.components.get(parameter);
575                 if (comp != null) {
576                     if (item.needsRestart
577                         && !comp.getValue().equals(
578                             config.getParameter(parameter))) {
579                         return true;
580                     }
581                 }
582             }
583         }
584         return false;
585     }
586 
587     private void storeConfig() {
588         boolean isChanged;
589         String parameter;
590         PropertyComponent comp;
591         boolean needsRestart = needsRestart();
592 
593         for (Iterator pit = propertyGroups.iterator(); pit.hasNext();) {
594             // Initialize
595             PropertyGroup propGroup = (PropertyGroup) pit.next();
596             for (Iterator it = propGroup.typeinfo.keySet().iterator();
597                 it.hasNext();
598                 ) {
599                 parameter = (String) it.next();
600                 comp = (PropertyComponent) propGroup.components.get(parameter);
601                 if (comp != null) {
602                     config.setParameter(parameter, comp.getValue());
603                 }
604             }
605         }
606 
607         if (needsRestart) {
608             JOptionPane.showMessageDialog(
609                 this,
610                 resourceManager.getText("configdlg.info.label"),
611                 resourceManager.getText("configdlg.info.title"),
612                 JOptionPane.INFORMATION_MESSAGE);
613         }
614     }
615 
616     public void show() {
617 
618         createTabs();
619 
620         super.show();
621     }
622 
623     private JComponent createTypedComponent(final PropertyItem item) {
624         PropertyComponent typedComp = null;
625         int type = item.type;
626         String label = item.labelName;
627         String name = item.propName;
628 
629         switch (type) {
630             case TEXT_PROPERTY :
631                 typedComp =
632                     new TextPropertyComponent(label, config.getParameter(name));
633                 break;
634             case COLOR_PROPERTY :
635                 typedComp =
636                     new ColorPropertyComponent(
637                         label,
638                         config.getColorParameter(name));
639                 break;
640             case FILE_PROPERTY :
641                 typedComp =
642                     new FilePropertyComponent(
643                         label,
644                         config.getFileParameter(name));
645                 break;
646             case DIR_PROPERTY :
647                 typedComp =
648                     new DirPropertyComponent(
649                         label,
650                         config.getFileParameter(name));
651                 break;
652             case BOOLEAN_PROPERTY :
653                 typedComp =
654                     new BooleanPropertyComponent(
655                         label,
656                         config.getBooleanParameter(name));
657                 break;
658             case LOCALE_PROPERTY :
659                 typedComp =
660                     new LocalePropertyComponent(
661                         label,
662                         config.getLocaleParameter(name));
663                 break;
664             default:
665                 break;
666 
667         }
668 
669         typedComp.setNeedRestart(item.needsRestart);
670 
671         return typedComp;
672     }
673 
674     private void openFileDialog(int type, JTextField label) {
675 
676         JFileChooser chooser = new JFileChooser();
677 
678         if (label != null && !label.getText().trim().equals("")) {
679             chooser = new JFileChooser(label.getText());
680         }
681 
682         chooser.setFileSelectionMode(type);
683         chooser.setDialogTitle(resourceManager.getText("filedlg.title"));
684         int returnVal = chooser.showOpenDialog(this);
685         if (returnVal == JFileChooser.APPROVE_OPTION) {
686             label.setText(chooser.getSelectedFile().getAbsolutePath());
687             label.setToolTipText(chooser.getSelectedFile().getAbsolutePath());
688         }
689     }
690 
691     private int guessType(String parameter) {
692 
693         if (parameter.startsWith("color")) {
694             return COLOR_PROPERTY;
695         }
696         if (parameter.startsWith("file")) {
697             return FILE_PROPERTY;
698         }
699         if (parameter.startsWith("dir")) {
700             return DIR_PROPERTY;
701         }
702         if (parameter.startsWith("boolean")) {
703             return BOOLEAN_PROPERTY;
704         }
705         if (parameter.startsWith("locale")) {
706             return LOCALE_PROPERTY;
707         }
708 
709         return TEXT_PROPERTY; //default
710     }
711 
712     public void setAvailableLocales(Locale[] locales) {
713         availableLocales = locales;
714     }
715 }