KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > gui > DockableWindowManager


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

22
23 package org.gjt.sp.jedit.gui;
24
25 //{{{ Imports
26
import java.awt.Color JavaDoc;
27 import java.awt.Component JavaDoc;
28 import java.awt.Graphics JavaDoc;
29 import java.awt.Rectangle JavaDoc;
30 import java.awt.event.ActionEvent JavaDoc;
31 import java.awt.event.ActionListener JavaDoc;
32 import java.awt.event.KeyAdapter JavaDoc;
33 import java.awt.event.KeyEvent JavaDoc;
34 import java.awt.event.KeyListener JavaDoc;
35 import java.util.*;
36
37 import javax.swing.AbstractButton JavaDoc;
38 import javax.swing.JComponent JavaDoc;
39 import javax.swing.JMenuItem JavaDoc;
40 import javax.swing.JPanel JavaDoc;
41 import javax.swing.JPopupMenu JavaDoc;
42 import javax.swing.SwingUtilities JavaDoc;
43
44 import org.gjt.sp.jedit.EBComponent;
45 import org.gjt.sp.jedit.EBMessage;
46 import org.gjt.sp.jedit.EditBus;
47 import org.gjt.sp.jedit.PluginJAR;
48 import org.gjt.sp.jedit.View;
49 import org.gjt.sp.jedit.jEdit;
50 import org.gjt.sp.jedit.gui.KeyEventTranslator.Key;
51 import org.gjt.sp.jedit.msg.DockableWindowUpdate;
52 import org.gjt.sp.jedit.msg.PluginUpdate;
53 import org.gjt.sp.jedit.msg.PropertiesChanged;
54 import org.gjt.sp.util.Log;
55 //}}}
56

57 /**
58  * The <code>DockableWindowManager</code> keeps track of dockable windows.
59  * Each {@link org.gjt.sp.jedit.View} has an instance of this class.<p>
60  *
61  * <b>dockables.xml:</b><p>
62  *
63  * Dockable window definitions are read from <code>dockables.xml</code> files
64  * contained inside plugin JARs. A dockable definition file has the following
65  * form:
66  *
67  * <pre>&lt;?xml version="1.0"?&gt;
68  *&lt;!DOCTYPE DOCKABLES SYSTEM "dockables.dtd"&gt;
69  *&lt;DOCKABLES&gt;
70  * &lt;DOCKABLE NAME="<i>dockableName</i>"&gt;
71  * // Code to create the dockable
72  * &lt;/DOCKABLE&gt;
73  *&lt;/DOCKABLES&gt;</pre>
74  *
75  * More than one <code>&lt;DOCKABLE&gt;<code> tag may be present. The code that
76  * creates the dockable can reference any BeanShell built-in variable
77  * (see {@link org.gjt.sp.jedit.BeanShell}), along with a variable
78  * <code>position</code> whose value is one of
79  * {@link #FLOATING}, {@link #TOP}, {@link #LEFT}, {@link #BOTTOM},
80  * and {@link #RIGHT}.<p>
81  *
82  * The following properties must be defined for each dockable window:
83  *
84  * <ul>
85  * <li><code><i>dockableName</i>.title</code> - the string to show on the dockable
86  * button. </li>
87  * <li><code><i>dockableName</i>.label</code> - The string to use for generating
88  * menu items and action names. </li>
89  * <li><code><i>dockableName</i>.longtitle</code> - (optional) the string to use
90  * in the dockable's floating window title (when it is floating).
91  * If not specified, the <code><i>dockableName</i>.title</code> property is used. </li>
92  * </ul>
93  *
94  * A number of actions are automatically created for each dockable window:
95  *
96  * <ul>
97  * <li><code><i>dockableName</i></code> - opens the dockable window.</li>
98  * <li><code><i>dockableName</i>-toggle</code> - toggles the dockable window's visibility.</li>
99  * <li><code><i>dockableName</i>-float</code> - opens the dockable window in a new
100  * floating window.</li>
101  * </ul>
102  *
103  * Note that only the first action needs a <code>label</code> property, the
104  * rest have automatically-generated labels.
105  *
106  * <b>Implementation details:</b><p>
107  *
108  * When an instance of this class is initialized by the {@link org.gjt.sp.jedit.View}
109  * class, it
110  * iterates through the list of registered dockable windows (from jEdit itself,
111  * and any loaded plugins) and
112  * examines options supplied by the user in the <b>Global
113  * Options</b> dialog box. Any plugins designated for one of the
114  * four docking positions are displayed.<p>
115  *
116  * To create an instance of a dockable window, the <code>DockableWindowManager</code>
117  * finds and executes the BeanShell code extracted from the appropriate
118  * <code>dockables.xml</code> file. This code will typically consist of a call
119  * to the constructor of the dockable window component. The result of the
120  * BeanShell expression, typically a newly constructed component, is placed
121  * in a window managed by this class.
122  *
123  * @see org.gjt.sp.jedit.View#getDockableWindowManager()
124  *
125  * @author Slava Pestov
126  * @author John Gellene (API documentation)
127  * @version $Id: DockableWindowManager.java 8690 2007-01-20 10:59:00Z kpouer $
128  * @since jEdit 2.6pre3
129  */

