PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/jEdit/tags/jedit-4-2-pre14/org/gjt/sp/jedit/gui/PanelWindowContainer.java

#
Java | 1130 lines | 860 code | 130 blank | 140 comment | 159 complexity | 7602fa35c0ad2c1a712be275106966aa 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. * PanelWindowContainer.java - holds dockable windows
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2000, 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.gui;
  23. //{{{ Imports
  24. import javax.swing.border.*;
  25. import javax.swing.plaf.metal.*;
  26. import javax.swing.*;
  27. import java.awt.event.*;
  28. import java.awt.font.*;
  29. import java.awt.geom.AffineTransform;
  30. import java.awt.*;
  31. import java.util.*;
  32. import org.gjt.sp.jedit.*;
  33. //}}}
  34. /**
  35. * A container for dockable windows. This class should never be used
  36. * directly.
  37. * @author Slava Pestov
  38. * @version $Id: PanelWindowContainer.java 4997 2004-03-19 22:42:21Z spestov $
  39. * @since jEdit 4.0pre1
  40. */
  41. public class PanelWindowContainer implements DockableWindowContainer
  42. {
  43. //{{{ PanelWindowContainer constructor
  44. public PanelWindowContainer(DockableWindowManager wm, String position,
  45. int dimension)
  46. {
  47. this.wm = wm;
  48. this.position = position;
  49. //{{{ Button box setup
  50. buttonPanel = new JPanel(new ButtonLayout());
  51. buttonPanel.setBorder(new EmptyBorder(1,1,1,1));
  52. closeBox = new JButton(GUIUtilities.loadIcon("closebox.gif"));
  53. closeBox.setRequestFocusEnabled(false);
  54. closeBox.setToolTipText(jEdit.getProperty("view.docking.close-tooltip"));
  55. if(OperatingSystem.isMacOSLF())
  56. closeBox.putClientProperty("JButton.buttonType","toolbar");
  57. closeBox.setMargin(new Insets(0,0,0,0));
  58. closeBox.addActionListener(new ActionHandler());
  59. menuBtn = new JButton(GUIUtilities.loadIcon("ToolbarMenu.gif"));
  60. menuBtn.setRequestFocusEnabled(false);
  61. menuBtn.setToolTipText(jEdit.getProperty("view.docking.menu-tooltip"));
  62. if(OperatingSystem.isMacOSLF())
  63. menuBtn.putClientProperty("JButton.buttonType","toolbar");
  64. menuBtn.setMargin(new Insets(0,0,0,0));
  65. menuBtn.addMouseListener(new MenuMouseHandler());
  66. buttonGroup = new ButtonGroup();
  67. // JDK 1.4 workaround
  68. buttonGroup.add(nullButton = new JToggleButton());
  69. //}}}
  70. dockables = new ArrayList();
  71. buttons = new ArrayList();
  72. dockablePanel = new DockablePanel();
  73. this.dimension = dimension;
  74. } //}}}
  75. //{{{ register() method
  76. public void register(final DockableWindowManager.Entry entry)
  77. {
  78. dockables.add(entry);
  79. //{{{ Create button
  80. int rotation;
  81. if(position.equals(DockableWindowManager.TOP)
  82. || position.equals(DockableWindowManager.BOTTOM))
  83. rotation = RotatedTextIcon.NONE;
  84. else if(position.equals(DockableWindowManager.LEFT))
  85. rotation = RotatedTextIcon.CCW;
  86. else if(position.equals(DockableWindowManager.RIGHT))
  87. rotation = RotatedTextIcon.CW;
  88. else
  89. throw new InternalError("Invalid position: " + position);
  90. JToggleButton button = new JToggleButton();
  91. button.setMargin(new Insets(1,1,1,1));
  92. button.setRequestFocusEnabled(false);
  93. button.setIcon(new RotatedTextIcon(rotation,button.getFont(),
  94. entry.title));
  95. button.setActionCommand(entry.factory.name);
  96. button.addActionListener(new ActionHandler());
  97. button.addMouseListener(new MenuMouseHandler());
  98. if(OperatingSystem.isMacOSLF())
  99. button.putClientProperty("JButton.buttonType","toolbar");
  100. //}}}
  101. buttonGroup.add(button);
  102. buttons.add(button);
  103. entry.btn = button;
  104. wm.revalidate();
  105. } //}}}
  106. //{{{ unregister() method
  107. public void unregister(DockableWindowManager.Entry entry)
  108. {
  109. if(entry.factory.name.equals(mostRecent))
  110. mostRecent = null;
  111. buttonPanel.remove(entry.btn);
  112. buttons.remove(entry.btn);
  113. entry.btn = null;
  114. dockables.remove(entry);
  115. if(entry.win != null)
  116. dockablePanel.remove(entry.win);
  117. if(current == entry)
  118. {
  119. current = null;
  120. show(null);
  121. }
  122. else
  123. {
  124. wm.revalidate();
  125. dockablePanel.repaint();
  126. buttonPanel.repaint();
  127. }
  128. } //}}}
  129. //{{{ remove() method
  130. public void remove(final DockableWindowManager.Entry entry)
  131. {
  132. if(entry.factory.name.equals(mostRecent))
  133. mostRecent = null;
  134. if(entry.win != null)
  135. {
  136. dockablePanel.remove(entry.win);
  137. entry.win = null;
  138. }
  139. if(current == entry)
  140. {
  141. current = null;
  142. show(null);
  143. }
  144. else
  145. {
  146. wm.revalidate();
  147. dockablePanel.repaint();
  148. }
  149. } //}}}
  150. //{{{ showMostRecent() method
  151. public void showMostRecent()
  152. {
  153. if(dockables.size() == 0)
  154. {
  155. Toolkit.getDefaultToolkit().beep();
  156. return;
  157. }
  158. if(mostRecent == null)
  159. {
  160. mostRecent = ((DockableWindowManager.Entry)
  161. dockables.get(0)).factory.name;
  162. }
  163. wm.showDockableWindow(mostRecent);
  164. } //}}}
  165. //{{{ show() method
  166. public void show(final DockableWindowManager.Entry entry)
  167. {
  168. if(current == entry)
  169. {
  170. if(entry != null)
  171. {
  172. if(entry.win instanceof DefaultFocusComponent)
  173. {
  174. ((DefaultFocusComponent)entry.win)
  175. .focusOnDefaultComponent();
  176. }
  177. else
  178. {
  179. entry.win.requestDefaultFocus();
  180. }
  181. }
  182. return;
  183. }
  184. if(entry != null)
  185. {
  186. if(current == null)
  187. {
  188. // we didn't have a component previously, so
  189. // create a border
  190. dockablePanel.setBorder(new DockBorder(position));
  191. }
  192. mostRecent = entry.factory.name;
  193. this.current = entry;
  194. if(entry.win.getParent() != dockablePanel)
  195. dockablePanel.add(entry.factory.name,entry.win);
  196. dockablePanel.showDockable(entry.factory.name);
  197. entry.btn.setSelected(true);
  198. if(entry.win instanceof DefaultFocusComponent)
  199. {
  200. ((DefaultFocusComponent)entry.win)
  201. .focusOnDefaultComponent();
  202. }
  203. else
  204. {
  205. entry.win.requestDefaultFocus();
  206. }
  207. }
  208. else
  209. {
  210. current = null;
  211. nullButton.setSelected(true);
  212. // removing last component, so remove border
  213. dockablePanel.setBorder(null);
  214. wm.getView().getTextArea().requestFocus();
  215. }
  216. wm.revalidate();
  217. dockablePanel.repaint();
  218. } //}}}
  219. //{{{ isVisible() method
  220. public boolean isVisible(DockableWindowManager.Entry entry)
  221. {
  222. return current == entry;
  223. } //}}}
  224. //{{{ getCurrent() method
  225. /**
  226. * Returns the name of the dockable in this container.
  227. * @since jEdit 4.2pre1
  228. */
  229. public String getCurrent()
  230. {
  231. if(current == null)
  232. return null;
  233. else
  234. return current.factory.name;
  235. } //}}}
  236. //{{{ getDimension() method
  237. /**
  238. * Returns the width or height (depending on position) of the dockable
  239. * window container.
  240. * @since jEdit 4.2pre1
  241. */
  242. public int getDimension()
  243. {
  244. return dimension;
  245. } //}}}
  246. //{{{ getDockables() method
  247. public String[] getDockables()
  248. {
  249. String[] retVal = new String[dockables.size()];
  250. for(int i = 0; i < dockables.size(); i++)
  251. {
  252. DockableWindowManager.Entry entry =
  253. (DockableWindowManager.Entry) dockables.get(i);
  254. retVal[i] = entry.factory.name;
  255. }
  256. return retVal;
  257. } //}}}
  258. //{{{ Package-private members
  259. static final int SPLITTER_WIDTH = 10;
  260. DockablePanel dockablePanel;
  261. JPanel buttonPanel;
  262. //{{{ save() method
  263. void save()
  264. {
  265. jEdit.setIntegerProperty("view.dock." + position + ".dimension",
  266. dimension);
  267. if(current == null)
  268. jEdit.unsetProperty("view.dock." + position + ".last");
  269. else
  270. {
  271. jEdit.setProperty("view.dock." + position + ".last",
  272. current.factory.name);
  273. }
  274. } //}}}
  275. //{{{ setDimension() method
  276. void setDimension(int dimension)
  277. {
  278. if(dimension != 0)
  279. this.dimension = dimension - SPLITTER_WIDTH;
  280. } //}}}
  281. //{{{ sortDockables() method
  282. void sortDockables()
  283. {
  284. buttonPanel.removeAll();
  285. buttonPanel.add(closeBox);
  286. buttonPanel.add(menuBtn);
  287. Collections.sort(buttons,new DockableWindowCompare());
  288. for(int i = 0; i < buttons.size(); i++)
  289. {
  290. buttonPanel.add((AbstractButton)buttons.get(i));
  291. }
  292. } //}}}
  293. //{{{ getWrappedDimension() method
  294. /**
  295. * Returns the width or height of wrapped rows or columns.
  296. */
  297. int getWrappedDimension(int dimension)
  298. {
  299. return ((ButtonLayout)buttonPanel.getLayout())
  300. .getWrappedDimension(buttonPanel,dimension);
  301. } //}}}
  302. //}}}
  303. //{{{ Private members
  304. private DockableWindowManager wm;
  305. private String position;
  306. private JButton closeBox;
  307. private JButton menuBtn;
  308. private ButtonGroup buttonGroup;
  309. private JToggleButton nullButton;
  310. private int dimension;
  311. private ArrayList dockables;
  312. private ArrayList buttons;
  313. private DockableWindowManager.Entry current;
  314. private JPopupMenu popup;
  315. // remember the most recent dockable
  316. private String mostRecent;
  317. //}}}
  318. //{{{ Inner classes
  319. //{{{ DockableWindowCompare class
  320. static class DockableWindowCompare implements Comparator
  321. {
  322. public int compare(Object o1, Object o2)
  323. {
  324. String name1 = ((AbstractButton)o1).getActionCommand();
  325. String name2 = ((AbstractButton)o2).getActionCommand();
  326. return MiscUtilities.compareStrings(
  327. jEdit.getProperty(name1 + ".title",""),
  328. jEdit.getProperty(name2 + ".title",""),
  329. true);
  330. }
  331. } //}}}
  332. //{{{ ActionHandler class
  333. class ActionHandler implements ActionListener
  334. {
  335. public void actionPerformed(ActionEvent evt)
  336. {
  337. if(popup != null && popup.isVisible())
  338. popup.setVisible(false);
  339. if(evt.getSource() == closeBox)
  340. show(null);
  341. else
  342. {
  343. if(wm.isDockableWindowVisible(evt.getActionCommand()))
  344. show(null);
  345. else
  346. wm.showDockableWindow(evt.getActionCommand());
  347. }
  348. }
  349. } //}}}
  350. //{{{ MenuMouseHandler class
  351. class MenuMouseHandler extends MouseAdapter
  352. {
  353. public void mousePressed(MouseEvent evt)
  354. {
  355. if(popup != null && popup.isVisible())
  356. {
  357. popup.setVisible(false);
  358. return;
  359. }
  360. Component comp = (Component)evt.getSource();
  361. String dockable;
  362. if(comp instanceof JToggleButton)
  363. dockable = ((JToggleButton)comp).getActionCommand();
  364. else
  365. dockable = getCurrent();
  366. if(comp == menuBtn || GUIUtilities.isPopupTrigger(evt))
  367. {
  368. if(dockable == null)
  369. {
  370. popup = wm.createPopupMenu(PanelWindowContainer.this,null,false);
  371. }
  372. else
  373. {
  374. popup = wm.createPopupMenu(PanelWindowContainer.this,dockable,false);
  375. }
  376. int x, y;
  377. boolean point;
  378. if(comp == menuBtn)
  379. {
  380. x = 0;
  381. y = menuBtn.getHeight();
  382. point = false;
  383. }
  384. else
  385. {
  386. x = evt.getX();
  387. y = evt.getY();
  388. point = true;
  389. }
  390. GUIUtilities.showPopupMenu(popup,
  391. comp,x,y,point);
  392. }
  393. }
  394. } //}}}
  395. //{{{ DockBorder class
  396. static class DockBorder implements Border
  397. {
  398. String position;
  399. Insets insets;
  400. Color color1;
  401. Color color2;
  402. Color color3;
  403. //{{{ DockBorder constructor
  404. DockBorder(String position)
  405. {
  406. this.position = position;
  407. insets = new Insets(
  408. position.equals(DockableWindowManager.BOTTOM)
  409. ? SPLITTER_WIDTH : 0,
  410. position.equals(DockableWindowManager.RIGHT)
  411. ? SPLITTER_WIDTH : 0,
  412. position.equals(DockableWindowManager.TOP)
  413. ? SPLITTER_WIDTH : 0,
  414. position.equals(DockableWindowManager.LEFT)
  415. ? SPLITTER_WIDTH : 0);
  416. } //}}}
  417. //{{{ paintBorder() method
  418. public void paintBorder(Component c, Graphics g,
  419. int x, int y, int width, int height)
  420. {
  421. updateColors();
  422. if(color1 == null || color2 == null || color3 == null)
  423. return;
  424. if(position.equals(DockableWindowManager.BOTTOM))
  425. paintHorizBorder(g,x,y,width);
  426. else if(position.equals(DockableWindowManager.RIGHT))
  427. paintVertBorder(g,x,y,height);
  428. else if(position.equals(DockableWindowManager.TOP))
  429. {
  430. paintHorizBorder(g,x,y + height
  431. - SPLITTER_WIDTH,width);
  432. }
  433. else if(position.equals(DockableWindowManager.LEFT))
  434. {
  435. paintVertBorder(g,x + width
  436. - SPLITTER_WIDTH,y,height);
  437. }
  438. } //}}}
  439. //{{{ getBorderInsets() method
  440. public Insets getBorderInsets(Component c)
  441. {
  442. return insets;
  443. } //}}}
  444. //{{{ isBorderOpaque() method
  445. public boolean isBorderOpaque()
  446. {
  447. return false;
  448. } //}}}
  449. //{{{ paintHorizBorder() method
  450. private void paintHorizBorder(Graphics g, int x, int y, int width)
  451. {
  452. g.setColor(color3);
  453. g.fillRect(x,y,width,SPLITTER_WIDTH);
  454. for(int i = 0; i < width / 4 - 1; i++)
  455. {
  456. g.setColor(color1);
  457. g.drawLine(x + i * 4 + 2,y + 3,
  458. x + i * 4 + 2,y + 3);
  459. g.setColor(color2);
  460. g.drawLine(x + i * 4 + 3,y + 4,
  461. x + i * 4 + 3,y + 4);
  462. g.setColor(color1);
  463. g.drawLine(x + i * 4 + 4,y + 5,
  464. x + i * 4 + 4,y + 5);
  465. g.setColor(color2);
  466. g.drawLine(x + i * 4 + 5,y + 6,
  467. x + i * 4 + 5,y + 6);
  468. }
  469. } //}}}
  470. //{{{ paintVertBorder() method
  471. private void paintVertBorder(Graphics g, int x, int y, int height)
  472. {
  473. g.setColor(color3);
  474. g.fillRect(x,y,SPLITTER_WIDTH,height);
  475. for(int i = 0; i < height / 4 - 1; i++)
  476. {
  477. g.setColor(color1);
  478. g.drawLine(x + 3,y + i * 4 + 2,
  479. x + 3,y + i * 4 + 2);
  480. g.setColor(color2);
  481. g.drawLine(x + 4,y + i * 4 + 3,
  482. x + 4,y + i * 4 + 3);
  483. g.setColor(color1);
  484. g.drawLine(x + 5,y + i * 4 + 4,
  485. x + 5,y + i * 4 + 4);
  486. g.setColor(color2);
  487. g.drawLine(x + 6,y + i * 4 + 5,
  488. x + 6,y + i * 4 + 5);
  489. }
  490. } //}}}
  491. //{{{ updateColors() method
  492. private void updateColors()
  493. {
  494. if(UIManager.getLookAndFeel() instanceof MetalLookAndFeel)
  495. {
  496. color1 = MetalLookAndFeel.getControlHighlight();
  497. color2 = MetalLookAndFeel.getControlDarkShadow();
  498. color3 = MetalLookAndFeel.getControl();
  499. }
  500. else
  501. {
  502. color1 = color2 = color3 = null;
  503. }
  504. } //}}}
  505. } //}}}
  506. //{{{ RotatedTextIcon class
  507. public static class RotatedTextIcon implements Icon
  508. {
  509. public static final int NONE = 0;
  510. public static final int CW = 1;
  511. public static final int CCW = 2;
  512. //{{{ RotatedTextIcon constructor
  513. public RotatedTextIcon(int rotate, Font font, String text)
  514. {
  515. this.rotate = rotate;
  516. this.font = font;
  517. FontRenderContext fontRenderContext
  518. = new FontRenderContext(null,true,true);
  519. this.text = text;
  520. glyphs = font.createGlyphVector(fontRenderContext,text);
  521. width = (int)glyphs.getLogicalBounds().getWidth() + 4;
  522. //height = (int)glyphs.getLogicalBounds().getHeight();
  523. LineMetrics lineMetrics = font.getLineMetrics(text,fontRenderContext);
  524. ascent = lineMetrics.getAscent();
  525. height = (int)lineMetrics.getHeight();
  526. renderHints = new RenderingHints(
  527. RenderingHints.KEY_ANTIALIASING,
  528. RenderingHints.VALUE_ANTIALIAS_ON);
  529. renderHints.put(RenderingHints.KEY_FRACTIONALMETRICS,
  530. RenderingHints.VALUE_FRACTIONALMETRICS_ON);
  531. renderHints.put(RenderingHints.KEY_RENDERING,
  532. RenderingHints.VALUE_RENDER_QUALITY);
  533. } //}}}
  534. //{{{ getIconWidth() method
  535. public int getIconWidth()
  536. {
  537. return (int)(rotate == RotatedTextIcon.CW
  538. || rotate == RotatedTextIcon.CCW
  539. ? height : width);
  540. } //}}}
  541. //{{{ getIconHeight() method
  542. public int getIconHeight()
  543. {
  544. return (int)(rotate == RotatedTextIcon.CW
  545. || rotate == RotatedTextIcon.CCW
  546. ? width : height);
  547. } //}}}
  548. //{{{ paintIcon() method
  549. public void paintIcon(Component c, Graphics g, int x, int y)
  550. {
  551. Graphics2D g2d = (Graphics2D)g;
  552. g2d.setFont(font);
  553. AffineTransform oldTransform = g2d.getTransform();
  554. RenderingHints oldHints = g2d.getRenderingHints();
  555. g2d.setRenderingHints(renderHints);
  556. g2d.setColor(c.getForeground());
  557. //{{{ No rotation
  558. if(rotate == RotatedTextIcon.NONE)
  559. {
  560. g2d.drawGlyphVector(glyphs,x + 2,y + ascent);
  561. } //}}}
  562. //{{{ Clockwise rotation
  563. else if(rotate == RotatedTextIcon.CW)
  564. {
  565. AffineTransform trans = new AffineTransform();
  566. trans.concatenate(oldTransform);
  567. trans.translate(x,y + 2);
  568. trans.rotate(Math.PI / 2,
  569. height / 2, width / 2);
  570. g2d.setTransform(trans);
  571. g2d.drawGlyphVector(glyphs,(height - width) / 2,
  572. (width - height) / 2
  573. + ascent);
  574. } //}}}
  575. //{{{ Counterclockwise rotation
  576. else if(rotate == RotatedTextIcon.CCW)
  577. {
  578. AffineTransform trans = new AffineTransform();
  579. trans.concatenate(oldTransform);
  580. trans.translate(x,y - 2);
  581. trans.rotate(Math.PI * 3 / 2,
  582. height / 2, width / 2);
  583. g2d.setTransform(trans);
  584. g2d.drawGlyphVector(glyphs,(height - width) / 2,
  585. (width - height) / 2
  586. + ascent);
  587. } //}}}
  588. g2d.setTransform(oldTransform);
  589. g2d.setRenderingHints(oldHints);
  590. } //}}}
  591. //{{{ Private members
  592. private int rotate;
  593. private Font font;
  594. private String text;
  595. private GlyphVector glyphs;
  596. private float width;
  597. private float height;
  598. private float ascent;
  599. private RenderingHints renderHints;
  600. //}}}
  601. } //}}}
  602. //{{{ ButtonLayout class
  603. class ButtonLayout implements LayoutManager
  604. {
  605. //{{{ addLayoutComponent() method
  606. public void addLayoutComponent(String name, Component comp) {} //}}}
  607. //{{{ removeLayoutComponent() method
  608. public void removeLayoutComponent(Component comp) {} //}}}
  609. //{{{ getWrappedDimension() method
  610. /**
  611. * Returns the width or height of wrapped rows or columns.
  612. */
  613. int getWrappedDimension(JComponent parent, int dimension)
  614. {
  615. Insets insets = ((JComponent)parent).getBorder()
  616. .getBorderInsets((JComponent)parent);
  617. Component[] comp = parent.getComponents();
  618. if(comp.length <= 2)
  619. return 0;
  620. Dimension dim = comp[2].getPreferredSize();
  621. if(position.equals(DockableWindowManager.TOP)
  622. || position.equals(DockableWindowManager.BOTTOM))
  623. {
  624. int width = dimension - insets.right;
  625. int rowHeight = Math.max(dim.height,closeBox.getPreferredSize().width);
  626. int x = rowHeight * 2 + insets.left;
  627. Dimension returnValue = new Dimension(0,rowHeight
  628. + insets.top + insets.bottom);
  629. for(int i = 2; i < comp.length; i++)
  630. {
  631. int btnWidth = comp[i].getPreferredSize().width;
  632. if(btnWidth + x > width)
  633. {
  634. returnValue.height += rowHeight;
  635. x = insets.left;
  636. }
  637. x += btnWidth;
  638. }
  639. return returnValue.height;
  640. }
  641. else
  642. {
  643. int height = dimension - insets.bottom;
  644. int colWidth = Math.max(dim.width,closeBox.getPreferredSize().height);
  645. int y = colWidth * 2 + insets.top;
  646. Dimension returnValue = new Dimension(colWidth
  647. + insets.left + insets.right,0);
  648. for(int i = 2; i < comp.length; i++)
  649. {
  650. int btnHeight = comp[i].getPreferredSize().height;
  651. if(btnHeight + y > height)
  652. {
  653. returnValue.width += colWidth;
  654. y = insets.top;
  655. }
  656. y += btnHeight;
  657. }
  658. return returnValue.width;
  659. }
  660. } //}}}
  661. //{{{ preferredLayoutSize() method
  662. public Dimension preferredLayoutSize(Container parent)
  663. {
  664. Insets insets = ((JComponent)parent).getBorder()
  665. .getBorderInsets((JComponent)parent);
  666. Component[] comp = parent.getComponents();
  667. if(comp.length <= 2)
  668. {
  669. // nothing 'cept close box
  670. return new Dimension(0,0);
  671. }
  672. Dimension dim = comp[2].getPreferredSize();
  673. if(position.equals(DockableWindowManager.TOP)
  674. || position.equals(DockableWindowManager.BOTTOM))
  675. {
  676. int width = parent.getWidth() - insets.right;
  677. int rowHeight = Math.max(dim.height,closeBox.getPreferredSize().width);
  678. int x = rowHeight * 2 + insets.left;
  679. Dimension returnValue = new Dimension(0,rowHeight
  680. + insets.top + insets.bottom);
  681. for(int i = 2; i < comp.length; i++)
  682. {
  683. int btnWidth = comp[i].getPreferredSize().width;
  684. if(btnWidth + x > width)
  685. {
  686. returnValue.height += rowHeight;
  687. x = insets.left;
  688. }
  689. x += btnWidth;
  690. }
  691. return returnValue;
  692. }
  693. else
  694. {
  695. int height = parent.getHeight() - insets.bottom;
  696. int colWidth = Math.max(dim.width,closeBox.getPreferredSize().height);
  697. int y = colWidth * 2 + insets.top;
  698. Dimension returnValue = new Dimension(colWidth
  699. + insets.left + insets.right,0);
  700. for(int i = 2; i < comp.length; i++)
  701. {
  702. int btnHeight = comp[i].getPreferredSize().height;
  703. if(btnHeight + y > height)
  704. {
  705. returnValue.width += colWidth;
  706. y = insets.top;
  707. }
  708. y += btnHeight;
  709. }
  710. return returnValue;
  711. }
  712. } //}}}
  713. //{{{ minimumLayoutSize() method
  714. public Dimension minimumLayoutSize(Container parent)
  715. {
  716. return preferredLayoutSize(parent);
  717. } //}}}
  718. //{{{ layoutContainer() method
  719. public void layoutContainer(Container parent)
  720. {
  721. Insets insets = ((JComponent)parent).getBorder()
  722. .getBorderInsets((JComponent)parent);
  723. Component[] comp = parent.getComponents();
  724. if(comp.length <= 2)
  725. {
  726. for(int i = 0; i < comp.length; i++)
  727. {
  728. comp[i].setVisible(false);
  729. }
  730. return;
  731. }
  732. comp[0].setVisible(true);
  733. comp[1].setVisible(true);
  734. Dimension dim = comp[2].getPreferredSize();
  735. if(position.equals(DockableWindowManager.TOP)
  736. || position.equals(DockableWindowManager.BOTTOM))
  737. {
  738. int width = parent.getWidth() - insets.right;
  739. int rowHeight = Math.max(dim.height,closeBox.getPreferredSize().width);
  740. int x = rowHeight * 2 + insets.left;
  741. int y = insets.top;
  742. closeBox.setBounds(insets.left,insets.top,rowHeight,rowHeight);
  743. menuBtn.setBounds(insets.left + rowHeight,insets.top,rowHeight,rowHeight);
  744. for(int i = 2; i < comp.length; i++)
  745. {
  746. int btnWidth = comp[i].getPreferredSize().width;
  747. if(btnWidth + x > width)
  748. {
  749. x = insets.left;
  750. y += rowHeight;
  751. }
  752. comp[i].setBounds(x,y,btnWidth,rowHeight);
  753. x += btnWidth;
  754. }
  755. /* if(y + rowHeight != parent.getHeight())
  756. {
  757. parent.setSize(
  758. parent.getWidth(),
  759. y + rowHeight);
  760. ((JComponent)parent).revalidate();
  761. } */
  762. }
  763. else
  764. {
  765. int height = parent.getHeight() - insets.bottom;
  766. int colWidth = Math.max(dim.width,closeBox.getPreferredSize().height);
  767. int x = insets.left;
  768. int y = colWidth * 2 + insets.top;
  769. closeBox.setBounds(insets.left,insets.top,colWidth,colWidth);
  770. menuBtn.setBounds(insets.left,insets.top + colWidth,colWidth,colWidth);
  771. for(int i = 2; i < comp.length; i++)
  772. {
  773. int btnHeight = comp[i].getPreferredSize().height;
  774. if(btnHeight + y > height)
  775. {
  776. x += colWidth;
  777. y = insets.top;
  778. }
  779. comp[i].setBounds(x,y,colWidth,btnHeight);
  780. y += btnHeight;
  781. }
  782. /* if(x + colWidth != parent.getWidth())
  783. {
  784. parent.setSize(x + colWidth,
  785. parent.getHeight());
  786. ((JComponent)parent).revalidate();
  787. } */
  788. }
  789. } //}}}
  790. } //}}}
  791. //{{{ DockablePanel class
  792. class DockablePanel extends JPanel
  793. {
  794. //{{{ DockablePanel constructor
  795. DockablePanel()
  796. {
  797. super(new CardLayout());
  798. ResizeMouseHandler resizeMouseHandler = new ResizeMouseHandler();
  799. addMouseListener(resizeMouseHandler);
  800. addMouseMotionListener(resizeMouseHandler);
  801. } //}}}
  802. //{{{ getWindowContainer() method
  803. PanelWindowContainer getWindowContainer()
  804. {
  805. return PanelWindowContainer.this;
  806. } //}}}
  807. //{{{ showDockable() method
  808. void showDockable(String name)
  809. {
  810. ((CardLayout)getLayout()).show(this,name);
  811. } //}}}
  812. //{{{ getMinimumSize() method
  813. public Dimension getMinimumSize()
  814. {
  815. return new Dimension(0,0);
  816. } //}}}
  817. //{{{ getPreferredSize() method
  818. public Dimension getPreferredSize()
  819. {
  820. if(current == null)
  821. return new Dimension(0,0);
  822. else
  823. {
  824. if(position.equals(DockableWindowManager.TOP)
  825. || position.equals(DockableWindowManager.BOTTOM))
  826. {
  827. if(dimension <= 0)
  828. {
  829. int height = super.getPreferredSize().height;
  830. dimension = height - SPLITTER_WIDTH;
  831. }
  832. return new Dimension(0,
  833. dimension + SPLITTER_WIDTH);
  834. }
  835. else
  836. {
  837. if(dimension <= 0)
  838. {
  839. int width = super.getPreferredSize().width;
  840. dimension = width - SPLITTER_WIDTH;
  841. }
  842. return new Dimension(dimension + SPLITTER_WIDTH,
  843. 0);
  844. }
  845. }
  846. } //}}}
  847. //{{{ setBounds() method
  848. public void setBounds(int x, int y, int width, int height)
  849. {
  850. if(position.equals(DockableWindowManager.TOP) ||
  851. position.equals(DockableWindowManager.BOTTOM))
  852. {
  853. if(dimension != 0 && height <= SPLITTER_WIDTH)
  854. PanelWindowContainer.this.show(null);
  855. else
  856. dimension = height - SPLITTER_WIDTH;
  857. }
  858. else
  859. {
  860. if(dimension != 0 && width <= SPLITTER_WIDTH)
  861. PanelWindowContainer.this.show(null);
  862. else
  863. dimension = width - SPLITTER_WIDTH;
  864. }
  865. super.setBounds(x,y,width,height);
  866. } //}}}
  867. //{{{ ResizeMouseHandler class
  868. class ResizeMouseHandler extends MouseAdapter implements MouseMotionListener
  869. {
  870. boolean canDrag;
  871. Point dragStart;
  872. //{{{ mousePressed() method
  873. public void mousePressed(MouseEvent evt)
  874. {
  875. if(canDrag)
  876. {
  877. wm.setResizePos(dimension,PanelWindowContainer.this);
  878. dragStart = evt.getPoint();
  879. }
  880. } //}}}
  881. //{{{ mouseReleased() method
  882. public void mouseReleased(MouseEvent evt)
  883. {
  884. if(canDrag)
  885. {
  886. dimension = wm.resizePos;
  887. wm.finishResizing();
  888. dragStart = null;
  889. wm.revalidate();
  890. }
  891. } //}}}
  892. //{{{ mouseMoved() method
  893. public void mouseMoved(MouseEvent evt)
  894. {
  895. Border border = getBorder();
  896. if(border == null)
  897. {
  898. // collapsed
  899. return;
  900. }
  901. Insets insets = border.getBorderInsets(DockablePanel.this);
  902. canDrag = false;
  903. //{{{ Top...
  904. if(position.equals(DockableWindowManager.TOP))
  905. {
  906. if(evt.getY() >= getHeight() - insets.bottom)
  907. canDrag = true;
  908. } //}}}
  909. //{{{ Left...
  910. else if(position.equals(DockableWindowManager.LEFT))
  911. {
  912. if(evt.getX() >= getWidth() - insets.right)
  913. canDrag = true;
  914. } //}}}
  915. //{{{ Bottom...
  916. else if(position.equals(DockableWindowManager.BOTTOM))
  917. {
  918. if(evt.getY() <= insets.top)
  919. canDrag = true;
  920. } //}}}
  921. //{{{ Right...
  922. else if(position.equals(DockableWindowManager.RIGHT))
  923. {
  924. if(evt.getX() <= insets.left)
  925. canDrag = true;
  926. } //}}}
  927. if(canDrag)
  928. {
  929. wm.setCursor(Cursor.getPredefinedCursor(
  930. getAppropriateCursor()));
  931. }
  932. else
  933. {
  934. wm.setCursor(Cursor.getPredefinedCursor(
  935. Cursor.DEFAULT_CURSOR));
  936. }
  937. } //}}}
  938. //{{{ mouseDragged() method
  939. public void mouseDragged(MouseEvent evt)
  940. {
  941. if(!canDrag)
  942. return;
  943. if(dragStart == null) // can't happen?
  944. return;
  945. wm.setCursor(Cursor.getPredefinedCursor(
  946. getAppropriateCursor()));
  947. //{{{ Top...
  948. if(position.equals(DockableWindowManager.TOP))
  949. {
  950. wm.setResizePos(
  951. evt.getY() - dragStart.y
  952. + dimension,
  953. PanelWindowContainer.this);
  954. } //}}}
  955. //{{{ Left...
  956. else if(position.equals(DockableWindowManager.LEFT))
  957. {
  958. wm.setResizePos(evt.getX() - dragStart.x
  959. + dimension,
  960. PanelWindowContainer.this);
  961. } //}}}
  962. //{{{ Bottom...
  963. else if(position.equals(DockableWindowManager.BOTTOM))
  964. {
  965. wm.setResizePos(dimension - evt.getY()
  966. + dragStart.y,
  967. PanelWindowContainer.this);
  968. } //}}}
  969. //{{{ Right...
  970. else if(position.equals(DockableWindowManager.RIGHT))
  971. {
  972. wm.setResizePos(dimension - evt.getX()
  973. + dragStart.x,
  974. PanelWindowContainer.this);
  975. } //}}}
  976. } //}}}
  977. //{{{ mouseExited() method
  978. public void mouseExited(MouseEvent evt)
  979. {
  980. wm.setCursor(Cursor.getPredefinedCursor(
  981. Cursor.DEFAULT_CURSOR));
  982. } //}}}
  983. //{{{ getCursor() method
  984. private int getAppropriateCursor()
  985. {
  986. if(position.equals(DockableWindowManager.TOP))
  987. return Cursor.N_RESIZE_CURSOR;
  988. else if(position.equals(DockableWindowManager.LEFT))
  989. return Cursor.W_RESIZE_CURSOR;
  990. else if(position.equals(DockableWindowManager.BOTTOM))
  991. return Cursor.S_RESIZE_CURSOR;
  992. else if(position.equals(DockableWindowManager.RIGHT))
  993. return Cursor.E_RESIZE_CURSOR;
  994. else
  995. throw new InternalError();
  996. } //}}}
  997. } //}}}
  998. } //}}}
  999. //}}}
  1000. }