PageRenderTime 56ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/jEdit/tags/jedit-4-2-pre4/org/gjt/sp/jedit/gui/DockableWindowManager.java

#
Java | 1718 lines | 1189 code | 197 blank | 332 comment | 193 complexity | 0a8709c72345241c7d42c871567d6629 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * DockableWindowManager.java - manages dockable windows
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2000, 2003 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.gui;
  23. //{{{ Imports
  24. import bsh.*;
  25. import com.microstar.xml.*;
  26. import javax.swing.*;
  27. import java.awt.event.*;
  28. import java.awt.*;
  29. import java.io.*;
  30. import java.net.URL;
  31. import java.util.*;
  32. import org.gjt.sp.jedit.msg.DockableWindowUpdate;
  33. import org.gjt.sp.jedit.msg.PluginUpdate;
  34. import org.gjt.sp.jedit.*;
  35. import org.gjt.sp.util.Log;
  36. //}}}
  37. /**
  38. * The <code>DockableWindowManager</code> keeps track of dockable windows.
  39. * Each {@link org.gjt.sp.jedit.View} has an instance of this class.<p>
  40. *
  41. * <b>dockables.xml:</b><p>
  42. *
  43. * Dockable window definitions are read from <code>dockables.xml</code> files
  44. * contained inside plugin JARs. A dockable definition file has the following
  45. * form:
  46. *
  47. * <pre>&lt;?xml version="1.0"?&gt;
  48. *&lt;!DOCTYPE DOCKABLES SYSTEM "dockables.dtd"&gt;
  49. *&lt;DOCKABLES&gt;
  50. * &lt;DOCKABLE NAME="name"&gt;
  51. * // Code to create the dockable
  52. * &lt;/DOCKABLE&gt;
  53. *&lt;/DOCKABLES&gt;</pre>
  54. *
  55. * More than one <code>&lt;DOCKABLE&gt;<code> tag may be present. The code that
  56. * creates the dockable can reference any BeanShell built-in variable
  57. * (see {@link org.gjt.sp.jedit.BeanShell}), along with a variable
  58. * <code>position</code> whose value is one of
  59. * {@link #FLOATING}, {@link #TOP}, {@link #LEFT}, {@link #BOTTOM},
  60. * and {@link #RIGHT}.<p>
  61. *
  62. * The following properties must be defined for each dockable window:
  63. *
  64. * <ul>
  65. * <li><code><i>name</i>.title</code> - the string to show in the title bar
  66. * of the dockable.</li>
  67. * <li><code><i>name</i>.label</code> - the dockable's menu item label.</li>
  68. * </ul>
  69. *
  70. * A number of actions are automatically created for each dockable window:
  71. *
  72. * <ul>
  73. * <li><code><i>name</i></code> - opens the dockable window.</li>
  74. * <li><code><i>name</i>-toggle</code> - toggles the dockable window's visibility.</li>
  75. * <li><code><i>name</i>-float</code> - opens the dockable window in a new
  76. * floating window.</li>
  77. * </ul>
  78. *
  79. * Note that only the first action needs a <code>label</code> property, the
  80. * rest have automatically-generated labels.
  81. *
  82. * <b>Implementation details:</b><p>
  83. *
  84. * When an instance of this class is initialized by the {@link org.gjt.sp.jedit.View}
  85. * class, it
  86. * iterates through the list of registered dockable windows (from jEdit itself,
  87. * and any loaded plugins) and
  88. * examines options supplied by the user in the <b>Global
  89. * Options</b> dialog box. Any plugins designated for one of the
  90. * four docking positions are displayed.<p>
  91. *
  92. * To create an instance of a dockable window, the <code>DockableWindowManager</code>
  93. * finds and executes the BeanShell code extracted from the appropriate
  94. * <code>dockables.xml</code> file. This code will typically consist of a call
  95. * to the constructor of the dockable window component. The result of the
  96. * BeanShell expression, typically a newly constructed component, is placed
  97. * in a window managed by this class.
  98. *
  99. * @see org.gjt.sp.jedit.View#getDockableWindowManager()
  100. *
  101. * @author Slava Pestov
  102. * @author John Gellene (API documentation)
  103. * @version $Id: DockableWindowManager.java 4831 2003-07-17 23:49:44Z spestov $
  104. * @since jEdit 2.6pre3
  105. */
  106. public class DockableWindowManager extends JPanel implements EBComponent
  107. {
  108. //{{{ Static part of class
  109. //{{{ Constants
  110. /**
  111. * Floating position.
  112. * @since jEdit 2.6pre3
  113. */
  114. public static final String FLOATING = "floating";
  115. /**
  116. * Top position.
  117. * @since jEdit 2.6pre3
  118. */
  119. public static final String TOP = "top";
  120. /**
  121. * Left position.
  122. * @since jEdit 2.6pre3
  123. */
  124. public static final String LEFT = "left";
  125. /**
  126. * Bottom position.
  127. * @since jEdit 2.6pre3
  128. */
  129. public static final String BOTTOM = "bottom";
  130. /**
  131. * Right position.
  132. * @since jEdit 2.6pre3
  133. */
  134. public static final String RIGHT = "right";
  135. //}}}
  136. //{{{ loadDockableWindows() method
  137. /**
  138. * Plugins shouldn't need to call this method.
  139. * @since jEdit 4.2pre1
  140. */
  141. public static void loadDockableWindows(PluginJAR plugin, URL uri,
  142. PluginJAR.PluginCacheEntry cache)
  143. {
  144. Reader in = null;
  145. try
  146. {
  147. Log.log(Log.DEBUG,DockableWindowManager.class,
  148. "Loading dockables from " + uri);
  149. DockableListHandler dh = new DockableListHandler(plugin,uri);
  150. in = new BufferedReader(
  151. new InputStreamReader(
  152. uri.openStream()));
  153. XmlParser parser = new XmlParser();
  154. parser.setHandler(dh);
  155. parser.parse(null, null, in);
  156. if(cache != null)
  157. {
  158. cache.cachedDockableNames = dh.getCachedDockableNames();
  159. cache.cachedDockableActionFlags = dh.getCachedDockableActionFlags();
  160. }
  161. }
  162. catch(XmlException xe)
  163. {
  164. int line = xe.getLine();
  165. String message = xe.getMessage();
  166. Log.log(Log.ERROR,DockableWindowManager.class,uri + ":" + line
  167. + ": " + message);
  168. }
  169. catch(Exception e)
  170. {
  171. Log.log(Log.ERROR,DockableWindowManager.class,e);
  172. }
  173. finally
  174. {
  175. try
  176. {
  177. if(in != null)
  178. in.close();
  179. }
  180. catch(IOException io)
  181. {
  182. Log.log(Log.ERROR,DockableWindowManager.class,io);
  183. }
  184. }
  185. } //}}}
  186. //{{{ unloadDockableWindows() method
  187. /**
  188. * Plugins shouldn't need to call this method.
  189. * @since jEdit 4.2pre1
  190. */
  191. public static void unloadDockableWindows(PluginJAR plugin)
  192. {
  193. Iterator entries = dockableWindowFactories.entrySet().iterator();
  194. while(entries.hasNext())
  195. {
  196. Map.Entry entry = (Map.Entry)entries.next();
  197. Factory factory = (Factory)entry.getValue();
  198. if(factory.plugin == plugin)
  199. entries.remove();
  200. }
  201. } //}}}
  202. //{{{ cacheDockableWindows() method
  203. /**
  204. * @since jEdit 4.2pre1
  205. */
  206. public static void cacheDockableWindows(PluginJAR plugin,
  207. String[] name, boolean[] actions)
  208. {
  209. for(int i = 0; i < name.length; i++)
  210. {
  211. Factory factory = new Factory(plugin,
  212. name[i],null,actions[i]);
  213. dockableWindowFactories.put(name[i],factory);
  214. }
  215. } //}}}
  216. //{{{ registerDockableWindow() method
  217. public static void registerDockableWindow(PluginJAR plugin,
  218. String name, String code, boolean actions)
  219. {
  220. Factory factory = (Factory)dockableWindowFactories.get(name);
  221. if(factory != null)
  222. {
  223. factory.code = code;
  224. factory.loaded = true;
  225. }
  226. else
  227. {
  228. factory = new Factory(plugin,name,code,actions);
  229. dockableWindowFactories.put(name,factory);
  230. }
  231. } //}}}
  232. //{{{ getRegisteredDockableWindows() method
  233. public static String[] getRegisteredDockableWindows()
  234. {
  235. String[] retVal = new String[dockableWindowFactories.size()];
  236. Iterator entries = dockableWindowFactories.values().iterator();
  237. int i = 0;
  238. while(entries.hasNext())
  239. {
  240. Factory factory = (Factory)entries.next();
  241. retVal[i++] = factory.name;
  242. }
  243. return retVal;
  244. } //}}}
  245. //{{{ DockableListHandler class
  246. static class DockableListHandler extends HandlerBase
  247. {
  248. //{{{ DockableListHandler constructor
  249. DockableListHandler(PluginJAR plugin, URL uri)
  250. {
  251. this.plugin = plugin;
  252. this.uri = uri;
  253. stateStack = new Stack();
  254. actions = true;
  255. cachedDockableNames = new LinkedList();
  256. cachedDockableActionFlags = new LinkedList();
  257. } //}}}
  258. //{{{ resolveEntity() method
  259. public Object resolveEntity(String publicId, String systemId)
  260. {
  261. if("dockables.dtd".equals(systemId))
  262. {
  263. // this will result in a slight speed up, since we
  264. // don't need to read the DTD anyway, as AElfred is
  265. // non-validating
  266. return new StringReader("<!-- -->");
  267. /* try
  268. {
  269. return new BufferedReader(new InputStreamReader(
  270. getClass().getResourceAsStream
  271. ("/org/gjt/sp/jedit/dockables.dtd")));
  272. }
  273. catch(Exception e)
  274. {
  275. Log.log(Log.ERROR,this,"Error while opening"
  276. + " dockables.dtd:");
  277. Log.log(Log.ERROR,this,e);
  278. } */
  279. }
  280. return null;
  281. } //}}}
  282. //{{{ attribute() method
  283. public void attribute(String aname, String value, boolean isSpecified)
  284. {
  285. aname = (aname == null) ? null : aname.intern();
  286. value = (value == null) ? null : value.intern();
  287. if(aname == "NAME")
  288. dockableName = value;
  289. else if(aname == "NO_ACTIONS")
  290. actions = (value == "FALSE");
  291. } //}}}
  292. //{{{ doctypeDecl() method
  293. public void doctypeDecl(String name, String publicId,
  294. String systemId) throws Exception
  295. {
  296. if("DOCKABLES".equals(name))
  297. return;
  298. Log.log(Log.ERROR,this,uri + ": DOCTYPE must be DOCKABLES");
  299. } //}}}
  300. //{{{ charData() method
  301. public void charData(char[] c, int off, int len)
  302. {
  303. String tag = peekElement();
  304. String text = new String(c, off, len);
  305. if (tag == "DOCKABLE")
  306. {
  307. code = text;
  308. }
  309. } //}}}
  310. //{{{ startElement() method
  311. public void startElement(String tag)
  312. {
  313. tag = pushElement(tag);
  314. } //}}}
  315. //{{{ endElement() method
  316. public void endElement(String name)
  317. {
  318. if(name == null)
  319. return;
  320. String tag = peekElement();
  321. if(name.equals(tag))
  322. {
  323. if(tag == "DOCKABLE")
  324. {
  325. registerDockableWindow(plugin,
  326. dockableName,code,actions);
  327. cachedDockableNames.add(dockableName);
  328. cachedDockableActionFlags.add(
  329. new Boolean(actions));
  330. // make default be true for the next
  331. // action
  332. actions = true;
  333. }
  334. popElement();
  335. }
  336. else
  337. {
  338. // can't happen
  339. throw new InternalError();
  340. }
  341. } //}}}
  342. //{{{ startDocument() method
  343. public void startDocument()
  344. {
  345. try
  346. {
  347. pushElement(null);
  348. }
  349. catch (Exception e)
  350. {
  351. e.printStackTrace();
  352. }
  353. } //}}}
  354. //{{{ getCachedDockableNames() method
  355. public String[] getCachedDockableNames()
  356. {
  357. return (String[])cachedDockableNames.toArray(new String[cachedDockableNames.size()]);
  358. } //}}}
  359. //{{{ getCachedDockableActionFlags() method
  360. public boolean[] getCachedDockableActionFlags()
  361. {
  362. boolean[] returnValue = new boolean[
  363. cachedDockableActionFlags.size()];
  364. Iterator iter = cachedDockableActionFlags.iterator();
  365. int i = 0;
  366. while(iter.hasNext())
  367. {
  368. boolean flag = ((Boolean)iter.next())
  369. .booleanValue();
  370. returnValue[i++] = flag;
  371. }
  372. return returnValue;
  373. } //}}}
  374. //{{{ Private members
  375. //{{{ Instance variables
  376. private PluginJAR plugin;
  377. private URL uri;
  378. private java.util.List cachedDockableNames;
  379. private java.util.List cachedDockableActionFlags;
  380. private String dockableName;
  381. private String code;
  382. private boolean actions;
  383. private Stack stateStack;
  384. //}}}
  385. //{{{ pushElement() method
  386. private String pushElement(String name)
  387. {
  388. name = (name == null) ? null : name.intern();
  389. stateStack.push(name);
  390. return name;
  391. } //}}}
  392. //{{{ peekElement() method
  393. private String peekElement()
  394. {
  395. return (String) stateStack.peek();
  396. } //}}}
  397. //{{{ popElement() method
  398. private String popElement()
  399. {
  400. return (String) stateStack.pop();
  401. } //}}}
  402. //}}}
  403. } //}}}
  404. //{{{ Factory class
  405. static class Factory
  406. {
  407. PluginJAR plugin;
  408. String name;
  409. String code;
  410. boolean loaded;
  411. //{{{ Factory constructor
  412. Factory(PluginJAR plugin, String name, String code,
  413. boolean actions)
  414. {
  415. this.plugin = plugin;
  416. this.name = name;
  417. this.code = code;
  418. if(code != null)
  419. loaded = true;
  420. if(actions)
  421. {
  422. ActionSet actionSet = (plugin == null
  423. ? jEdit.getBuiltInActionSet()
  424. : plugin.getActionSet());
  425. actionSet.addAction(new OpenAction(name));
  426. actionSet.addAction(new ToggleAction(name));
  427. actionSet.addAction(new FloatAction(name));
  428. String label = jEdit.getProperty(name
  429. + ".label");
  430. if(label == null)
  431. label = "NO LABEL PROPERTY: " + name;
  432. String[] args = { label };
  433. jEdit.setTemporaryProperty(name + ".label",
  434. label);
  435. jEdit.setTemporaryProperty(name
  436. + "-toggle.label",
  437. jEdit.getProperty(
  438. "view.docking.toggle.label",args));
  439. jEdit.setTemporaryProperty(name
  440. + "-toggle.toggle","true");
  441. jEdit.setTemporaryProperty(name
  442. + "-float.label",
  443. jEdit.getProperty(
  444. "view.docking.float.label",args));
  445. }
  446. } //}}}
  447. //{{{ load() method
  448. void load()
  449. {
  450. if(loaded)
  451. return;
  452. loadDockableWindows(plugin,plugin.getDockablesURI(),null);
  453. } //}}}
  454. //{{{ createDockableWindow() method
  455. JComponent createDockableWindow(View view, String position)
  456. {
  457. load();
  458. if(!loaded)
  459. {
  460. Log.log(Log.WARNING,this,"Outdated cache");
  461. return null;
  462. }
  463. NameSpace nameSpace = new NameSpace(
  464. BeanShell.getNameSpace(),
  465. "DockableWindowManager.Factory"
  466. + ".createDockableWindow()");
  467. try
  468. {
  469. nameSpace.setVariable(
  470. "position",position);
  471. }
  472. catch(UtilEvalError e)
  473. {
  474. Log.log(Log.ERROR,this,e);
  475. }
  476. JComponent win = (JComponent)BeanShell.eval(view,
  477. nameSpace,code);
  478. return win;
  479. } //}}}
  480. //{{{ OpenAction class
  481. static class OpenAction extends EditAction
  482. {
  483. private String dockable;
  484. //{{{ OpenAction constructor
  485. OpenAction(String name)
  486. {
  487. super(name);
  488. this.dockable = name;
  489. } //}}}
  490. //{{{ invoke() method
  491. public void invoke(View view)
  492. {
  493. view.getDockableWindowManager()
  494. .showDockableWindow(dockable);
  495. } //}}}
  496. //{{{ getCode() method
  497. public String getCode()
  498. {
  499. return "view.getDockableWindowManager()"
  500. + ".showDockableWindow(\"" + dockable + "\");";
  501. } //}}}
  502. } //}}}
  503. //{{{ ToggleAction class
  504. static class ToggleAction extends EditAction
  505. {
  506. private String dockable;
  507. //{{{ ToggleAction constructor
  508. ToggleAction(String name)
  509. {
  510. super(name + "-toggle");
  511. this.dockable = name;
  512. } //}}}
  513. //{{{ invoke() method
  514. public void invoke(View view)
  515. {
  516. view.getDockableWindowManager()
  517. .toggleDockableWindow(dockable);
  518. } //}}}
  519. //{{{ isSelected() method
  520. public boolean isSelected(View view)
  521. {
  522. return view.getDockableWindowManager()
  523. .isDockableWindowVisible(dockable);
  524. } //}}}
  525. //{{{ getCode() method
  526. public String getCode()
  527. {
  528. return "view.getDockableWindowManager()"
  529. + ".toggleDockableWindow(\"" + dockable + "\");";
  530. } //}}}
  531. } //}}}
  532. //{{{ FloatAction class
  533. static class FloatAction extends EditAction
  534. {
  535. private String dockable;
  536. //{{{ FloatAction constructor
  537. FloatAction(String name)
  538. {
  539. super(name + "-float");
  540. this.dockable = name;
  541. } //}}}
  542. //{{{ invoke() method
  543. public void invoke(View view)
  544. {
  545. view.getDockableWindowManager()
  546. .floatDockableWindow(dockable);
  547. } //}}}
  548. //{{{ getCode() method
  549. public String getCode()
  550. {
  551. return "view.getDockableWindowManager()"
  552. + ".floatDockableWindow(\"" + dockable + "\");";
  553. } //}}}
  554. } //}}}
  555. } //}}}
  556. private static HashMap dockableWindowFactories;
  557. //{{{ Static initializer
  558. static
  559. {
  560. dockableWindowFactories = new HashMap();
  561. } //}}}
  562. //}}}
  563. //{{{ Instance part of class
  564. //{{{ DockableWindowManager constructor
  565. /**
  566. * Creates a new dockable window manager.
  567. * @param view The view
  568. * @since jEdit 2.6pre3
  569. */
  570. public DockableWindowManager(View view, View.ViewConfig config)
  571. {
  572. setLayout(new DockableLayout());
  573. this.view = view;
  574. windows = new Hashtable();
  575. clones = new ArrayList();
  576. top = new PanelWindowContainer(this,TOP,config.topPos);
  577. left = new PanelWindowContainer(this,LEFT,config.leftPos);
  578. bottom = new PanelWindowContainer(this,BOTTOM,config.bottomPos);
  579. right = new PanelWindowContainer(this,RIGHT,config.rightPos);
  580. add(DockableLayout.TOP_BUTTONS,top.buttonPanel);
  581. add(DockableLayout.LEFT_BUTTONS,left.buttonPanel);
  582. add(DockableLayout.BOTTOM_BUTTONS,bottom.buttonPanel);
  583. add(DockableLayout.RIGHT_BUTTONS,right.buttonPanel);
  584. add(TOP,top.dockablePanel);
  585. add(LEFT,left.dockablePanel);
  586. add(BOTTOM,bottom.dockablePanel);
  587. add(RIGHT,right.dockablePanel);
  588. } //}}}
  589. //{{{ init() method
  590. /**
  591. * Initialises dockable window manager. Do not call this method directly.
  592. */
  593. public void init()
  594. {
  595. EditBus.addToBus(this);
  596. Iterator entries = dockableWindowFactories.values().iterator();
  597. while(entries.hasNext())
  598. addEntry((Factory)entries.next());
  599. propertiesChanged();
  600. } //}}}
  601. //{{{ getView() method
  602. /**
  603. * Returns this dockable window manager's view.
  604. * @since jEdit 4.0pre2
  605. */
  606. public View getView()
  607. {
  608. return view;
  609. } //}}}
  610. //{{{ floatDockableWindow() method
  611. /**
  612. * Opens a new instance of the specified dockable window in a floating
  613. * container.
  614. * @param name The dockable window name
  615. * @return The new dockable window instance
  616. * @since jEdit 4.1pre2
  617. */
  618. public JComponent floatDockableWindow(String name)
  619. {
  620. Entry entry = (Entry)windows.get(name);
  621. if(entry == null)
  622. {
  623. Log.log(Log.ERROR,this,"Unknown dockable window: " + name);
  624. return null;
  625. }
  626. // create a copy of this dockable window and float it
  627. Entry newEntry = new Entry(entry.factory,FLOATING);
  628. newEntry.win = newEntry.factory.createDockableWindow(view,FLOATING);
  629. if(newEntry.win != null)
  630. {
  631. newEntry.container = new FloatingWindowContainer(this,true);
  632. newEntry.container.register(newEntry);
  633. newEntry.container.show(newEntry);
  634. }
  635. clones.add(newEntry);
  636. return newEntry.win;
  637. } //}}}
  638. //{{{ showDockableWindow() method
  639. /**
  640. * Opens the specified dockable window.
  641. * @param name The dockable window name
  642. * @since jEdit 2.6pre3
  643. */
  644. public void showDockableWindow(String name)
  645. {
  646. Entry entry = (Entry)windows.get(name);
  647. if(entry == null)
  648. {
  649. Log.log(Log.ERROR,this,"Unknown dockable window: " + name);
  650. return;
  651. }
  652. if(entry.win == null)
  653. {
  654. entry.win = entry.factory.createDockableWindow(
  655. view,entry.position);
  656. }
  657. if(entry.win != null)
  658. {
  659. if(entry.position.equals(FLOATING)
  660. && entry.container == null)
  661. {
  662. entry.container = new FloatingWindowContainer(
  663. this,view.isPlainView());
  664. entry.container.register(entry);
  665. }
  666. entry.container.show(entry);
  667. }
  668. else
  669. /* an error occurred */;
  670. } //}}}
  671. //{{{ addDockableWindow() method
  672. /**
  673. * Opens the specified dockable window. As of jEdit 4.0pre1, has the
  674. * same effect as calling showDockableWindow().
  675. * @param name The dockable window name
  676. * @since jEdit 2.6pre3
  677. */
  678. public void addDockableWindow(String name)
  679. {
  680. showDockableWindow(name);
  681. } //}}}
  682. //{{{ hideDockableWindow() method
  683. /**
  684. * Hides the specified dockable window.
  685. * @param name The dockable window name
  686. * @since jEdit 2.6pre3
  687. */
  688. public void hideDockableWindow(String name)
  689. {
  690. Entry entry = (Entry)windows.get(name);
  691. if(entry == null)
  692. {
  693. Log.log(Log.ERROR,this,"Unknown dockable window: " + name);
  694. return;
  695. }
  696. if(entry.win == null)
  697. return;
  698. entry.container.show(null);
  699. } //}}}
  700. //{{{ removeDockableWindow() method
  701. /**
  702. * Hides the specified dockable window. As of jEdit 4.2pre1, has the
  703. * same effect as calling hideDockableWindow().
  704. * @param name The dockable window name
  705. * @since jEdit 4.2pre1
  706. */
  707. public void removeDockableWindow(String name)
  708. {
  709. hideDockableWindow(name);
  710. } //}}}
  711. //{{{ toggleDockableWindow() method
  712. /**
  713. * Toggles the visibility of the specified dockable window.
  714. * @param name The dockable window name
  715. */
  716. public void toggleDockableWindow(String name)
  717. {
  718. if(isDockableWindowVisible(name))
  719. removeDockableWindow(name);
  720. else
  721. addDockableWindow(name);
  722. } //}}}
  723. //{{{ getDockableWindow() method
  724. /**
  725. * Returns the specified dockable window.
  726. * @param name The name of the dockable window
  727. * @since jEdit 4.1pre2
  728. */
  729. public JComponent getDockableWindow(String name)
  730. {
  731. return getDockable(name);
  732. } //}}}
  733. //{{{ getDockable() method
  734. /**
  735. * Returns the specified dockable window. For historical reasons, this
  736. * does the same thing as {@link #getDockableWindow(String)}.
  737. * @param name The name of the dockable window
  738. * @since jEdit 4.0pre1
  739. */
  740. public JComponent getDockable(String name)
  741. {
  742. Entry entry = (Entry)windows.get(name);
  743. if(entry == null || entry.win == null)
  744. return null;
  745. else
  746. return entry.win;
  747. } //}}}
  748. //{{{ getDockableTitle() method
  749. /**
  750. * Returns the title of the specified dockable window.
  751. * @param name The name of the dockable window.
  752. * @since jEdit 4.1pre5
  753. */
  754. public String getDockableTitle(String name)
  755. {
  756. String title = jEdit.getProperty(name + ".title");
  757. if(title == null)
  758. return "NO TITLE PROPERTY: " + name;
  759. else
  760. return title;
  761. } //}}}
  762. //{{{ isDockableWindowVisible() method
  763. /**
  764. * Returns if the specified dockable window is visible.
  765. * @param name The dockable window name
  766. */
  767. public boolean isDockableWindowVisible(String name)
  768. {
  769. Entry entry = (Entry)windows.get(name);
  770. if(entry == null || entry.win == null)
  771. return false;
  772. else
  773. return entry.container.isVisible(entry);
  774. } //}}}
  775. //{{{ isDockableWindowDocked() method
  776. /**
  777. * Returns if the specified dockable window is docked into the
  778. * view.
  779. * @param name The dockable's name
  780. * @since jEdit 4.0pre2
  781. */
  782. public boolean isDockableWindowDocked(String name)
  783. {
  784. Entry entry = (Entry)windows.get(name);
  785. if(entry == null)
  786. return false;
  787. else
  788. return !entry.position.equals(FLOATING);
  789. } //}}}
  790. //{{{ closeCurrentArea() method
  791. /**
  792. * Closes the currently focused docking area.
  793. * @since jEdit 4.1pre3
  794. */
  795. public void closeCurrentArea()
  796. {
  797. // I don't know of any other way to fix this, since invoking this
  798. // command from a menu results in the focus owner being the menu
  799. // until the menu goes away.
  800. SwingUtilities.invokeLater(new Runnable()
  801. {
  802. public void run()
  803. {
  804. Component comp = view.getFocusOwner();
  805. while(comp != null)
  806. {
  807. //System.err.println(comp.getClass());
  808. if(comp instanceof PanelWindowContainer
  809. .DockablePanel)
  810. {
  811. PanelWindowContainer container =
  812. ((PanelWindowContainer.DockablePanel)
  813. comp).getWindowContainer();
  814. container.show(null);
  815. return;
  816. }
  817. comp = comp.getParent();
  818. }
  819. getToolkit().beep();
  820. }
  821. });
  822. } //}}}
  823. //{{{ close() method
  824. /**
  825. * Called when the view is being closed.
  826. * @since jEdit 2.6pre3
  827. */
  828. public void close()
  829. {
  830. EditBus.removeFromBus(this);
  831. Iterator iter = windows.values().iterator();
  832. while(iter.hasNext())
  833. {
  834. Entry entry = (Entry)iter.next();
  835. if(entry.win != null)
  836. {
  837. entry.container.unregister(entry);
  838. }
  839. }
  840. iter = clones.iterator();
  841. while(iter.hasNext())
  842. {
  843. Entry entry = (Entry)iter.next();
  844. if(entry.win != null)
  845. {
  846. entry.container.unregister(entry);
  847. }
  848. }
  849. } //}}}
  850. //{{{ getTopDockingArea() method
  851. public PanelWindowContainer getTopDockingArea()
  852. {
  853. return top;
  854. } //}}}
  855. //{{{ getLeftDockingArea() method
  856. public PanelWindowContainer getLeftDockingArea()
  857. {
  858. return left;
  859. } //}}}
  860. //{{{ getBottomDockingArea() method
  861. public PanelWindowContainer getBottomDockingArea()
  862. {
  863. return bottom;
  864. } //}}}
  865. //{{{ getRightDockingArea() method
  866. public PanelWindowContainer getRightDockingArea()
  867. {
  868. return right;
  869. } //}}}
  870. //{{{ createPopupMenu() method
  871. public JPopupMenu createPopupMenu(
  872. final DockableWindowContainer container,
  873. final String dockable,
  874. final boolean clone)
  875. {
  876. JPopupMenu popup = new JPopupMenu();
  877. if(dockable == null && container instanceof PanelWindowContainer)
  878. {
  879. ActionListener listener = new ActionListener()
  880. {
  881. public void actionPerformed(ActionEvent evt)
  882. {
  883. showDockableWindow(evt.getActionCommand());
  884. }
  885. };
  886. String[] dockables = ((PanelWindowContainer)
  887. container).getDockables();
  888. for(int i = 0; i < dockables.length; i++)
  889. {
  890. String name = dockables[i];
  891. JMenuItem item = new JMenuItem(getDockableTitle(name));
  892. item.setActionCommand(name);
  893. item.addActionListener(listener);
  894. popup.add(item);
  895. }
  896. }
  897. else
  898. {
  899. JMenuItem caption = new JMenuItem(getDockableTitle(dockable));
  900. caption.setEnabled(false);
  901. popup.add(caption);
  902. popup.addSeparator();
  903. String currentPos = jEdit.getProperty(dockable + ".dock-position",FLOATING);
  904. if(!clone)
  905. {
  906. String[] positions = { FLOATING, TOP, LEFT, BOTTOM, RIGHT };
  907. for(int i = 0; i < positions.length; i++)
  908. {
  909. final String pos = positions[i];
  910. if(pos.equals(currentPos))
  911. continue;
  912. JMenuItem moveMenuItem = new JMenuItem(jEdit.getProperty("view.docking.menu-"
  913. + pos));
  914. moveMenuItem.addActionListener(new ActionListener()
  915. {
  916. public void actionPerformed(ActionEvent evt)
  917. {
  918. jEdit.setProperty(dockable + ".dock-position",pos);
  919. EditBus.send(new DockableWindowUpdate(
  920. DockableWindowManager.this,
  921. DockableWindowUpdate.PROPERTIES_CHANGED,
  922. null
  923. ));
  924. showDockableWindow(dockable);
  925. }
  926. });
  927. popup.add(moveMenuItem);
  928. }
  929. popup.addSeparator();
  930. }
  931. JMenuItem cloneMenuItem = new JMenuItem(jEdit.getProperty("view.docking.menu-clone"));
  932. cloneMenuItem.addActionListener(new ActionListener()
  933. {
  934. public void actionPerformed(ActionEvent evt)
  935. {
  936. floatDockableWindow(dockable);
  937. }
  938. });
  939. popup.add(cloneMenuItem);
  940. popup.addSeparator();
  941. JMenuItem closeMenuItem = new JMenuItem(jEdit.getProperty("view.docking.menu-close"));
  942. closeMenuItem.addActionListener(new ActionListener()
  943. {
  944. public void actionPerformed(ActionEvent evt)
  945. {
  946. if(clone)
  947. ((FloatingWindowContainer)container).dispose();
  948. else
  949. removeDockableWindow(dockable);
  950. }
  951. });
  952. popup.add(closeMenuItem);
  953. if(!(clone || currentPos.equals(FLOATING)))
  954. {
  955. JMenuItem undockMenuItem = new JMenuItem(jEdit.getProperty("view.docking.menu-undock"));
  956. undockMenuItem.addActionListener(new ActionListener()
  957. {
  958. public void actionPerformed(ActionEvent evt)
  959. {
  960. jEdit.setProperty(dockable + ".dock-position",FLOATING);
  961. EditBus.send(new DockableWindowUpdate(
  962. DockableWindowManager.this,
  963. DockableWindowUpdate.PROPERTIES_CHANGED,
  964. null
  965. ));
  966. }
  967. });
  968. popup.add(undockMenuItem);
  969. }
  970. }
  971. return popup;
  972. } //}}}
  973. //{{{ paintChildren() method
  974. public void paintChildren(Graphics g)
  975. {
  976. super.paintChildren(g);
  977. if(resizeRect != null)
  978. {
  979. g.setColor(Color.darkGray);
  980. g.fillRect(resizeRect.x,resizeRect.y,
  981. resizeRect.width,resizeRect.height);
  982. }
  983. } //}}}
  984. //{{{ handleMessage() method
  985. public void handleMessage(EBMessage msg)
  986. {
  987. if(msg instanceof DockableWindowUpdate)
  988. {
  989. if(((DockableWindowUpdate)msg).getWhat()
  990. == DockableWindowUpdate.PROPERTIES_CHANGED)
  991. propertiesChanged();
  992. }
  993. else if(msg instanceof PluginUpdate)
  994. {
  995. PluginUpdate pmsg = (PluginUpdate)msg;
  996. if(pmsg.getWhat() == PluginUpdate.LOADED)
  997. {
  998. Iterator iter = dockableWindowFactories
  999. .values().iterator();
  1000. while(iter.hasNext())
  1001. {
  1002. Factory factory = (Factory)iter.next();
  1003. if(factory.plugin == pmsg.getPluginJAR())
  1004. addEntry(factory);
  1005. }
  1006. propertiesChanged();
  1007. }
  1008. else if(pmsg.isExiting())
  1009. {
  1010. // we don't care
  1011. }
  1012. else if(pmsg.getWhat() == PluginUpdate.DEACTIVATED)
  1013. {
  1014. Iterator iter = windows.values().iterator();
  1015. while(iter.hasNext())
  1016. {
  1017. Entry entry = (Entry)iter.next();
  1018. if(entry.factory.plugin == pmsg.getPluginJAR())
  1019. {
  1020. if(entry.container != null
  1021. && entry.container
  1022. .isVisible(entry))
  1023. {
  1024. entry.container.remove(entry);
  1025. }
  1026. }
  1027. }
  1028. iter = clones.iterator();
  1029. while(iter.hasNext())
  1030. {
  1031. Entry entry = (Entry)iter.next();
  1032. if(entry.factory.plugin == pmsg.getPluginJAR())
  1033. {
  1034. if(entry.container != null)
  1035. entry.container.unregister(entry);
  1036. iter.remove();
  1037. }
  1038. }
  1039. }
  1040. else if(pmsg.getWhat() == PluginUpdate.UNLOADED)
  1041. {
  1042. Iterator iter = windows.values().iterator();
  1043. while(iter.hasNext())
  1044. {
  1045. Entry entry = (Entry)iter.next();
  1046. if(entry.factory.plugin == pmsg.getPluginJAR())
  1047. {
  1048. if(entry.container != null)
  1049. entry.container.unregister(entry);
  1050. iter.remove();
  1051. }
  1052. }
  1053. }
  1054. }
  1055. } //}}}
  1056. //{{{ Package-private members
  1057. int resizePos;
  1058. Rectangle resizeRect;
  1059. //{{{ setResizePos() method
  1060. void setResizePos(PanelWindowContainer resizing)
  1061. {
  1062. if(resizePos < 0)
  1063. resizePos = 0;
  1064. Rectangle newResizeRect = new Rectangle(0,0,
  1065. PanelWindowContainer.SPLITTER_WIDTH - 2,
  1066. PanelWindowContainer.SPLITTER_WIDTH - 2);
  1067. if(resizing == top)
  1068. {
  1069. resizePos = Math.min(resizePos,getHeight()
  1070. - top.buttonPanel.getHeight()
  1071. - bottom.dockablePanel.getHeight()
  1072. - bottom.buttonPanel.getHeight()
  1073. - PanelWindowContainer.SPLITTER_WIDTH);
  1074. newResizeRect.x = top.dockablePanel.getX() + 1;
  1075. newResizeRect.y = resizePos + top.buttonPanel.getHeight() + 1;
  1076. newResizeRect.width = top.dockablePanel.getWidth() - 2;
  1077. }
  1078. else if(resizing == left)
  1079. {
  1080. resizePos = Math.min(resizePos,getWidth()
  1081. - left.buttonPanel.getWidth()
  1082. - right.dockablePanel.getWidth()
  1083. - right.buttonPanel.getWidth()
  1084. - PanelWindowContainer.SPLITTER_WIDTH);
  1085. newResizeRect.x = resizePos + left.buttonPanel.getWidth() + 1;
  1086. newResizeRect.y = left.dockablePanel.getY() + 1;
  1087. newResizeRect.height = left.dockablePanel.getHeight() - 2;
  1088. }
  1089. else if(resizing == bottom)
  1090. {
  1091. resizePos = Math.min(resizePos,getHeight()
  1092. - bottom.buttonPanel.getHeight()
  1093. - top.dockablePanel.getHeight()
  1094. - top.buttonPanel.getHeight()
  1095. - PanelWindowContainer.SPLITTER_WIDTH);
  1096. newResizeRect.x = bottom.dockablePanel.getX() + 1;
  1097. newResizeRect.y = getHeight() - bottom.buttonPanel.getHeight() - resizePos
  1098. - PanelWindowContainer.SPLITTER_WIDTH + 2;
  1099. newResizeRect.width = bottom.dockablePanel.getWidth() - 2;
  1100. }
  1101. else if(resizing == right)
  1102. {
  1103. resizePos = Math.min(resizePos,getWidth()
  1104. - right.buttonPanel.getWidth()
  1105. - left.dockablePanel.getWidth()
  1106. - left.buttonPanel.getWidth()
  1107. - PanelWindowContainer.SPLITTER_WIDTH);
  1108. newResizeRect.x = getWidth() - right.buttonPanel.getWidth() - resizePos
  1109. - PanelWindowContainer.SPLITTER_WIDTH + 1;
  1110. newResizeRect.y = right.dockablePanel.getY() + 1;
  1111. newResizeRect.height = right.dockablePanel.getHeight() - 2;
  1112. }
  1113. Rectangle toRepaint;
  1114. if(resizeRect == null)
  1115. toRepaint = newResizeRect;
  1116. else
  1117. toRepaint = resizeRect.union(newResizeRect);
  1118. resizeRect = newResizeRect;
  1119. repaint(toRepaint);
  1120. } //}}}
  1121. //{{{ finishResizing() method
  1122. void finishResizing()
  1123. {
  1124. resizeRect = null;
  1125. repaint();
  1126. } //}}}
  1127. //}}}
  1128. //{{{ Private members
  1129. private View view;
  1130. private Hashtable windows;
  1131. private boolean alternateLayout;
  1132. private PanelWindowContainer left;
  1133. private PanelWindowContainer right;
  1134. private PanelWindowContainer top;
  1135. private PanelWindowContainer bottom;
  1136. private ArrayList clones;
  1137. //{{{ propertiesChanged() method
  1138. private void propertiesChanged()
  1139. {
  1140. if(view.isPlainView())
  1141. return;
  1142. alternateLayout = jEdit.getBooleanProperty("view.docking.alternateLayout");
  1143. String[] windowList = getRegisteredDockableWindows();
  1144. for(int i = 0; i < windowList.length; i++)
  1145. {
  1146. String dockable = windowList[i];
  1147. Entry entry = (Entry)windows.get(dockable);
  1148. String newPosition = jEdit.getProperty(dockable
  1149. + ".dock-position",FLOATING);
  1150. if(newPosition.equals(entry.position))
  1151. {
  1152. continue;
  1153. }
  1154. entry.position = newPosition;
  1155. if(entry.container != null)
  1156. {
  1157. entry.container.unregister(entry);
  1158. entry.container = null;
  1159. entry.win = null;
  1160. }
  1161. if(newPosition.equals(FLOATING))
  1162. /* do nothing */;
  1163. else
  1164. {
  1165. if(newPosition.equals(TOP))
  1166. entry.container = top;
  1167. else if(newPosition.equals(LEFT))
  1168. entry.container = left;
  1169. else if(newPosition.equals(BOTTOM))
  1170. entry.container = bottom;
  1171. else if(newPosition.equals(RIGHT))
  1172. entry.container = right;
  1173. else
  1174. {
  1175. Log.log(Log.WARNING,this,
  1176. "Unknown position: "
  1177. + newPosition);
  1178. continue;
  1179. }
  1180. entry.container.register(entry);
  1181. }
  1182. }
  1183. top.sortDockables();
  1184. left.sortDockables();
  1185. bottom.sortDockables();
  1186. right.sortDockables();
  1187. revalidate();
  1188. repaint();
  1189. } //}}}
  1190. //{{{ addEntry() method
  1191. private void addEntry(Factory factory)
  1192. {
  1193. Entry e;
  1194. if(view.isPlainView())
  1195. {
  1196. // don't show menu items to dock into a plain view
  1197. e = new Entry(factory,FLOATING);
  1198. }
  1199. else
  1200. {
  1201. e = new Entry(factory);
  1202. if(e.position.equals(FLOATING))
  1203. /* nothing to do */;
  1204. else if(e.position.equals(TOP))
  1205. e.container = top;
  1206. else if(e.position.equals(LEFT))
  1207. e.container = left;
  1208. else if(e.position.equals(BOTTOM))
  1209. e.container = bottom;
  1210. else if(e.position.equals(RIGHT))
  1211. e.container = right;
  1212. else
  1213. {
  1214. Log.log(Log.WARNING,this,
  1215. "Unknown position: "
  1216. + e.position);
  1217. }
  1218. if(e.container != null)
  1219. e.container.register(e);
  1220. }
  1221. windows.put(factory.name,e);
  1222. } //}}}
  1223. //}}}
  1224. //}}}
  1225. //{{{ DockableLayout class
  1226. public class DockableLayout implements LayoutManager2
  1227. {
  1228. // for backwards compatibility with plugins that fiddle with
  1229. // jEdit's UI layout
  1230. static final String CENTER = BorderLayout.CENTER;
  1231. public static final String TOP_TOOLBARS = "top-toolbars";
  1232. public static final String BOTTOM_TOOLBARS = "bottom-toolbars";
  1233. static final String TOP_BUTTONS = "top-buttons";
  1234. static final String LEFT_BUTTONS = "left-buttons";
  1235. static final String BOTTOM_BUTTONS = "bottom-buttons";
  1236. static final String RIGHT_BUTTONS = "right-buttons";
  1237. Component topToolbars, bottomToolbars;
  1238. Component center;
  1239. Component top, left, bottom, right;
  1240. Component topButtons, leftButtons, bottomButtons, rightButtons;
  1241. //{{{ addLayoutComponent() method
  1242. public void addLayoutComponent(String name, Component comp)
  1243. {
  1244. addLayoutComponent(comp,name);
  1245. } //}}}
  1246. //{{{ addLayoutComponent() method
  1247. public void addLayoutComponent(Component comp, Object cons)
  1248. {
  1249. if(cons == null || CENTER.equals(cons))
  1250. center = comp;
  1251. else if(TOP_TOOLBARS.equals(cons))
  1252. topToolbars = comp;
  1253. else if(BOTTOM_TOOLBARS.equals(cons))
  1254. bottomToolbars = comp;
  1255. else if(TOP.equals(cons))
  1256. top = comp;
  1257. else if(LEFT.equals(cons))
  1258. left = comp;
  1259. else if(BOTTOM.equals(cons))
  1260. bottom = comp;
  1261. else if(RIGHT.equals(cons))
  1262. right = comp;
  1263. else if(TOP_BUTTONS.equals(cons))
  1264. topButtons = comp;
  1265. else if(LEFT_BUTTONS.equals(cons))
  1266. leftButtons = comp;
  1267. else if(BOTTOM_BUTTONS.equals(cons))
  1268. bottomButtons = comp;
  1269. else if(RIGHT_BUTTONS.equals(cons))
  1270. rightButtons = comp;
  1271. } //}}}
  1272. //{{{ removeLayoutComponent() method
  1273. public void removeLayoutComponent(Component comp)
  1274. {
  1275. if(center == comp)
  1276. center = null;
  1277. if(comp == topToolbars)
  1278. topToolbars = null;
  1279. if(comp == bottomToolbars)
  1280. bottomToolbars = null;
  1281. {
  1282. // none of the others are ever meant to be
  1283. // removed. retarded, eh? this needs to be
  1284. // fixed eventually, for plugins might
  1285. // want to do weird stuff to jEdit's UI
  1286. }
  1287. } //}}}
  1288. //{{{ preferredLayoutSize() method
  1289. public Dimension preferredLayoutSize(Container parent)
  1290. {
  1291. Dimension prefSize = new Dimension(0,0);
  1292. Dimension _top = top.getPreferredSize();
  1293. Dimension _left = left.getPreferredSize();
  1294. Dimension _bottom = bottom.getPreferredSize();
  1295. Dimension _right = right.getPreferredSize();
  1296. Dimension _topButtons = topButtons.getPreferredSize();
  1297. Dimension _leftButtons = leftButtons.getPreferredSize();
  1298. Dimension _bottomButtons = bottomButtons.getPreferredSize();
  1299. Dimension _rightButtons = rightButtons.getPreferredSize();
  1300. Dimension _center = (center == null
  1301. ? new Dimension(0,0)
  1302. : center.getPreferredSize());
  1303. Dimension _topToolbars = (topToolbars == null
  1304. ? new Dimension(0,0)
  1305. : topToolbars.getPreferredSize());
  1306. Dimension _bottomToolbars = (bottomToolbars == null
  1307. ? new Dimension(0,0)
  1308. : bottomToolbars.getPreferredSize());
  1309. prefSize.height = _top.height + _bottom.height + _center.height
  1310. + _topButtons.height + _bottomButtons.height
  1311. + _topToolbars.height + _bottomToolbars.height;
  1312. prefSize.width = _left.width + _right.width
  1313. + Math.max(_center.width,
  1314. Math.max(_topToolbars.width,_bottomToolbars.width))
  1315. + _leftButtons.width + _rightButtons.width;
  1316. return prefSize;
  1317. } //}}}
  1318. //{{{ minimumLayoutSize() method
  1319. public Dimension minimumLayoutSize(Container parent)
  1320. {
  1321. // I'm lazy
  1322. return preferredLayoutSize(parent);
  1323. } //}}}
  1324. //{{{ maximumLayoutSize() method
  1325. public Dimension maximumLayoutSize(Container parent)
  1326. {
  1327. return new Dimension(Integer.MAX_VALUE,Integer.MAX_VALUE);
  1328. } //}}}
  1329. //{{{ layoutContainer() method
  1330. public void layoutContainer(Container parent)
  1331. {
  1332. Dimension size = parent.getSize();
  1333. Dimension _topButtons = topButtons.getPreferredSize();
  1334. Dimension _leftButtons = leftButtons.getPreferredSize();
  1335. Dimension _bottomButtons = bottomButtons.getPreferredSize();
  1336. Dimension _rightButtons = rightButtons.getPreferredSize();
  1337. Dimension _topToolbars = (topToolbars == null
  1338. ? new Dimension(0,0)
  1339. : topToolbars.getPreferredSize());
  1340. Dimension _bottomToolbars = (bottomToolbars == null
  1341. ? new Dimension(0,0)
  1342. : bottomToolbars.getPreferredSize());
  1343. int _width = size.width - _leftButtons.width - _rightButtons.width;
  1344. int _height = size.height - _topButtons.height - _bottomButtons.height;
  1345. Dimension _top = top.getPreferredSize();
  1346. Dimension _left = left.getPreferredSize();
  1347. Dimension _bottom = bottom.getPreferredSize();
  1348. Dimension _right = right.getPreferredSize();
  1349. int maxTopHeight = _height - _bottom.height
  1350. - _topToolbars.height - _bottomToolbars.height;
  1351. int topHeight = Math.min(Math.max(0,maxTopHeight),
  1352. _top.height);
  1353. int leftWidth = Math.min(Math.max(0,_width - _right.width),_left.width);
  1354. int maxBottomHeight = _height - topHeight
  1355. - _topToolbars.height - _bottomToolbars.height;
  1356. int bottomHeight = Math.min(Math.max(0,maxBottomHeight),
  1357. _bottom.height);
  1358. int rightWidth = Math.min(Math.max(0,_width - leftWidth),_right.width);
  1359. DockableWindowManager.this.top.setDimension(topHeight);
  1360. DockableWindowManager.this.left.setDimension(leftWidth);
  1361. DockableWindowManager.this.bottom.setDimension(bottomHeight);
  1362. DockableWindowManager.this.right.setDimension(rightWidth);
  1363. if(alternateLayout)
  1364. {
  1365. topButtons.setBounds(
  1366. _leftButtons.width,
  1367. 0,
  1368. _width,
  1369. _topButtons.height);
  1370. leftButtons.setBounds(
  1371. 0,
  1372. _topButtons.height + _top.height,
  1373. _leftButtons.width,
  1374. _height - _top.height - _bottom.height);
  1375. bottomButtons.setBounds(
  1376. _leftButtons.width,
  1377. size.height - _bottomButtons.height,
  1378. _width,
  1379. _bottomButtons.height);
  1380. rightButtons.setBounds(
  1381. size.width - _rightButtons.width,
  1382. _topButtons.height + _top.height,
  1383. _rightButtons.width,
  1384. _height - _top.height - _bottom.height);
  1385. top.setBounds(
  1386. _leftButtons.width,
  1387. _topButtons.height,
  1388. _width,
  1389. topHeight);
  1390. bottom.setBounds(
  1391. _leftButtons.width,
  1392. size.height - bottomHeight - _bottomButtons.height,
  1393. _width,
  1394. bottomHeight);
  1395. left.setBounds(
  1396. _leftButtons.width,
  1397. _topButtons.height + topHeight,
  1398. leftWidth,
  1399. _height - topHeight - bottomHeight);
  1400. right.setBounds(
  1401. size.width - rightWidth - _rightButtons.width,
  1402. _topButtons.height + topHeight,
  1403. rightWidth,
  1404. _height - topHeight - bottomHeight);
  1405. }
  1406. else
  1407. {
  1408. topButtons.setBounds(
  1409. _leftButtons.width + leftWidth,
  1410. 0,
  1411. _width - leftWidth - rightWidth,
  1412. _topButtons.height);
  1413. leftButtons.setBounds(
  1414. 0,
  1415. _topButtons.height,
  1416. _leftButtons.width,
  1417. _height);
  1418. bottomButtons.setBounds(
  1419. _leftButtons.width + leftWidth,
  1420. size.height - _bottomButtons.height,
  1421. _width - leftWidth - rightWidth,
  1422. _bottomButtons.height);
  1423. rightButtons.setBounds(
  1424. size.width - _rightButtons.width,
  1425. _topButtons.height,
  1426. _rightButtons.width,
  1427. _height);
  1428. top.setBounds(
  1429. _leftButtons.width + leftWidth,
  1430. _topButtons.height,
  1431. _width - leftWidth - rightWidth,
  1432. topHeight);
  1433. bottom.setBounds(
  1434. _leftButtons.width + leftWidth,
  1435. size.height - bottomHeight - _bottomButtons.height,
  1436. _width - leftWidth - rightWidth,
  1437. bottomHeight);
  1438. left.setBounds(
  1439. _leftButtons.width,
  1440. _topButtons.height,
  1441. leftWidth,
  1442. _height);
  1443. right.setBounds(
  1444. size.width - rightWidth - _rightButtons.width,
  1445. _topButtons.height,
  1446. rightWidth,
  1447. _height);
  1448. }
  1449. if(topToolbars != null)
  1450. {
  1451. topToolbars.setBounds(
  1452. _leftButtons.width + leftWidth,
  1453. _topButtons.height + topHeight,
  1454. _width - leftWidth - rightWidth,
  1455. _topToolbars.height);
  1456. }
  1457. if(bottomToolbars != null)
  1458. {
  1459. bottomToolbars.setBounds(
  1460. _leftButtons.width + leftWidth,
  1461. _height - bottomHeight
  1462. - _bottomToolbars.height
  1463. + _topButtons.height,
  1464. _width - leftWidth - rightWidth,
  1465. _bottomToolbars.height);
  1466. }
  1467. if(center != null)
  1468. {
  1469. center.setBounds(
  1470. _leftButtons.width + leftWidth,
  1471. _topButtons.height + topHeight
  1472. + _topToolbars.height,
  1473. _width - leftWidth - rightWidth,
  1474. _height - topHeight - bottomHeight
  1475. - _topToolbars.height
  1476. - _bottomToolbars.height);
  1477. }
  1478. } //}}}
  1479. //{{{ getLayoutAlignmentX() method
  1480. public float getLayoutAlignmentX(Container target)
  1481. {
  1482. return 0.5f;
  1483. } //}}}
  1484. //{{{ getLayoutAlignmentY() method
  1485. public float getLayoutAlignmentY(Container target)
  1486. {
  1487. return 0.5f;
  1488. } //}}}
  1489. //{{{ invalidateLayout() method
  1490. public void invalidateLayout(Container target) {}
  1491. //}}}
  1492. } //}}}
  1493. //{{{ Entry class
  1494. class Entry
  1495. {
  1496. Factory factory;
  1497. String title;
  1498. String position;
  1499. DockableWindowContainer container;
  1500. // only set if open
  1501. JComponent win;
  1502. // only for docked
  1503. AbstractButton btn;
  1504. //{{{ Entry constructor
  1505. Entry(Factory factory)
  1506. {
  1507. this(factory,jEdit.getProperty(factory.name
  1508. + ".dock-position",FLOATING));
  1509. } //}}}
  1510. //{{{ Entry constructor
  1511. Entry(Factory factory, String position)
  1512. {
  1513. this.factory = factory;
  1514. this.position = position;
  1515. // get the title here, not in the factory constructor,
  1516. // since the factory might be created before a plugin's
  1517. // props are loaded
  1518. title = getDockableTitle(factory.name);
  1519. } //}}}
  1520. } //}}}
  1521. }