130 public class DockableWindowManager extends JPanel JavaDoc implements EBComponent
131 {
132     //{{{ Constants
133
/**
134      * Floating position.
135      * @since jEdit 2.6pre3
136      */

137     public static final String JavaDoc FLOATING = "floating";
138     
139     /**
140      * Top position.
141      * @since jEdit 2.6pre3
142      */

143     public static final String JavaDoc TOP = "top";
144
145     /**
146      * Left position.
147      * @since jEdit 2.6pre3
148      */

149     public static final String JavaDoc LEFT = "left";
150
151     /**
152      * Bottom position.
153      * @since jEdit 2.6pre3
154      */

155     public static final String JavaDoc BOTTOM = "bottom";
156
157     /**
158      * Right position.
159      * @since jEdit 2.6pre3
160      */

161     public static final String JavaDoc RIGHT = "right";
162     //}}}
163

164     //{{{ Data members
165
private View view;
166     private DockableWindowFactory factory;
167
168     /** A mapping from Strings to Entry objects. */
169     private Map<String JavaDoc, Entry> windows;
170     private PanelWindowContainer left;
171     private PanelWindowContainer right;
172     private PanelWindowContainer top;
173     private PanelWindowContainer bottom;
174     private List<Entry> clones;
175     
176     private Entry lastEntry;
177     public Stack showStack = new Stack();
178     // }}}
179

180     //{{{ getRegisteredDockableWindows() method
181
/**
182      * @since jEdit 4.3pre2
183      */

184     public static String JavaDoc[] getRegisteredDockableWindows()
185     {
186         return DockableWindowFactory.getInstance()
187             .getRegisteredDockableWindows();
188     } //}}}
189

190     //{{{ DockableWindowManager constructor
191
/**
192      * Creates a new dockable window manager.
193      * @param view The view
194      * @param factory A {@link DockableWindowFactory}, usually
195      * <code>DockableWindowFactory.getInstance()</code>.
196      * @param config A docking configuration
197      * @since jEdit 2.6pre3
198      */

199     public DockableWindowManager(View view, DockableWindowFactory factory,
200         View.ViewConfig config)
201     {
202         setLayout(new DockableLayout());
203         this.view = view;
204         this.factory = factory;
205
206         windows = new HashMap<String JavaDoc, Entry>();
207         clones = new ArrayList<Entry>();
208
209         top = new PanelWindowContainer(this,TOP,config.topPos);
210         left = new PanelWindowContainer(this,LEFT,config.leftPos);
211         bottom = new PanelWindowContainer(this,BOTTOM,config.bottomPos);
212         right = new PanelWindowContainer(this,RIGHT,config.rightPos);
213
214         add(DockableLayout.TOP_BUTTONS,top.buttonPanel);
215         add(DockableLayout.LEFT_BUTTONS,left.buttonPanel);
216         add(DockableLayout.BOTTOM_BUTTONS,bottom.buttonPanel);
217         add(DockableLayout.RIGHT_BUTTONS,right.buttonPanel);
218
219         add(TOP,top.dockablePanel);
220         add(LEFT,left.dockablePanel);
221         add(BOTTOM,bottom.dockablePanel);
222         add(RIGHT,right.dockablePanel);
223     } //}}}
224

225     //{{{ init() method
226
/**
227      * Initialises dockable window manager. Do not call this method directly.
228      */

229     public void init()
230     {
231         EditBus.addToBus(this);
232
233         Iterator<DockableWindowFactory.Window> entries = factory.getDockableWindowIterator();
234
235         while(entries.hasNext())
236             addEntry(entries.next());
237
238         propertiesChanged();
239     } //}}}
240

241     // {{{ closeListener() method
242
/**
243      *
244      * The actionEvent "close-docking-area" by default only works on
245      * windows that are docked. If you want your floatable plugins to also
246      * respond to this event, you need to add key listeners to each component
247      * in your plugin that usually has keyboard focus.
248      * This function returns a key listener which does exactly that.
249      * You should not need to call this method - it is used by FloatingWindowContainer.
250      *
251      * @param dockableName the name of your dockable
252      * @return a KeyListener you can add to that plugin's component.
253      * @since jEdit 4.3pre6
254      *
255      */

256     public KeyListener JavaDoc closeListener(String JavaDoc dockableName) {
257         return new KeyHandler(dockableName);
258     }
259     // }}}
260

261     //{{{ getView() method
262
/**
263      * Returns this dockable window manager's view.
264      * @since jEdit 4.0pre2
265      */

266     public View getView()
267     {
268         return view;
269     } //}}}
270

271     //{{{ floatDockableWindow() method
272
/**
273      * Opens a new instance of the specified dockable window in a floating
274      * container.
275      * @param name The dockable window name
276      * @return The new dockable window instance
277      * @since jEdit 4.1pre2
278      */

279     public JComponent JavaDoc floatDockableWindow(String JavaDoc name)
280     {
281         Entry entry = windows.get(name);
282         if(entry == null)
283         {
284             Log.log(Log.ERROR,this,"Unknown dockable window: " + name);
285             return null;
286         }
287         
288         // create a copy of this dockable window and float it
289
Entry newEntry = new Entry(entry.factory,FLOATING);
290         newEntry.win = newEntry.factory.createDockableWindow(view,FLOATING);
291         
292         if(newEntry.win != null)
293         {
294             FloatingWindowContainer fwc = new FloatingWindowContainer(this,true);
295             newEntry.container = fwc;
296             newEntry.container.register(newEntry);
297             newEntry.container.show(newEntry);
298             
299             
300         }
301         clones.add(newEntry);
302         return newEntry.win;
303     } //}}}
304

305     //{{{ showDockableWindow() method
306
/**
307      * Opens the specified dockable window.
308      * @param name The dockable window name
309      * @since jEdit 2.6pre3
310      */

311     public void showDockableWindow(String JavaDoc name)
312     {
313         lastEntry = windows.get(name);
314         if(lastEntry == null)
315         {
316             Log.log(Log.ERROR,this,"Unknown dockable window: " + name);
317             return;
318         }
319
320         if(lastEntry.win == null)
321         {
322             lastEntry.win = lastEntry.factory.createDockableWindow(
323                 view,lastEntry.position);
324         }
325
326         if(lastEntry.win != null)
327         {
328             if(lastEntry.position.equals(FLOATING)
329                 && lastEntry.container == null)
330             {
331                 FloatingWindowContainer fwc = new FloatingWindowContainer(
332                     this,view.isPlainView());
333                 lastEntry.container = fwc;
334                 lastEntry.container.register(lastEntry);
335             }
336             showStack.push(name);
337             lastEntry.container.show(lastEntry);
338             Object JavaDoc reason = DockableWindowUpdate.ACTIVATED;
339             EditBus.send(new DockableWindowUpdate(this, reason, name));
340         }
341         else
342             /* an error occurred */;
343     } //}}}
344

345     //{{{ addDockableWindow() method
346
/**
347      * Opens the specified dockable window. As of jEdit 4.0pre1, has the
348      * same effect as calling showDockableWindow().
349      * @param name The dockable window name
350      * @since jEdit 2.6pre3
351      */

352     public void addDockableWindow(String JavaDoc name)
353     {
354         showDockableWindow(name);
355     } //}}}
356

357     //{{{ hideDockableWindow() method
358
/**
359      * Hides the specified dockable window.
360      * @param name The dockable window name
361      * @since jEdit 2.6pre3
362      */

363     public void hideDockableWindow(String JavaDoc name)
364     {
365
366         Entry entry = windows.get(name);
367         if(entry == null)
368         {
369             Log.log(Log.ERROR,this,"Unknown dockable window: " + name);
370             return;
371         }
372
373
374
375         if(entry.win == null)
376             return;
377         Object JavaDoc reason = DockableWindowUpdate.DEACTIVATED;
378         EditBus.send(new DockableWindowUpdate(this, reason, name));
379
380         entry.container.show(null);
381     } //}}}
382

383     //{{{ removeDockableWindow() method
384
/**
385      * Hides the specified dockable window. As of jEdit 4.2pre1, has the
386      * same effect as calling hideDockableWindow().
387      * @param name The dockable window name
388      * @since jEdit 4.2pre1
389      */

390     public void removeDockableWindow(String JavaDoc name)
391     {
392         hideDockableWindow(name);
393     } //}}}
394

395     //{{{ toggleDockableWindow() method
396
/**
397      * Toggles the visibility of the specified dockable window.
398      * @param name The dockable window name
399      */

400     public void toggleDockableWindow(String JavaDoc name)
401     {
402         if(isDockableWindowVisible(name))
403             removeDockableWindow(name);
404         else
405             addDockableWindow(name);
406     } //}}}
407

408     //{{{ getDockableWindow() method
409
/**
410      * Returns the specified dockable window.
411      *
412      * Note that this method
413      * will return null if the dockable has not been added yet.
414      * Make sure you call {@link #addDockableWindow(String)} first.
415      *
416      * @param name The name of the dockable window
417      * @since jEdit 4.1pre2
418      */

419     public JComponent JavaDoc getDockableWindow(String JavaDoc name)
420     {
421         return getDockable(name);
422     } //}}}
423

424     //{{{ getDockable() method
425
/**
426      * Returns the specified dockable window.
427      *
428      * Note that this method
429      * will return null if the dockable has not been added yet.
430      * Make sure you call {@link #addDockableWindow(String)} first.
431      *
432      * For historical reasons, this
433      * does the same thing as {@link #getDockableWindow(String)}.
434      *
435      * @param name The name of the dockable window
436      * @since jEdit 4.0pre1
437      */

438     public JComponent JavaDoc getDockable(String JavaDoc name)
439     {
440         
441         Entry entry = windows.get(name);
442         if(entry == null || entry.win == null)
443             return null;
444         else
445             return entry.win;
446     } //}}}
447

448     //{{{ getDockableTitle() method
449
/**
450      * Returns the title of the specified dockable window.
451      * @param name The name of the dockable window.
452      * @since jEdit 4.1pre5
453      */

454     public String JavaDoc getDockableTitle(String JavaDoc name)
455     {
456         Entry e = windows.get(name);
457         return e.longTitle();
458     } //}}}
459

460     //{{{ setDockableTitle() method
461
/**
462      * Changes the .longtitle property of a dockable window, which corresponds to the
463      * title shown when it is floating (not docked). Fires a change event that makes sure
464      * all floating dockables change their title.
465      *
466      * @param dockableName the name of the dockable, as specified in the dockables.xml
467      * @param newTitle the new .longtitle you want to see above it.
468      * @since 4.3pre5
469      *
470      */

471     public void setDockableTitle(String JavaDoc dockableName, String JavaDoc newTitle) {
472         Entry entry = windows.get(dockableName);
473         String JavaDoc propName = entry.factory.name + ".longtitle";
474         String JavaDoc oldTitle = jEdit.getProperty(propName);
475         jEdit.setProperty(propName, newTitle);
476         firePropertyChange(propName, oldTitle, newTitle);
477     }
478     // }}}
479

480     //{{{ isDockableWindowVisible() method
481
/**
482      * Returns if the specified dockable window is visible.
483      * @param name The dockable window name
484      */

485     public boolean isDockableWindowVisible(String JavaDoc name)
486     {
487         Entry entry = windows.get(name);
488         if(entry == null || entry.win == null)
489             return false;
490         else
491             return entry.container.isVisible(entry);
492     } //}}}
493

494     //{{{ isDockableWindowDocked() method
495
/**
496      * Returns if the specified dockable window is docked into the
497      * view.
498      * @param name The dockable's name
499      * @since jEdit 4.0pre2
500      */

501     public boolean isDockableWindowDocked(String JavaDoc name)
502     {
503         Entry entry = windows.get(name);
504         if(entry == null)
505             return false;
506         else
507             return !entry.position.equals(FLOATING);
508     } //}}}
509

510     //{{{ closeCurrentArea() method
511
/**
512      * Closes the most recently focused dockable.
513      * @since jEdit 4.1pre3
514      */

515     public void closeCurrentArea()
516     {
517         // I don't know of any other way to fix this, since invoking this
518
// command from a menu results in the focus owner being the menu
519
// until the menu goes away.
520
SwingUtilities.invokeLater(new Runnable JavaDoc()
521         {
522             public void run()
523             {
524                 /* Try to hide the last entry that was shown */
525                 try {
526                     String JavaDoc dockableName = showStack.pop().toString();
527                     hideDockableWindow(dockableName);
528                     return;
529                 }
530                 catch (Exception JavaDoc e) {}
531                 
532                 Component JavaDoc comp = view.getFocusOwner();
533                 while(comp != null)
534                 {
535                     //System.err.println(comp.getClass());
536
if(comp instanceof DockablePanel)
537                     {
538                         DockablePanel panel = (DockablePanel) comp;
539                         
540                         PanelWindowContainer container = panel.getWindowContainer();
541                         
542                         container.show(null);
543                         return;
544                     }
545
546                     comp = comp.getParent();
547                 }
548
549                 getToolkit().beep();
550             }
551         });
552     } //}}}
553

554     //{{{ close() method
555
/**
556      * Called when the view is being closed.
557      * @since jEdit 2.6pre3
558      */

559     public void close()
560     {
561         EditBus.removeFromBus(this);
562
563         for (Entry entry : windows.values())
564         {
565             if (entry.win != null)
566                 entry.container.unregister(entry);
567         }
568
569         for (Entry clone : clones)
570         {
571             if (clone.win != null)
572                 clone.container.unregister(clone);
573         }
574     } //}}}
575

576     //{{{ getTopDockingArea() method
577
public PanelWindowContainer getTopDockingArea()
578     {
579         return top;
580     } //}}}
581

582     //{{{ getLeftDockingArea() method
583
public PanelWindowContainer getLeftDockingArea()
584     {
585         return left;
586     } //}}}
587

588     //{{{ getBottomDockingArea() method
589
public PanelWindowContainer getBottomDockingArea()
590     {
591         return bottom;
592     } //}}}
593

594     //{{{ getRightDockingArea() method
595
public PanelWindowContainer getRightDockingArea()
596     {
597         return right;
598     } //}}}
599

600     //{{{ createPopupMenu() method
601
public JPopupMenu JavaDoc createPopupMenu(
602         final DockableWindowContainer container,
603         final String JavaDoc dockable,
604         final boolean clone)
605     {
606         JPopupMenu JavaDoc popup = new JPopupMenu JavaDoc();
607         if(dockable == null && container instanceof PanelWindowContainer)
608         {
609             ActionListener JavaDoc listener = new ActionListener JavaDoc()
610             {
611                 public void actionPerformed(ActionEvent JavaDoc evt)
612                 {
613                     showDockableWindow(evt.getActionCommand());
614                 }
615             };
616
617             String JavaDoc[] dockables = ((PanelWindowContainer)
618                 container).getDockables();
619             Map<String JavaDoc,String JavaDoc> dockableMap = new TreeMap<String JavaDoc, String JavaDoc>();
620             for (int i = 0; i < dockables.length; i++)
621             {
622                 String JavaDoc action = dockables[i];
623                 dockableMap.put(getDockableTitle(action), action);
624             }
625             for (Map.Entry<String JavaDoc, String JavaDoc> entry : dockableMap.entrySet())
626             {
627                 JMenuItem JavaDoc item = new JMenuItem JavaDoc(entry.getKey());
628                 item.setActionCommand(entry.getValue());
629                 item.addActionListener(listener);
630                 popup.add(item);
631             }
632         }
633         else
634         {
635             JMenuItem JavaDoc caption = new JMenuItem JavaDoc(getDockableTitle(dockable));
636             caption.setEnabled(false);
637             popup.add(caption);
638             popup.addSeparator();
639             String JavaDoc currentPos = jEdit.getProperty(dockable + ".dock-position",FLOATING);
640             if(!clone)
641             {
642                 String JavaDoc[] positions = { FLOATING, TOP, LEFT, BOTTOM, RIGHT };
643                 for(int i = 0; i < positions.length; i++)
644                 {
645                     final String JavaDoc pos = positions[i];
646                     if(pos.equals(currentPos))
647                         continue;
648
649                     JMenuItem JavaDoc moveMenuItem = new JMenuItem JavaDoc(jEdit.getProperty("view.docking.menu-"
650                         + pos));
651
652                     moveMenuItem.addActionListener(new ActionListener JavaDoc()
653                     {
654                         public void actionPerformed(ActionEvent JavaDoc evt)
655                         {
656                             jEdit.setProperty(dockable + ".dock-position",pos);
657                             EditBus.send(new DockableWindowUpdate(
658                                 DockableWindowManager.this,
659                                 DockableWindowUpdate.PROPERTIES_CHANGED,
660                                 null
661                             ));
662                             showDockableWindow(dockable);
663                         }
664                     });
665                     popup.add(moveMenuItem);
666                 }
667
668                 popup.addSeparator();
669             }
670
671             JMenuItem JavaDoc cloneMenuItem = new JMenuItem JavaDoc(jEdit.getProperty("view.docking.menu-clone"));
672
673             cloneMenuItem.addActionListener(new ActionListener JavaDoc()
674             {
675                 public void actionPerformed(ActionEvent JavaDoc evt)
676                 {
677                     floatDockableWindow(dockable);
678                 }
679             });
680             popup.add(cloneMenuItem);
681
682             popup.addSeparator();
683
684             JMenuItem JavaDoc closeMenuItem = new JMenuItem JavaDoc(jEdit.getProperty("view.docking.menu-close"));
685
686             closeMenuItem.addActionListener(new ActionListener JavaDoc()
687             {
688                 public void actionPerformed(ActionEvent JavaDoc evt)
689                 {
690                     if(clone)
691                         ((FloatingWindowContainer)container).dispose();
692                     else
693                         removeDockableWindow(dockable);
694                 }
695             });
696             popup.add(closeMenuItem);
697
698             if(!(clone || currentPos.equals(FLOATING)))
699             {
700                 JMenuItem JavaDoc undockMenuItem = new JMenuItem JavaDoc(jEdit.getProperty("view.docking.menu-undock"));
701
702                 undockMenuItem.addActionListener(new ActionListener JavaDoc()
703                 {
704                     public void actionPerformed(ActionEvent JavaDoc evt)
705                     {
706                         jEdit.setProperty(dockable + ".dock-position",FLOATING);
707                         EditBus.send(new DockableWindowUpdate(
708                             DockableWindowManager.this,
709                             DockableWindowUpdate.PROPERTIES_CHANGED,
710                             null
711                         ));
712                     }
713                 });
714                 popup.add(undockMenuItem);
715             }
716         }
717
718         return popup;
719     } //}}}
720

721     //{{{ paintChildren() method
722
public void paintChildren(Graphics JavaDoc g)
723     {
724         super.paintChildren(g);
725
726         if(resizeRect != null)
727         {
728             g.setColor(Color.darkGray);
729             g.fillRect(resizeRect.x,resizeRect.y,
730                 resizeRect.width,resizeRect.height);
731         }
732     } //}}}
733

734     //{{{ handleMessage() method
735
public void handleMessage(EBMessage msg)
736     {
737         if(msg instanceof DockableWindowUpdate)
738         {
739             if(((DockableWindowUpdate)msg).getWhat()
740                 == DockableWindowUpdate.PROPERTIES_CHANGED)
741                 propertiesChanged();
742         }
743         else if(msg instanceof PropertiesChanged)
744             propertiesChanged();
745         else if(msg instanceof PluginUpdate)
746         {
747             PluginUpdate pmsg = (PluginUpdate)msg;
748             if(pmsg.getWhat() == PluginUpdate.LOADED)
749             {
750                 Iterator<DockableWindowFactory.Window> iter = factory.getDockableWindowIterator();
751
752                 while(iter.hasNext())
753                 {
754                     DockableWindowFactory.Window w = iter.next();
755                     if(w.plugin == pmsg.getPluginJAR())
756                         addEntry(w);
757                 }
758
759                 propertiesChanged();
760             }
761             else if(pmsg.isExiting())
762             {
763                 // we don't care
764
}
765             else if(pmsg.getWhat() == PluginUpdate.DEACTIVATED)
766             {
767                 Iterator<Entry> iter = getAllPluginEntries(
768                     pmsg.getPluginJAR(),false);
769                 while(iter.hasNext())
770                 {
771                     Entry entry = iter.next();
772                     if(entry.container != null)
773                         entry.container.remove(entry);
774                 }
775             }
776             else if(pmsg.getWhat() == PluginUpdate.UNLOADED)
777             {
778                 Iterator<Entry> iter = getAllPluginEntries(
779                     pmsg.getPluginJAR(),true);
780                 while(iter.hasNext())
781                 {
782                     Entry entry = iter.next();
783                     if(entry.container != null)
784                     {
785                         entry.container.unregister(entry);
786                         entry.win = null;
787                         entry.container = null;
788                     }
789                 }
790             }
791         }
792     } //}}}
793

794     //{{{ Package-private members
795
int resizePos;
796     /**
797      * This is the rectangle you drag to resize the split.
798      * It is used with non continuous layout.
799      */

800     Rectangle JavaDoc resizeRect;
801
802     //{{{ setResizePos() method
803
void setResizePos(int resizePos, PanelWindowContainer resizing)
804     {
805         this.resizePos = resizePos;
806
807         if(resizePos < 0)
808             resizePos = 0;
809
810         Rectangle JavaDoc newResizeRect = new Rectangle JavaDoc(0,0,
811             PanelWindowContainer.SPLITTER_WIDTH - 2,
812             PanelWindowContainer.SPLITTER_WIDTH - 2);
813         if(resizing == top)
814         {
815             resizePos = Math.min(resizePos,getHeight()
816                 - top.buttonPanel.getHeight()
817                 - bottom.dockablePanel.getHeight()
818                 - bottom.buttonPanel.getHeight()
819                 - PanelWindowContainer.SPLITTER_WIDTH);
820             newResizeRect.x = top.dockablePanel.getX() + 1;
821             newResizeRect.y = resizePos + top.buttonPanel.getHeight() + 1;
822             newResizeRect.width = top.dockablePanel.getWidth() - 2;
823         }
824         else if(resizing == left)
825         {
826             resizePos = Math.min(resizePos,getWidth()
827                 - left.buttonPanel.getWidth()
828                 - right.dockablePanel.getWidth()
829                 - right.buttonPanel.getWidth()
830                 - PanelWindowContainer.SPLITTER_WIDTH);
831             newResizeRect.x = resizePos + left.buttonPanel.getWidth() + 1;
832             newResizeRect.y = left.dockablePanel.getY() + 1;
833             newResizeRect.height = left.dockablePanel.getHeight() - 2;
834         }
835         else if(resizing == bottom)
836         {
837             resizePos = Math.min(resizePos,getHeight()
838                 - bottom.buttonPanel.getHeight()
839                 - top.dockablePanel.getHeight()
840                 - top.buttonPanel.getHeight()
841                 - PanelWindowContainer.SPLITTER_WIDTH);
842             newResizeRect.x = bottom.dockablePanel.getX() + 1;
843             newResizeRect.y = getHeight() - bottom.buttonPanel.getHeight() - resizePos
844                 - PanelWindowContainer.SPLITTER_WIDTH + 2;
845             newResizeRect.width = bottom.dockablePanel.getWidth() - 2;
846         }
847         else if(resizing == right)
848         {
849             resizePos = Math.min(resizePos,getWidth()
850                 - right.buttonPanel.getWidth()
851                 - left.dockablePanel.getWidth()
852                 - left.buttonPanel.getWidth()
853                 - PanelWindowContainer.SPLITTER_WIDTH);
854             newResizeRect.x = getWidth() - right.buttonPanel.getWidth() - resizePos
855                 - PanelWindowContainer.SPLITTER_WIDTH + 1;
856             newResizeRect.y = right.dockablePanel.getY() + 1;
857             newResizeRect.height = right.dockablePanel.getHeight() - 2;
858         }
859
860         Rectangle JavaDoc toRepaint;
861         if(resizeRect == null)
862             toRepaint = newResizeRect;
863         else
864             toRepaint = resizeRect.union(newResizeRect);
865         resizeRect = newResizeRect;
866         repaint(toRepaint);
867     } //}}}
868

869     //{{{ finishResizing() method
870
void finishResizing()
871     {
872         resizeRect = null;
873         repaint();
874     } //}}}
875

876     //}}}
877

878     //{{{ propertiesChanged() method
879
private void propertiesChanged()
880     {
881         if(view.isPlainView())
882             return;
883
884         ((DockableLayout)getLayout()).setAlternateLayout(
885             jEdit.getBooleanProperty("view.docking.alternateLayout"));
886
887         String JavaDoc[] windowList = factory.getRegisteredDockableWindows();
888
889         for(int i = 0; i < windowList.length; i++)
890         {
891             String JavaDoc dockable = windowList[i];
892             Entry entry = windows.get(dockable);
893
894             String JavaDoc newPosition = jEdit.getProperty(dockable
895                 + ".dock-position",FLOATING);
896             if(newPosition.equals(entry.position))
897             {
898                 continue;
899             }
900
901             entry.position = newPosition;
902             if(entry.container != null)
903             {
904                 entry.container.unregister(entry);
905                 entry.container = null;
906                 entry.win = null;
907             }
908
909             if(newPosition.equals(FLOATING))
910             {
911             }
912                 
913             else
914             {
915                 if(newPosition.equals(TOP))
916                     entry.container = top;
917                 else if(newPosition.equals(LEFT))
918                     entry.container = left;
919                 else if(newPosition.equals(BOTTOM))
920                     entry.container = bottom;
921                 else if(newPosition.equals(RIGHT))
922                     entry.container = right;
923                 else
924                 {
925                     Log.log(Log.WARNING,this,
926                         "Unknown position: "
927                         + newPosition);
928                     continue;
929                 }
930
931                 entry.container.register(entry);
932             }
933         }
934
935         top.sortDockables();
936         left.sortDockables();
937         bottom.sortDockables();
938         right.sortDockables();
939
940         revalidate();
941         repaint();
942     } //}}}
943

944     //{{{ addEntry() method
945
private void addEntry(DockableWindowFactory.Window factory)
946     {
947         Entry e;
948         if(view.isPlainView())
949         {
950             // don't show menu items to dock into a plain view
951
e = new Entry(factory,FLOATING);
952         }
953         else
954         {
955             e = new Entry(factory);
956             if(e.position.equals(FLOATING))
957                 /* nothing to do */;
958             else if(e.position.equals(TOP))
959                 e.container = top;
960             else if(e.position.equals(LEFT))
961                 e.container = left;
962             else if(e.position.equals(BOTTOM))
963                 e.container = bottom;
964             else if(e.position.equals(RIGHT))
965                 e.container = right;
966             else
967             {
968                 Log.log(Log.WARNING,this,
969                     "Unknown position: "
970                     + e.position);
971             }
972
973             if(e.container != null)
974                 e.container.register(e);
975         }
976         windows.put(factory.name,e);
977     } //}}}
978

979     //{{{ getAllPluginEntries() method
980
/**
981      * If remove is false, only remove from clones list, otherwise remove
982      * from both entries and clones.
983      */

984     private Iterator<Entry> getAllPluginEntries(PluginJAR plugin, boolean remove)
985     {
986         List<Entry> returnValue = new LinkedList<Entry>();
987         Iterator<Entry> iter = windows.values().iterator();
988         while(iter.hasNext())
989         {
990             Entry entry = iter.next();
991             if(entry.factory.plugin == plugin)
992             {
993                 returnValue.add(entry);
994                 if(remove)
995                     iter.remove();
996             }
997         }
998
999         iter = clones.iterator();
1000        while(iter.hasNext())
1001        {
1002            Entry entry = iter.next();
1003            if(entry.factory.plugin == plugin)
1004            {
1005                returnValue.add(entry);
1006                iter.remove();
1007            }
1008        }
1009
1010        return returnValue.iterator();
1011    } //}}}
1012

1013    //{{{ Entry class
1014
class Entry
1015    {
1016        DockableWindowFactory.Window factory;
1017
1018// String title;
1019
String JavaDoc position;
1020        DockableWindowContainer container;
1021
1022        // only set if open
1023
JComponent JavaDoc win;
1024
1025        // only for docked
1026
AbstractButton JavaDoc btn;
1027
1028        //{{{ Entry constructor
1029
Entry(DockableWindowFactory.Window factory)
1030        {
1031            this(factory,jEdit.getProperty(factory.name
1032                + ".dock-position",FLOATING));
1033        } //}}}
1034

1035        
1036        /**
1037         * @return the long title for the dockable floating window.
1038         */

1039        public String JavaDoc longTitle()
1040        {
1041            String JavaDoc title = jEdit.getProperty(factory.name + ".longtitle");
1042            if (title == null) return shortTitle();
1043            else return title;
1044            
1045        }
1046        
1047        /**
1048         * @return The short title, for the dockable button text
1049         */

1050        public String JavaDoc shortTitle()
1051        {
1052            
1053            String JavaDoc title = jEdit.getProperty(factory.name + ".title");
1054            if(title == null)
1055                return "NO TITLE PROPERTY: " + factory.name;
1056            else
1057                return title;
1058        }
1059        /**
1060         * @return A label appropriate for the title on the dock buttons.
1061         */

1062        public String JavaDoc label() {
1063            String JavaDoc retval = jEdit.getProperty(factory.name + ".label");
1064            retval = retval.replaceAll("\\$", "");
1065            return retval;
1066        }
1067        //{{{ Entry constructor
1068
Entry(DockableWindowFactory.Window factory, String JavaDoc position)
1069        {
1070            this.factory = factory;
1071            this.position = position;
1072
1073            // get the title here, not in the factory constructor,
1074
// since the factory might be created before a plugin's
1075
// props are loaded
1076

1077        } //}}}
1078
} //}}}
1079

1080    /**
1081     * This keyhandler responds to only two key events - those corresponding to
1082     * the close-docking-area action event.
1083     *
1084     * @author ezust
1085     *
1086     */

1087    class KeyHandler extends KeyAdapter JavaDoc {
1088        static final String JavaDoc action = "close-docking-area";
1089        Key b1, b2;
1090        String JavaDoc name;
1091        
1092        public KeyHandler(String JavaDoc dockableName) {
1093            String JavaDoc shortcut1=jEdit.getProperty(action + ".shortcut");
1094            String JavaDoc shortcut2=jEdit.getProperty(action + ".shortcut2");
1095            if (shortcut1 != null)
1096                b1 = KeyEventTranslator.parseKey(shortcut1);
1097            if (shortcut2 != null)
1098                b2 = KeyEventTranslator.parseKey(shortcut2);
1099            name = dockableName;
1100        }
1101        public void keyTyped(KeyEvent JavaDoc e)
1102        {
1103            char cc = e.getKeyChar();
1104            if ((b1 != null && cc == b1.key) ||
1105                 (b2 != null && cc == b2.key))
1106                hideDockableWindow(name);
1107        }
1108
1109
1110    }
1111    
1112}
1113
Popular Tags