Source Code Cross Referenced for DockableWindowManager.java in  » Swing-Library » jEdit » org » gjt » sp » jedit » gui » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Swing Library » jEdit » org.gjt.sp.jedit.gui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DockableWindowManager.java - manages dockable windows
0003:         * :tabSize=8:indentSize=8:noTabs=false:
0004:         * :folding=explicit:collapseFolds=1:
0005:         *
0006:         * Copyright (C) 2000, 2005 Slava Pestov
0007:         *
0008:         * This program is free software; you can redistribute it and/or
0009:         * modify it under the terms of the GNU General Public License
0010:         * as published by the Free Software Foundation; either version 2
0011:         * of the License, or any later version.
0012:         *
0013:         * This program is distributed in the hope that it will be useful,
0014:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0016:         * GNU General Public License for more details.
0017:         *
0018:         * You should have received a copy of the GNU General Public License
0019:         * along with this program; if not, write to the Free Software
0020:         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
0021:         */
0022:
0023:        package org.gjt.sp.jedit.gui;
0024:
0025:        //{{{ Imports
0026:        import java.awt.Color;
0027:        import java.awt.Component;
0028:        import java.awt.Graphics;
0029:        import java.awt.Rectangle;
0030:        import java.awt.event.ActionEvent;
0031:        import java.awt.event.ActionListener;
0032:        import java.awt.event.KeyAdapter;
0033:        import java.awt.event.KeyEvent;
0034:        import java.awt.event.KeyListener;
0035:        import java.util.*;
0036:
0037:        import javax.swing.AbstractButton;
0038:        import javax.swing.JComponent;
0039:        import javax.swing.JMenuItem;
0040:        import javax.swing.JPanel;
0041:        import javax.swing.JPopupMenu;
0042:        import javax.swing.SwingUtilities;
0043:
0044:        import org.gjt.sp.jedit.EBComponent;
0045:        import org.gjt.sp.jedit.EBMessage;
0046:        import org.gjt.sp.jedit.EditBus;
0047:        import org.gjt.sp.jedit.PluginJAR;
0048:        import org.gjt.sp.jedit.View;
0049:        import org.gjt.sp.jedit.jEdit;
0050:        import org.gjt.sp.jedit.gui.KeyEventTranslator.Key;
0051:        import org.gjt.sp.jedit.msg.DockableWindowUpdate;
0052:        import org.gjt.sp.jedit.msg.PluginUpdate;
0053:        import org.gjt.sp.jedit.msg.PropertiesChanged;
0054:        import org.gjt.sp.util.Log;
0055:
0056:        //}}}
0057:
0058:        /**
0059:         * <p>Keeps track of all dockable windows for a single View, and provides
0060:         * an API for getting/showing/hiding them. </p>
0061:         * 
0062:         * <p>Each {@link org.gjt.sp.jedit.View} has an instance of this class.</p>
0063:         *
0064:         * <p><b>dockables.xml:</b></p>
0065:         *
0066:         * <p>Dockable window definitions are read from <code>dockables.xml</code> files
0067:         * contained inside plugin JARs. A dockable definition file has the following
0068:         * form: </p>
0069:         *
0070:         * <pre>&lt;?xml version="1.0"?&gt;
0071:         *&lt;!DOCTYPE DOCKABLES SYSTEM "dockables.dtd"&gt;
0072:         *&lt;DOCKABLES&gt;
0073:         *    &lt;DOCKABLE NAME="<i>dockableName</i>" MOVABLE="TRUE|FALSE"&gt;
0074:         *        // Code to create the dockable
0075:         *    &lt;/DOCKABLE&gt;
0076:         *&lt;/DOCKABLES&gt;</pre>
0077:         *
0078:         * <p>The MOVABLE attribute specifies the behavior when the docking position of
0079:         * the dockable window is changed. If MOVABLE is TRUE, the existing instance of
0080:         * the dockable window is moved to the new docking position, and if the dockable
0081:         * window implements the DockableWindow interface (see {@link DockableWindow}),
0082:         * it is also notified about the change in docking position before it is moved.
0083:         * If MOVABLE is FALSE, the BeanShell code is invoked to get the instance of
0084:         * the dockable window to put in the new docking position. Typically, the
0085:         * BeanShell code returns a new instance of the dockable window, and the state
0086:         * of the existing instance is not preserved after the change. It is therefore
0087:         * recommended to set MOVABLE to TRUE for all dockables in order to make them
0088:         * preserve their state when they are moved. For backward compatibility reasons,
0089:         * this attribute is set to FALSE by default.</p>
0090:         * <p>More than one <code>&lt;DOCKABLE&gt;</code> tag may be present. The code that
0091:         * creates the dockable can reference any BeanShell built-in variable
0092:         * (see {@link org.gjt.sp.jedit.BeanShell}), along with a variable
0093:         * <code>position</code> whose value is one of
0094:         * {@link #FLOATING}, {@link #TOP}, {@link #LEFT}, {@link #BOTTOM},
0095:         * and {@link #RIGHT}. </p>
0096:         *
0097:         * <p>The following properties must be defined for each dockable window: </p>
0098:         *
0099:         * <ul>
0100:         * <li><code><i>dockableName</i>.title</code> - the string to show on the dockable
0101:         * button. </li>
0102:         * <li><code><i>dockableName</i>.label</code> - The string to use for generating
0103:         *    menu items and action names. </li> 
0104:         * <li><code><i>dockableName</i>.longtitle</code> - (optional) the string to use
0105:         *      in the dockable's floating window title (when it is floating).
0106:         *       If not specified, the <code><i>dockableName</i>.title</code> property is used. </li>
0107:         * </ul>
0108:         *
0109:         * A number of actions are automatically created for each dockable window:
0110:         *
0111:         * <ul>
0112:         * <li><code><i>dockableName</i></code> - opens the dockable window.</li>
0113:         * <li><code><i>dockableName</i>-toggle</code> - toggles the dockable window's visibility.</li>
0114:         * <li><code><i>dockableName</i>-float</code> - opens the dockable window in a new
0115:         * floating window.</li>
0116:         * </ul>
0117:         *
0118:         * Note that only the first action needs a <code>label</code> property, the
0119:         * rest have automatically-generated labels.
0120:         *
0121:         * <p> <b>Implementation details:</b></p>
0122:         *
0123:         * <p> When an instance of this class is initialized by the {@link org.gjt.sp.jedit.View}
0124:         * class, it
0125:         * iterates through the list of registered dockable windows (from jEdit itself,
0126:         * and any loaded plugins) and
0127:         * examines options supplied by the user in the <b>Global
0128:         * Options</b> dialog box. Any plugins designated for one of the
0129:         * four docking positions are displayed.</p>
0130:         *
0131:         * <p> To create an instance of a dockable window, the <code>DockableWindowManager</code>
0132:         * finds and executes the BeanShell code extracted from the appropriate
0133:         * <code>dockables.xml</code> file. This code will typically consist of a call
0134:         * to the constructor of the dockable window component. The result of the
0135:         * BeanShell expression, typically a newly constructed component, is placed
0136:         * in a window managed by this class. </p>
0137:         *
0138:         * @see org.gjt.sp.jedit.View#getDockableWindowManager()
0139:         *
0140:         * @author Slava Pestov
0141:         * @author John Gellene (API documentation)
0142:         * @version $Id: DockableWindowManager.java 10703 2007-09-21 13:14:03Z shlomy $
0143:         * @since jEdit 2.6pre3
0144:         */
0145:        public class DockableWindowManager extends JPanel implements 
0146:                EBComponent {
0147:            //{{{ Constants
0148:            /**
0149:             * Floating position.
0150:             * @since jEdit 2.6pre3
0151:             */
0152:            public static final String FLOATING = "floating";
0153:
0154:            /**
0155:             * Top position.
0156:             * @since jEdit 2.6pre3
0157:             */
0158:            public static final String TOP = "top";
0159:
0160:            /**
0161:             * Left position.
0162:             * @since jEdit 2.6pre3
0163:             */
0164:            public static final String LEFT = "left";
0165:
0166:            /**
0167:             * Bottom position.
0168:             * @since jEdit 2.6pre3
0169:             */
0170:            public static final String BOTTOM = "bottom";
0171:
0172:            /**
0173:             * Right position.
0174:             * @since jEdit 2.6pre3
0175:             */
0176:            public static final String RIGHT = "right";
0177:            //}}}
0178:
0179:            //{{{ Data members
0180:            private View view;
0181:            private DockableWindowFactory factory;
0182:
0183:            /** A mapping from Strings to Entry objects. */
0184:            private Map<String, Entry> windows;
0185:            private PanelWindowContainer left;
0186:            private PanelWindowContainer right;
0187:            private PanelWindowContainer top;
0188:            private PanelWindowContainer bottom;
0189:            private List<Entry> clones;
0190:
0191:            private Entry lastEntry;
0192:            public Stack showStack = new Stack();
0193:
0194:            // }}}
0195:
0196:            //{{{ getRegisteredDockableWindows() method
0197:            /**
0198:             * @since jEdit 4.3pre2
0199:             */
0200:            public static String[] getRegisteredDockableWindows() {
0201:                return DockableWindowFactory.getInstance()
0202:                        .getRegisteredDockableWindows();
0203:            } //}}}
0204:
0205:            //{{{ DockableWindowManager constructor
0206:            /**
0207:             * Creates a new dockable window manager.
0208:             * @param view The view
0209:             * @param factory A {@link DockableWindowFactory}, usually
0210:             * <code>DockableWindowFactory.getInstance()</code>.
0211:             * @param config A docking configuration
0212:             * @since jEdit 2.6pre3
0213:             */
0214:            public DockableWindowManager(View view,
0215:                    DockableWindowFactory factory, View.ViewConfig config) {
0216:                setLayout(new DockableLayout());
0217:                this .view = view;
0218:                this .factory = factory;
0219:
0220:                windows = new HashMap<String, Entry>();
0221:                clones = new ArrayList<Entry>();
0222:
0223:                top = new PanelWindowContainer(this , TOP, config.topPos);
0224:                left = new PanelWindowContainer(this , LEFT, config.leftPos);
0225:                bottom = new PanelWindowContainer(this , BOTTOM,
0226:                        config.bottomPos);
0227:                right = new PanelWindowContainer(this , RIGHT, config.rightPos);
0228:
0229:                add(DockableLayout.TOP_BUTTONS, top.buttonPanel);
0230:                add(DockableLayout.LEFT_BUTTONS, left.buttonPanel);
0231:                add(DockableLayout.BOTTOM_BUTTONS, bottom.buttonPanel);
0232:                add(DockableLayout.RIGHT_BUTTONS, right.buttonPanel);
0233:
0234:                add(TOP, top.dockablePanel);
0235:                add(LEFT, left.dockablePanel);
0236:                add(BOTTOM, bottom.dockablePanel);
0237:                add(RIGHT, right.dockablePanel);
0238:            } //}}}
0239:
0240:            //{{{ init() method
0241:            /**
0242:             * Initialises dockable window manager. Do not call this method directly.
0243:             */
0244:            public void init() {
0245:                EditBus.addToBus(this );
0246:
0247:                Iterator<DockableWindowFactory.Window> entries = factory
0248:                        .getDockableWindowIterator();
0249:
0250:                while (entries.hasNext())
0251:                    addEntry(entries.next());
0252:
0253:                propertiesChanged();
0254:            } //}}}
0255:
0256:            // {{{ closeListener() method
0257:            /**
0258:             * 
0259:             * The actionEvent "close-docking-area" by default only works on 
0260:             * windows that are docked. If you want your floatable plugins to also
0261:             * respond to this event, you need to add key listeners to each component
0262:             * in your plugin that usually has keyboard focus. 
0263:             * This function returns a key listener which does exactly that.
0264:             * You should not need to call this method - it is used by FloatingWindowContainer.
0265:             * 
0266:             * @param dockableName the name of your dockable
0267:             * @return a KeyListener you can add to that plugin's component.
0268:             * @since jEdit 4.3pre6
0269:             * 
0270:             */
0271:            public KeyListener closeListener(String dockableName) {
0272:                return new KeyHandler(dockableName);
0273:            }
0274:
0275:            // }}}
0276:
0277:            //{{{ getView() method
0278:            /**
0279:             * Returns this dockable window manager's view.
0280:             * @since jEdit 4.0pre2
0281:             */
0282:            public View getView() {
0283:                return view;
0284:            } //}}}
0285:
0286:            //{{{ floatDockableWindow() method
0287:            /**
0288:             * Opens a new instance of the specified dockable window in a floating
0289:             * container.
0290:             * @param name The dockable window name
0291:             * @return The new dockable window instance
0292:             * @since jEdit 4.1pre2
0293:             */
0294:            public JComponent floatDockableWindow(String name) {
0295:                Entry entry = windows.get(name);
0296:                if (entry == null) {
0297:                    Log
0298:                            .log(Log.ERROR, this , "Unknown dockable window: "
0299:                                    + name);
0300:                    return null;
0301:                }
0302:
0303:                // create a copy of this dockable window and float it
0304:                Entry newEntry = new Entry(entry.factory, FLOATING);
0305:                newEntry.win = newEntry.factory.createDockableWindow(view,
0306:                        FLOATING);
0307:
0308:                if (newEntry.win != null) {
0309:                    FloatingWindowContainer fwc = new FloatingWindowContainer(
0310:                            this , true);
0311:                    newEntry.container = fwc;
0312:                    newEntry.container.register(newEntry);
0313:                    newEntry.container.show(newEntry);
0314:
0315:                }
0316:                clones.add(newEntry);
0317:                return newEntry.win;
0318:            } //}}}
0319:
0320:            //{{{ showDockableWindow() method
0321:            /**
0322:             * Opens the specified dockable window.
0323:             * @param name The dockable window name
0324:             * @since jEdit 2.6pre3
0325:             */
0326:            public void showDockableWindow(String name) {
0327:                lastEntry = windows.get(name);
0328:                if (lastEntry == null) {
0329:                    Log
0330:                            .log(Log.ERROR, this , "Unknown dockable window: "
0331:                                    + name);
0332:                    return;
0333:                }
0334:
0335:                if (lastEntry.win == null) {
0336:                    lastEntry.win = lastEntry.factory.createDockableWindow(
0337:                            view, lastEntry.position);
0338:                }
0339:
0340:                if (lastEntry.win != null) {
0341:                    if (lastEntry.position.equals(FLOATING)
0342:                            && lastEntry.container == null) {
0343:                        FloatingWindowContainer fwc = new FloatingWindowContainer(
0344:                                this , view.isPlainView());
0345:                        lastEntry.container = fwc;
0346:                        lastEntry.container.register(lastEntry);
0347:                    }
0348:                    showStack.push(name);
0349:                    lastEntry.container.show(lastEntry);
0350:                    Object reason = DockableWindowUpdate.ACTIVATED;
0351:                    EditBus.send(new DockableWindowUpdate(this , reason, name));
0352:                } else
0353:                    /* an error occurred */;
0354:            } //}}}
0355:
0356:            //{{{ addDockableWindow() method
0357:            /**
0358:             * Opens the specified dockable window. As of jEdit 4.0pre1, has the
0359:             * same effect as calling showDockableWindow().
0360:             * @param name The dockable window name
0361:             * @since jEdit 2.6pre3
0362:             */
0363:            public void addDockableWindow(String name) {
0364:                showDockableWindow(name);
0365:            } //}}}
0366:
0367:            //{{{ hideDockableWindow() method
0368:            /**
0369:             * Hides the specified dockable window.
0370:             * @param name The dockable window name
0371:             * @since jEdit 2.6pre3
0372:             */
0373:            public void hideDockableWindow(String name) {
0374:
0375:                Entry entry = windows.get(name);
0376:                if (entry == null) {
0377:                    Log
0378:                            .log(Log.ERROR, this , "Unknown dockable window: "
0379:                                    + name);
0380:                    return;
0381:                }
0382:
0383:                if (entry.win == null)
0384:                    return;
0385:                Object reason = DockableWindowUpdate.DEACTIVATED;
0386:                EditBus.send(new DockableWindowUpdate(this , reason, name));
0387:
0388:                entry.container.show(null);
0389:            } //}}}
0390:
0391:            //{{{ removeDockableWindow() method
0392:            /**
0393:             * Hides the specified dockable window. As of jEdit 4.2pre1, has the
0394:             * same effect as calling hideDockableWindow().
0395:             * @param name The dockable window name
0396:             * @since jEdit 4.2pre1
0397:             */
0398:            public void removeDockableWindow(String name) {
0399:                hideDockableWindow(name);
0400:            } //}}}
0401:
0402:            //{{{ toggleDockableWindow() method
0403:            /**
0404:             * Toggles the visibility of the specified dockable window.
0405:             * @param name The dockable window name
0406:             */
0407:            public void toggleDockableWindow(String name) {
0408:                if (isDockableWindowVisible(name))
0409:                    removeDockableWindow(name);
0410:                else
0411:                    addDockableWindow(name);
0412:            } //}}}
0413:
0414:            //{{{ getDockableWindow() method
0415:            /**
0416:             * Returns the specified dockable window.
0417:             *
0418:             * Note that this method
0419:             * will return null if the dockable has not been added yet.
0420:             * Make sure you call {@link #addDockableWindow(String)} first.
0421:             *
0422:             * @param name The name of the dockable window
0423:             * @since jEdit 4.1pre2
0424:             */
0425:            public JComponent getDockableWindow(String name) {
0426:                return getDockable(name);
0427:            } //}}}
0428:
0429:            //{{{ getDockable() method
0430:            /**
0431:             * Returns the specified dockable window.
0432:             *
0433:             * Note that this method
0434:             * will return null if the dockable has not been added yet.
0435:             * Make sure you call {@link #addDockableWindow(String)} first.
0436:             *
0437:             * For historical reasons, this
0438:             * does the same thing as {@link #getDockableWindow(String)}.
0439:             *
0440:             * @param name The name of the dockable window
0441:             * @since jEdit 4.0pre1
0442:             */
0443:            public JComponent getDockable(String name) {
0444:
0445:                Entry entry = windows.get(name);
0446:                if (entry == null || entry.win == null)
0447:                    return null;
0448:                else
0449:                    return entry.win;
0450:            } //}}}
0451:
0452:            //{{{ getDockableTitle() method
0453:            /**
0454:             * Returns the title of the specified dockable window.
0455:             * @param name The name of the dockable window.
0456:             * @since jEdit 4.1pre5
0457:             */
0458:            public String getDockableTitle(String name) {
0459:                Entry e = windows.get(name);
0460:                return e.longTitle();
0461:            } //}}}
0462:
0463:            //{{{ setDockableTitle() method
0464:            /**
0465:             * Changes the .longtitle property of a dockable window, which corresponds to the 
0466:             * title shown when it is floating (not docked). Fires a change event that makes sure
0467:             * all floating dockables change their title.
0468:             * 
0469:             * @param dockableName the name of the dockable, as specified in the dockables.xml
0470:             * @param newTitle the new .longtitle you want to see above it.
0471:             * @since 4.3pre5
0472:             * 
0473:             */
0474:            public void setDockableTitle(String dockableName, String newTitle) {
0475:                Entry entry = windows.get(dockableName);
0476:                String propName = entry.factory.name + ".longtitle";
0477:                String oldTitle = jEdit.getProperty(propName);
0478:                jEdit.setProperty(propName, newTitle);
0479:                firePropertyChange(propName, oldTitle, newTitle);
0480:            }
0481:
0482:            // }}}
0483:
0484:            //{{{ isDockableWindowVisible() method
0485:            /**
0486:             * Returns if the specified dockable window is visible.
0487:             * @param name The dockable window name
0488:             */
0489:            public boolean isDockableWindowVisible(String name) {
0490:                Entry entry = windows.get(name);
0491:                if (entry == null || entry.win == null)
0492:                    return false;
0493:                else
0494:                    return entry.container.isVisible(entry);
0495:            } //}}}
0496:
0497:            //{{{ isDockableWindowDocked() method
0498:            /**
0499:             * Returns if the specified dockable window is docked into the
0500:             * view.
0501:             * @param name The dockable's name
0502:             * @since jEdit 4.0pre2
0503:             */
0504:            public boolean isDockableWindowDocked(String name) {
0505:                Entry entry = windows.get(name);
0506:                if (entry == null)
0507:                    return false;
0508:                else
0509:                    return !entry.position.equals(FLOATING);
0510:            } //}}}
0511:
0512:            //{{{ closeCurrentArea() method
0513:            /**
0514:             * Closes the most recently focused dockable. 
0515:             * @since jEdit 4.1pre3
0516:             */
0517:            public void closeCurrentArea() {
0518:                // I don't know of any other way to fix this, since invoking this
0519:                // command from a menu results in the focus owner being the menu
0520:                // until the menu goes away.
0521:                SwingUtilities.invokeLater(new Runnable() {
0522:                    public void run() {
0523:                        /* Try to hide the last entry that was shown */
0524:                        try {
0525:                            String dockableName = showStack.pop().toString();
0526:                            hideDockableWindow(dockableName);
0527:                            return;
0528:                        } catch (Exception e) {
0529:                        }
0530:
0531:                        Component comp = view.getFocusOwner();
0532:                        while (comp != null) {
0533:                            //System.err.println(comp.getClass());
0534:                            if (comp instanceof  DockablePanel) {
0535:                                DockablePanel panel = (DockablePanel) comp;
0536:
0537:                                PanelWindowContainer container = panel
0538:                                        .getWindowContainer();
0539:
0540:                                container.show(null);
0541:                                return;
0542:                            }
0543:
0544:                            comp = comp.getParent();
0545:                        }
0546:
0547:                        getToolkit().beep();
0548:                    }
0549:                });
0550:            } //}}}
0551:
0552:            //{{{ close() method
0553:            /**
0554:             * Called when the view is being closed.
0555:             * @since jEdit 2.6pre3
0556:             */
0557:            public void close() {
0558:                EditBus.removeFromBus(this );
0559:
0560:                for (Entry entry : windows.values()) {
0561:                    if (entry.win != null)
0562:                        entry.container.unregister(entry);
0563:                }
0564:
0565:                for (Entry clone : clones) {
0566:                    if (clone.win != null)
0567:                        clone.container.unregister(clone);
0568:                }
0569:            } //}}}
0570:
0571:            //{{{ getTopDockingArea() method
0572:            public PanelWindowContainer getTopDockingArea() {
0573:                return top;
0574:            } //}}}
0575:
0576:            //{{{ getLeftDockingArea() method
0577:            public PanelWindowContainer getLeftDockingArea() {
0578:                return left;
0579:            } //}}}
0580:
0581:            //{{{ getBottomDockingArea() method
0582:            public PanelWindowContainer getBottomDockingArea() {
0583:                return bottom;
0584:            } //}}}
0585:
0586:            //{{{ getRightDockingArea() method
0587:            public PanelWindowContainer getRightDockingArea() {
0588:                return right;
0589:            } //}}}
0590:
0591:            //{{{ createPopupMenu() method
0592:            public JPopupMenu createPopupMenu(
0593:                    final DockableWindowContainer container,
0594:                    final String dockable, final boolean clone) {
0595:                JPopupMenu popup = new JPopupMenu();
0596:                if (dockable == null
0597:                        && container instanceof  PanelWindowContainer) {
0598:                    ActionListener listener = new ActionListener() {
0599:                        public void actionPerformed(ActionEvent evt) {
0600:                            showDockableWindow(evt.getActionCommand());
0601:                        }
0602:                    };
0603:
0604:                    String[] dockables = ((PanelWindowContainer) container)
0605:                            .getDockables();
0606:                    Map<String, String> dockableMap = new TreeMap<String, String>();
0607:                    for (int i = 0; i < dockables.length; i++) {
0608:                        String action = dockables[i];
0609:                        dockableMap.put(getDockableTitle(action), action);
0610:                    }
0611:                    for (Map.Entry<String, String> entry : dockableMap
0612:                            .entrySet()) {
0613:                        JMenuItem item = new JMenuItem(entry.getKey());
0614:                        item.setActionCommand(entry.getValue());
0615:                        item.addActionListener(listener);
0616:                        popup.add(item);
0617:                    }
0618:                } else {
0619:                    JMenuItem caption = new JMenuItem(
0620:                            getDockableTitle(dockable));
0621:                    caption.setEnabled(false);
0622:                    popup.add(caption);
0623:                    popup.addSeparator();
0624:                    String currentPos = jEdit.getProperty(dockable
0625:                            + ".dock-position", FLOATING);
0626:                    if (!clone) {
0627:                        String[] positions = { FLOATING, TOP, LEFT, BOTTOM,
0628:                                RIGHT };
0629:                        for (int i = 0; i < positions.length; i++) {
0630:                            final String pos = positions[i];
0631:                            if (pos.equals(currentPos))
0632:                                continue;
0633:
0634:                            JMenuItem moveMenuItem = new JMenuItem(jEdit
0635:                                    .getProperty("view.docking.menu-" + pos));
0636:
0637:                            moveMenuItem
0638:                                    .addActionListener(new ActionListener() {
0639:                                        public void actionPerformed(
0640:                                                ActionEvent evt) {
0641:                                            jEdit.setProperty(dockable
0642:                                                    + ".dock-position", pos);
0643:                                            EditBus
0644:                                                    .send(new DockableWindowUpdate(
0645:                                                            DockableWindowManager.this ,
0646:                                                            DockableWindowUpdate.PROPERTIES_CHANGED,
0647:                                                            null));
0648:                                            showDockableWindow(dockable);
0649:                                        }
0650:                                    });
0651:                            popup.add(moveMenuItem);
0652:                        }
0653:
0654:                        popup.addSeparator();
0655:                    }
0656:
0657:                    JMenuItem cloneMenuItem = new JMenuItem(jEdit
0658:                            .getProperty("view.docking.menu-clone"));
0659:
0660:                    cloneMenuItem.addActionListener(new ActionListener() {
0661:                        public void actionPerformed(ActionEvent evt) {
0662:                            floatDockableWindow(dockable);
0663:                        }
0664:                    });
0665:                    popup.add(cloneMenuItem);
0666:
0667:                    popup.addSeparator();
0668:
0669:                    JMenuItem closeMenuItem = new JMenuItem(jEdit
0670:                            .getProperty("view.docking.menu-close"));
0671:
0672:                    closeMenuItem.addActionListener(new ActionListener() {
0673:                        public void actionPerformed(ActionEvent evt) {
0674:                            if (clone)
0675:                                ((FloatingWindowContainer) container).dispose();
0676:                            else
0677:                                removeDockableWindow(dockable);
0678:                        }
0679:                    });
0680:                    popup.add(closeMenuItem);
0681:
0682:                    if (!(clone || currentPos.equals(FLOATING))) {
0683:                        JMenuItem undockMenuItem = new JMenuItem(jEdit
0684:                                .getProperty("view.docking.menu-undock"));
0685:
0686:                        undockMenuItem.addActionListener(new ActionListener() {
0687:                            public void actionPerformed(ActionEvent evt) {
0688:                                jEdit.setProperty(dockable + ".dock-position",
0689:                                        FLOATING);
0690:                                EditBus
0691:                                        .send(new DockableWindowUpdate(
0692:                                                DockableWindowManager.this ,
0693:                                                DockableWindowUpdate.PROPERTIES_CHANGED,
0694:                                                null));
0695:                                // Reset the window, propertiesChanged() doesn't
0696:                                // reset it for MOVABLE windows.
0697:                                Entry entry = windows.get(dockable);
0698:                                if (entry == null)
0699:                                    Log.log(Log.ERROR, this ,
0700:                                            "Unknown dockable window: "
0701:                                                    + dockable);
0702:                                else
0703:                                    entry.win = null;
0704:                            }
0705:                        });
0706:                        popup.add(undockMenuItem);
0707:                    }
0708:                }
0709:
0710:                return popup;
0711:            } //}}}
0712:
0713:            //{{{ paintChildren() method
0714:            public void paintChildren(Graphics g) {
0715:                super .paintChildren(g);
0716:
0717:                if (resizeRect != null) {
0718:                    g.setColor(Color.darkGray);
0719:                    g.fillRect(resizeRect.x, resizeRect.y, resizeRect.width,
0720:                            resizeRect.height);
0721:                }
0722:            } //}}}
0723:
0724:            //{{{ handleMessage() method
0725:            public void handleMessage(EBMessage msg) {
0726:                if (msg instanceof  DockableWindowUpdate) {
0727:                    if (((DockableWindowUpdate) msg).getWhat() == DockableWindowUpdate.PROPERTIES_CHANGED)
0728:                        propertiesChanged();
0729:                } else if (msg instanceof  PropertiesChanged)
0730:                    propertiesChanged();
0731:                else if (msg instanceof  PluginUpdate) {
0732:                    PluginUpdate pmsg = (PluginUpdate) msg;
0733:                    if (pmsg.getWhat() == PluginUpdate.LOADED) {
0734:                        Iterator<DockableWindowFactory.Window> iter = factory
0735:                                .getDockableWindowIterator();
0736:
0737:                        while (iter.hasNext()) {
0738:                            DockableWindowFactory.Window w = iter.next();
0739:                            if (w.plugin == pmsg.getPluginJAR())
0740:                                addEntry(w);
0741:                        }
0742:
0743:                        propertiesChanged();
0744:                    } else if (pmsg.isExiting()) {
0745:                        // we don't care
0746:                    } else if (pmsg.getWhat() == PluginUpdate.DEACTIVATED) {
0747:                        Iterator<Entry> iter = getAllPluginEntries(pmsg
0748:                                .getPluginJAR(), false);
0749:                        while (iter.hasNext()) {
0750:                            Entry entry = iter.next();
0751:                            if (entry.container != null)
0752:                                entry.container.remove(entry);
0753:                        }
0754:                    } else if (pmsg.getWhat() == PluginUpdate.UNLOADED) {
0755:                        Iterator<Entry> iter = getAllPluginEntries(pmsg
0756:                                .getPluginJAR(), true);
0757:                        while (iter.hasNext()) {
0758:                            Entry entry = iter.next();
0759:                            if (entry.container != null) {
0760:                                entry.container.unregister(entry);
0761:                                entry.win = null;
0762:                                entry.container = null;
0763:                            }
0764:                        }
0765:                    }
0766:                }
0767:            } //}}}
0768:
0769:            //{{{ Package-private members
0770:            int resizePos;
0771:            /**
0772:             * This is the rectangle you drag to resize the split.
0773:             * It is used with non continuous layout.
0774:             */
0775:            Rectangle resizeRect;
0776:
0777:            //{{{ setResizePos() method
0778:            void setResizePos(int resizePos, PanelWindowContainer resizing) {
0779:                this .resizePos = resizePos;
0780:
0781:                if (resizePos < 0)
0782:                    resizePos = 0;
0783:
0784:                if (continuousLayout)
0785:                    return;
0786:
0787:                Rectangle newResizeRect = new Rectangle(0, 0,
0788:                        PanelWindowContainer.SPLITTER_WIDTH - 2,
0789:                        PanelWindowContainer.SPLITTER_WIDTH - 2);
0790:                if (resizing == top) {
0791:                    resizePos = Math.min(resizePos, getHeight()
0792:                            - top.buttonPanel.getHeight()
0793:                            - bottom.dockablePanel.getHeight()
0794:                            - bottom.buttonPanel.getHeight()
0795:                            - PanelWindowContainer.SPLITTER_WIDTH);
0796:                    newResizeRect.x = top.dockablePanel.getX() + 1;
0797:                    newResizeRect.y = resizePos + top.buttonPanel.getHeight()
0798:                            + 1;
0799:                    newResizeRect.width = top.dockablePanel.getWidth() - 2;
0800:                } else if (resizing == left) {
0801:                    resizePos = Math.min(resizePos, getWidth()
0802:                            - left.buttonPanel.getWidth()
0803:                            - right.dockablePanel.getWidth()
0804:                            - right.buttonPanel.getWidth()
0805:                            - PanelWindowContainer.SPLITTER_WIDTH);
0806:                    newResizeRect.x = resizePos + left.buttonPanel.getWidth()
0807:                            + 1;
0808:                    newResizeRect.y = left.dockablePanel.getY() + 1;
0809:                    newResizeRect.height = left.dockablePanel.getHeight() - 2;
0810:                } else if (resizing == bottom) {
0811:                    resizePos = Math.min(resizePos, getHeight()
0812:                            - bottom.buttonPanel.getHeight()
0813:                            - top.dockablePanel.getHeight()
0814:                            - top.buttonPanel.getHeight()
0815:                            - PanelWindowContainer.SPLITTER_WIDTH);
0816:                    newResizeRect.x = bottom.dockablePanel.getX() + 1;
0817:                    newResizeRect.y = getHeight()
0818:                            - bottom.buttonPanel.getHeight() - resizePos
0819:                            - PanelWindowContainer.SPLITTER_WIDTH + 2;
0820:                    newResizeRect.width = bottom.dockablePanel.getWidth() - 2;
0821:                } else if (resizing == right) {
0822:                    resizePos = Math.min(resizePos, getWidth()
0823:                            - right.buttonPanel.getWidth()
0824:                            - left.dockablePanel.getWidth()
0825:                            - left.buttonPanel.getWidth()
0826:                            - PanelWindowContainer.SPLITTER_WIDTH);
0827:                    newResizeRect.x = getWidth() - right.buttonPanel.getWidth()
0828:                            - resizePos - PanelWindowContainer.SPLITTER_WIDTH
0829:                            + 1;
0830:                    newResizeRect.y = right.dockablePanel.getY() + 1;
0831:                    newResizeRect.height = right.dockablePanel.getHeight() - 2;
0832:                }
0833:
0834:                Rectangle toRepaint;
0835:                if (resizeRect == null)
0836:                    toRepaint = newResizeRect;
0837:                else
0838:                    toRepaint = resizeRect.union(newResizeRect);
0839:                resizeRect = newResizeRect;
0840:                repaint(toRepaint);
0841:            } //}}}
0842:
0843:            //{{{ finishResizing() method
0844:            void finishResizing() {
0845:                resizeRect = null;
0846:                repaint();
0847:            } //}}}
0848:
0849:            //}}}
0850:
0851:            //{{{ propertiesChanged() method
0852:            private void propertiesChanged() {
0853:                if (view.isPlainView())
0854:                    return;
0855:
0856:                ((DockableLayout) getLayout()).setAlternateLayout(jEdit
0857:                        .getBooleanProperty("view.docking.alternateLayout"));
0858:
0859:                String[] windowList = factory.getRegisteredDockableWindows();
0860:
0861:                for (int i = 0; i < windowList.length; i++) {
0862:                    String dockable = windowList[i];
0863:                    Entry entry = windows.get(dockable);
0864:
0865:                    String newPosition = jEdit.getProperty(dockable
0866:                            + ".dock-position", FLOATING);
0867:                    if (newPosition.equals(entry.position)) {
0868:                        continue;
0869:                    }
0870:
0871:                    entry.position = newPosition;
0872:                    if (entry.container != null) {
0873:                        entry.container.unregister(entry);
0874:                        entry.container = null;
0875:                        if (entry.factory.movable) {
0876:                            if (entry.win instanceof  DockableWindow)
0877:                                ((DockableWindow) entry.win).move(newPosition);
0878:                        } else
0879:                            entry.win = null;
0880:                    }
0881:
0882:                    if (newPosition.equals(FLOATING)) {
0883:                    }
0884:
0885:                    else {
0886:                        if (newPosition.equals(TOP))
0887:                            entry.container = top;
0888:                        else if (newPosition.equals(LEFT))
0889:                            entry.container = left;
0890:                        else if (newPosition.equals(BOTTOM))
0891:                            entry.container = bottom;
0892:                        else if (newPosition.equals(RIGHT))
0893:                            entry.container = right;
0894:                        else {
0895:                            Log.log(Log.WARNING, this , "Unknown position: "
0896:                                    + newPosition);
0897:                            continue;
0898:                        }
0899:
0900:                        entry.container.register(entry);
0901:                    }
0902:                }
0903:
0904:                top.sortDockables();
0905:                left.sortDockables();
0906:                bottom.sortDockables();
0907:                right.sortDockables();
0908:
0909:                continuousLayout = jEdit
0910:                        .getBooleanProperty("appearance.continuousLayout");
0911:                revalidate();
0912:                repaint();
0913:            } //}}}
0914:
0915:            //{{{ addEntry() method
0916:            private void addEntry(DockableWindowFactory.Window factory) {
0917:                Entry e;
0918:                if (view.isPlainView()) {
0919:                    // don't show menu items to dock into a plain view
0920:                    e = new Entry(factory, FLOATING);
0921:                } else {
0922:                    e = new Entry(factory);
0923:                    if (e.position.equals(FLOATING))
0924:                        /* nothing to do */;
0925:                    else if (e.position.equals(TOP))
0926:                        e.container = top;
0927:                    else if (e.position.equals(LEFT))
0928:                        e.container = left;
0929:                    else if (e.position.equals(BOTTOM))
0930:                        e.container = bottom;
0931:                    else if (e.position.equals(RIGHT))
0932:                        e.container = right;
0933:                    else {
0934:                        Log.log(Log.WARNING, this , "Unknown position: "
0935:                                + e.position);
0936:                    }
0937:
0938:                    if (e.container != null)
0939:                        e.container.register(e);
0940:                }
0941:                windows.put(factory.name, e);
0942:            } //}}}
0943:
0944:            //{{{ getAllPluginEntries() method
0945:            /**
0946:             * If remove is false, only remove from clones list, otherwise remove
0947:             * from both entries and clones.
0948:             */
0949:            private Iterator<Entry> getAllPluginEntries(PluginJAR plugin,
0950:                    boolean remove) {
0951:                List<Entry> returnValue = new LinkedList<Entry>();
0952:                Iterator<Entry> iter = windows.values().iterator();
0953:                while (iter.hasNext()) {
0954:                    Entry entry = iter.next();
0955:                    if (entry.factory.plugin == plugin) {
0956:                        returnValue.add(entry);
0957:                        if (remove)
0958:                            iter.remove();
0959:                    }
0960:                }
0961:
0962:                iter = clones.iterator();
0963:                while (iter.hasNext()) {
0964:                    Entry entry = iter.next();
0965:                    if (entry.factory.plugin == plugin) {
0966:                        returnValue.add(entry);
0967:                        iter.remove();
0968:                    }
0969:                }
0970:
0971:                return returnValue.iterator();
0972:            } //}}}
0973:
0974:            private boolean continuousLayout;
0975:
0976:            //{{{ Entry class
0977:            class Entry {
0978:                DockableWindowFactory.Window factory;
0979:
0980:                //		String title;
0981:                String position;
0982:                DockableWindowContainer container;
0983:
0984:                // only set if open
0985:                JComponent win;
0986:
0987:                // only for docked
0988:                AbstractButton btn;
0989:
0990:                //{{{ Entry constructor
0991:                Entry(DockableWindowFactory.Window factory) {
0992:                    this (factory, jEdit.getProperty(factory.name
0993:                            + ".dock-position", FLOATING));
0994:                } //}}}
0995:
0996:                /**
0997:                 * @return the long title for the dockable floating window.
0998:                 */
0999:                public String longTitle() {
1000:                    String title = jEdit.getProperty(factory.name
1001:                            + ".longtitle");
1002:                    if (title == null)
1003:                        return shortTitle();
1004:                    else
1005:                        return title;
1006:
1007:                }
1008:
1009:                /**
1010:                 * @return The short title, for the dockable button text
1011:                 */
1012:                public String shortTitle() {
1013:
1014:                    String title = jEdit.getProperty(factory.name + ".title");
1015:                    if (title == null)
1016:                        return "NO TITLE PROPERTY: " + factory.name;
1017:                    else
1018:                        return title;
1019:                }
1020:
1021:                /**
1022:                 * @return A label appropriate for the title on the dock buttons.
1023:                 */
1024:                public String label() {
1025:                    String retval = jEdit.getProperty(factory.name + ".label");
1026:                    retval = retval.replaceAll("\\$", "");
1027:                    return retval;
1028:                }
1029:
1030:                //{{{ Entry constructor
1031:                Entry(DockableWindowFactory.Window factory, String position) {
1032:                    this .factory = factory;
1033:                    this .position = position;
1034:
1035:                    // get the title here, not in the factory constructor,
1036:                    // since the factory might be created before a plugin's
1037:                    // props are loaded
1038:
1039:                } //}}}
1040:            } //}}}
1041:
1042:            /**
1043:             * This keyhandler responds to only two key events - those corresponding to
1044:             * the close-docking-area action event. 
1045:             * 
1046:             * @author ezust
1047:             *
1048:             */
1049:            class KeyHandler extends KeyAdapter {
1050:                static final String action = "close-docking-area";
1051:                Key b1, b2;
1052:                String name;
1053:
1054:                public KeyHandler(String dockableName) {
1055:                    String shortcut1 = jEdit.getProperty(action + ".shortcut");
1056:                    String shortcut2 = jEdit.getProperty(action + ".shortcut2");
1057:                    if (shortcut1 != null)
1058:                        b1 = KeyEventTranslator.parseKey(shortcut1);
1059:                    if (shortcut2 != null)
1060:                        b2 = KeyEventTranslator.parseKey(shortcut2);
1061:                    name = dockableName;
1062:                }
1063:
1064:                public void keyTyped(KeyEvent e) {
1065:                    char cc = e.getKeyChar();
1066:                    if ((b1 != null && cc == b1.key)
1067:                            || (b2 != null && cc == b2.key))
1068:                        hideDockableWindow(name);
1069:                }
1070:
1071:            }
1072:
1073:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.