KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > gui > OptionsDialog


1 /*
2  * OptionsDialog.java - Tree options dialog
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 1998, 2003 Slava Pestov
7  * Portions copyright (C) 1999 mike dillon
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22  */

23
24 package org.gjt.sp.jedit.gui;
25
26 //{{{ Imports
27
import javax.swing.*;
28 import javax.swing.border.*;
29 import javax.swing.event.*;
30 import javax.swing.tree.*;
31 import java.awt.*;
32 import java.awt.event.*;
33 import java.util.*;
34 import java.util.List JavaDoc;
35
36
37 import org.gjt.sp.jedit.*;
38 import org.gjt.sp.util.Log;
39 //}}}
40

41 /**
42  * An abstract options dialog box.
43  * @author Slava Pestov
44  * @version $Id: OptionsDialog.java 8676 2007-01-19 20:14:58Z kpouer $
45  */

46 public abstract class OptionsDialog extends EnhancedDialog
47     implements ActionListener, TreeSelectionListener
48 {
49     //{{{ Instance variables
50
private String JavaDoc name;
51     private JSplitPane splitter;
52     protected JTree paneTree;
53     private JScrollPane stage;
54     private JButton ok;
55     private JButton cancel;
56     private JButton apply;
57     protected OptionPane currentPane;
58     private Map<Object JavaDoc, OptionPane> deferredOptionPanes;
59     //}}}
60

61     //{{{ OptionsDialog constructor
62
/**
63      * @param frame - the parent frame for dialogs created
64      * @param name the name of an option pane - it must have a .title and .code
65      * property defined in order to instantiate.
66      * @param pane the initial pane to show when this is created.
67      */

68     protected OptionsDialog(Frame frame, String JavaDoc name, String JavaDoc pane)
69     {
70         super(frame, jEdit.getProperty(name + ".title"), true);
71         init(name,pane);
72     } //}}}
73

74     //{{{ OptionsDialog constructor
75
protected OptionsDialog(Dialog dialog, String JavaDoc name, String JavaDoc pane)
76     {
77         super(dialog, jEdit.getProperty(name + ".title"), true);
78         init(name,pane);
79     } //}}}
80

81     //{{{ addOptionGroup() method
82
public void addOptionGroup(OptionGroup group)
83     {
84         getDefaultGroup().addOptionGroup(group);
85     } //}}}
86

87     //{{{ addOptionPane() method
88
public void addOptionPane(OptionPane pane)
89     {
90         getDefaultGroup().addOptionPane(pane);
91     } //}}}
92

93     //{{{ ok() method
94
public void ok()
95     {
96         if(currentPane != null)
97             jEdit.setProperty(name + ".last",currentPane.getName());
98         ok(true);
99     } //}}}
100

101     //{{{ cancel() method
102
public void cancel()
103     {
104         if(currentPane != null)
105             jEdit.setProperty(name + ".last",currentPane.getName());
106         dispose();
107     } //}}}
108

109     //{{{ ok() method
110
public void ok(boolean dispose)
111     {
112         OptionTreeModel m = (OptionTreeModel) paneTree
113             .getModel();
114         save(m.getRoot());
115
116         /* This will fire the PROPERTIES_CHANGED event */
117         jEdit.propertiesChanged();
118
119         // Save settings to disk
120
jEdit.saveSettings();
121
122         // get rid of this dialog if necessary
123
if(dispose)
124             dispose();
125     } //}}}
126

127     //{{{ dispose() method
128
public void dispose()
129     {
130         GUIUtilities.saveGeometry(this,name);
131         jEdit.setIntegerProperty(name + ".splitter",splitter.getDividerLocation());
132         super.dispose();
133     } //}}}
134

135     //{{{ actionPerformed() method
136
public void actionPerformed(ActionEvent evt)
137     {
138         Object JavaDoc source = evt.getSource();
139
140         if(source == ok)
141         {
142             ok();
143         }
144         else if(source == cancel)
145         {
146             cancel();
147         }
148         else if(source == apply)
149         {
150             ok(false);
151         }
152     } //}}}
153

154     //{{{ valueChanged() method
155
public void valueChanged(TreeSelectionEvent evt)
156     {
157         TreePath path = evt.getPath();
158
159         if(path == null)
160             return;
161
162         Object JavaDoc lastPathComponent = path.getLastPathComponent();
163         if(!(lastPathComponent instanceof String JavaDoc
164             || lastPathComponent instanceof OptionPane))
165         {
166             return;
167         }
168
169         Object JavaDoc[] nodes = path.getPath();
170
171         StringBuilder JavaDoc buf = new StringBuilder JavaDoc();
172
173         OptionPane optionPane = null;
174
175         int lastIdx = nodes.length - 1;
176
177         for (int i = paneTree.isRootVisible() ? 0 : 1;
178             i <= lastIdx; i++)
179         {
180             String JavaDoc label;
181             Object JavaDoc node = nodes[i];
182             if (node instanceof OptionPane)
183             {
184                 optionPane = (OptionPane)node;
185                 label = jEdit.getProperty("options."
186                     + optionPane.getName()
187                     + ".label");
188             }
189             else if (node instanceof OptionGroup)
190             {
191                 label = ((OptionGroup)node).getLabel();
192             }
193             else if (node instanceof String JavaDoc)
194             {
195                 label = jEdit.getProperty("options."
196                     + node + ".label");
197                 optionPane = deferredOptionPanes.get(node);
198                 if(optionPane == null)
199                 {
200                     String JavaDoc propName = "options." + node + ".code";
201                     String JavaDoc code = jEdit.getProperty(propName);
202                     if(code != null)
203                     {
204                         optionPane = (OptionPane)
205                             BeanShell.eval(
206                             jEdit.getActiveView(),
207                             BeanShell.getNameSpace(),
208                             code
209                         );
210
211                         if(optionPane != null)
212                         {
213                             deferredOptionPanes.put(
214                                 node,optionPane);
215                         }
216                         else
217                             continue;
218                     }
219                     else
220                     {
221                         Log.log(Log.ERROR,this,propName
222                             + " not defined");
223                         continue;
224                     }
225                 }
226             }
227             else
228             {
229                 continue;
230             }
231
232             buf.append(label);
233
234             if (i != lastIdx)
235                 buf.append(": ");
236         }
237
238         if(optionPane == null)
239             return;
240
241         setTitle(jEdit.getProperty("options.title-template",
242             new Object JavaDoc[] { jEdit.getProperty(name + ".title"),
243             buf.toString() }));
244
245         try
246         {
247             optionPane.init();
248         }
249         catch(Throwable JavaDoc t)
250         {
251             Log.log(Log.ERROR,this,"Error initializing options:");
252             Log.log(Log.ERROR,this,t);
253         }
254
255         currentPane = optionPane;
256         stage.setViewportView(currentPane.getComponent());
257         stage.revalidate();
258         stage.repaint();
259
260         if(!isShowing())
261             addNotify();
262
263         updateSize();
264
265         currentPane = optionPane;
266     } //}}}
267

268     //{{{ Protected members
269
// {{{ createOptionTreeModel
270
/**
271      * Creates the tree model that goes on the left of the option pane,
272      * loading all the items that are needed.
273      */

274     protected abstract OptionTreeModel createOptionTreeModel();
275     // }}}
276

277     protected abstract OptionGroup getDefaultGroup();
278     //}}}
279

280     //{{{ init() method
281
/**
282      * @param name the name of this pane
283      * @param pane - a sub-pane name to select (?)
284      * Could someone please write better docs for this function?
285      * Creates buttons, adds listeners, and makes the pane visible.
286      * This method is called automatically from the constructor,
287      *
288      * and also calls init on each of the optionPanes?
289      *
290      * @since jEdit 4.3pre9 (was private before)
291      */

292     protected void init(String JavaDoc name, String JavaDoc pane)
293     {
294         this.name = name;
295
296         deferredOptionPanes = new HashMap<Object JavaDoc, OptionPane>();
297
298         JPanel content = new JPanel(new BorderLayout(12,12));
299         content.setBorder(new EmptyBorder(12,12,12,12));
300         setContentPane(content);
301         stage = new JScrollPane();
302
303         paneTree = new JTree(createOptionTreeModel());
304         paneTree.setVisibleRowCount(1);
305         paneTree.setCellRenderer(new PaneNameRenderer());
306
307         // looks bad with the OS X L&F, apparently...
308
if(!OperatingSystem.isMacOSLF())
309             paneTree.putClientProperty("JTree.lineStyle", "Angled");
310
311         paneTree.setShowsRootHandles(true);
312         paneTree.setRootVisible(false);
313
314         JScrollPane scroller = new JScrollPane(paneTree,
315                                ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
316                                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
317         scroller.setMinimumSize(new Dimension(100, 0));
318         splitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
319                       jEdit.getBooleanProperty("appearance.continuousLayout"),
320                       scroller,
321                       stage);
322         content.add(splitter, BorderLayout.CENTER);
323
324         Box buttons = new Box(BoxLayout.X_AXIS);
325         buttons.add(Box.createGlue());
326
327         ok = new JButton(jEdit.getProperty("common.ok"));
328         ok.addActionListener(this);
329         buttons.add(ok);
330         buttons.add(Box.createHorizontalStrut(6));
331         getRootPane().setDefaultButton(ok);
332         cancel = new JButton(jEdit.getProperty("common.cancel"));
333         cancel.addActionListener(this);
334         buttons.add(cancel);
335         buttons.add(Box.createHorizontalStrut(6));
336         apply = new JButton(jEdit.getProperty("common.apply"));
337         apply.addActionListener(this);
338         buttons.add(apply);
339
340         buttons.add(Box.createGlue());
341
342         content.add(buttons, BorderLayout.SOUTH);
343
344         // register the Options dialog as a TreeSelectionListener.
345
// this is done before the initial selection to ensure that the
346
// first selected OptionPane is displayed on startup.
347
paneTree.getSelectionModel().addTreeSelectionListener(this);
348
349         OptionGroup rootNode = (OptionGroup)paneTree.getModel().getRoot();
350         for(int i = 0; i < rootNode.getMemberCount(); i++)
351         {
352             paneTree.expandPath(new TreePath(
353             new Object JavaDoc[] { rootNode, rootNode.getMember(i) }));
354         }
355
356         // returns false if no such pane exists; calling with null
357
// param selects first option pane found
358
if(!selectPane(rootNode, pane))
359             selectPane(rootNode,null);
360
361         splitter.setDividerLocation(paneTree.getPreferredSize().width
362             + scroller.getVerticalScrollBar().getPreferredSize()
363             .width);
364
365         GUIUtilities.loadGeometry(this,name);
366         int dividerLocation = jEdit.getIntegerProperty(name + ".splitter",-1);
367         if(dividerLocation != -1)
368             splitter.setDividerLocation(dividerLocation);
369
370         // in case saved geometry is too small
371
updateSize();
372
373         setVisible(true);
374     } //}}}
375

376     //{{{ Private members
377

378     //{{{ selectPane() method
379
private boolean selectPane(OptionGroup node, String JavaDoc name)
380     {
381         return selectPane(node,name,new ArrayList());
382     } //}}}
383

384     //{{{ selectPane() method
385
private boolean selectPane(OptionGroup node, String JavaDoc name, List JavaDoc path)
386     {
387         path.add(node);
388
389         Enumeration e = node.getMembers();
390         while(e.hasMoreElements())
391         {
392             Object JavaDoc obj = e.nextElement();
393             if(obj instanceof OptionGroup)
394             {
395                 OptionGroup grp = (OptionGroup)obj;
396                 if(grp.getName().equals(name))
397                 {
398                     path.add(grp);
399                     path.add(grp.getMember(0));
400                     TreePath treePath = new TreePath(
401                         path.toArray());
402                     paneTree.scrollPathToVisible(treePath);
403                     paneTree.setSelectionPath(treePath);
404                     return true;
405                 }
406                 else if(selectPane((OptionGroup)obj,name,path))
407                     return true;
408             }
409             else if(obj instanceof OptionPane)
410             {
411                 OptionPane pane = (OptionPane)obj;
412                 if(pane.getName().equals(name)
413                     || name == null)
414                 {
415                     path.add(pane);
416                     TreePath treePath = new TreePath(
417                         path.toArray());
418                     paneTree.scrollPathToVisible(treePath);
419                     paneTree.setSelectionPath(treePath);
420                     return true;
421                 }
422             }
423             else if(obj instanceof String JavaDoc)
424             {
425                 String JavaDoc pane = (String JavaDoc)obj;
426                 if(pane.equals(name)
427                     || name == null)
428                 {
429                     path.add(pane);
430                     TreePath treePath = new TreePath(
431                         path.toArray());
432                     paneTree.scrollPathToVisible(treePath);
433                     paneTree.setSelectionPath(treePath);
434                     return true;
435                 }
436             }
437         }
438
439         path.remove(node);
440
441         return false;
442     } //}}}
443

444     //{{{ save() method
445
private void save(Object JavaDoc obj)
446     {
447         if(obj instanceof OptionGroup)
448         {
449             OptionGroup grp = (OptionGroup)obj;
450             Enumeration members = grp.getMembers();
451             while(members.hasMoreElements())
452             {
453                 save(members.nextElement());
454             }
455         }
456         else if(obj instanceof OptionPane)
457         {
458             try
459             {
460                 ((OptionPane)obj).save();
461             }
462             catch(Throwable JavaDoc t)
463             {
464                 Log.log(Log.ERROR,this,"Error saving options:");
465                 Log.log(Log.ERROR,this,t);
466             }
467         }
468         else if(obj instanceof String JavaDoc)
469         {
470             save(deferredOptionPanes.get(obj));
471         }
472     } //}}}
473

474     //{{{ updateSize() method
475
private void updateSize()
476     {
477         Dimension currentSize = getSize();
478         Dimension requestedSize = getPreferredSize();
479         Dimension newSize = new Dimension(
480             Math.max(currentSize.width,requestedSize.width),
481             Math.max(currentSize.height,requestedSize.height)
482         );
483         if(newSize.width < 300)
484             newSize.width = 300;
485         if(newSize.height < 200)
486             newSize.height = 200;
487         setSize(newSize);
488         validate();
489     } //}}}
490

491     //}}}
492

493     //{{{ PaneNameRenderer class
494
public static class PaneNameRenderer extends DefaultTreeCellRenderer
495     {
496         public PaneNameRenderer()
497         {
498             paneFont = UIManager.getFont("Tree.font");
499             if(paneFont == null)
500                 paneFont = jEdit.getFontProperty("metal.secondary.font");
501             groupFont = paneFont.deriveFont(Font.BOLD);
502         }
503
504         public Component getTreeCellRendererComponent(JTree tree,
505             Object JavaDoc value, boolean selected, boolean expanded,
506             boolean leaf, int row, boolean hasFocus)
507         {
508             super.getTreeCellRendererComponent(tree,value,
509                 selected,expanded,leaf,row,hasFocus);
510
511             String JavaDoc name = null;
512
513             if (value instanceof OptionGroup)
514             {
515                 setText(((OptionGroup)value).getLabel());
516                 setFont(groupFont);
517             }
518             else if (value instanceof OptionPane)
519             {
520                 name = ((OptionPane)value).getName();
521                 setFont(paneFont);
522             }
523             else if (value instanceof String JavaDoc)
524             {
525                 name = (String JavaDoc) value;
526                 setFont(paneFont);
527             }
528
529             if (name != null)
530             {
531                 String JavaDoc label = jEdit.getProperty("options." +
532                     name + ".label");
533
534                 if (label == null)
535                 {
536                     setText("NO LABEL PROPERTY: " + name);
537                 }
538                 else
539                 {
540                     setText(label);
541                 }
542             }
543
544             setIcon(null);
545
546             return this;
547         }
548
549         private Font paneFont;
550         private final Font groupFont;
551     } //}}}
552

553     //{{{ OptionTreeModel class
554
public class OptionTreeModel implements TreeModel
555     {
556         public void addTreeModelListener(TreeModelListener l)
557         {
558             listenerList.add(TreeModelListener.class, l);
559         }
560
561         public void removeTreeModelListener(TreeModelListener l)
562         {
563             listenerList.remove(TreeModelListener.class, l);
564         }
565
566         public Object JavaDoc getChild(Object JavaDoc parent, int index)
567         {
568             if (parent instanceof OptionGroup)
569             {
570                 return ((OptionGroup)parent).getMember(index);
571             }
572             else
573             {
574                 return null;
575             }
576         }
577
578         public int getChildCount(Object JavaDoc parent)
579         {
580             if (parent instanceof OptionGroup)
581             {
582                 return ((OptionGroup)parent).getMemberCount();
583             }
584             else
585             {
586                 return 0;
587             }
588         }
589
590         public int getIndexOfChild(Object JavaDoc parent, Object JavaDoc child)
591         {
592             if (parent instanceof OptionGroup)
593             {
594                 return ((OptionGroup)parent)
595                     .getMemberIndex(child);
596             }
597             else
598             {
599                 return -1;
600             }
601         }
602
603         public Object JavaDoc getRoot()
604         {
605             return root;
606         }
607
608         public boolean isLeaf(Object JavaDoc node)
609         {
610             return !(node instanceof OptionGroup);
611         }
612
613         public void valueForPathChanged(TreePath path, Object JavaDoc newValue)
614         {
615             // this model may not be changed by the TableCellEditor
616
}
617
618         protected void fireNodesChanged(Object JavaDoc source, Object JavaDoc[] path,
619             int[] childIndices, Object JavaDoc[] children)
620         {
621             Object JavaDoc[] listeners = listenerList.getListenerList();
622
623             TreeModelEvent modelEvent = null;
624             for (int i = listeners.length - 2; i >= 0; i -= 2)
625             {
626                 if (listeners[i] != TreeModelListener.class)
627                     continue;
628
629                 if (modelEvent == null)
630                 {
631                     modelEvent = new TreeModelEvent(source,
632                         path, childIndices, children);
633                 }
634
635                 ((TreeModelListener)listeners[i + 1])
636                     .treeNodesChanged(modelEvent);
637             }
638         }
639
640         protected void fireNodesInserted(Object JavaDoc source, Object JavaDoc[] path,
641             int[] childIndices, Object JavaDoc[] children)
642         {
643             Object JavaDoc[] listeners = listenerList.getListenerList();
644
645             TreeModelEvent modelEvent = null;
646             for (int i = listeners.length - 2; i >= 0; i -= 2)
647             {
648                 if (listeners[i] != TreeModelListener.class)
649                     continue;
650
651                 if (modelEvent == null)
652                 {
653                     modelEvent = new TreeModelEvent(source,
654                         path, childIndices, children);
655                 }
656
657                 ((TreeModelListener)listeners[i + 1])
658                     .treeNodesInserted(modelEvent);
659             }
660         }
661
662         protected void fireNodesRemoved(Object JavaDoc source, Object JavaDoc[] path,
663             int[] childIndices, Object JavaDoc[] children)
664         {
665             Object JavaDoc[] listeners = listenerList.getListenerList();
666
667             TreeModelEvent modelEvent = null;
668             for (int i = listeners.length - 2; i >= 0; i -= 2)
669             {
670                 if (listeners[i] != TreeModelListener.class)
671                     continue;
672
673                 if (modelEvent == null)
674                 {
675                     modelEvent = new TreeModelEvent(source,
676                         path, childIndices, children);
677                 }
678
679                 ((TreeModelListener)listeners[i + 1])
680                     .treeNodesRemoved(modelEvent);
681             }
682         }
683
684         protected void fireTreeStructureChanged(Object JavaDoc source,
685             Object JavaDoc[] path, int[] childIndices, Object JavaDoc[] children)
686         {
687             Object JavaDoc[] listeners = listenerList.getListenerList();
688
689             TreeModelEvent modelEvent = null;
690             for (int i = listeners.length - 2; i >= 0; i -= 2)
691             {
692                 if (listeners[i] != TreeModelListener.class)
693                     continue;
694
695                 if (modelEvent == null)
696                 {
697                     modelEvent = new TreeModelEvent(source,
698                         path, childIndices, children);
699                 }
700
701                 ((TreeModelListener)listeners[i + 1])
702                     .treeStructureChanged(modelEvent);
703             }
704         }
705
706         private final OptionGroup root = new OptionGroup(null);
707         private final EventListenerList listenerList = new EventListenerList();
708     } //}}}
709
}
710
Popular Tags