KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > GUIUtilities


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

22
23 package org.gjt.sp.jedit;
24
25 //{{{ Imports
26

27 import java.awt.Color JavaDoc;
28 import java.awt.Component JavaDoc;
29 import java.awt.Container JavaDoc;
30 import java.awt.Dimension JavaDoc;
31 import java.awt.Font JavaDoc;
32 import java.awt.Frame JavaDoc;
33 import java.awt.GraphicsConfiguration JavaDoc;
34 import java.awt.GraphicsDevice JavaDoc;
35 import java.awt.GraphicsEnvironment JavaDoc;
36 import java.awt.Image JavaDoc;
37 import java.awt.Point JavaDoc;
38 import java.awt.Rectangle JavaDoc;
39 import java.awt.Window JavaDoc;
40
41 import java.awt.event.ComponentAdapter JavaDoc;
42 import java.awt.event.ComponentEvent JavaDoc;
43 import java.awt.event.MouseEvent JavaDoc;
44 import java.awt.event.WindowAdapter JavaDoc;
45 import java.awt.event.WindowEvent JavaDoc;
46 import java.awt.event.WindowStateListener JavaDoc;
47
48 import java.net.URL JavaDoc;
49
50 import java.util.Hashtable JavaDoc;
51 import java.util.Locale JavaDoc;
52 import java.util.Map JavaDoc;
53 import java.util.StringTokenizer JavaDoc;
54
55 import javax.swing.*;
56
57 import org.gjt.sp.jedit.browser.VFSFileChooserDialog;
58
59 import org.gjt.sp.jedit.gui.EnhancedButton;
60 import org.gjt.sp.jedit.gui.FloatingWindowContainer;
61 import org.gjt.sp.jedit.gui.SplashScreen;
62 import org.gjt.sp.jedit.gui.VariableGridLayout;
63
64 import org.gjt.sp.jedit.menu.EnhancedCheckBoxMenuItem;
65 import org.gjt.sp.jedit.menu.EnhancedMenu;
66 import org.gjt.sp.jedit.menu.EnhancedMenuItem;
67
68 import org.gjt.sp.jedit.syntax.SyntaxStyle;
69 import org.gjt.sp.jedit.syntax.Token;
70
71 import org.gjt.sp.jedit.textarea.TextAreaMouseHandler;
72
73 import org.gjt.sp.util.Log;
74 //}}}
75

76 /**
77  * Various GUI functions.<p>
78  *
79  * The most frequently used members of this class are:
80  *
81  * <ul>
82  * <li>{@link #loadIcon(String)}</li>
83  * <li>{@link #confirm(Component,String,Object[],int,int)}</li>
84  * <li>{@link #error(Component,String,Object[])}</li>
85  * <li>{@link #message(Component,String,Object[])}</li>
86  * <li>{@link #showPopupMenu(JPopupMenu,Component,int,int)}</li>
87  * <li>{@link #showVFSFileDialog(View,String,int,boolean)}</li>
88  * <li>{@link #loadGeometry(Window,String)}</li>
89  * <li>{@link #saveGeometry(Window,String)}</li>
90  * </ul>
91  *
92  * @author Slava Pestov
93  * @version $Id: GUIUtilities.java 8676 2007-01-19 20:14:58Z kpouer $
94  */

