1   /*
2    *  Copyright (c) 1998-2001, The University of Sheffield.
3    *
4    *  This file is part of GATE (see http://gate.ac.uk/), and is free
5    *  software, licenced under the GNU Library General Public License,
6    *  Version 2, June 1991 (in the distribution as file licence.html,
7    *  and also available at http://gate.ac.uk/gate/licence.html).
8    *
9    *  Valentin Tablan 15/11/2001
10   *
11   *  $Id: OptionsDialog.java,v 1.2 2001/11/16 15:15:28 valyt Exp $
12   *
13   */
14  package gate.gui;
15  
16  import gate.*;
17  import gate.util.*;
18  import gate.swing.*;
19  
20  import javax.swing.*;
21  import javax.swing.event.*;
22  import java.awt.event.*;
23  import java.awt.Frame;
24  import java.awt.Font;
25  import java.awt.Component;
26  import java.awt.font.TextAttribute;
27  import javax.swing.plaf.FontUIResource;
28  import java.beans.PropertyChangeListener;
29  import java.beans.PropertyChangeEvent;
30  import java.util.*;
31  
32  /**
33   * The options dialog for Gate.
34   */
35  public class OptionsDialog extends JDialog {
36    public OptionsDialog(Frame owner){
37      super(owner, "Gate Options", true);
38      MainFrame.getGuiRoots().add(this);
39    }
40  
41    protected void initLocalData(){
42      lookAndFeelClassName = Gate.getUserConfig().
43                             getString(GateConstants.LOOK_AND_FEEL);
44  
45      textComponentsFont = Gate.getUserConfig().
46                           getFont(GateConstants.TEXT_COMPONENTS_FONT);
47  
48      menusFont = Gate.getUserConfig().
49                  getFont(GateConstants.MENUS_FONT);
50  
51      componentsFont = Gate.getUserConfig().
52                       getFont(GateConstants.OTHER_COMPONENTS_FONT);
53      dirtyGUI = false;
54    }
55  
56  
57    protected void initGuiComponents(){
58      getContentPane().removeAll();
59      mainTabbedPane = new JTabbedPane(JTabbedPane.TOP);
60      getContentPane().setLayout(new BoxLayout(getContentPane(),
61                                               BoxLayout.Y_AXIS));
62      getContentPane().add(mainTabbedPane);
63  
64      Box appearanceBox = Box.createVerticalBox();
65      //the LNF combo
66      List supportedLNFs = new ArrayList();
67      LNFData currentLNF = null;
68      UIManager.LookAndFeelInfo[] lnfs = UIManager.getInstalledLookAndFeels();
69      for(int i = 0; i < lnfs.length; i++){
70        UIManager.LookAndFeelInfo lnf = lnfs[i];
71        try{
72          Class lnfClass = Class.forName(lnf.getClassName());
73          if(((LookAndFeel)(lnfClass.newInstance())).isSupportedLookAndFeel()){
74            if(lnf.getName().equals(UIManager.getLookAndFeel().getName())){
75              supportedLNFs.add(currentLNF =
76                                new LNFData(lnf.getClassName(), lnf.getName()));
77            }else{
78              supportedLNFs.add(new LNFData(lnf.getClassName(), lnf.getName()));
79            }
80          }
81        }catch(ClassNotFoundException cnfe){
82        }catch(IllegalAccessException iae){
83        }catch(InstantiationException ie){
84        }
85      }
86      lnfCombo = new JComboBox(supportedLNFs.toArray());
87      lnfCombo.setSelectedItem(currentLNF);
88  
89      Box horBox = Box.createHorizontalBox();
90      horBox.add(Box.createHorizontalStrut(5));
91      horBox.add(new JLabel("Look and feel:"));
92      horBox.add(Box.createHorizontalStrut(5));
93      horBox.add(lnfCombo);
94      horBox.add(Box.createHorizontalStrut(5));
95      appearanceBox.add(Box.createVerticalStrut(10));
96      appearanceBox.add(horBox);
97      appearanceBox.add(Box.createVerticalStrut(10));
98  
99      JPanel panel = new JPanel();
100     panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
101     panel.setBorder(BorderFactory.createTitledBorder(" Font options "));
102 
103     fontBG = new ButtonGroup();
104     textBtn = new JRadioButton("Text components font");
105     textBtn.setActionCommand("text");
106     fontBG.add(textBtn);
107     menuBtn = new JRadioButton("Menu components font");
108     menuBtn.setActionCommand("menu");
109     fontBG.add(menuBtn);
110     otherCompsBtn = new JRadioButton("Other components font");
111     otherCompsBtn.setActionCommand("other");
112     fontBG.add(otherCompsBtn);
113     Box verBox = Box.createVerticalBox();
114     verBox.add(Box.createVerticalStrut(5));
115     verBox.add(textBtn);
116     verBox.add(Box.createVerticalStrut(5));
117     verBox.add(menuBtn);
118     verBox.add(Box.createVerticalStrut(5));
119     verBox.add(otherCompsBtn);
120     verBox.add(Box.createVerticalStrut(5));
121     verBox.add(Box.createVerticalGlue());
122     panel.add(verBox);
123 
124     fontChooser = new JFontChooser();
125     panel.add(fontChooser);
126 
127     appearanceBox.add(panel);
128 
129     mainTabbedPane.add("Appearance", appearanceBox);
130 
131     Box advancedBox = Box.createVerticalBox();
132     saveOptionsChk = new JCheckBox(
133         "Save options on exit",
134         Gate.getUserConfig().getBoolean(GateConstants.SAVE_OPTIONS_ON_EXIT).
135         booleanValue());
136 
137     saveSessionChk = new JCheckBox(
138         "Save session on exit",
139         Gate.getUserConfig().getBoolean(GateConstants.SAVE_SESSION_ON_EXIT).
140         booleanValue());
141     advancedBox.add(Box.createVerticalStrut(10));
142     advancedBox.add(saveOptionsChk);
143     advancedBox.add(Box.createVerticalStrut(10));
144     advancedBox.add(saveSessionChk);
145     advancedBox.add(Box.createVerticalStrut(10));
146     mainTabbedPane.add("Advanced", advancedBox);
147 
148     Box buttonsBox = Box.createHorizontalBox();
149     buttonsBox.add(Box.createHorizontalGlue());
150     buttonsBox.add(okButton = new JButton(new OKAction()));
151     buttonsBox.add(Box.createHorizontalStrut(10));
152     buttonsBox.add(cancelButton = new JButton("Cancel"));
153     buttonsBox.add(Box.createHorizontalGlue());
154 
155     getContentPane().add(Box.createVerticalStrut(10));
156     getContentPane().add(buttonsBox);
157     getContentPane().add(Box.createVerticalStrut(10));
158   }
159 
160   protected void initListeners(){
161     lnfCombo.addActionListener(new ActionListener() {
162       public void actionPerformed(ActionEvent e) {
163         if(!lookAndFeelClassName.equals(
164            ((LNFData)lnfCombo.getSelectedItem()).className)
165           ){
166           dirtyGUI = true;
167           lookAndFeelClassName = ((LNFData)lnfCombo.getSelectedItem()).
168                                  className;
169         }
170       }
171     });
172 
173     fontChooser.addPropertyChangeListener(new PropertyChangeListener() {
174       public void propertyChange(PropertyChangeEvent e) {
175         if(e.getPropertyName().equals("fontValue")){
176           String selectedFont = fontBG.getSelection().getActionCommand();
177           if(selectedFont.equals("text")){
178             textComponentsFont = (Font)e.getNewValue();
179             dirtyGUI = true;
180           }else if(selectedFont.equals("menu")){
181             menusFont = (Font)e.getNewValue();
182             dirtyGUI = true;
183           }else if(selectedFont.equals("other")){
184             componentsFont = (Font)e.getNewValue();
185             dirtyGUI = true;
186           }
187         }
188       }
189     });
190 
191     textBtn.addActionListener(new ActionListener() {
192       public void actionPerformed(ActionEvent e) {
193         if(textBtn.isSelected()) selectedFontChanged();
194         selectedFontBtn = "text";
195         fontChooser.setFontValue(textComponentsFont);
196       }
197     });
198 
199     menuBtn.addActionListener(new ActionListener() {
200       public void actionPerformed(ActionEvent e) {
201         if(menuBtn.isSelected()) selectedFontChanged();
202         selectedFontBtn = "menu";
203         fontChooser.setFontValue(menusFont);
204       }
205     });
206 
207     otherCompsBtn.addActionListener(new ActionListener() {
208       public void actionPerformed(ActionEvent e) {
209         if(otherCompsBtn.isSelected()) selectedFontChanged();
210         selectedFontBtn = "other";
211         fontChooser.setFontValue(componentsFont);
212       }
213     });
214 
215     cancelButton.setAction(new AbstractAction("Cancel"){
216       public void actionPerformed(ActionEvent evt){
217         hide();
218       }
219     });
220     textBtn.setSelected(true);
221   }
222 
223   public void dispose(){
224     MainFrame.getGuiRoots().remove(this);
225     super.dispose();
226   }
227 
228   protected void selectedFontChanged(){
229     if(selectedFontBtn != null){
230       //save the old font
231       if(selectedFontBtn.equals("text")){
232         textComponentsFont = fontChooser.getFontValue();
233       }else if(selectedFontBtn.equals("menu")){
234         menusFont = fontChooser.getFontValue();
235       }else if(selectedFontBtn.equals("other")){
236         componentsFont = fontChooser.getFontValue();
237       }
238     }
239   }
240 
241   public void show(){
242     initLocalData();
243     initGuiComponents();
244     textBtn.setSelected(true);
245     fontChooser.setFontValue(textComponentsFont);
246     initListeners();
247     pack();
248     setLocationRelativeTo(getOwner());
249     super.show();
250   }
251 
252   public static void main(String args[]){
253     try{
254       UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
255     }catch(Exception e){
256       e.printStackTrace();
257     }
258     final JFrame frame = new JFrame("Foo frame");
259     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
260     JButton btn = new JButton("Show dialog");
261     btn.addActionListener(new ActionListener() {
262       public void actionPerformed(ActionEvent e) {
263         OptionsDialog dialog = new OptionsDialog(frame);
264         dialog.pack();
265         dialog.show();
266       }
267     });
268     frame.getContentPane().add(btn);
269     frame.pack();
270     frame.setVisible(true);
271     System.out.println("Font: " + UIManager.getFont("Button.font"));
272   }// main
273 
274 
275   protected static void setUIDefaults(Object[] keys, Object value) {
276     for(int i = 0; i < keys.length; i++){
277       UIManager.put(keys[i], value);
278     }
279   }// setUIDefaults(Object[] keys, Object value)
280 
281   /**
282    * Updates the Swing defaults table with the provided font to be used for the
283    * text components
284    */
285   public static void setTextComponentsFont(Font font){
286     setUIDefaults(textComponentsKeys, new FontUIResource(font));
287     Gate.getUserConfig().put(GateConstants.TEXT_COMPONENTS_FONT, font);
288   }
289 
290   /**
291    * Updates the Swing defaults table with the provided font to be used for the
292    * menu components
293    */
294   public static void setMenuComponentsFont(Font font){
295     setUIDefaults(menuKeys, new FontUIResource(font));
296     Gate.getUserConfig().put(GateConstants.MENUS_FONT, font);
297   }
298 
299   /**
300    * Updates the Swing defaults table with the provided font to be used for
301    * various compoents that neither text or menu components
302    */
303   public static void setComponentsFont(Font font){
304     setUIDefaults(componentsKeys, new FontUIResource(font));
305     Gate.getUserConfig().put(GateConstants.OTHER_COMPONENTS_FONT, font);
306   }
307 
308   class OKAction extends AbstractAction{
309     OKAction(){
310       super("OK");
311     }
312 
313     public void actionPerformed(ActionEvent evt) {
314       OptionsMap userConfig = Gate.getUserConfig();
315       if(dirtyGUI){
316         setMenuComponentsFont(menusFont);
317         setComponentsFont(componentsFont);
318         setTextComponentsFont(textComponentsFont);
319         userConfig.put(GateConstants.LOOK_AND_FEEL, lookAndFeelClassName);
320         try{
321           UIManager.setLookAndFeel(lookAndFeelClassName);
322           Iterator rootsIter = MainFrame.getGuiRoots().iterator();
323           while(rootsIter.hasNext()){
324             SwingUtilities.updateComponentTreeUI((Component)rootsIter.next());
325           }
326         }catch(Exception e){}
327       }
328 
329       userConfig.put(GateConstants.SAVE_OPTIONS_ON_EXIT,
330                      new Boolean(saveOptionsChk.isSelected()));
331       userConfig.put(GateConstants.SAVE_SESSION_ON_EXIT,
332                      new Boolean(saveSessionChk.isSelected()));
333       hide();
334     }// void actionPerformed(ActionEvent evt)
335   }
336 
337   protected static class LNFData{
338     public LNFData(String className, String name){
339       this.className = className;
340       this.name = name;
341     }
342 
343     public String toString(){
344       return name;
345     }
346 
347     String className;
348     String name;
349   }
350 
351 
352   public static String[] menuKeys = new String[]{"CheckBoxMenuItem.acceleratorFont",
353                                           "CheckBoxMenuItem.font",
354                                           "Menu.acceleratorFont",
355                                           "Menu.font",
356                                           "MenuBar.font",
357                                           "MenuItem.acceleratorFont",
358                                           "MenuItem.font",
359                                           "RadioButtonMenuItem.acceleratorFont",
360                                           "RadioButtonMenuItem.font"};
361 
362   public static String[] componentsKeys =
363                              new String[]{"Button.font",
364                                           "CheckBox.font",
365                                           "ColorChooser.font",
366                                           "ComboBox.font",
367                                           "InternalFrame.titleFont",
368                                           "Label.font",
369                                           "List.font",
370                                           "OptionPane.font",
371                                           "Panel.font",
372                                           "PasswordField.font",
373                                           "PopupMenu.font",
374                                           "ProgressBar.font",
375                                           "RadioButton.font",
376                                           "ScrollPane.font",
377                                           "TabbedPane.font",
378                                           "Table.font",
379                                           "TableHeader.font",
380                                           "TitledBorder.font",
381                                           "ToggleButton.font",
382                                           "ToolBar.font",
383                                           "ToolTip.font",
384                                           "Tree.font",
385                                           "Viewport.font"};
386 
387   public static String[] textComponentsKeys =
388                              new String[]{"EditorPane.font",
389                                           "TextArea.font",
390                                           "TextField.font",
391                                           "TextPane.font"};
392 
393   /**
394    * The main tabbed pane
395    */
396   JTabbedPane mainTabbedPane;
397 
398   /**
399    * The OK button. The action for this button is an {@link OKAction}
400    */
401   JButton okButton;
402 
403   /**
404    * The Cancel button: hides the dialog without doing anything
405    */
406   JButton cancelButton;
407 
408   /**
409    * Radio button used to set the font for text components
410    */
411   JRadioButton textBtn;
412 
413   /**
414    * which text is currently being edited; values are: "text", "menu", "other"
415    */
416   String selectedFontBtn = null;
417 
418   /**
419    * Radio button used to set the font for menu components
420    */
421   JRadioButton menuBtn;
422 
423   /**
424    * Radio button used to set the font for other components
425    */
426   JRadioButton otherCompsBtn;
427 
428   /**
429    * Button group for the font setting radio buttons
430    */
431   ButtonGroup fontBG;
432 
433   /**
434    * The font chooser used for selecting fonts
435    */
436   JFontChooser fontChooser;
437 
438   /**
439    * The "Save Options on close" checkbox
440    */
441   JCheckBox saveOptionsChk;
442 
443   /**
444    * The "Save Session on close" checkbox
445    */
446   JCheckBox saveSessionChk;
447   /**
448    * The name of the look and feel class
449    */
450   String lookAndFeelClassName;
451 
452   /**
453    * The font to be used for the menus; cached value for the one in the user
454    * config map.
455    */
456   Font menusFont;
457 
458   /**
459    * The font to be used for text components; cached value for the one in the
460    * user config map.
461    */
462   Font textComponentsFont;
463 
464   /**
465    * The font to be used for GUI components; cached value for the one in the
466    * user config map.
467    */
468   Font componentsFont;
469 
470   /**
471    * This flag becomes true when an GUI related option has been changed
472    */
473   boolean dirtyGUI;
474 
475   /**
476    * The combobox for the look and feel selection
477    */
478   JComboBox lnfCombo;
479 }