/jEdit/tags/jedit-4-2-pre13/org/gjt/sp/jedit/GUIUtilities.java

# · Java · 1515 lines · 848 code · 151 blank · 516 comment · 173 complexity · 97ca7a4d17021df9d3ca2ef82e63be5e MD5 · raw file

  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. package org.gjt.sp.jedit;
  23. //{{{ Imports
  24. import javax.swing.*;
  25. import java.awt.*;
  26. import java.awt.event.*;
  27. import java.net.*;
  28. import java.util.*;
  29. import org.gjt.sp.jedit.browser.*;
  30. import org.gjt.sp.jedit.gui.*;
  31. import org.gjt.sp.jedit.menu.*;
  32. import org.gjt.sp.jedit.syntax.SyntaxStyle;
  33. import org.gjt.sp.jedit.syntax.Token;
  34. import org.gjt.sp.util.Log;
  35. //}}}
  36. /**
  37. * Various GUI functions.<p>
  38. *
  39. * The most frequently used members of this class are:
  40. *
  41. * <ul>
  42. * <li>{@link #loadIcon(String)}</li>
  43. * <li>{@link #confirm(Component,String,Object[],int,int)}</li>
  44. * <li>{@link #error(Component,String,Object[])}</li>
  45. * <li>{@link #message(Component,String,Object[])}</li>
  46. * <li>{@link #showPopupMenu(JPopupMenu,Component,int,int)}</li>
  47. * <li>{@link #showVFSFileDialog(View,String,int,boolean)}</li>
  48. * <li>{@link #loadGeometry(Window,String)}</li>
  49. * <li>{@link #saveGeometry(Window,String)}</li>
  50. * </ul>
  51. *
  52. * @author Slava Pestov
  53. * @version $Id: GUIUtilities.java 4996 2004-03-19 19:16:36Z spestov $
  54. */
  55. public class GUIUtilities
  56. {
  57. //{{{ Some predefined icons
  58. public static Icon NEW_BUFFER_ICON;
  59. public static Icon DIRTY_BUFFER_ICON;
  60. public static Icon READ_ONLY_BUFFER_ICON;
  61. public static Icon NORMAL_BUFFER_ICON;
  62. public static Icon WINDOW_ICON;
  63. //}}}
  64. //{{{ Icon methods
  65. //{{{ setIconPath() method
  66. /**
  67. * Sets the path where jEdit looks for icons.
  68. * @since jEdit 4.2pre5
  69. */
  70. public static void setIconPath(String iconPath)
  71. {
  72. GUIUtilities.iconPath = iconPath;
  73. if(icons != null)
  74. icons.clear();
  75. } //}}}
  76. //{{{ loadIcon() method
  77. /**
  78. * Loads an icon.
  79. * @param iconName The icon name
  80. * @since jEdit 2.6pre7
  81. */
  82. public static Icon loadIcon(String iconName)
  83. {
  84. if(icons == null)
  85. icons = new Hashtable();
  86. // check if there is a cached version first
  87. Icon icon = (Icon)icons.get(iconName);
  88. if(icon != null)
  89. return icon;
  90. // get the icon
  91. if(MiscUtilities.isURL(iconName))
  92. {
  93. icon = new ImageIcon(iconName.substring(5));
  94. }
  95. else
  96. {
  97. try
  98. {
  99. URL url = new URL(iconPath + iconName);
  100. icon = new ImageIcon(url);
  101. }
  102. catch(Exception e)
  103. {
  104. try
  105. {
  106. URL url = new URL(defaultIconPath + iconName);
  107. icon = new ImageIcon(url);
  108. }
  109. catch(Exception ex)
  110. {
  111. Log.log(Log.ERROR,GUIUtilities.class,
  112. "Icon not found: " + iconName);
  113. Log.log(Log.ERROR,GUIUtilities.class,ex);
  114. return null;
  115. }
  116. }
  117. }
  118. icons.put(iconName,icon);
  119. return icon;
  120. } //}}}
  121. //{{{ getEditorIcon() method
  122. /**
  123. * Returns the default editor window image.
  124. */
  125. public static Image getEditorIcon()
  126. {
  127. return ((ImageIcon)WINDOW_ICON).getImage();
  128. } //}}}
  129. //{{{ getPluginIcon() method
  130. /**
  131. * Returns the default plugin window image.
  132. */
  133. public static Image getPluginIcon()
  134. {
  135. return ((ImageIcon)WINDOW_ICON).getImage();
  136. } //}}}
  137. //}}}
  138. //{{{ Menus, tool bars
  139. //{{{ loadMenuBar() method
  140. /**
  141. * Creates a menubar. Plugins should not need to call this method.
  142. * @param name The menu bar name
  143. * @since jEdit 3.2pre5
  144. */
  145. public static JMenuBar loadMenuBar(String name)
  146. {
  147. return loadMenuBar(jEdit.getActionContext(),name);
  148. } //}}}
  149. //{{{ loadMenuBar() method
  150. /**
  151. * Creates a menubar. Plugins should not need to call this method.
  152. * @param context An action context
  153. * @param name The menu bar name
  154. * @since jEdit 4.2pre1
  155. */
  156. public static JMenuBar loadMenuBar(ActionContext context, String name)
  157. {
  158. String menus = jEdit.getProperty(name);
  159. StringTokenizer st = new StringTokenizer(menus);
  160. JMenuBar mbar = new JMenuBar();
  161. while(st.hasMoreTokens())
  162. {
  163. mbar.add(loadMenu(context,st.nextToken()));
  164. }
  165. return mbar;
  166. } //}}}
  167. //{{{ loadMenu() method
  168. /**
  169. * Creates a menu. The menu label is set from the
  170. * <code><i>name</i>.label</code> property. The menu contents is taken
  171. * from the <code><i>name</i></code> property, which is a whitespace
  172. * separated list of action names. An action name of <code>-</code>
  173. * inserts a separator in the menu.
  174. * @param name The menu name
  175. * @see #loadMenuItem(String)
  176. * @since jEdit 2.6pre2
  177. */
  178. public static JMenu loadMenu(String name)
  179. {
  180. return loadMenu(jEdit.getActionContext(),name);
  181. } //}}}
  182. //{{{ loadMenu() method
  183. /**
  184. * Creates a menu. The menu label is set from the
  185. * <code><i>name</i>.label</code> property. The menu contents is taken
  186. * from the <code><i>name</i></code> property, which is a whitespace
  187. * separated list of action names. An action name of <code>-</code>
  188. * inserts a separator in the menu.
  189. * @param context An action context; either
  190. * <code>jEdit.getActionContext()</code> or
  191. * <code>VFSBrowser.getActionContext()</code>.
  192. * @param name The menu name
  193. * @see #loadMenuItem(String)
  194. * @since jEdit 4.2pre1
  195. */
  196. public static JMenu loadMenu(ActionContext context, String name)
  197. {
  198. return new EnhancedMenu(name,
  199. jEdit.getProperty(name.concat(".label")),
  200. context);
  201. } //}}}
  202. //{{{ loadPopupMenu() method
  203. /**
  204. * Creates a popup menu.
  205. * @param name The menu name
  206. * @since jEdit 2.6pre2
  207. */
  208. public static JPopupMenu loadPopupMenu(String name)
  209. {
  210. return loadPopupMenu(jEdit.getActionContext(),name);
  211. } //}}}
  212. //{{{ loadPopupMenu() method
  213. /**
  214. * Creates a popup menu.
  215. * @param context An action context; either
  216. * <code>jEdit.getActionContext()</code> or
  217. * <code>VFSBrowser.getActionContext()</code>.
  218. * @param name The menu name
  219. * @since jEdit 4.2pre1
  220. */
  221. public static JPopupMenu loadPopupMenu(ActionContext context, String name)
  222. {
  223. JPopupMenu menu = new JPopupMenu();
  224. String menuItems = jEdit.getProperty(name);
  225. if(menuItems != null)
  226. {
  227. StringTokenizer st = new StringTokenizer(menuItems);
  228. while(st.hasMoreTokens())
  229. {
  230. String menuItemName = st.nextToken();
  231. if(menuItemName.equals("-"))
  232. menu.addSeparator();
  233. else
  234. menu.add(loadMenuItem(context,menuItemName,false));
  235. }
  236. }
  237. return menu;
  238. } //}}}
  239. //{{{ loadMenuItem() method
  240. /**
  241. * Creates a menu item. The menu item is bound to the action named by
  242. * <code>name</code> with label taken from the return value of the
  243. * {@link EditAction#getLabel()} method.
  244. *
  245. * @param name The menu item name
  246. * @see #loadMenu(String)
  247. * @since jEdit 2.6pre1
  248. */
  249. public static JMenuItem loadMenuItem(String name)
  250. {
  251. return loadMenuItem(jEdit.getActionContext(),name,true);
  252. } //}}}
  253. //{{{ loadMenuItem() method
  254. /**
  255. * Creates a menu item.
  256. * @param name The menu item name
  257. * @param setMnemonic True if the menu item should have a mnemonic
  258. * @since jEdit 3.1pre1
  259. */
  260. public static JMenuItem loadMenuItem(String name, boolean setMnemonic)
  261. {
  262. return loadMenuItem(jEdit.getActionContext(),name,setMnemonic);
  263. } //}}}
  264. //{{{ loadMenuItem() method
  265. /**
  266. * Creates a menu item.
  267. * @param context An action context; either
  268. * <code>jEdit.getActionContext()</code> or
  269. * <code>VFSBrowser.getActionContext()</code>.
  270. * @param name The menu item name
  271. * @param setMnemonic True if the menu item should have a mnemonic
  272. * @since jEdit 4.2pre1
  273. */
  274. public static JMenuItem loadMenuItem(ActionContext context, String name,
  275. boolean setMnemonic)
  276. {
  277. if(name.startsWith("%"))
  278. return loadMenu(context,name.substring(1));
  279. String label = jEdit.getProperty(name + ".label");
  280. if(label == null)
  281. label = name;
  282. char mnemonic;
  283. int index = label.indexOf('$');
  284. if(index != -1 && label.length() - index > 1)
  285. {
  286. mnemonic = Character.toLowerCase(label.charAt(index + 1));
  287. label = label.substring(0,index).concat(label.substring(++index));
  288. }
  289. else
  290. mnemonic = '\0';
  291. JMenuItem mi;
  292. if(jEdit.getBooleanProperty(name + ".toggle"))
  293. mi = new EnhancedCheckBoxMenuItem(label,name,context);
  294. else
  295. mi = new EnhancedMenuItem(label,name,context);
  296. if(!OperatingSystem.isMacOS() && setMnemonic && mnemonic != '\0')
  297. mi.setMnemonic(mnemonic);
  298. return mi;
  299. } //}}}
  300. //{{{ loadToolBar() method
  301. /**
  302. * Creates a toolbar.
  303. * @param name The toolbar name
  304. * @since jEdit 4.2pre2
  305. */
  306. public static Box loadToolBar(String name)
  307. {
  308. return loadToolBar(jEdit.getActionContext(),name);
  309. } //}}}
  310. //{{{ loadToolBar() method
  311. /**
  312. * Creates a toolbar.
  313. * @param context An action context; either
  314. * <code>jEdit.getActionContext()</code> or
  315. * <code>VFSBrowser.getActionContext()</code>.
  316. * @param name The toolbar name
  317. * @since jEdit 4.2pre2
  318. */
  319. public static Box loadToolBar(ActionContext context, String name)
  320. {
  321. Box toolBar = new Box(BoxLayout.X_AXIS);
  322. String buttons = jEdit.getProperty(name);
  323. if(buttons != null)
  324. {
  325. StringTokenizer st = new StringTokenizer(buttons);
  326. while(st.hasMoreTokens())
  327. {
  328. String button = st.nextToken();
  329. if(button.equals("-"))
  330. toolBar.add(Box.createHorizontalStrut(12));
  331. else
  332. {
  333. JButton b = loadToolButton(context,button);
  334. if(b != null)
  335. toolBar.add(b);
  336. }
  337. }
  338. }
  339. toolBar.add(Box.createGlue());
  340. return toolBar;
  341. } //}}}
  342. //{{{ loadToolButton() method
  343. /**
  344. * Loads a tool bar button. The tooltip is constructed from
  345. * the <code><i>name</i>.label</code> and
  346. * <code><i>name</i>.shortcut</code> properties and the icon is loaded
  347. * from the resource named '/org/gjt/sp/jedit/icons/' suffixed
  348. * with the value of the <code><i>name</i>.icon</code> property.
  349. * @param name The name of the button
  350. */
  351. public static EnhancedButton loadToolButton(String name)
  352. {
  353. return loadToolButton(jEdit.getActionContext(),name);
  354. } //}}}
  355. //{{{ loadToolButton() method
  356. /**
  357. * Loads a tool bar button. The tooltip is constructed from
  358. * the <code><i>name</i>.label</code> and
  359. * <code><i>name</i>.shortcut</code> properties and the icon is loaded
  360. * from the resource named '/org/gjt/sp/jedit/icons/' suffixed
  361. * with the value of the <code><i>name</i>.icon</code> property.
  362. * @param context An action context; either
  363. * <code>jEdit.getActionContext()</code> or
  364. * <code>VFSBrowser.getActionContext()</code>.
  365. * @param name The name of the button
  366. * @since jEdit 4.2pre1
  367. */
  368. public static EnhancedButton loadToolButton(ActionContext context,
  369. String name)
  370. {
  371. String label = jEdit.getProperty(name + ".label");
  372. if(label == null)
  373. label = name;
  374. Icon icon;
  375. String iconName = jEdit.getProperty(name + ".icon");
  376. if(iconName == null)
  377. icon = loadIcon("BrokenImage.png");
  378. else
  379. {
  380. icon = loadIcon(iconName);
  381. if(icon == null)
  382. icon = loadIcon("BrokenImage.png");
  383. }
  384. String toolTip = prettifyMenuLabel(label);
  385. String shortcut1 = jEdit.getProperty(name + ".shortcut");
  386. String shortcut2 = jEdit.getProperty(name + ".shortcut2");
  387. if(shortcut1 != null || shortcut2 != null)
  388. {
  389. toolTip = toolTip + " ("
  390. + (shortcut1 != null
  391. ? shortcut1 : "")
  392. + ((shortcut1 != null && shortcut2 != null)
  393. ? " or " : "")
  394. + (shortcut2 != null
  395. ? shortcut2
  396. : "") + ")";
  397. }
  398. return new EnhancedButton(icon,toolTip,name,context);
  399. } //}}}
  400. //{{{ prettifyMenuLabel() method
  401. /**
  402. * `Prettifies' a menu item label by removing the `$' sign. This
  403. * can be used to process the contents of an <i>action</i>.label
  404. * property.
  405. */
  406. public static String prettifyMenuLabel(String label)
  407. {
  408. int index = label.indexOf('$');
  409. if(index != -1)
  410. {
  411. label = label.substring(0,index)
  412. .concat(label.substring(index + 1));
  413. }
  414. return label;
  415. } //}}}
  416. //}}}
  417. //{{{ Canned dialog boxes
  418. //{{{ message() method
  419. /**
  420. * Displays a dialog box.
  421. * The title of the dialog is fetched from
  422. * the <code><i>name</i>.title</code> property. The message is fetched
  423. * from the <code><i>name</i>.message</code> property. The message
  424. * is formatted by the property manager with <code>args</code> as
  425. * positional parameters.
  426. * @param comp The component to display the dialog for
  427. * @param name The name of the dialog
  428. * @param args Positional parameters to be substituted into the
  429. * message text
  430. */
  431. public static void message(Component comp, String name, Object[] args)
  432. {
  433. hideSplashScreen();
  434. JOptionPane.showMessageDialog(comp,
  435. jEdit.getProperty(name.concat(".message"),args),
  436. jEdit.getProperty(name.concat(".title"),args),
  437. JOptionPane.INFORMATION_MESSAGE);
  438. } //}}}
  439. //{{{ error() method
  440. /**
  441. * Displays an error dialog box.
  442. * The title of the dialog is fetched from
  443. * the <code><i>name</i>.title</code> property. The message is fetched
  444. * from the <code><i>name</i>.message</code> property. The message
  445. * is formatted by the property manager with <code>args</code> as
  446. * positional parameters.
  447. * @param comp The component to display the dialog for
  448. * @param name The name of the dialog
  449. * @param args Positional parameters to be substituted into the
  450. * message text
  451. */
  452. public static void error(Component comp, String name, Object[] args)
  453. {
  454. hideSplashScreen();
  455. JOptionPane.showMessageDialog(comp,
  456. jEdit.getProperty(name.concat(".message"),args),
  457. jEdit.getProperty(name.concat(".title"),args),
  458. JOptionPane.ERROR_MESSAGE);
  459. } //}}}
  460. //{{{ input() method
  461. /**
  462. * Displays an input dialog box and returns any text the user entered.
  463. * The title of the dialog is fetched from
  464. * the <code><i>name</i>.title</code> property. The message is fetched
  465. * from the <code><i>name</i>.message</code> property.
  466. * @param comp The component to display the dialog for
  467. * @param name The name of the dialog
  468. * @param def The text to display by default in the input field
  469. */
  470. public static String input(Component comp, String name, Object def)
  471. {
  472. return input(comp,name,null,def);
  473. } //}}}
  474. //{{{ inputProperty() method
  475. /**
  476. * Displays an input dialog box and returns any text the user entered.
  477. * The title of the dialog is fetched from
  478. * the <code><i>name</i>.title</code> property. The message is fetched
  479. * from the <code><i>name</i>.message</code> property.
  480. * @param comp The component to display the dialog for
  481. * @param name The name of the dialog
  482. * @param def The property whose text to display in the input field
  483. */
  484. public static String inputProperty(Component comp, String name,
  485. String def)
  486. {
  487. return inputProperty(comp,name,null,def);
  488. } //}}}
  489. //{{{ input() method
  490. /**
  491. * Displays an input dialog box and returns any text the user entered.
  492. * The title of the dialog is fetched from
  493. * the <code><i>name</i>.title</code> property. The message is fetched
  494. * from the <code><i>name</i>.message</code> property.
  495. * @param comp The component to display the dialog for
  496. * @param name The name of the dialog
  497. * @param def The text to display by default in the input field
  498. * @param args Positional parameters to be substituted into the
  499. * message text
  500. * @since jEdit 3.1pre3
  501. */
  502. public static String input(Component comp, String name,
  503. Object[] args, Object def)
  504. {
  505. hideSplashScreen();
  506. String retVal = (String)JOptionPane.showInputDialog(comp,
  507. jEdit.getProperty(name.concat(".message"),args),
  508. jEdit.getProperty(name.concat(".title")),
  509. JOptionPane.QUESTION_MESSAGE,null,null,def);
  510. return retVal;
  511. } //}}}
  512. //{{{ inputProperty() method
  513. /**
  514. * Displays an input dialog box and returns any text the user entered.
  515. * The title of the dialog is fetched from
  516. * the <code><i>name</i>.title</code> property. The message is fetched
  517. * from the <code><i>name</i>.message</code> property.
  518. * @param comp The component to display the dialog for
  519. * @param name The name of the dialog
  520. * @param args Positional parameters to be substituted into the
  521. * message text
  522. * @param def The property whose text to display in the input field
  523. * @since jEdit 3.1pre3
  524. */
  525. public static String inputProperty(Component comp, String name,
  526. Object[] args, String def)
  527. {
  528. hideSplashScreen();
  529. String retVal = (String)JOptionPane.showInputDialog(comp,
  530. jEdit.getProperty(name.concat(".message"),args),
  531. jEdit.getProperty(name.concat(".title")),
  532. JOptionPane.QUESTION_MESSAGE,
  533. null,null,jEdit.getProperty(def));
  534. if(retVal != null)
  535. jEdit.setProperty(def,retVal);
  536. return retVal;
  537. } //}}}
  538. //{{{ confirm() method
  539. /**
  540. * Displays a confirm dialog box and returns the button pushed by the
  541. * user. The title of the dialog is fetched from the
  542. * <code><i>name</i>.title</code> property. The message is fetched
  543. * from the <code><i>name</i>.message</code> property.
  544. * @param comp The component to display the dialog for
  545. * @param name The name of the dialog
  546. * @param args Positional parameters to be substituted into the
  547. * message text
  548. * @param buttons The buttons to display - for example,
  549. * JOptionPane.YES_NO_CANCEL_OPTION
  550. * @param type The dialog type - for example,
  551. * JOptionPane.WARNING_MESSAGE
  552. * @since jEdit 3.1pre3
  553. */
  554. public static int confirm(Component comp, String name,
  555. Object[] args, int buttons, int type)
  556. {
  557. hideSplashScreen();
  558. return JOptionPane.showConfirmDialog(comp,
  559. jEdit.getProperty(name + ".message",args),
  560. jEdit.getProperty(name + ".title"),buttons,type);
  561. } //}}}
  562. //{{{ showVFSFileDialog() method
  563. /**
  564. * Displays a VFS file selection dialog box.
  565. * @param view The view, should be non-null
  566. * @param path The initial directory to display. May be null
  567. * @param type The dialog type. One of
  568. * {@link org.gjt.sp.jedit.browser.VFSBrowser#OPEN_DIALOG},
  569. * {@link org.gjt.sp.jedit.browser.VFSBrowser#SAVE_DIALOG}, or
  570. * {@link org.gjt.sp.jedit.browser.VFSBrowser#CHOOSE_DIRECTORY_DIALOG}.
  571. * @param multipleSelection True if multiple selection should be allowed
  572. * @return The selected file(s)
  573. * @since jEdit 2.6pre2
  574. */
  575. public static String[] showVFSFileDialog(View view, String path,
  576. int type, boolean multipleSelection)
  577. {
  578. // the view should not be null, but some plugins might do this
  579. if(view == null)
  580. {
  581. Log.log(Log.WARNING,GUIUtilities.class,
  582. "showVFSFileDialog(): given null view, assuming jEdit.getActiveView()");
  583. view = jEdit.getActiveView();
  584. }
  585. hideSplashScreen();
  586. VFSFileChooserDialog fileChooser = new VFSFileChooserDialog(
  587. view,path,type,multipleSelection);
  588. String[] selectedFiles = fileChooser.getSelectedFiles();
  589. if(selectedFiles == null)
  590. return null;
  591. return selectedFiles;
  592. } //}}}
  593. //}}}
  594. //{{{ Colors and styles
  595. //{{{ parseColor() method
  596. /**
  597. * Converts a color name to a color object. The name must either be
  598. * a known string, such as `red', `green', etc (complete list is in
  599. * the <code>java.awt.Color</code> class) or a hex color value
  600. * prefixed with `#', for example `#ff0088'.
  601. * @param name The color name
  602. */
  603. public static Color parseColor(String name)
  604. {
  605. return parseColor(name, Color.black);
  606. } //}}}
  607. //{{{ parseColor() method
  608. public static Color parseColor(String name, Color defaultColor)
  609. {
  610. if(name == null)
  611. return defaultColor;
  612. else if(name.startsWith("#"))
  613. {
  614. try
  615. {
  616. return Color.decode(name);
  617. }
  618. catch(NumberFormatException nf)
  619. {
  620. return defaultColor;
  621. }
  622. }
  623. else if("red".equals(name))
  624. return Color.red;
  625. else if("green".equals(name))
  626. return Color.green;
  627. else if("blue".equals(name))
  628. return Color.blue;
  629. else if("yellow".equals(name))
  630. return Color.yellow;
  631. else if("orange".equals(name))
  632. return Color.orange;
  633. else if("white".equals(name))
  634. return Color.white;
  635. else if("lightGray".equals(name))
  636. return Color.lightGray;
  637. else if("gray".equals(name))
  638. return Color.gray;
  639. else if("darkGray".equals(name))
  640. return Color.darkGray;
  641. else if("black".equals(name))
  642. return Color.black;
  643. else if("cyan".equals(name))
  644. return Color.cyan;
  645. else if("magenta".equals(name))
  646. return Color.magenta;
  647. else if("pink".equals(name))
  648. return Color.pink;
  649. else
  650. return defaultColor;
  651. } //}}}
  652. //{{{ getColorHexString() method
  653. /**
  654. * Converts a color object to its hex value. The hex value
  655. * prefixed is with `#', for example `#ff0088'.
  656. * @param c The color object
  657. */
  658. public static String getColorHexString(Color c)
  659. {
  660. String colString = Integer.toHexString(c.getRGB() & 0xffffff);
  661. return "#000000".substring(0,7 - colString.length()).concat(colString);
  662. } //}}}
  663. //{{{ parseStyle() method
  664. /**
  665. * Converts a style string to a style object.
  666. * @param str The style string
  667. * @param family Style strings only specify font style, not font family
  668. * @param size Style strings only specify font style, not font family
  669. * @exception IllegalArgumentException if the style is invalid
  670. * @since jEdit 3.2pre6
  671. */
  672. public static SyntaxStyle parseStyle(String str, String family, int size)
  673. throws IllegalArgumentException
  674. {
  675. return parseStyle(str,family,size,true);
  676. } //}}}
  677. //{{{ parseStyle() method
  678. /**
  679. * Converts a style string to a style object.
  680. * @param str The style string
  681. * @param family Style strings only specify font style, not font family
  682. * @param size Style strings only specify font style, not font family
  683. * @param color If false, the styles will be monochrome
  684. * @exception IllegalArgumentException if the style is invalid
  685. * @since jEdit 4.0pre4
  686. */
  687. public static SyntaxStyle parseStyle(String str, String family, int size,
  688. boolean color)
  689. throws IllegalArgumentException
  690. {
  691. Color fgColor = Color.black;
  692. Color bgColor = null;
  693. boolean italic = false;
  694. boolean bold = false;
  695. StringTokenizer st = new StringTokenizer(str);
  696. while(st.hasMoreTokens())
  697. {
  698. String s = st.nextToken();
  699. if(s.startsWith("color:"))
  700. {
  701. if(color)
  702. fgColor = GUIUtilities.parseColor(s.substring(6), Color.black);
  703. }
  704. else if(s.startsWith("bgColor:"))
  705. {
  706. if(color)
  707. bgColor = GUIUtilities.parseColor(s.substring(8), null);
  708. }
  709. else if(s.startsWith("style:"))
  710. {
  711. for(int i = 6; i < s.length(); i++)
  712. {
  713. if(s.charAt(i) == 'i')
  714. italic = true;
  715. else if(s.charAt(i) == 'b')
  716. bold = true;
  717. else
  718. throw new IllegalArgumentException(
  719. "Invalid style: " + s);
  720. }
  721. }
  722. else
  723. throw new IllegalArgumentException(
  724. "Invalid directive: " + s);
  725. }
  726. return new SyntaxStyle(fgColor,bgColor,
  727. new Font(family,
  728. (italic ? Font.ITALIC : 0) | (bold ? Font.BOLD : 0),
  729. size));
  730. } //}}}
  731. //{{{ getStyleString() method
  732. /**
  733. * Converts a style into it's string representation.
  734. * @param style The style
  735. */
  736. public static String getStyleString(SyntaxStyle style)
  737. {
  738. StringBuffer buf = new StringBuffer();
  739. if(style.getForegroundColor() != null)
  740. {
  741. buf.append("color:" + getColorHexString(style.getForegroundColor()));
  742. }
  743. if(style.getBackgroundColor() != null)
  744. {
  745. buf.append(" bgColor:" + getColorHexString(style.getBackgroundColor()));
  746. }
  747. if(!style.getFont().isPlain())
  748. {
  749. buf.append(" style:" + (style.getFont().isItalic() ? "i" : "")
  750. + (style.getFont().isBold() ? "b" : ""));
  751. }
  752. return buf.toString();
  753. } //}}}
  754. //{{{ loadStyles() method
  755. /**
  756. * Loads the syntax styles from the properties, giving them the specified
  757. * base font family and size.
  758. * @param family The font family
  759. * @param size The font size
  760. * @since jEdit 3.2pre6
  761. */
  762. public static SyntaxStyle[] loadStyles(String family, int size)
  763. {
  764. return loadStyles(family,size,true);
  765. } //}}}
  766. //{{{ loadStyles() method
  767. /**
  768. * Loads the syntax styles from the properties, giving them the specified
  769. * base font family and size.
  770. * @param family The font family
  771. * @param size The font size
  772. * @param color If false, the styles will be monochrome
  773. * @since jEdit 4.0pre4
  774. */
  775. public static SyntaxStyle[] loadStyles(String family, int size, boolean color)
  776. {
  777. SyntaxStyle[] styles = new SyntaxStyle[Token.ID_COUNT];
  778. // start at 1 not 0 to skip Token.NULL
  779. for(int i = 1; i < styles.length; i++)
  780. {
  781. try
  782. {
  783. String styleName = "view.style."
  784. + Token.tokenToString((byte)i)
  785. .toLowerCase();
  786. styles[i] = GUIUtilities.parseStyle(
  787. jEdit.getProperty(styleName),
  788. family,size,color);
  789. }
  790. catch(Exception e)
  791. {
  792. Log.log(Log.ERROR,GUIUtilities.class,e);
  793. }
  794. }
  795. return styles;
  796. } //}}}
  797. //}}}
  798. //{{{ Loading, saving window geometry
  799. //{{{ loadGeometry() method
  800. /**
  801. * Loads a windows's geometry from the properties.
  802. * The geometry is loaded from the <code><i>name</i>.x</code>,
  803. * <code><i>name</i>.y</code>, <code><i>name</i>.width</code> and
  804. * <code><i>name</i>.height</code> properties.
  805. *
  806. * @param win The window
  807. * @param name The window name
  808. */
  809. public static void loadGeometry(Window win, String name)
  810. {
  811. int x, y, width, height;
  812. Dimension size = win.getSize();
  813. GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
  814. Rectangle gcbounds = gd.getDefaultConfiguration().getBounds();
  815. x = gcbounds.x;
  816. y = gcbounds.y;
  817. width = jEdit.getIntegerProperty(name + ".width",size.width);
  818. height = jEdit.getIntegerProperty(name + ".height",size.height);
  819. Component parent = win.getParent();
  820. if(parent == null)
  821. {
  822. x += (gcbounds.width - width) / 2;
  823. y += (gcbounds.height - height) / 2;
  824. }
  825. else
  826. {
  827. Rectangle bounds = parent.getBounds();
  828. x += bounds.x + (bounds.width - width) / 2;
  829. y += bounds.y + (bounds.height - height) / 2;
  830. }
  831. x = jEdit.getIntegerProperty(name + ".x",x);
  832. y = jEdit.getIntegerProperty(name + ".y",y);
  833. int extState = jEdit.getIntegerProperty(name + ".extendedState", 0);
  834. Rectangle desired = new Rectangle(x,y,width,height);
  835. adjustForScreenBounds(desired);
  836. if(OperatingSystem.isX11() && Debug.GEOMETRY_WORKAROUND)
  837. new UnixWorkaround(win,name,desired,extState);
  838. else
  839. {
  840. win.setBounds(desired);
  841. if(win instanceof Frame)
  842. setExtendedState((Frame)win,extState);
  843. }
  844. } //}}}
  845. //{{{ adjustForScreenBounds() method
  846. /**
  847. * Gives a rectangle the specified bounds, ensuring it is within the
  848. * screen bounds.
  849. * @since jEdit 4.2pre3
  850. */
  851. public static void adjustForScreenBounds(Rectangle desired)
  852. {
  853. // Make sure the window is displayed in visible region
  854. Rectangle osbounds = OperatingSystem.getScreenBounds(desired);
  855. if(desired.x < osbounds.x || desired.x+desired.width
  856. > osbounds.width)
  857. {
  858. if (desired.width > osbounds.width)
  859. desired.width = osbounds.width;
  860. desired.x = (osbounds.width - desired.width) / 2;
  861. }
  862. if(desired.y < osbounds.y || desired.y+desired.height
  863. > osbounds.height)
  864. {
  865. if (desired.height >= osbounds.height)
  866. desired.height = osbounds.height;
  867. desired.y = (osbounds.height - desired.height) / 2;
  868. }
  869. } //}}}
  870. //{{{ UnixWorkaround class
  871. static class UnixWorkaround
  872. {
  873. Window win;
  874. String name;
  875. Rectangle desired;
  876. Rectangle required;
  877. long start;
  878. boolean windowOpened;
  879. //{{{ UnixWorkaround constructor
  880. UnixWorkaround(Window win, String name, Rectangle desired,
  881. int extState)
  882. {
  883. this.win = win;
  884. this.name = name;
  885. this.desired = desired;
  886. int adjust_x, adjust_y, adjust_width, adjust_height;
  887. adjust_x = jEdit.getIntegerProperty(name + ".dx",0);
  888. adjust_y = jEdit.getIntegerProperty(name + ".dy",0);
  889. adjust_width = jEdit.getIntegerProperty(name + ".d-width",0);
  890. adjust_height = jEdit.getIntegerProperty(name + ".d-height",0);
  891. required = new Rectangle(
  892. desired.x - adjust_x,
  893. desired.y - adjust_y,
  894. desired.width - adjust_width,
  895. desired.height - adjust_height);
  896. Log.log(Log.DEBUG,GUIUtilities.class,"Window " + name
  897. + ": desired geometry is " + desired);
  898. Log.log(Log.DEBUG,GUIUtilities.class,"Window " + name
  899. + ": setting geometry to " + required);
  900. start = System.currentTimeMillis();
  901. win.setBounds(required);
  902. if(win instanceof Frame)
  903. setExtendedState((Frame)win,extState);
  904. win.addComponentListener(new ComponentHandler());
  905. win.addWindowListener(new WindowHandler());
  906. } //}}}
  907. //{{{ ComponentHandler class
  908. class ComponentHandler extends ComponentAdapter
  909. {
  910. //{{{ componentMoved() method
  911. public void componentMoved(ComponentEvent evt)
  912. {
  913. if(System.currentTimeMillis() - start < 1000)
  914. {
  915. Rectangle r = win.getBounds();
  916. if(!windowOpened && r.equals(required))
  917. return;
  918. if(!r.equals(desired))
  919. {
  920. Log.log(Log.DEBUG,GUIUtilities.class,
  921. "Window resize blocked: " + win.getBounds());
  922. win.setBounds(desired);
  923. }
  924. }
  925. win.removeComponentListener(this);
  926. } //}}}
  927. //{{{ componentResized() method
  928. public void componentResized(ComponentEvent evt)
  929. {
  930. if(System.currentTimeMillis() - start < 1000)
  931. {
  932. Rectangle r = win.getBounds();
  933. if(!windowOpened && r.equals(required))
  934. return;
  935. if(!r.equals(desired))
  936. {
  937. Log.log(Log.DEBUG,GUIUtilities.class,
  938. "Window resize blocked: " + win.getBounds());
  939. win.setBounds(desired);
  940. }
  941. }
  942. win.removeComponentListener(this);
  943. } //}}}
  944. } //}}}
  945. //{{{ WindowHandler class
  946. class WindowHandler extends WindowAdapter
  947. {
  948. //{{{ windowOpened() method
  949. public void windowOpened(WindowEvent evt)
  950. {
  951. windowOpened = true;
  952. Rectangle r = win.getBounds();
  953. Log.log(Log.DEBUG,GUIUtilities.class,"Window "
  954. + name + ": bounds after opening: " + r);
  955. jEdit.setIntegerProperty(name + ".dx",
  956. r.x - required.x);
  957. jEdit.setIntegerProperty(name + ".dy",
  958. r.y - required.y);
  959. jEdit.setIntegerProperty(name + ".d-width",
  960. r.width - required.width);
  961. jEdit.setIntegerProperty(name + ".d-height",
  962. r.height - required.height);
  963. win.removeWindowListener(this);
  964. } //}}}
  965. } //}}}
  966. } //}}}
  967. //{{{ saveGeometry() method
  968. /**
  969. * Saves a window's geometry to the properties.
  970. * The geometry is saved to the <code><i>name</i>.x</code>,
  971. * <code><i>name</i>.y</code>, <code><i>name</i>.width</code> and
  972. * <code><i>name</i>.height</code> properties.
  973. * @param win The window
  974. * @param name The window name
  975. */
  976. public static void saveGeometry(Window win, String name)
  977. {
  978. if(win instanceof Frame)
  979. {
  980. jEdit.setIntegerProperty(name + ".extendedState",
  981. getExtendedState((Frame)win));
  982. }
  983. Rectangle bounds = win.getBounds();
  984. jEdit.setIntegerProperty(name + ".x",bounds.x);
  985. jEdit.setIntegerProperty(name + ".y",bounds.y);
  986. jEdit.setIntegerProperty(name + ".width",bounds.width);
  987. jEdit.setIntegerProperty(name + ".height",bounds.height);
  988. } //}}}
  989. //{{{ getExtendedState() method
  990. /**
  991. * On Java 1.4, calls <code>Frame.getExtendedState()</code>.
  992. * On Java 1.3, returns 0.
  993. * @since jEdit 4.2pre1
  994. */
  995. public static int getExtendedState(Frame frame)
  996. {
  997. if(OperatingSystem.hasJava14())
  998. {
  999. try
  1000. {
  1001. java.lang.reflect.Method meth =
  1002. Frame.class.getMethod("getExtendedState",
  1003. new Class[0]);
  1004. Integer extState = (Integer)meth.invoke(frame,
  1005. new Object[0]);
  1006. return extState.intValue();
  1007. }
  1008. catch(Exception e)
  1009. {
  1010. Log.log(Log.ERROR,GUIUtilities.class,e);
  1011. }
  1012. }
  1013. return 0;
  1014. } //}}}
  1015. //{{{ setExtendedState() method
  1016. /**
  1017. * On Java 1.4, calls <code>Frame.setExtendedState()</code>.
  1018. * On Java 1.3, does nothing.
  1019. * @since jEdit 4.2pre1
  1020. */
  1021. public static void setExtendedState(Frame frame, int extState)
  1022. {
  1023. if(OperatingSystem.hasJava14())
  1024. {
  1025. try
  1026. {
  1027. java.lang.reflect.Method meth =
  1028. Frame.class.getMethod("setExtendedState",
  1029. new Class[] {int.class});
  1030. meth.invoke(frame, new Object[] {
  1031. new Integer(extState)});
  1032. }
  1033. catch(Exception e)
  1034. {
  1035. Log.log(Log.ERROR,GUIUtilities.class,e);
  1036. }
  1037. }
  1038. } //}}}
  1039. //{{{ centerOnScreen() method
  1040. /**
  1041. * Centers the given window on the screen. This method is needed because
  1042. * JDK 1.3 does not have a <code>JWindow.setLocationRelativeTo()</code>
  1043. * method.
  1044. * @since jEdit 4.2pre3
  1045. */
  1046. public static void centerOnScreen(Window win)
  1047. {
  1048. GraphicsDevice gd = GraphicsEnvironment
  1049. .getLocalGraphicsEnvironment()
  1050. .getDefaultScreenDevice();
  1051. Rectangle gcbounds = gd.getDefaultConfiguration().getBounds();
  1052. int x = gcbounds.x + (gcbounds.width - win.getWidth()) / 2;
  1053. int y = gcbounds.y + (gcbounds.height - win.getHeight()) / 2;
  1054. win.setLocation(x,y);
  1055. } //}}}
  1056. //}}}
  1057. //{{{ hideSplashScreen() method
  1058. /**
  1059. * Ensures that the splash screen is not visible. This should be
  1060. * called before displaying any dialog boxes or windows at
  1061. * startup.
  1062. */
  1063. public static void hideSplashScreen()
  1064. {
  1065. if(splash != null)
  1066. {
  1067. splash.dispose();
  1068. splash = null;
  1069. }
  1070. } //}}}
  1071. //{{{ createMultilineLabel() method
  1072. /**
  1073. * Creates a component that displays a multiple line message. This
  1074. * is implemented by assembling a number of <code>JLabels</code> in
  1075. * a <code>JPanel</code>.
  1076. * @param str The string, with lines delimited by newline
  1077. * (<code>\n</code>) characters.
  1078. * @since jEdit 4.1pre3
  1079. */
  1080. public static JComponent createMultilineLabel(String str)
  1081. {
  1082. JPanel panel = new JPanel(new VariableGridLayout(
  1083. VariableGridLayout.FIXED_NUM_COLUMNS,1,1,1));
  1084. int lastOffset = 0;
  1085. for(;;)
  1086. {
  1087. int index = str.indexOf('\n',lastOffset);
  1088. if(index == -1)
  1089. break;
  1090. else
  1091. {
  1092. panel.add(new JLabel(str.substring(lastOffset,index)));
  1093. lastOffset = index + 1;
  1094. }
  1095. }
  1096. if(lastOffset != str.length())
  1097. panel.add(new JLabel(str.substring(lastOffset)));
  1098. return panel;
  1099. } //}}}
  1100. //{{{ requestFocus() method
  1101. /**
  1102. * Focuses on the specified component as soon as the window becomes
  1103. * active.
  1104. * @param win The window
  1105. * @param comp The component
  1106. */
  1107. public static void requestFocus(final Window win, final Component comp)
  1108. {
  1109. win.addWindowListener(new WindowAdapter()
  1110. {
  1111. public void windowActivated(WindowEvent evt)
  1112. {
  1113. SwingUtilities.invokeLater(new Runnable()
  1114. {
  1115. public void run()
  1116. {
  1117. comp.requestFocus();
  1118. }
  1119. });
  1120. win.removeWindowListener(this);
  1121. }
  1122. });
  1123. } //}}}
  1124. //{{{ isPopupTrigger() method
  1125. /**
  1126. * Returns if the specified event is the popup trigger event.
  1127. * This implements precisely defined behavior, as opposed to
  1128. * MouseEvent.isPopupTrigger().
  1129. * @param evt The event
  1130. * @since jEdit 3.2pre8
  1131. */
  1132. public static boolean isPopupTrigger(MouseEvent evt)
  1133. {
  1134. return isRightButton(evt.getModifiers());
  1135. } //}}}
  1136. //{{{ isMiddleButton() method
  1137. /**
  1138. * @param modifiers The modifiers flag from a mouse event
  1139. * @since jEdit 4.1pre9
  1140. */
  1141. public static boolean isMiddleButton(int modifiers)
  1142. {
  1143. if (OperatingSystem.isMacOS())
  1144. {
  1145. if((modifiers & MouseEvent.BUTTON1_MASK) != 0)
  1146. return ((modifiers & MouseEvent.ALT_MASK) != 0);
  1147. if(!OperatingSystem.hasJava14())
  1148. return ((modifiers & MouseEvent.BUTTON3_MASK) != 0);
  1149. else
  1150. return ((modifiers & MouseEvent.BUTTON2_MASK) != 0);
  1151. }
  1152. else
  1153. return ((modifiers & MouseEvent.BUTTON2_MASK) != 0);
  1154. } //}}}
  1155. //{{{ isRightButton() method
  1156. /**
  1157. * @param modifiers The modifiers flag from a mouse event
  1158. * @since jEdit 4.1pre9
  1159. */
  1160. public static boolean isRightButton(int modifiers)
  1161. {
  1162. if (OperatingSystem.isMacOS())
  1163. {
  1164. if((modifiers & MouseEvent.BUTTON1_MASK) != 0)
  1165. return ((modifiers & MouseEvent.CTRL_MASK) != 0);
  1166. if(!OperatingSystem.hasJava14())
  1167. return ((modifiers & MouseEvent.BUTTON2_MASK) != 0);
  1168. else
  1169. return ((modifiers & MouseEvent.BUTTON3_MASK) != 0);
  1170. }
  1171. else
  1172. return ((modifiers & MouseEvent.BUTTON3_MASK) != 0);
  1173. } //}}}
  1174. //{{{ showPopupMenu() method
  1175. /**
  1176. * Shows the specified popup menu, ensuring it is displayed within
  1177. * the bounds of the screen.
  1178. * @param popup The popup menu
  1179. * @param comp The component to show it for
  1180. * @param x The x co-ordinate
  1181. * @param y The y co-ordinate
  1182. * @since jEdit 4.0pre1
  1183. */
  1184. public static void showPopupMenu(JPopupMenu popup, Component comp,
  1185. int x, int y)
  1186. {
  1187. showPopupMenu(popup,comp,x,y,true);
  1188. } //}}}
  1189. //{{{ showPopupMenu() method
  1190. /**
  1191. * Shows the specified popup menu, ensuring it is displayed within
  1192. * the bounds of the screen.
  1193. * @param popup The popup menu
  1194. * @param comp The component to show it for
  1195. * @param x The x co-ordinate
  1196. * @param y The y co-ordinate
  1197. * @param point If true, then the popup originates from a single point;
  1198. * otherwise it will originate from the component itself. This affects
  1199. * positioning in the case where the popup does not fit onscreen.
  1200. *
  1201. * @since jEdit 4.1pre1
  1202. */
  1203. public static void showPopupMenu(JPopupMenu popup, Component comp,
  1204. int x, int y, boolean point)
  1205. {
  1206. int offsetX = 0;
  1207. int offsetY = 0;
  1208. int extraOffset = (point ? 1 : 0);
  1209. Component win = comp;
  1210. while(!(win instanceof Window || win == null))
  1211. {
  1212. offsetX += win.getX();
  1213. offsetY += win.getY();
  1214. win = win.getParent();
  1215. }
  1216. if(win != null)
  1217. {
  1218. Dimension size = popup.getPreferredSize();
  1219. Rectangle screenSize = win.getGraphicsConfiguration()
  1220. .getBounds();
  1221. if(x + offsetX + size.width + win.getX() > screenSize.width
  1222. && x + offsetX + win.getX() >= size.width)
  1223. {
  1224. //System.err.println("x overflow");
  1225. if(point)
  1226. x -= (size.width + extraOffset);
  1227. else
  1228. x = (win.getWidth() - size.width - offsetX + extraOffset);
  1229. }
  1230. else
  1231. {
  1232. x += extraOffset;
  1233. }
  1234. //System.err.println("y=" + y + ",offsetY=" + offsetY
  1235. // + ",size.height=" + size.height
  1236. // + ",win.height=" + win.getHeight());
  1237. if(y + offsetY + size.height + win.getY() > screenSize.height
  1238. && y + offsetY + win.getY() >= size.height)
  1239. {
  1240. if(point)
  1241. y = (win.getHeight() - size.height - offsetY + extraOffset);
  1242. else
  1243. y = -size.height - 1;
  1244. }
  1245. else
  1246. {
  1247. y += extraOffset;
  1248. }
  1249. popup.show(comp,x,y);
  1250. }
  1251. else
  1252. popup.show(comp,x + extraOffset,y + extraOffset);
  1253. } //}}}
  1254. //{{{ isAncestorOf() method
  1255. /**
  1256. * Returns if the first component is an ancestor of the
  1257. * second by traversing up the component hierarchy.
  1258. *
  1259. * @param comp1 The ancestor
  1260. * @param comp2 The component to check
  1261. * @since jEdit 4.1pre5
  1262. */
  1263. public static boolean isAncestorOf(Component comp1, Component comp2)
  1264. {
  1265. while(comp2 != null)
  1266. {
  1267. if(comp1 == comp2)
  1268. return true;
  1269. else
  1270. comp2 = comp2.getParent();
  1271. }
  1272. return false;
  1273. } //}}}
  1274. //{{{ getParentDialog() method
  1275. /**
  1276. * Traverses the given component's parent tree looking for an
  1277. * instance of JDialog, and return it. If not found, return null.
  1278. * @param c The component
  1279. */
  1280. public static JDialog getParentDialog(Component c)
  1281. {
  1282. Component p = c.getParent();
  1283. while (p != null && !(p instanceof JDialog))
  1284. p = p.getParent();
  1285. return (p instanceof JDialog) ? (JDialog) p : null;
  1286. } //}}}
  1287. //{{{ getComponentParent() method
  1288. /**
  1289. * Finds a parent of the specified component.
  1290. * @param comp The component
  1291. * @param clazz Looks for a parent with this class (exact match, not
  1292. * derived).
  1293. * @since jEdit 4.2pre1
  1294. */
  1295. public static Component getComponentParent(Component comp, Class clazz)
  1296. {
  1297. for(;;)
  1298. {
  1299. if(comp == null)
  1300. break;
  1301. if(comp instanceof JComponent)
  1302. {
  1303. Component real = (Component)((JComponent)comp)
  1304. .getClientProperty("KORTE_REAL_FRAME");
  1305. if(real != null)
  1306. comp = real;
  1307. }
  1308. if(comp.getClass().equals(clazz))
  1309. return comp;
  1310. else if(comp instanceof JPopupMenu)
  1311. comp = ((JPopupMenu)comp).getInvoker();
  1312. else if(comp instanceof FloatingWindowContainer)
  1313. {
  1314. comp = ((FloatingWindowContainer)comp)
  1315. .getDockableWindowManager();
  1316. }
  1317. else
  1318. comp = comp.getParent();
  1319. }
  1320. return null;
  1321. } //}}}
  1322. //{{{ getView() method
  1323. /**
  1324. * Finds the view parent of the specified component.
  1325. * @since jEdit 4.0pre2
  1326. */
  1327. public static View getView(Component comp)
  1328. {
  1329. return (View)getComponentParent(comp,View.class);
  1330. } //}}}
  1331. //{{{ Package-private members
  1332. //{{{ init() method
  1333. static void init()
  1334. {
  1335. // don't do this in static{} since we need jEdit.initMisc()
  1336. // run first so we have the jeditresource: protocol
  1337. NEW_BUFFER_ICON = loadIcon("new.gif");
  1338. DIRTY_BUFFER_ICON = loadIcon("dirty.gif");
  1339. READ_ONLY_BUFFER_ICON = loadIcon("readonly.gif");
  1340. NORMAL_BUFFER_ICON = loadIcon("normal.gif");
  1341. WINDOW_ICON = loadIcon("jedit-icon.gif");
  1342. } //}}}
  1343. //{{{ showSplashScreen() method
  1344. static void showSplashScreen()
  1345. {
  1346. splash = new SplashScreen();
  1347. } //}}}
  1348. //{{{ advanceSplashProgress() method
  1349. static void advanceSplashProgress()
  1350. {
  1351. if(splash != null)
  1352. splash.advance();
  1353. } //}}}
  1354. //}}}
  1355. //{{{ Private members
  1356. private static SplashScreen splash;
  1357. private static Hashtable icons;
  1358. private static String iconPath = "jeditresource:/org/gjt/sp/jedit/icons/";
  1359. private static String defaultIconPath = "jeditresource:/org/gjt/sp/jedit/icons/";
  1360. private GUIUtilities() {}
  1361. //}}}
  1362. }