/plugins/MyDoggyPlugin/tags/rel_0_2/src/myDoggy/MyDoggyWindowManager.java

# · Java · 604 lines · 546 code · 54 blank · 4 comment · 84 complexity · ae333776ba1c604e1f5d0accbd008f7a MD5 · raw file

  1. package myDoggy;
  2. import java.awt.BorderLayout;
  3. import java.awt.Component;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.MouseAdapter;
  6. import java.awt.event.MouseEvent;
  7. import java.beans.PropertyChangeEvent;
  8. import java.beans.PropertyChangeListener;
  9. import java.io.File;
  10. import java.io.FileInputStream;
  11. import java.io.FileNotFoundException;
  12. import java.io.IOException;
  13. import javax.swing.Icon;
  14. import javax.swing.JComponent;
  15. import javax.swing.JLabel;
  16. import javax.swing.JPanel;
  17. import javax.swing.SwingUtilities;
  18. import javax.swing.UIManager;
  19. import org.gjt.sp.jedit.EditBus;
  20. import org.gjt.sp.jedit.View;
  21. import org.gjt.sp.jedit.View.ViewConfig;
  22. import org.gjt.sp.jedit.gui.DockableWindowFactory;
  23. import org.gjt.sp.jedit.gui.DockableWindowManager;
  24. import org.gjt.sp.jedit.msg.DockableWindowUpdate;
  25. import org.noos.xing.mydoggy.Content;
  26. import org.noos.xing.mydoggy.DockedTypeDescriptor;
  27. import org.noos.xing.mydoggy.FloatingTypeDescriptor;
  28. import org.noos.xing.mydoggy.PersistenceDelegateCallback;
  29. import org.noos.xing.mydoggy.PushAwayMode;
  30. import org.noos.xing.mydoggy.ToolWindow;
  31. import org.noos.xing.mydoggy.ToolWindowAction;
  32. import org.noos.xing.mydoggy.ToolWindowAnchor;
  33. import org.noos.xing.mydoggy.ToolWindowBar;
  34. import org.noos.xing.mydoggy.ToolWindowManager;
  35. import org.noos.xing.mydoggy.ToolWindowType;
  36. import org.noos.xing.mydoggy.PersistenceDelegate.MergePolicy;
  37. import org.noos.xing.mydoggy.plaf.MyDoggyToolWindowManager;
  38. import org.noos.xing.mydoggy.plaf.ui.CustomDockableDescriptor;
  39. import org.noos.xing.mydoggy.plaf.ui.DockableDescriptor;
  40. import org.noos.xing.mydoggy.plaf.ui.MyDoggyKeySpace;
  41. @SuppressWarnings("serial")
  42. public class MyDoggyWindowManager extends DockableWindowManager {
  43. private MyDoggyToolWindowManager wm = null;
  44. private boolean addAnchorButtons = true;
  45. private class ToggleBarDockableDescriptor extends CustomDockableDescriptor
  46. {
  47. public ToggleBarDockableDescriptor(MyDoggyToolWindowManager manager,
  48. ToolWindowAnchor anchor)
  49. {
  50. super(manager, anchor);
  51. setAvailable(true);
  52. setAnchor(anchor, 0);
  53. setAnchorPositionLocked(true);
  54. }
  55. @Override
  56. public boolean isAvailableCountable() {
  57. return false;
  58. }
  59. public JComponent getRepresentativeAnchor(Component parent) {
  60. if (representativeAnchor == null) {
  61. representativeAnchor = new ToggleBarButton(manager.getToolWindowBar(anchor));
  62. }
  63. return representativeAnchor;
  64. }
  65. public void updateRepresentativeAnchor() {
  66. }
  67. private class ToggleBarButton extends JLabel
  68. {
  69. ToolWindowBar twb;
  70. public ToggleBarButton(ToolWindowBar bar)
  71. {
  72. twb = bar;
  73. if (twb == null)
  74. return;
  75. setIcon();
  76. addMouseListener(new MouseAdapter() {
  77. @Override
  78. public void mouseClicked(MouseEvent e) {
  79. if (twb != null)
  80. twb.setVisible(! twb.isVisible());
  81. }
  82. });
  83. twb.addPropertyChangeListener("visible", new PropertyChangeListener() {
  84. public void propertyChange(PropertyChangeEvent evt) {
  85. setIcon();
  86. }
  87. });
  88. }
  89. void setIcon()
  90. {
  91. Icon icon;
  92. if (twb.isVisible())
  93. icon = UIManager.getIcon(MyDoggyKeySpace.CONTENT_PAGE_CLOSE);
  94. else
  95. icon = UIManager.getIcon(MyDoggyKeySpace.CONTENT_PAGE_MAXIMIZE);
  96. setIcon(icon);
  97. }
  98. public DockableDescriptor getDockableDescriptor() {
  99. return ToggleBarDockableDescriptor.this;
  100. }
  101. }
  102. }
  103. public MyDoggyWindowManager(View view, DockableWindowFactory instance,
  104. ViewConfig config)
  105. {
  106. super(view, instance, config);
  107. UIManager.put(MyDoggyKeySpace.DEBUG, false);
  108. setLayout(new BorderLayout());
  109. wm = new MyDoggyToolWindowManager();
  110. wm.getTypeDescriptorTemplate(ToolWindowType.DOCKED).setAnimating(
  111. OptionPane.getEnableAnimationsProp());
  112. add(wm, BorderLayout.CENTER);
  113. }
  114. @Override
  115. protected void dockableLoaded(String name, String position)
  116. {
  117. if (position == null || position.equals(DockableWindowManager.FLOATING))
  118. return;
  119. ToolWindow tw = createFakeToolWindow(name);
  120. tw.setAvailable(true);
  121. }
  122. @Override
  123. protected void dockingPositionChanged(String name,
  124. String oldPosition, String newPosition)
  125. {
  126. showDockableWindow(name);
  127. ToolWindow tw = getToolWindow(name);
  128. if (tw != null)
  129. {
  130. ToolWindowAnchor anchor = position2anchor(getDockablePosition(name));
  131. if (anchor != tw.getAnchor())
  132. tw.setAnchor(anchor);
  133. }
  134. }
  135. @Override
  136. public void closeCurrentArea()
  137. {
  138. Object activeWindowId = wm.getActiveToolWindowId();
  139. if (activeWindowId == null)
  140. return;
  141. ToolWindow tw = wm.getToolWindow(activeWindowId);
  142. if (tw == null)
  143. return;
  144. ToolWindowAnchor anchor = tw.getAnchor();
  145. if (anchor != null)
  146. wm.getToolWindowBar(anchor).setVisible(false);
  147. }
  148. @Override
  149. public JComponent floatDockableWindow(String name)
  150. {
  151. ToolWindow tw = wm.getToolWindow(name);
  152. if (tw == null)
  153. tw = createToolWindow(name);
  154. if (tw == null)
  155. return null;
  156. tw.setType(ToolWindowType.FLOATING);
  157. tw.setActive(true);
  158. return (JComponent) tw.getComponent();
  159. }
  160. @Override
  161. public DockingLayout getDockingLayout(ViewConfig config)
  162. {
  163. MyDoggyDockingLayout layout = new MyDoggyDockingLayout(wm);
  164. return layout;
  165. }
  166. private String getToolWindowID(String dockableName)
  167. {
  168. return dockableName;
  169. }
  170. private ToolWindow getToolWindow(String dockableName)
  171. {
  172. return wm.getToolWindow(getToolWindowID(dockableName));
  173. }
  174. @Override
  175. public void hideDockableWindow(String name)
  176. {
  177. ToolWindow tw = getToolWindow(name);
  178. if (tw == null)
  179. return;
  180. tw.setVisible(false);
  181. EditBus.send(new DockableWindowUpdate(this, DockableWindowUpdate.DEACTIVATED,
  182. name));
  183. if (tw.getType() == ToolWindowType.DOCKED ||
  184. tw.getType() == ToolWindowType.SLIDING)
  185. {
  186. // See if another window has become active
  187. tw = getCurrentToolWindow(tw.getAnchor());
  188. if (tw != null)
  189. EditBus.send(new DockableWindowUpdate(this,
  190. DockableWindowUpdate.ACTIVATED, tw.getId()));
  191. }
  192. }
  193. @Override
  194. public boolean isDockableWindowDocked(String name)
  195. {
  196. ToolWindow tw = getToolWindow(name);
  197. if (tw == null)
  198. return false;
  199. return (tw.getType() == ToolWindowType.DOCKED);
  200. }
  201. @Override
  202. public boolean isDockableWindowVisible(String name)
  203. {
  204. ToolWindow tw = getToolWindow(name);
  205. if (tw == null)
  206. return false;
  207. return (tw.isVisible());
  208. }
  209. private void loadMyDoggyLayout(String filename)
  210. {
  211. FileInputStream inputStream;
  212. try {
  213. inputStream = new FileInputStream(filename);
  214. PersistenceDelegateCallback callback = new PersistenceCallback();
  215. wm.getPersistenceDelegate().merge(inputStream, MergePolicy.RESET, callback);
  216. inputStream.close();
  217. } catch (FileNotFoundException e) {
  218. e.printStackTrace();
  219. } catch (IOException e) {
  220. e.printStackTrace();
  221. }
  222. }
  223. @Override
  224. public void applyDockingLayout(DockingLayout docking)
  225. {
  226. // 'docking' is null if jEdit was started without a perspective file
  227. boolean loaded = false;
  228. if (docking != null)
  229. {
  230. MyDoggyDockingLayout layout = (MyDoggyDockingLayout) docking;
  231. String filename = layout.getLayoutFilename();
  232. if (filename != null) {
  233. java.io.File f = new File(filename);
  234. if (f.exists()) {
  235. loadMyDoggyLayout(filename);
  236. loaded = true;
  237. }
  238. }
  239. }
  240. if (! loaded) // No saved layout - just use the docking positions specified by jEdit properties
  241. super.applyDockingLayout(null);
  242. if (addAnchorButtons) {
  243. new ToggleBarDockableDescriptor(wm, ToolWindowAnchor.TOP);
  244. new ToggleBarDockableDescriptor(wm, ToolWindowAnchor.BOTTOM);
  245. new ToggleBarDockableDescriptor(wm, ToolWindowAnchor.LEFT);
  246. new ToggleBarDockableDescriptor(wm, ToolWindowAnchor.RIGHT);
  247. addAnchorButtons = false;
  248. }
  249. }
  250. public class PersistenceCallback implements PersistenceDelegateCallback
  251. {
  252. public Content contentNotFound(ToolWindowManager toolWindowManager,
  253. String contentId, PersistenceNode node) {
  254. return null;
  255. }
  256. public ToolWindow toolwindowNotFound(
  257. ToolWindowManager toolWindowManager, String toolWindowId,
  258. PersistenceNode node) {
  259. if (! node.getBoolean("visible", true))
  260. return createFakeToolWindow(toolWindowId);
  261. return createToolWindow(toolWindowId);
  262. }
  263. public String validate(PersistenceNode node, String attribute,
  264. String attributeValue, Object attributeDefaultValue) {
  265. return attributeValue;
  266. }
  267. }
  268. private ToolWindow createFakeToolWindow(String name)
  269. {
  270. JComponent window = new JPanel(new BorderLayout());
  271. if (window == null)
  272. return null;
  273. String title = getDockableTitle(name);
  274. String position = getDockablePosition(name);
  275. String id = getToolWindowID(name);
  276. ToolWindowAnchor anchor = position2anchor(position);
  277. ToolWindow tw = wm.registerToolWindow(id, title, null, window, anchor);
  278. initToolWindowsDescriptors(name, tw);
  279. PropertyChangeListener listener = new VisibilityChangeListener(tw, name,
  280. window, true);
  281. tw.addPropertyChangeListener("visible", listener);
  282. tw.getRepresentativeAnchorDescriptor().setPreviewEnabled(OptionPane.getEnablePreviewProp());
  283. return tw;
  284. }
  285. private class VisibilityChangeListener implements PropertyChangeListener
  286. {
  287. ToolWindow tw;
  288. String name;
  289. JComponent window;
  290. boolean fake;
  291. public VisibilityChangeListener(ToolWindow tw, String name,
  292. JComponent window, boolean fake)
  293. {
  294. this.tw = tw;
  295. this.name = name;
  296. this.window = window;
  297. this.fake = fake;
  298. }
  299. public void propertyChange(PropertyChangeEvent evt)
  300. {
  301. if (fake)
  302. {
  303. if (! tw.isVisible())
  304. return;
  305. JComponent comp = createDockable(name);
  306. window.add(comp, BorderLayout.CENTER);
  307. fake = false;
  308. }
  309. Object reason = tw.isVisible() ? DockableWindowUpdate.ACTIVATED :
  310. DockableWindowUpdate.DEACTIVATED;
  311. EditBus.send(new DockableWindowUpdate(MyDoggyWindowManager.this,
  312. reason, name));
  313. }
  314. }
  315. private ToolWindow createToolWindow(String name)
  316. {
  317. JComponent window = getDockable(name);
  318. String position = getDockablePosition(name);
  319. if (window == null)
  320. window = createDockable(name);
  321. if (window == null)
  322. return null;
  323. String id = getToolWindowID(name);
  324. String title = getDockableTitle(name);
  325. ToolWindowAnchor anchor = position2anchor(position);
  326. ToolWindow tw = wm.registerToolWindow(id, title, null, window, anchor);
  327. initToolWindowsDescriptors(name, tw);
  328. PropertyChangeListener listener = new VisibilityChangeListener(tw,
  329. name, window, false);
  330. tw.addPropertyChangeListener("visible", listener);
  331. return tw;
  332. }
  333. private void initToolWindowsDescriptors(String name, ToolWindow tw) {
  334. tw.getRepresentativeAnchorDescriptor().setTitle(shortTitle(name));
  335. tw.getTypeDescriptor(ToolWindowType.DOCKED).setIdVisibleOnTitleBar(false);
  336. DockedTypeDescriptor dockedDescriptor = tw.getTypeDescriptor(DockedTypeDescriptor.class);
  337. dockedDescriptor.addToolWindowAction(new FloatingFreeAction());
  338. dockedDescriptor.addToolWindowAction(new RemoveDockableAction(), 0);
  339. setFloatingProperties(tw);
  340. tw.getRepresentativeAnchorDescriptor().setPreviewEnabled(OptionPane.getEnablePreviewProp());
  341. }
  342. private void setFloatingProperties(ToolWindow tw) {
  343. setFloatingDescriptorProperties((FloatingTypeDescriptor) tw.getTypeDescriptor(ToolWindowType.FLOATING));
  344. setFloatingDescriptorProperties((FloatingTypeDescriptor) tw.getTypeDescriptor(ToolWindowType.FLOATING_FREE));
  345. }
  346. private void setFloatingDescriptorProperties(FloatingTypeDescriptor floatDescriptor) {
  347. floatDescriptor.setAlwaysOnTop(OptionPane.getFloatOnTopProp());
  348. floatDescriptor.setOsDecorated(OptionPane.getFloatOsDecorationsProp());
  349. floatDescriptor.setAddToTaskBar(OptionPane.getFloatAddToTaskBarProp());
  350. floatDescriptor.addToolWindowAction(new RemoveDockableAction(), 0);
  351. }
  352. private static abstract class DockableAction extends ToolWindowAction {
  353. public DockableAction(String name, Icon icon, String text, String tooltip) {
  354. super(name, icon);
  355. setText(text);
  356. setTooltipText(tooltip);
  357. setVisibleOnMenuBar(true);
  358. setVisibleOnTitleBar(true);
  359. setVisible(true);
  360. }
  361. }
  362. private static class RemoveDockableAction extends DockableAction {
  363. public RemoveDockableAction() {
  364. super("RemoveDockableAction",
  365. UIManager.getIcon(MyDoggyKeySpace.HIDE_TOOL_WINDOW),
  366. "Remove", "Remove dockable completely");
  367. }
  368. public void actionPerformed(ActionEvent e) {
  369. ToolWindowManager wm = getToolWindow().getDockableManager();
  370. String id = getToolWindow().getId();
  371. wm.unregisterToolWindow(id);
  372. }
  373. }
  374. private static class FloatingFreeAction extends DockableAction {
  375. public FloatingFreeAction() {
  376. super("FloatingFreeAction",
  377. UIManager.getIcon(MyDoggyKeySpace.FLOATING_INACTIVE),
  378. "Floating free", "Floating free (without an anchor button)");
  379. }
  380. @Override
  381. public void setToolWindow(final ToolWindow toolWindow) {
  382. super.setToolWindow(toolWindow);
  383. toolWindow.addPropertyChangeListener("type", new PropertyChangeListener() {
  384. public void propertyChange(PropertyChangeEvent evt) {
  385. if (evt.getOldValue() == ToolWindowType.FLOATING) {
  386. toolWindow.getRepresentativeAnchorDescriptor().setVisible(true);
  387. }
  388. }
  389. });
  390. }
  391. public void actionPerformed(ActionEvent e) {
  392. toolWindow.getRepresentativeAnchorDescriptor().setVisible(false);
  393. toolWindow.setType(ToolWindowType.FLOATING);
  394. }
  395. }
  396. @Override
  397. public void showDockableWindow(String name)
  398. {
  399. ToolWindow tw = getToolWindow(name);
  400. if (tw != null)
  401. {
  402. activateToolWindow(tw);
  403. return;
  404. }
  405. tw = createToolWindow(name);
  406. if (DockableWindowManager.FLOATING.equals(getDockablePosition(name)))
  407. tw.setType(ToolWindowType.FLOATING_FREE);
  408. else
  409. tw.setType(ToolWindowType.DOCKED);
  410. activateToolWindow(tw);
  411. }
  412. private void activateToolWindow(ToolWindow tw)
  413. {
  414. ToolWindowAnchor anchor = tw.getAnchor();
  415. if (anchor != null)
  416. {
  417. ToolWindowBar bar = wm.getToolWindowBar(anchor);
  418. if (! bar.isVisible())
  419. bar.setVisible(true);
  420. }
  421. // If another window is currently active, it is becoming deactivated
  422. ToolWindow current = getCurrentToolWindow(anchor);
  423. if (current != null && current != tw)
  424. EditBus.send(new DockableWindowUpdate(this, DockableWindowUpdate.DEACTIVATED,
  425. current.getId()));
  426. tw.setActive(true);
  427. final ToolWindow twToFocus = tw;
  428. SwingUtilities.invokeLater(new Runnable()
  429. {
  430. public void run()
  431. {
  432. focusDockable(twToFocus.getId());
  433. EditBus.send(new DockableWindowUpdate(MyDoggyWindowManager.this,
  434. DockableWindowUpdate.ACTIVATED, twToFocus.getId()));
  435. }
  436. });
  437. }
  438. private ToolWindowAnchor position2anchor(String position)
  439. {
  440. if (position.equals(DockableWindowManager.LEFT))
  441. return ToolWindowAnchor.LEFT;
  442. if (position.equals(DockableWindowManager.TOP))
  443. return ToolWindowAnchor.TOP;
  444. if (position.equals(DockableWindowManager.RIGHT))
  445. return ToolWindowAnchor.RIGHT;
  446. return ToolWindowAnchor.BOTTOM;
  447. }
  448. @Override
  449. public void setMainPanel(JPanel panel)
  450. {
  451. wm.getContentManager().addContent("main", "main", null, panel);
  452. }
  453. public class MyDoggyDockingArea implements DockingArea {
  454. ToolWindowAnchor anchor;
  455. public MyDoggyDockingArea(ToolWindowAnchor anchor) {
  456. this.anchor = anchor;
  457. }
  458. public void showMostRecent() {
  459. wm.getToolWindowBar(anchor).setVisible(true);
  460. }
  461. private ToolWindow getCurrentToolWindow() {
  462. return MyDoggyWindowManager.this.getCurrentToolWindow(anchor);
  463. }
  464. public String getCurrent() {
  465. ToolWindow current = getCurrentToolWindow();
  466. if (current == null)
  467. return null;
  468. return current.getId();
  469. }
  470. public void show(String name) {
  471. ToolWindow tw;
  472. if (name == null)
  473. { // Hide the visible windows in this area
  474. wm.getToolWindowBar(anchor).setVisible(false);
  475. }
  476. else
  477. { // Show the window
  478. showDockableWindow(name);
  479. tw = getToolWindow(name);
  480. if (tw != null)
  481. tw.setAnchor(anchor);
  482. }
  483. }
  484. public String[] getDockables() {
  485. ToolWindow[] tools = wm.getToolsByAnchor(anchor);
  486. String [] docked = new String[tools.length];
  487. for (int i = 0; i < tools.length; i++)
  488. docked[i] = tools[i].getId();
  489. return docked;
  490. }
  491. }
  492. public ToolWindow getCurrentToolWindow(ToolWindowAnchor anchor)
  493. {
  494. ToolWindow[] tools = wm.getToolsByAnchor(anchor);
  495. for (ToolWindow tw: tools)
  496. if (tw.isActive())
  497. return tw;
  498. for (ToolWindow tw: tools)
  499. if (tw.isVisible())
  500. return tw;
  501. return null;
  502. }
  503. public DockingArea getBottomDockingArea() {
  504. return new MyDoggyDockingArea(ToolWindowAnchor.BOTTOM);
  505. }
  506. public DockingArea getLeftDockingArea() {
  507. return new MyDoggyDockingArea(ToolWindowAnchor.LEFT);
  508. }
  509. public DockingArea getRightDockingArea() {
  510. return new MyDoggyDockingArea(ToolWindowAnchor.RIGHT);
  511. }
  512. public DockingArea getTopDockingArea() {
  513. return new MyDoggyDockingArea(ToolWindowAnchor.TOP);
  514. }
  515. @Override
  516. protected void propertiesChanged() {
  517. super.propertiesChanged();
  518. setPushAwayMode();
  519. wm.getTypeDescriptorTemplate(ToolWindowType.DOCKED).setAnimating(
  520. OptionPane.getEnableAnimationsProp());
  521. // Update floating properties
  522. ToolWindow[] windows = wm.getToolWindows();
  523. for (ToolWindow w: windows) {
  524. setFloatingProperties(w);
  525. w.getRepresentativeAnchorDescriptor().setPreviewEnabled(OptionPane.getEnablePreviewProp());
  526. }
  527. }
  528. private void setPushAwayMode() {
  529. if (! OptionPane.getUseAlternateLayoutProp())
  530. wm.getToolWindowManagerDescriptor().setPushAwayMode(OptionPane.getPushAwayModeProp());
  531. else
  532. wm.getToolWindowManagerDescriptor().setPushAwayMode(getAlternateLayoutProp() ?
  533. PushAwayMode.VERTICAL : PushAwayMode.HORIZONTAL);
  534. }
  535. @Override
  536. public void dockableTitleChanged(String dockable, String newTitle) {
  537. ToolWindow tw = getToolWindow(dockable);
  538. if (tw != null)
  539. tw.setTitle(newTitle);
  540. }
  541. @Override
  542. protected void applyAlternateLayout(boolean alternateLayout) {
  543. setPushAwayMode();
  544. }
  545. public void disposeDockableWindow(String name) {
  546. ToolWindow tw = getToolWindow(name);
  547. if (tw != null)
  548. wm.unregisterToolWindow(name);
  549. }
  550. }