95 public class GUIUtilities
96 {
97     //{{{ Some predefined icons
98
/**
99      * @deprecated Use <code>GUIUtilities.loadIcon("new.gif");</code>
100      * instead.
101      */

102     public static Icon NEW_BUFFER_ICON;
103
104     /**
105      * @deprecated Use <code>GUIUtilities.loadIcon("dirty.gif");</code>
106      * instead.
107      */

108     public static Icon DIRTY_BUFFER_ICON;
109
110     /**
111      * @deprecated Use <code>GUIUtilities.loadIcon("readonly.gif");</code>
112      * instead.
113      */

114     public static Icon READ_ONLY_BUFFER_ICON;
115
116     /**
117      * @deprecated Use <code>GUIUtilities.loadIcon("normal.gif");</code>
118      * instead.
119      */

120     public static Icon NORMAL_BUFFER_ICON;
121
122     /**
123      * @deprecated Use <code>GUIUtilities.loadIcon("jedit-icon.gif");</code>
124      * instead.
125      */

126     public static Icon WINDOW_ICON;
127     //}}}
128

129     //{{{ Icon methods
130

131     //{{{ setIconPath() method
132
/**
133      * Sets the path where jEdit looks for icons.
134      * @since jEdit 4.2pre5
135      */

136     public static void setIconPath(String JavaDoc iconPath)
137     {
138         GUIUtilities.iconPath = iconPath;
139         if(icons != null)
140             icons.clear();
141     } //}}}
142

143     //{{{ loadIcon() method
144
/**
145      * Loads an icon.
146      * @param iconName The icon name
147      * @since jEdit 2.6pre7
148      */

149     public static Icon loadIcon(String JavaDoc iconName)
150     {
151         if(icons == null)
152             icons = new Hashtable JavaDoc<String JavaDoc, Icon>();
153
154         // check if there is a cached version first
155
Icon icon = icons.get(iconName);
156         if(icon != null)
157             return icon;
158
159         URL JavaDoc url;
160
161         try
162         {
163             // get the icon
164
if(MiscUtilities.isURL(iconName))
165                 url = new URL JavaDoc(iconName);
166             else
167                 url = new URL JavaDoc(iconPath + iconName);
168         }
169         catch(Exception JavaDoc e)
170         {
171             try
172             {
173                 url = new URL JavaDoc(defaultIconPath + iconName);
174             }
175             catch(Exception JavaDoc ex)
176             {
177                 Log.log(Log.ERROR,GUIUtilities.class,
178                     "Icon not found: " + iconName);
179                 Log.log(Log.ERROR,GUIUtilities.class,ex);
180                 return null;
181             }
182         }
183
184         icon = new ImageIcon(url);
185
186         icons.put(iconName,icon);
187         return icon;
188     } //}}}
189

190     //{{{ getEditorIcon() method
191
/**
192      * Returns the default editor window image.
193      */

194     public static Image JavaDoc getEditorIcon()
195     {
196         return ((ImageIcon)loadIcon("jedit-icon.gif")).getImage();
197     } //}}}
198

199     //{{{ getPluginIcon() method
200
/**
201      * Returns the default plugin window image.
202      */

203     public static Image JavaDoc getPluginIcon()
204     {
205         return getEditorIcon();
206     } //}}}
207

208     //}}}
209

210     //{{{ Menus, tool bars
211

212     //{{{ loadMenuBar() method
213
/**
214      * Creates a menubar. Plugins should not need to call this method.
215      * @param name The menu bar name
216      * @since jEdit 3.2pre5
217      */

218     public static JMenuBar loadMenuBar(String JavaDoc name)
219     {
220         return loadMenuBar(jEdit.getActionContext(),name);
221     } //}}}
222

223     //{{{ loadMenuBar() method
224
/**
225      * Creates a menubar. Plugins should not need to call this method.
226      * @param context An action context
227      * @param name The menu bar name
228      * @since jEdit 4.2pre1
229      */

230     public static JMenuBar loadMenuBar(ActionContext context, String JavaDoc name)
231     {
232         String JavaDoc menus = jEdit.getProperty(name);
233         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(menus);
234
235         JMenuBar mbar = new JMenuBar();
236
237         while(st.hasMoreTokens())
238         {
239             String JavaDoc menuName = st.nextToken();
240             mbar.add(loadMenu(context, menuName));
241         }
242
243         return mbar;
244     } //}}}
245

246     //{{{ loadMenu() method
247
/**
248      * Creates a menu. The menu label is set from the
249      * <code><i>name</i>.label</code> property. The menu contents is taken
250      * from the <code><i>name</i></code> property, which is a whitespace
251      * separated list of action names. An action name of <code>-</code>
252      * inserts a separator in the menu.
253      * @param name The menu name
254      * @see #loadMenuItem(String)
255      * @since jEdit 2.6pre2
256      */

257     public static JMenu loadMenu(String JavaDoc name)
258     {
259         return loadMenu(jEdit.getActionContext(),name);
260     } //}}}
261

262     //{{{ loadMenu() method
263
/**
264      * Creates a menu. The menu label is set from the
265      * <code><i>name</i>.label</code> property. The menu contents is taken
266      * from the <code><i>name</i></code> property, which is a whitespace
267      * separated list of action names. An action name of <code>-</code>
268      * inserts a separator in the menu.
269      * @param context An action context; either
270      * <code>jEdit.getActionContext()</code> or
271      * <code>VFSBrowser.getActionContext()</code>.
272      * @param name The menu name
273      * @see #loadMenuItem(String)
274      * @since jEdit 4.2pre1
275      */

276     public static JMenu loadMenu(ActionContext context, String JavaDoc name)
277     {
278         return new EnhancedMenu(name,
279             jEdit.getProperty(name.concat(".label")),
280             context);
281     } //}}}
282

283     //{{{ loadPopupMenu() method
284
/**
285      * Creates a popup menu.
286
287      * @param name The menu name
288      * @since jEdit 2.6pre2
289      */

290     public static JPopupMenu loadPopupMenu(String JavaDoc name)
291     {
292         return loadPopupMenu(jEdit.getActionContext(),name);
293     } //}}}
294

295     //{{{ loadPopupMenu() method
296
/**
297      * Creates a popup menu.
298
299      * @param context An action context; either
300      * <code>jEdit.getActionContext()</code> or
301      * <code>VFSBrowser.getActionContext()</code>.
302      * @param name The menu name
303      * @since jEdit 4.2pre1
304      */

305     public static JPopupMenu loadPopupMenu(ActionContext context, String JavaDoc name)
306     {
307         JPopupMenu menu = new JPopupMenu();
308
309         String JavaDoc menuItems = jEdit.getProperty(name);
310         if(menuItems != null)
311         {
312             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(menuItems);
313             while(st.hasMoreTokens())
314             {
315                 String JavaDoc menuItemName = st.nextToken();
316                 if(menuItemName.equals("-"))
317                     menu.addSeparator();
318                 else
319                     menu.add(loadMenuItem(context,menuItemName,false));
320             }
321         }
322
323         return menu;
324     } //}}}
325

326     //{{{ loadMenuItem() method
327
/**
328      * Creates a menu item. The menu item is bound to the action named by
329      * <code>name</code> with label taken from the return value of the
330      * {@link EditAction#getLabel()} method.
331      *
332      * @param name The menu item name
333      * @see #loadMenu(String)
334      * @since jEdit 2.6pre1
335      */

336     public static JMenuItem loadMenuItem(String JavaDoc name)
337     {
338         return loadMenuItem(jEdit.getActionContext(),name,true);
339     } //}}}
340

341     //{{{ loadMenuItem() method
342
/**
343      * Creates a menu item.
344      * @param name The menu item name
345      * @param setMnemonic True if the menu item should have a mnemonic
346      * @since jEdit 3.1pre1
347      */

348     public static JMenuItem loadMenuItem(String JavaDoc name, boolean setMnemonic)
349     {
350         return loadMenuItem(jEdit.getActionContext(),name,setMnemonic);
351     } //}}}
352

353     //{{{ loadMenuItem() method
354
/**
355      * Creates a menu item.
356      * @param context An action context; either
357      * <code>jEdit.getActionContext()</code> or
358      * <code>VFSBrowser.getActionContext()</code>.
359      * @param name The menu item name
360      * @param setMnemonic True if the menu item should have a mnemonic
361      * @since jEdit 4.2pre1
362      */

363     public static JMenuItem loadMenuItem(ActionContext context, String JavaDoc name,
364         boolean setMnemonic)
365     {
366         if(name.charAt(0) == '%')
367             return loadMenu(context,name.substring(1));
368
369         String JavaDoc label = jEdit.getProperty(name + ".label");
370         if(label == null)
371             label = name;
372
373         char mnemonic;
374         int index = label.indexOf('$');
375         if(index != -1 && label.length() - index > 1)
376         {
377             mnemonic = Character.toLowerCase(label.charAt(index + 1));
378             label = label.substring(0,index).concat(label.substring(++index));
379         }
380         else
381             mnemonic = '\0';
382
383         JMenuItem mi;
384         if(jEdit.getBooleanProperty(name + ".toggle"))
385             mi = new EnhancedCheckBoxMenuItem(label,name,context);
386         else
387             mi = new EnhancedMenuItem(label,name,context);
388
389         if(!OperatingSystem.isMacOS() && setMnemonic && mnemonic != '\0')
390             mi.setMnemonic(mnemonic);
391
392         return mi;
393     } //}}}
394

395     // {{{ loadMenuItem(EditAction, boolean)
396
public static JMenuItem loadMenuItem(EditAction editAction,
397         boolean setMnemonic)
398     {
399         String JavaDoc name = editAction.getName();
400         ActionContext context = jEdit.getActionContext();
401
402         // String label = jEdit.getProperty(name + ".label");
403
String JavaDoc label = editAction.getLabel();
404         if(label == null)
405             label = name;
406
407         char mnemonic;
408         int index = label.indexOf('$');
409         if(index != -1 && label.length() - index > 1)
410         {
411             mnemonic = Character.toLowerCase(label.charAt(index + 1));
412             label = label.substring(0,index).concat(label.substring(++index));
413         }
414         else
415             mnemonic = '\0';
416
417         JMenuItem mi;
418         if(jEdit.getBooleanProperty(name + ".toggle"))
419             mi = new EnhancedCheckBoxMenuItem(label,name,context);
420         else
421             mi = new EnhancedMenuItem(label,name,context);
422
423         if(!OperatingSystem.isMacOS() && setMnemonic && mnemonic != '\0')
424             mi.setMnemonic(mnemonic);
425
426         return mi;
427     } //}}}
428

429     //{{{ loadToolBar() method
430
/**
431      * Creates a toolbar.
432      * @param name The toolbar name
433      * @since jEdit 4.2pre2
434      */

435     public static Box loadToolBar(String JavaDoc name)
436     {
437         return loadToolBar(jEdit.getActionContext(),name);
438     } //}}}
439

440     //{{{ loadToolBar() method
441
/**
442      * Creates a toolbar.
443      * @param context An action context; either
444      * <code>jEdit.getActionContext()</code> or
445      * <code>VFSBrowser.getActionContext()</code>.
446      * @param name The toolbar name
447      * @since jEdit 4.2pre2
448      */

449     public static Box loadToolBar(ActionContext context, String JavaDoc name)
450     {
451         Box toolBar = new Box(BoxLayout.X_AXIS);
452
453         String JavaDoc buttons = jEdit.getProperty(name);
454         if(buttons != null)
455         {
456             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(buttons);
457             while(st.hasMoreTokens())
458             {
459                 String JavaDoc button = st.nextToken();
460                 if(button.equals("-"))
461                     toolBar.add(Box.createHorizontalStrut(12));
462                 else
463                 {
464                     JButton b = loadToolButton(context,button);
465                     if(b != null)
466                         toolBar.add(b);
467                 }
468             }
469         }
470
471         toolBar.add(Box.createGlue());
472
473         return toolBar;
474     } //}}}
475

476     //{{{ loadToolButton() method
477
/**
478      * Loads a tool bar button. The tooltip is constructed from
479      * the <code><i>name</i>.label</code> and
480      * <code><i>name</i>.shortcut</code> properties and the icon is loaded
481      * from the resource named '/org/gjt/sp/jedit/icons/' suffixed
482      * with the value of the <code><i>name</i>.icon</code> property.
483      * @param name The name of the button
484      */

485     public static EnhancedButton loadToolButton(String JavaDoc name)
486     {
487         return loadToolButton(jEdit.getActionContext(),name);
488     } //}}}
489

490     //{{{ loadToolButton() method
491
/**
492      * Loads a tool bar button. The tooltip is constructed from
493      * the <code><i>name</i>.label</code> and
494      * <code><i>name</i>.shortcut</code> properties and the icon is loaded
495      * from the resource named '/org/gjt/sp/jedit/icons/' suffixed
496      * with the value of the <code><i>name</i>.icon</code> property.
497      * @param context An action context; either
498      * <code>jEdit.getActionContext()</code> or
499      * <code>VFSBrowser.getActionContext()</code>.
500      * @param name The name of the button
501      * @since jEdit 4.2pre1
502      */

503     public static EnhancedButton loadToolButton(ActionContext context,
504         String JavaDoc name)
505     {
506         String JavaDoc label = jEdit.getProperty(name + ".label");
507
508         if(label == null)
509             label = name;
510
511         Icon icon;
512         String JavaDoc iconName = jEdit.getProperty(name + ".icon");
513         if(iconName == null)
514             icon = loadIcon("BrokenImage.png");
515         else
516         {
517             icon = loadIcon(iconName);
518             if(icon == null)
519                 icon = loadIcon("BrokenImage.png");
520         }
521
522         String JavaDoc toolTip = prettifyMenuLabel(label);
523         String JavaDoc shortcut1 = jEdit.getProperty(name + ".shortcut");
524         String JavaDoc shortcut2 = jEdit.getProperty(name + ".shortcut2");
525         if(shortcut1 != null || shortcut2 != null)
526         {
527             toolTip = toolTip + " ("
528                 + (shortcut1 != null
529                 ? shortcut1 : "")
530                 + ((shortcut1 != null && shortcut2 != null)
531                 ? " or " : "")
532                 + (shortcut2 != null
533                 ? shortcut2
534                 : "") + ')';
535         }
536
537         return new EnhancedButton(icon,toolTip,name,context);
538     } //}}}
539

540     //{{{ prettifyMenuLabel() method
541
/**
542      * `Prettifies' a menu item label by removing the `$' sign. This
543      * can be used to process the contents of an <i>action</i>.label
544      * property.
545      */

546     public static String JavaDoc prettifyMenuLabel(String JavaDoc label)
547     {
548         int index = label.indexOf('$');
549         if(index != -1)
550         {
551             label = label.substring(0,index)
552                 .concat(label.substring(index + 1));
553         }
554         return label;
555     } //}}}
556

557     //}}}
558

559     //{{{ Canned dialog boxes
560

561     //{{{ message() method
562
/**
563      * Displays a dialog box.
564      * The title of the dialog is fetched from
565      * the <code><i>name</i>.title</code> property. The message is fetched
566      * from the <code><i>name</i>.message</code> property. The message
567      * is formatted by the property manager with <code>args</code> as
568      * positional parameters.
569      * @param comp The component to display the dialog for
570      * @param name The name of the dialog
571      * @param args Positional parameters to be substituted into the
572      * message text
573      */

574     public static void message(Component JavaDoc comp, String JavaDoc name, Object JavaDoc[] args)
575     {
576         hideSplashScreen();
577
578         JOptionPane.showMessageDialog(comp,
579             jEdit.getProperty(name.concat(".message"),args),
580             jEdit.getProperty(name.concat(".title"),args),
581             JOptionPane.INFORMATION_MESSAGE);
582     } //}}}
583

584     //{{{ error() method
585
/**
586      * Displays an error dialog box.
587      * The title of the dialog is fetched from
588      * the <code><i>name</i>.title</code> property. The message is fetched
589      * from the <code><i>name</i>.message</code> property. The message
590      * is formatted by the property manager with <code>args</code> as
591      * positional parameters.
592      * @param comp The component to display the dialog for
593      * @param name The name of the dialog
594      * @param args Positional parameters to be substituted into the
595      * message text
596      */

597     public static void error(Component JavaDoc comp, String JavaDoc name, Object JavaDoc[] args)
598     {
599         hideSplashScreen();
600
601         JOptionPane.showMessageDialog(comp,
602             jEdit.getProperty(name.concat(".message"),args),
603             jEdit.getProperty(name.concat(".title"),args),
604             JOptionPane.ERROR_MESSAGE);
605     } //}}}
606

607     //{{{ input() method
608
/**
609      * Displays an input dialog box and returns any text the user entered.
610      * The title of the dialog is fetched from
611      * the <code><i>name</i>.title</code> property. The message is fetched
612      * from the <code><i>name</i>.message</code> property.
613      * @param comp The component to display the dialog for
614      * @param name The name of the dialog
615      * @param def The text to display by default in the input field
616      */

617     public static String JavaDoc input(Component JavaDoc comp, String JavaDoc name, Object JavaDoc def)
618     {
619         return input(comp,name,null,def);
620     } //}}}
621

622     //{{{ inputProperty() method
623
/**
624      * Displays an input dialog box and returns any text the user entered.
625      * The title of the dialog is fetched from
626      * the <code><i>name</i>.title</code> property. The message is fetched
627      * from the <code><i>name</i>.message</code> property.
628      * @param comp The component to display the dialog for
629      * @param name The name of the dialog
630      * @param def The property whose text to display in the input field
631      */

632     public static String JavaDoc inputProperty(Component JavaDoc comp, String JavaDoc name,
633         String JavaDoc def)
634     {
635         return inputProperty(comp,name,null,def);
636     } //}}}
637

638     //{{{ input() method
639
/**
640      * Displays an input dialog box and returns any text the user entered.
641      * The title of the dialog is fetched from
642      * the <code><i>name</i>.title</code> property. The message is fetched
643      * from the <code><i>name</i>.message</code> property.
644      * @param comp The component to display the dialog for
645      * @param name The name of the dialog
646      * @param def The text to display by default in the input field
647      * @param args Positional parameters to be substituted into the
648      * message text
649      * @since jEdit 3.1pre3
650      */

651     public static String JavaDoc input(Component JavaDoc comp, String JavaDoc name,
652         Object JavaDoc[] args, Object JavaDoc def)
653     {
654         hideSplashScreen();
655
656         String JavaDoc retVal = (String JavaDoc)JOptionPane.showInputDialog(comp,
657             jEdit.getProperty(name.concat(".message"),args),
658             jEdit.getProperty(name.concat(".title")),
659             JOptionPane.QUESTION_MESSAGE,null,null,def);
660         return retVal;
661     } //}}}
662

663     //{{{ inputProperty() method
664
/**
665      * Displays an input dialog box and returns any text the user entered.
666      * The title of the dialog is fetched from
667      * the <code><i>name</i>.title</code> property. The message is fetched
668      * from the <code><i>name</i>.message</code> property.
669      * @param comp The component to display the dialog for
670      * @param name The name of the dialog
671      * @param args Positional parameters to be substituted into the
672      * message text
673      * @param def The property whose text to display in the input field
674      * @since jEdit 3.1pre3
675      */

676     public static String JavaDoc inputProperty(Component JavaDoc comp, String JavaDoc name,
677         Object JavaDoc[] args, String JavaDoc def)
678     {
679         hideSplashScreen();
680
681         String JavaDoc retVal = (String JavaDoc)JOptionPane.showInputDialog(comp,
682             jEdit.getProperty(name.concat(".message"),args),
683             jEdit.getProperty(name.concat(".title")),
684             JOptionPane.QUESTION_MESSAGE,
685             null,null,jEdit.getProperty(def));
686         if(retVal != null)
687             jEdit.setProperty(def,retVal);
688         return retVal;
689     } //}}}
690

691     //{{{ confirm() method
692
/**
693      * Displays a confirm dialog box and returns the button pushed by the
694      * user. The title of the dialog is fetched from the
695      * <code><i>name</i>.title</code> property. The message is fetched
696      * from the <code><i>name</i>.message</code> property.
697      * @param comp The component to display the dialog for
698      * @param name The name of the dialog
699      * @param args Positional parameters to be substituted into the
700      * message text
701      * @param buttons The buttons to display - for example,
702      * JOptionPane.YES_NO_CANCEL_OPTION
703      * @param type The dialog type - for example,
704      * JOptionPane.WARNING_MESSAGE
705      * @since jEdit 3.1pre3
706      */

707     public static int confirm(Component JavaDoc comp, String JavaDoc name,
708         Object JavaDoc[] args, int buttons, int type)
709     {
710         hideSplashScreen();
711
712         return JOptionPane.showConfirmDialog(comp,
713             jEdit.getProperty(name + ".message",args),
714             jEdit.getProperty(name + ".title"),buttons,type);
715     } //}}}
716

717     //{{{ listConfirm() method
718
/**
719      * Displays a confirm dialog box and returns the button pushed by the
720      * user. The title of the dialog is fetched from the
721      * <code><i>name</i>.title</code> property. The message is fetched
722      * from the <code><i>name</i>.message</code> property. The dialog
723      * also shows a list of entries given by the <code>listModel</code>
724      * parameter.
725      * @since jEdit 4.3pre1
726      */

727     public static int listConfirm(Component JavaDoc comp, String JavaDoc name, String JavaDoc[] args,
728         Object JavaDoc[] listModel)
729     {
730         JList list = new JList(listModel);
731         list.setVisibleRowCount(8);
732
733         Object JavaDoc[] message = {
734             jEdit.getProperty(name + ".message",args),
735             new JScrollPane(list)
736         };
737
738         return JOptionPane.showConfirmDialog(comp,
739             message,
740             jEdit.getProperty(name + ".title"),
741             JOptionPane.YES_NO_OPTION,
742             JOptionPane.QUESTION_MESSAGE);
743     } //}}}
744

745     //{{{ showVFSFileDialog() method
746
/**
747      * Displays a VFS file selection dialog box.
748      * @param view The view, should be non-null
749      * @param path The initial directory to display. May be null
750      * @param type The dialog type. One of
751      * {@link org.gjt.sp.jedit.browser.VFSBrowser#OPEN_DIALOG},
752      * {@link org.gjt.sp.jedit.browser.VFSBrowser#SAVE_DIALOG}, or
753      * {@link org.gjt.sp.jedit.browser.VFSBrowser#CHOOSE_DIRECTORY_DIALOG}.
754      * @param multipleSelection True if multiple selection should be allowed
755      * @return The selected file(s)
756      * @since jEdit 2.6pre2
757      */

758     public static String JavaDoc[] showVFSFileDialog(View view, String JavaDoc path,
759         int type, boolean multipleSelection)
760     {
761         // the view should not be null, but some plugins might do this
762
if(view == null)
763         {
764             Log.log(Log.WARNING,GUIUtilities.class,
765             "showVFSFileDialog(): given null view, assuming jEdit.getActiveView()");
766             view = jEdit.getActiveView();
767         }
768
769         hideSplashScreen();
770
771         VFSFileChooserDialog fileChooser = new VFSFileChooserDialog(
772             view,path,type,multipleSelection);
773         String JavaDoc[] selectedFiles = fileChooser.getSelectedFiles();
774         if(selectedFiles == null)
775             return null;
776
777         return selectedFiles;
778     } //}}}
779

780     //}}}
781

782     //{{{ Colors and styles
783

784     //{{{ parseColor() method
785
/**
786      * Converts a color name to a color object. The name must either be
787      * a known string, such as `red', `green', etc (complete list is in
788      * the <code>java.awt.Color</code> class) or a hex color value
789      * prefixed with `#', for example `#ff0088'.
790      * @param name The color name
791      */

792     public static Color JavaDoc parseColor(String JavaDoc name)
793     {
794         return parseColor(name, Color.black);
795     } //}}}
796

797     //{{{ parseColor() method
798
public static Color JavaDoc parseColor(String JavaDoc name, Color JavaDoc defaultColor)
799     {
800         if(name == null)
801             return defaultColor;
802         else if(name.charAt(0) == '#')
803         {
804             try
805             {
806                 return Color.decode(name);
807             }
808             catch(NumberFormatException JavaDoc nf)
809             {
810                 return defaultColor;
811             }
812         }
813         else if("red".equals(name))
814             return Color.red;
815         else if("green".equals(name))
816             return Color.green;
817         else if("blue".equals(name))
818             return Color.blue;
819         else if("yellow".equals(name))
820             return Color.yellow;
821         else if("orange".equals(name))
822             return Color.orange;
823         else if("white".equals(name))
824             return Color.white;
825         else if("lightGray".equals(name))
826             return Color.lightGray;
827         else if("gray".equals(name))
828             return Color.gray;
829         else if("darkGray".equals(name))
830             return Color.darkGray;
831         else if("black".equals(name))
832             return Color.black;
833         else if("cyan".equals(name))
834             return Color.cyan;
835         else if("magenta".equals(name))
836             return Color.magenta;
837         else if("pink".equals(name))
838             return Color.pink;
839         else
840             return defaultColor;
841     } //}}}
842

843     //{{{ getColorHexString() method
844
/**
845      * Converts a color object to its hex value. The hex value
846      * prefixed is with `#', for example `#ff0088'.
847      * @param c The color object
848      */

849     public static String JavaDoc getColorHexString(Color JavaDoc c)
850     {
851         String JavaDoc colString = Integer.toHexString(c.getRGB() & 0xffffff);
852         return "#000000".substring(0,7 - colString.length()).concat(colString);
853     } //}}}
854

855     //{{{ parseStyle() method
856
/**
857      * Converts a style string to a style object.
858      * @param str The style string
859      * @param family Style strings only specify font style, not font family
860      * @param size Style strings only specify font style, not font family
861      * @exception IllegalArgumentException if the style is invalid
862      * @since jEdit 3.2pre6
863      */

864     public static SyntaxStyle parseStyle(String JavaDoc str, String JavaDoc family, int size)
865         throws IllegalArgumentException JavaDoc
866     {
867         return parseStyle(str,family,size,true);
868     } //}}}
869

870     //{{{ parseStyle() method
871
/**
872      * Converts a style string to a style object.
873      * @param str The style string
874      * @param family Style strings only specify font style, not font family
875      * @param size Style strings only specify font style, not font family
876      * @param color If false, the styles will be monochrome
877      * @exception IllegalArgumentException if the style is invalid
878      * @since jEdit 4.0pre4
879      */

880     public static SyntaxStyle parseStyle(String JavaDoc str, String JavaDoc family, int size,
881         boolean color)
882         throws IllegalArgumentException JavaDoc
883     {
884         Color JavaDoc fgColor = Color.black;
885         Color JavaDoc bgColor = null;
886         boolean italic = false;
887         boolean bold = false;
888         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(str);
889         while(st.hasMoreTokens())
890         {
891             String JavaDoc s = st.nextToken();
892             if(s.startsWith("color:"))
893             {
894                 if(color)
895                     fgColor = GUIUtilities.parseColor(s.substring(6), Color.black);
896             }
897             else if(s.startsWith("bgColor:"))
898             {
899                 if(color)
900                     bgColor = GUIUtilities.parseColor(s.substring(8), null);
901             }
902             else if(s.startsWith("style:"))
903             {
904                 for(int i = 6; i < s.length(); i++)
905                 {
906                     if(s.charAt(i) == 'i')
907                         italic = true;
908                     else if(s.charAt(i) == 'b')
909                         bold = true;
910                     else
911                         throw new IllegalArgumentException JavaDoc(
912                             "Invalid style: " + s);
913                 }
914             }
915             else
916                 throw new IllegalArgumentException JavaDoc(
917                     "Invalid directive: " + s);
918         }
919         return new SyntaxStyle(fgColor,bgColor,
920             new Font JavaDoc(family,
921             (italic ? Font.ITALIC : 0) | (bold ? Font.BOLD : 0),
922             size));
923     } //}}}
924

925     //{{{ getStyleString() method
926
/**
927      * Converts a style into it's string representation.
928      * @param style The style
929      */

930     public static String JavaDoc getStyleString(SyntaxStyle style)
931     {
932         StringBuilder JavaDoc buf = new StringBuilder JavaDoc();
933
934         if (style.getForegroundColor() != null)
935         {
936             buf.append("color:").append(getColorHexString(style.getForegroundColor()));
937         }
938
939         if (style.getBackgroundColor() != null)
940         {
941             buf.append(" bgColor:").append(getColorHexString(style.getBackgroundColor()));
942         }
943
944         Font JavaDoc font = style.getFont();
945         if (!font.isPlain())
946         {
947             buf.append(" style:");
948             if (font.isItalic())
949                 buf.append('i');
950             if (font.isBold())
951                 buf.append('b');
952         }
953
954         return buf.toString();
955     } //}}}
956

957     //{{{ loadStyles() method
958
/**
959      * Loads the syntax styles from the properties, giving them the specified
960      * base font family and size.
961      * @param family The font family
962      * @param size The font size
963      * @since jEdit 3.2pre6
964      */

965     public static SyntaxStyle[] loadStyles(String JavaDoc family, int size)
966     {
967         return loadStyles(family,size,true);
968     } //}}}
969

970     //{{{ loadStyles() method
971
/**
972      * Loads the syntax styles from the properties, giving them the specified
973      * base font family and size.
974      * @param family The font family
975      * @param size The font size
976      * @param color If false, the styles will be monochrome
977      * @since jEdit 4.0pre4
978      */

979     public static SyntaxStyle[] loadStyles(String JavaDoc family, int size, boolean color)
980     {
981         SyntaxStyle[] styles = new SyntaxStyle[Token.ID_COUNT];
982
983         // start at 1 not 0 to skip Token.NULL
984
for(int i = 1; i < styles.length; i++)
985         {
986             try
987             {
988                 String JavaDoc styleName = "view.style."
989                     + Token.tokenToString((byte)i)
990                     .toLowerCase(Locale.ENGLISH);
991                 styles[i] = GUIUtilities.parseStyle(
992                     jEdit.getProperty(styleName),
993                     family,size,color);
994             }
995             catch(Exception JavaDoc e)
996             {
997                 Log.log(Log.ERROR,GUIUtilities.class,e);
998             }
999         }
1000
1001        return styles;
1002    } //}}}
1003

1004    //}}}
1005

1006    //{{{ Loading, saving window geometry
1007

1008    //{{{ loadGeometry() method
1009
/**
1010     * Loads a windows's geometry from the properties.
1011     * The geometry is loaded from the <code><i>name</i>.x</code>,
1012     * <code><i>name</i>.y</code>, <code><i>name</i>.width</code> and
1013     * <code><i>name</i>.height</code> properties.
1014     *
1015     * @param win The window to load geometry from
1016     * @param parent The parent frame to be relative to.
1017     * @param name The name of the window
1018     */

1019    public static void loadGeometry(Window JavaDoc win, Container JavaDoc parent, String JavaDoc name ) {
1020        int x, y, width, height;
1021
1022        Dimension JavaDoc size = win.getSize();
1023        width = jEdit.getIntegerProperty(name + ".width", size.width);
1024        height = jEdit.getIntegerProperty(name + ".height", size.height);
1025        x = jEdit.getIntegerProperty(name + ".x",50);
1026        y = jEdit.getIntegerProperty(name + ".y",50);
1027        if(parent != null)
1028        {
1029            Point JavaDoc location = parent.getLocation();
1030            x = location.x + x;
1031            y = location.y + y;
1032        }
1033
1034        int extState = jEdit.getIntegerProperty(name + ".extendedState", Frame.NORMAL);
1035
1036        Rectangle JavaDoc desired = new Rectangle JavaDoc(x,y,width,height);
1037        try
1038        {
1039            if(!Debug.DISABLE_MULTIHEAD)
1040                adjustForScreenBounds(desired);
1041        }
1042        catch(Exception JavaDoc e)
1043        {
1044            /* Workaround for OS X bug. */
1045            Log.log(Log.ERROR,GUIUtilities.class,e);
1046        }
1047
1048        if(OperatingSystem.isX11() && Debug.GEOMETRY_WORKAROUND)
1049            new UnixWorkaround(win,name,desired,extState);
1050        else
1051        {
1052            win.setBounds(desired);
1053            if(win instanceof Frame JavaDoc)
1054                ((Frame JavaDoc)win).setExtendedState(extState);
1055        }
1056        
1057    } //}}}
1058

1059    //{{{ loadGeometry() method
1060
/**
1061     * Loads a windows's geometry from the properties.
1062     * The geometry is loaded from the <code><i>name</i>.x</code>,
1063     * <code><i>name</i>.y</code>, <code><i>name</i>.width</code> and
1064     * <code><i>name</i>.height</code> properties.
1065     *
1066     * @param win The window to load geometry from
1067     * @param name The name of the window
1068     */

1069    public static void loadGeometry(Window JavaDoc win, String JavaDoc name)
1070    {
1071        loadGeometry(win, win.getParent(), name);
1072    } //}}}
1073

1074    //{{{ adjustForScreenBounds() method
1075
/**
1076     * Gives a rectangle the specified bounds, ensuring it is within the
1077     * screen bounds.
1078     * @since jEdit 4.2pre3
1079     */

1080    public static void adjustForScreenBounds(Rectangle JavaDoc desired)
1081    {
1082        // Make sure the window is displayed in visible region
1083
Rectangle JavaDoc osbounds = OperatingSystem.getScreenBounds(desired);
1084
1085        if(desired.x < osbounds.x || desired.x+desired.width
1086            > desired.x + osbounds.width)
1087        {
1088            if (desired.width > osbounds.width)
1089                desired.width = osbounds.width;
1090            desired.x = (osbounds.width - desired.width) / 2;
1091        }
1092        if(desired.y < osbounds.y || desired.y+desired.height
1093            > osbounds.y + osbounds.height)
1094        {
1095            if (desired.height >= osbounds.height)
1096                desired.height = osbounds.height;
1097            desired.y = (osbounds.height - desired.height) / 2;
1098        }
1099    } //}}}
1100

1101    //{{{ UnixWorkaround class
1102
static class UnixWorkaround
1103    {
1104        Window JavaDoc win;
1105        String JavaDoc name;
1106        Rectangle JavaDoc desired;
1107        Rectangle JavaDoc required;
1108        long start;
1109        boolean windowOpened;
1110
1111        //{{{ UnixWorkaround constructor
1112
UnixWorkaround(Window JavaDoc win, String JavaDoc name, Rectangle JavaDoc desired,
1113            int extState)
1114        {
1115            this.win = win;
1116            this.name = name;
1117            this.desired = desired;
1118
1119            int adjust_x, adjust_y, adjust_width, adjust_height;
1120            adjust_x = jEdit.getIntegerProperty(name + ".dx",0);
1121            adjust_y = jEdit.getIntegerProperty(name + ".dy",0);
1122            adjust_width = jEdit.getIntegerProperty(name + ".d-width",0);
1123            adjust_height = jEdit.getIntegerProperty(name + ".d-height",0);
1124
1125            required = new Rectangle JavaDoc(
1126                desired.x - adjust_x,
1127                desired.y - adjust_y,
1128                desired.width - adjust_width,
1129                desired.height - adjust_height);
1130
1131            Log.log(Log.DEBUG,GUIUtilities.class,"Window " + name
1132                + ": desired geometry is " + desired);
1133            Log.log(Log.DEBUG,GUIUtilities.class,"Window " + name
1134                + ": setting geometry to " + required);
1135
1136            start = System.currentTimeMillis();
1137
1138            win.setBounds(required);
1139            if(win instanceof Frame JavaDoc)
1140                ((Frame JavaDoc)win).setExtendedState(extState);
1141
1142            win.addComponentListener(new ComponentHandler());
1143            win.addWindowListener(new WindowHandler());
1144        } //}}}
1145

1146        //{{{ ComponentHandler class
1147
class ComponentHandler extends ComponentAdapter JavaDoc
1148        {
1149            //{{{ componentMoved() method
1150
public void componentMoved(ComponentEvent JavaDoc evt)
1151            {
1152                if(System.currentTimeMillis() - start < 1000L)
1153                {
1154                    Rectangle JavaDoc r = win.getBounds();
1155                    if(!windowOpened && r.equals(required))
1156                        return;
1157
1158                    if(!r.equals(desired))
1159                    {
1160                        Log.log(Log.DEBUG,GUIUtilities.class,
1161                            "Window resize blocked: " + win.getBounds());
1162                        win.setBounds(desired);
1163                    }
1164                }
1165
1166                win.removeComponentListener(this);
1167            } //}}}
1168

1169            //{{{ componentResized() method
1170
public void componentResized(ComponentEvent JavaDoc evt)
1171            {
1172                if(System.currentTimeMillis() - start < 1000L)
1173                {
1174                    Rectangle JavaDoc r = win.getBounds();
1175                    if(!windowOpened && r.equals(required))
1176                        return;
1177
1178                    if(!r.equals(desired))
1179                    {
1180                        Log.log(Log.DEBUG,GUIUtilities.class,
1181                            "Window resize blocked: " + win.getBounds());
1182                        win.setBounds(desired);
1183                    }
1184                }
1185
1186                win.removeComponentListener(this);
1187            } //}}}
1188
} //}}}
1189

1190        //{{{ WindowHandler class
1191
class WindowHandler extends WindowAdapter JavaDoc
1192        {
1193            //{{{ windowOpened() method
1194
public void windowOpened(WindowEvent JavaDoc evt)
1195            {
1196                windowOpened = true;
1197
1198                Rectangle JavaDoc r = win.getBounds();
1199                Log.log(Log.DEBUG,GUIUtilities.class,"Window "
1200                    + name + ": bounds after opening: " + r);
1201
1202                jEdit.setIntegerProperty(name + ".dx",
1203                    r.x - required.x);
1204                jEdit.setIntegerProperty(name + ".dy",
1205                    r.y - required.y);
1206                jEdit.setIntegerProperty(name + ".d-width",
1207                    r.width - required.width);
1208                jEdit.setIntegerProperty(name + ".d-height",
1209                    r.height - required.height);
1210
1211                win.removeWindowListener(this);
1212            } //}}}
1213
} //}}}
1214
} //}}}
1215

1216    //{{{ saveGeometry() method
1217
/**
1218     * Saves a window's geometry to the properties.
1219     * The geometry is saved to the <code><i>name</i>.x</code>,
1220     * <code><i>name</i>.y</code>, <code><i>name</i>.width</code> and
1221     * <code><i>name</i>.height</code> properties.<br />
1222     * For Frame's and descendents use {@link #addSizeSaver(Frame,String)} to save the sizes
1223     * correct even if the Frame is in maximized or iconified state.
1224     * @param win The window to load geometry from
1225     * @param name The name of the window
1226     * @see #addSizeSaver(Frame,String)
1227     */

1228    public static void saveGeometry(Window JavaDoc win, String JavaDoc name) {
1229        saveGeometry (win, win.getParent(), name);
1230    } //}}}
1231

1232    //{{{ saveGeometry() method
1233
/**
1234     * Saves a window's geometry to the properties.
1235     * The geometry is saved to the <code><i>name</i>.x</code>,
1236     * <code><i>name</i>.y</code>, <code><i>name</i>.width</code> and
1237     * <code><i>name</i>.height</code> properties.<br />
1238     * For Frame's and descendents use {@link #addSizeSaver(Frame,Container,String)} to save the sizes
1239     * correct even if the Frame is in maximized or iconified state.
1240     * @param win The window to load geometry from
1241     * @param parent The parent frame to be relative to.
1242     * @param name The name of the window
1243     * @see #addSizeSaver(Frame,Container,String)
1244     */

1245    public static void saveGeometry(Window JavaDoc win, Container JavaDoc parent, String JavaDoc name)
1246    {
1247        if(win instanceof Frame JavaDoc)
1248        {
1249            jEdit.setIntegerProperty(name + ".extendedState",
1250                ((Frame JavaDoc)win).getExtendedState());
1251        }
1252
1253        Rectangle JavaDoc bounds = win.getBounds();
1254        int x = bounds.x;
1255        int y = bounds.y;
1256        if (parent != null)
1257        {
1258            Rectangle JavaDoc parentBounds = parent.getBounds();
1259            x = x - parentBounds.x;
1260            y = y - parentBounds.y;
1261        }
1262        jEdit.setIntegerProperty(name + ".x",x);
1263        jEdit.setIntegerProperty(name + ".y",y);
1264        jEdit.setIntegerProperty(name + ".width", bounds.width);
1265        jEdit.setIntegerProperty(name + ".height", bounds.height);
1266    } //}}}
1267

1268    //{{{ centerOnScreen() method
1269
/**
1270     * Centers the given window on the screen. This method is needed because
1271     * JDK 1.3 does not have a <code>JWindow.setLocationRelativeTo()</code>
1272     * method.
1273     * @since jEdit 4.2pre3
1274     */

1275    public static void centerOnScreen(Window JavaDoc win)
1276    {
1277        GraphicsDevice JavaDoc gd = GraphicsEnvironment
1278            .getLocalGraphicsEnvironment()
1279            .getDefaultScreenDevice();
1280        Rectangle JavaDoc gcbounds = gd.getDefaultConfiguration().getBounds();
1281        int x = gcbounds.x + (gcbounds.width - win.getWidth()) / 2;
1282        int y = gcbounds.y + (gcbounds.height - win.getHeight()) / 2;
1283        win.setLocation(x,y);
1284    } //}}}
1285

1286    //}}}
1287

1288    //{{{ hideSplashScreen() method
1289
/**
1290     * Ensures that the splash screen is not visible. This should be
1291     * called before displaying any dialog boxes or windows at
1292     * startup.
1293     */

1294    public static void hideSplashScreen()
1295    {
1296        if(splash != null)
1297        {
1298            splash.dispose();
1299            splash = null;
1300        }
1301    } //}}}
1302

1303    //{{{ createMultilineLabel() method
1304
/**
1305     * Creates a component that displays a multiple line message. This
1306     * is implemented by assembling a number of <code>JLabels</code> in
1307     * a <code>JPanel</code>.
1308     * @param str The string, with lines delimited by newline
1309     * (<code>\n</code>) characters.
1310     * @since jEdit 4.1pre3
1311     */

1312    public static JComponent createMultilineLabel(String JavaDoc str)
1313    {
1314        JPanel panel = new JPanel(new VariableGridLayout(
1315            VariableGridLayout.FIXED_NUM_COLUMNS,1,1,1));
1316        int lastOffset = 0;
1317        while(true)
1318        {
1319            int index = str.indexOf('\n',lastOffset);
1320            if(index == -1)
1321                break;
1322            else
1323            {
1324                panel.add(new JLabel(str.substring(lastOffset,index)));
1325                lastOffset = index + 1;
1326            }
1327        }
1328
1329        if(lastOffset != str.length())
1330            panel.add(new JLabel(str.substring(lastOffset)));
1331
1332        return panel;
1333    } //}}}
1334

1335    //{{{ requestFocus() method
1336
/**
1337     * Focuses on the specified component as soon as the window becomes
1338     * active.
1339     * @param win The window
1340     * @param comp The component
1341     */

1342    public static void requestFocus(final Window JavaDoc win, final Component JavaDoc comp)
1343    {
1344        win.addWindowFocusListener(new WindowAdapter JavaDoc()
1345        {
1346            public void windowGainedFocus(WindowEvent JavaDoc evt)
1347            {
1348                SwingUtilities.invokeLater(new Runnable JavaDoc(){
1349                        public void run() {
1350                            comp.requestFocusInWindow();
1351                        }
1352                });
1353                win.removeWindowFocusListener(this);
1354            }
1355        });
1356    } //}}}
1357

1358    //{{{ isPopupTrigger() method
1359
/**
1360     * Returns if the specified event is the popup trigger event.
1361     * This implements precisely defined behavior, as opposed to
1362     * MouseEvent.isPopupTrigger().
1363     * @param evt The event
1364     * @since jEdit 3.2pre8
1365     */

1366    public static boolean isPopupTrigger(MouseEvent JavaDoc evt)
1367    {
1368        return TextAreaMouseHandler.isRightButton(evt.getModifiers());
1369    } //}}}
1370

1371    //{{{ isMiddleButton() method
1372
/**
1373     * @param modifiers The modifiers flag from a mouse event
1374     * @since jEdit 4.1pre9
1375     */

1376    public static boolean isMiddleButton(int modifiers)
1377    {
1378        return TextAreaMouseHandler.isMiddleButton(modifiers);
1379    } //}}}
1380

1381    //{{{ isRightButton() method
1382
/**
1383     * @param modifiers The modifiers flag from a mouse event
1384     * @since jEdit 4.1pre9
1385     */

1386    public static boolean isRightButton(int modifiers)
1387    {
1388        return TextAreaMouseHandler.isRightButton(modifiers);
1389    } //}}}
1390

1391    //{{{ showPopupMenu() method
1392
/**
1393     * Shows the specified popup menu, ensuring it is displayed within
1394     * the bounds of the screen.
1395     * @param popup The popup menu
1396     * @param comp The component to show it for
1397     * @param x The x co-ordinate
1398     * @param y The y co-ordinate
1399     * @since jEdit 4.0pre1
1400     */

1401    public static void showPopupMenu(JPopupMenu popup, Component JavaDoc comp,
1402        int x, int y)
1403    {
1404        showPopupMenu(popup,comp,x,y,true);
1405    } //}}}
1406

1407    //{{{ showPopupMenu() method
1408
/**
1409     * Shows the specified popup menu, ensuring it is displayed within
1410     * the bounds of the screen.
1411     * @param popup The popup menu
1412     * @param comp The component to show it for
1413     * @param x The x co-ordinate
1414     * @param y The y co-ordinate
1415     * @param point If true, then the popup originates from a single point;
1416     * otherwise it will originate from the component itself. This affects
1417     * positioning in the case where the popup does not fit onscreen.
1418     *
1419     * @since jEdit 4.1pre1
1420     */

1421    public static void showPopupMenu(JPopupMenu popup, Component JavaDoc comp,
1422        int x, int y, boolean point)
1423    {
1424        int offsetX = 0;
1425        int offsetY = 0;
1426
1427        int extraOffset = (point ? 1 : 0);
1428
1429        Component JavaDoc win = comp;
1430        while(!(win instanceof Window JavaDoc || win == null))
1431        {
1432            offsetX += win.getX();
1433            offsetY += win.getY();
1434            win = win.getParent();
1435        }
1436
1437        if(win != null)
1438        {
1439            Dimension JavaDoc size = popup.getPreferredSize();
1440
1441            Rectangle JavaDoc screenSize = new Rectangle JavaDoc();
1442            
1443            GraphicsEnvironment JavaDoc ge = GraphicsEnvironment
1444                .getLocalGraphicsEnvironment();
1445            
1446            GraphicsDevice JavaDoc[] devices = ge.getScreenDevices();
1447            
1448            for (int j = 0; j < devices.length; j++)
1449            {
1450                GraphicsDevice JavaDoc device = devices[j];
1451                
1452                GraphicsConfiguration JavaDoc[] gc =
1453                    device.getConfigurations();
1454                
1455                for (int i=0; i < gc.length; i++)
1456                {
1457                    screenSize =
1458                        screenSize.union(
1459                            gc[i].getBounds());
1460                }
1461            }
1462
1463            if(x + offsetX + size.width + win.getX() > screenSize.width
1464                && x + offsetX + win.getX() >= size.width)
1465            {
1466                //System.err.println("x overflow");
1467
if(point)
1468                    x -= (size.width + extraOffset);
1469                else
1470                    x = (win.getWidth() - size.width - offsetX + extraOffset);
1471            }
1472            else
1473            {
1474                x += extraOffset;
1475            }
1476
1477            //System.err.println("y=" + y + ",offsetY=" + offsetY
1478
// + ",size.height=" + size.height
1479
// + ",win.height=" + win.getHeight());
1480
if(y + offsetY + size.height + win.getY() > screenSize.height
1481                && y + offsetY + win.getY() >= size.height)
1482            {
1483                if(point)
1484                    y = (win.getHeight() - size.height - offsetY + extraOffset);
1485                else
1486                    y = -size.height - 1;
1487            }
1488            else
1489            {
1490                y += extraOffset;
1491            }
1492
1493            popup.show(comp,x,y);
1494        }
1495        else
1496            popup.show(comp,x + extraOffset,y + extraOffset);
1497
1498    } //}}}
1499

1500    //{{{ isAncestorOf() method
1501
/**
1502     * Returns if the first component is an ancestor of the
1503     * second by traversing up the component hierarchy.
1504     *
1505     * @param comp1 The ancestor
1506     * @param comp2 The component to check
1507     * @since jEdit 4.1pre5
1508     */

1509    public static boolean isAncestorOf(Component JavaDoc comp1, Component JavaDoc comp2)
1510    {
1511        while(comp2 != null)
1512        {
1513            if(comp1 == comp2)
1514                return true;
1515            else
1516                comp2 = comp2.getParent();
1517        }
1518
1519        return false;
1520    } //}}}
1521

1522    //{{{ getParentDialog() method
1523
/**
1524     * Traverses the given component's parent tree looking for an
1525     * instance of JDialog, and return it. If not found, return null.
1526     * @param c The component
1527     */

1528    public static JDialog getParentDialog(Component JavaDoc c)
1529    {
1530        return (JDialog) SwingUtilities.getAncestorOfClass(JDialog.class, c);
1531    } //}}}
1532

1533    //{{{ getComponentParent() method
1534
/**
1535     * Finds a parent of the specified component.
1536     * @param comp The component
1537     * @param clazz Looks for a parent with this class (exact match, not
1538     * derived).
1539     * @since jEdit 4.2pre1
1540     */

1541    public static Component JavaDoc getComponentParent(Component JavaDoc comp, Class JavaDoc clazz)
1542    {
1543        while(true)
1544        {
1545            if(comp == null)
1546                break;
1547
1548            if(comp instanceof JComponent)
1549            {
1550                Component JavaDoc real = (Component JavaDoc)((JComponent)comp)
1551                    .getClientProperty("KORTE_REAL_FRAME");
1552                if(real != null)
1553                    comp = real;
1554            }
1555
1556            if(comp.getClass().equals(clazz))
1557                return comp;
1558            else if(comp instanceof JPopupMenu)
1559                comp = ((JPopupMenu)comp).getInvoker();
1560            else if(comp instanceof FloatingWindowContainer)
1561            {
1562                comp = ((FloatingWindowContainer)comp)
1563                    .getDockableWindowManager();
1564            }
1565            else
1566                comp = comp.getParent();
1567        }
1568        return null;
1569    } //}}}
1570

1571    //{{{ getView() method
1572
/**
1573     * Finds the view parent of the specified component.
1574     * @since jEdit 4.0pre2
1575     */

1576    public static View getView(Component JavaDoc comp)
1577    {
1578        return (View)getComponentParent(comp,View.class);
1579    } //}}}
1580

1581    //{{{ addSizeSaver() method
1582
/**
1583    * Adds a SizeSaver to the specified Frame. For non-Frame's use {@link #saveGeometry(Window,String)}
1584     *
1585     * @param frame The Frame for which to save the size
1586     * @param name The prefix for the settings
1587     * @since jEdit 4.3pre6
1588     * @see #saveGeometry(Window,String)
1589     */

1590    public static void addSizeSaver(Frame JavaDoc frame, String JavaDoc name)
1591    {
1592        addSizeSaver(frame,frame.getParent(),name);
1593    } //}}}
1594

1595    //{{{ addSizeSaver() method
1596
/**
1597     * Adds a SizeSaver to the specified Frame. For non-Frame's use {@link #saveGeometry(Window,Container,String)}
1598     *
1599     * @param frame The Frame for which to save the size
1600     * @param parent The parent to be relative to
1601     * @param name The prefix for the settings
1602     * @since jEdit 4.3pre7
1603     * @see #saveGeometry(Window,Container,String)
1604     */

1605    public static void addSizeSaver(Frame JavaDoc frame, Container JavaDoc parent, String JavaDoc name)
1606    {
1607        SizeSaver ss = new SizeSaver(frame,parent,name);
1608        frame.addWindowStateListener(ss);
1609        frame.addComponentListener(ss);
1610    } //}}}
1611

1612    //{{{ initContinuousLayout() method
1613
/**
1614     * Init the continuous layout flag using the jEdit's property
1615     * appearance.continuousLayout
1616     *
1617     * @param split the split. It must never be null
1618     * @since jEdit 4.3pre9
1619     */

1620    public static void initContinuousLayout(JSplitPane split)
1621    {
1622        boolean continuousLayout = split.isContinuousLayout();
1623        if (continuousLayout != jEdit.getBooleanProperty("appearance.continuousLayout"))
1624            split.setContinuousLayout(!continuousLayout);
1625    } //}}}
1626

1627    //{{{ Package-private members
1628

1629    //{{{ init() method
1630
static void init()
1631    {
1632        // don't do this in static{} since we need jEdit.initMisc()
1633
// run first so we have the jeditresource: protocol
1634
NEW_BUFFER_ICON = loadIcon("new.gif");
1635        DIRTY_BUFFER_ICON = loadIcon("dirty.gif");
1636        READ_ONLY_BUFFER_ICON = loadIcon("readonly.gif");
1637        NORMAL_BUFFER_ICON = loadIcon("normal.gif");
1638        WINDOW_ICON = loadIcon("jedit-icon.gif");
1639    } //}}}
1640

1641    //{{{ showSplashScreen() method
1642
static void showSplashScreen()
1643    {
1644        splash = new SplashScreen();
1645    } //}}}
1646

1647    //{{{ advanceSplashProgress() method
1648
static void advanceSplashProgress()
1649    {
1650        if(splash != null)
1651            splash.advance();
1652    } //}}}
1653

1654    //{{{ advanceSplashProgress() method
1655
static void advanceSplashProgress(String JavaDoc label)
1656    {
1657        if(splash != null)
1658            splash.advance(label);
1659    } //}}}
1660

1661    //}}}
1662

1663    //{{{ Private members
1664
private static SplashScreen splash;
1665    private static Map JavaDoc<String JavaDoc, Icon> icons;
1666    private static String JavaDoc iconPath = "jeditresource:/org/gjt/sp/jedit/icons/";
1667    private static String JavaDoc defaultIconPath = "jeditresource:/org/gjt/sp/jedit/icons/";
1668
1669    private GUIUtilities() {}
1670    //}}}
1671

1672    //{{{ Inner classes
1673

1674    //{{{ SizeSaver class
1675
/**
1676     * A combined ComponentListener and WindowStateListener to continually save a Frames size.<br />
1677     * For non-Frame's use {@link #saveGeometry(Window,String)}
1678     *
1679     * @author Björn Kautler
1680     * @version $Id: GUIUtilities.java 8676 2007-01-19 20:14:58Z kpouer $
1681     * @since jEdit 4.3pre6
1682     * @see #saveGeometry(Window,Container,String)
1683     */

1684    static class SizeSaver extends ComponentAdapter JavaDoc implements WindowStateListener JavaDoc
1685    {
1686        private Frame JavaDoc frame;
1687        private Container JavaDoc parent;
1688        private String JavaDoc name;
1689        
1690        //{{{ SizeSaver constructor
1691
/**
1692         * Constructs a new SizeSaver.
1693         *
1694         * @param frame The Frame for which to save the size
1695         * @param name The prefix for the settings
1696         */

1697        SizeSaver(Frame JavaDoc frame, String JavaDoc name)
1698        {
1699            this.frame = frame;
1700            this.parent = frame.getParent();
1701        } //}}}
1702

1703        //{{{ SizeSaver constructor
1704
/**
1705         * Constructs a new SizeSaver.
1706         *
1707         * @param frame The Frame for which to save the size
1708         * @param parent The parent to be relative to.
1709         * @param name The prefix for the settings
1710         */

1711        public SizeSaver(Frame JavaDoc frame, Container JavaDoc parent, String JavaDoc name)
1712        {
1713            if ((null == frame) || (null == name))
1714            {
1715                throw new NullPointerException JavaDoc();
1716            }
1717            this.frame = frame;
1718            this.parent = parent;
1719            this.name = name;
1720        } //}}}
1721

1722        //{{{ windowStateChanged() method
1723
public void windowStateChanged(WindowEvent JavaDoc wse)
1724        {
1725            int extendedState = wse.getNewState();
1726            jEdit.setIntegerProperty(name + ".extendedState",extendedState);
1727            Rectangle JavaDoc bounds = frame.getBounds();
1728            save(extendedState, bounds);
1729        } //}}}
1730

1731        //{{{ save() method
1732
private void save(int extendedState, Rectangle JavaDoc bounds)
1733        {
1734            switch (extendedState)
1735            {
1736                case Frame.MAXIMIZED_VERT:
1737                    jEdit.setIntegerProperty(name + ".x",bounds.x);
1738                    jEdit.setIntegerProperty(name + ".width",bounds.width);
1739                    break;
1740
1741                case Frame.MAXIMIZED_HORIZ:
1742                    jEdit.setIntegerProperty(name + ".y",bounds.y);
1743                    jEdit.setIntegerProperty(name + ".height",bounds.height);
1744                    break;
1745
1746                case Frame.NORMAL:
1747                    saveGeometry(frame,parent,name );
1748                    break;
1749            }
1750        } //}}}
1751

1752        //{{{ componentResized() method
1753
public void componentResized(ComponentEvent JavaDoc ce)
1754        {
1755            componentMoved(ce);
1756        } //}}}
1757

1758        //{{{ componentMoved() method
1759
public void componentMoved(ComponentEvent JavaDoc ce)
1760        {
1761            final Rectangle JavaDoc bounds = frame.getBounds();
1762            final Runnable JavaDoc sizeSaver = new Runnable JavaDoc()
1763            {
1764                public void run()
1765                {
1766                    int extendedState = frame.getExtendedState();
1767                    save(extendedState, bounds);
1768                }
1769            };
1770            new Thread JavaDoc("Sizesavingdelay")
1771            {
1772                public void run()
1773                {
1774                    try
1775                    {
1776                        Thread.sleep(500L);
1777                    }
1778                    catch (InterruptedException JavaDoc ie)
1779                    {
1780                    }
1781                    SwingUtilities.invokeLater(sizeSaver);
1782                }
1783            }.start();
1784        } //}}}
1785
} //}}}
1786

1787    //}}}
1788
}
1789
Popular Tags