Source Code Cross Referenced for WorkbenchFrame.java in  » GIS » openjump » com » vividsolutions » jump » workbench » ui » 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 » GIS » openjump » com.vividsolutions.jump.workbench.ui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI for
0003:         * visualizing and manipulating spatial features with geometry and attributes.
0004:         *
0005:         * Copyright (C) 2003 Vivid Solutions
0006:         *
0007:         * This program is free software; you can redistribute it and/or modify it
0008:         * under the terms of the GNU General Public License as published by the Free
0009:         * Software Foundation; either version 2 of the License, or (at your option)
0010:         * any later version.
0011:         *
0012:         * This program is distributed in the hope that it will be useful, but WITHOUT
0013:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0014:         * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
0015:         * more details.
0016:         *
0017:         * You should have received a copy of the GNU General Public License along with
0018:         * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
0019:         * Place - Suite 330, Boston, MA 02111-1307, USA.
0020:         *
0021:         * For more information, contact:
0022:         *
0023:         * Vivid Solutions Suite #1A 2328 Government Street Victoria BC V8T 5G5 Canada
0024:         *
0025:         * (250)385-6040 www.vividsolutions.com
0026:         */
0027:        package com.vividsolutions.jump.workbench.ui;
0028:
0029:        import com.vividsolutions.jts.geom.Envelope;
0030:        import com.vividsolutions.jts.util.Assert;
0031:        import com.vividsolutions.jump.I18N;
0032:        import com.vividsolutions.jump.util.Block;
0033:        import com.vividsolutions.jump.util.CollectionUtil;
0034:        import com.vividsolutions.jump.util.StringUtil;
0035:        import com.vividsolutions.jump.workbench.WorkbenchContext;
0036:        import com.vividsolutions.jump.workbench.model.Category;
0037:        import com.vividsolutions.jump.workbench.model.CategoryEvent;
0038:        import com.vividsolutions.jump.workbench.model.FeatureEvent;
0039:        import com.vividsolutions.jump.workbench.model.Layer;
0040:        import com.vividsolutions.jump.workbench.model.LayerEvent;
0041:        import com.vividsolutions.jump.workbench.model.LayerEventType;
0042:        import com.vividsolutions.jump.workbench.model.LayerListener;
0043:        import com.vividsolutions.jump.workbench.model.LayerManager;
0044:        import com.vividsolutions.jump.workbench.model.LayerManagerProxy;
0045:        import com.vividsolutions.jump.workbench.model.Layerable;
0046:        import com.vividsolutions.jump.workbench.model.StandardCategoryNames;
0047:        import com.vividsolutions.jump.workbench.model.Task;
0048:        import com.vividsolutions.jump.workbench.model.UndoableEditReceiver;
0049:        import com.vividsolutions.jump.workbench.model.WMSLayer;
0050:        import com.vividsolutions.jump.workbench.plugin.*;
0051:        import com.vividsolutions.jump.workbench.plugin.EnableCheck;
0052:        import com.vividsolutions.jump.workbench.plugin.PlugIn;
0053:        import com.vividsolutions.jump.workbench.plugin.PlugInContext;
0054:        import com.vividsolutions.jump.workbench.plugin.ThreadedPlugIn;
0055:        import com.vividsolutions.jump.workbench.ui.plugin.CloneWindowPlugIn;
0056:        import com.vividsolutions.jump.workbench.ui.plugin.FeatureInstaller;
0057:        import com.vividsolutions.jump.workbench.ui.renderer.style.ChoosableStyle;
0058:        import com.vividsolutions.jump.workbench.ui.task.TaskMonitorManager;
0059:        import java.awt.BorderLayout;
0060:        import java.awt.Color;
0061:        import java.awt.Component;
0062:        import java.awt.Dialog;
0063:        import java.awt.Dimension;
0064:        import java.awt.Graphics;
0065:        import java.awt.GridBagConstraints;
0066:        import java.awt.GridBagLayout;
0067:        import java.awt.Insets;
0068:        import java.awt.Window;
0069:        import java.awt.event.ActionEvent;
0070:        import java.awt.event.ActionListener;
0071:        import java.awt.event.ComponentEvent;
0072:        import java.awt.event.KeyEvent;
0073:        import java.awt.event.KeyListener;
0074:        import java.awt.event.WindowEvent;
0075:        import java.beans.PropertyChangeEvent;
0076:        import java.beans.PropertyChangeListener;
0077:        import java.beans.PropertyVetoException;
0078:        import java.text.DecimalFormat;
0079:        import java.util.*;
0080:        import java.util.ArrayList;
0081:        import java.util.Collection;
0082:        import java.util.Collections;
0083:        import java.util.Date;
0084:        import java.util.HashSet;
0085:        import java.util.Iterator;
0086:        import java.util.Map;
0087:        import java.util.Set;
0088:        import javax.swing.*;
0089:        import javax.swing.BorderFactory;
0090:        import javax.swing.ImageIcon;
0091:        import javax.swing.JDesktopPane;
0092:        import javax.swing.JFrame;
0093:        import javax.swing.JInternalFrame;
0094:        import javax.swing.JLabel;
0095:        import javax.swing.JMenu;
0096:        import javax.swing.JMenuBar;
0097:        import javax.swing.JMenuItem;
0098:        import javax.swing.JOptionPane;
0099:        import javax.swing.JPanel;
0100:        import javax.swing.SwingConstants;
0101:        import javax.swing.SwingUtilities;
0102:        import javax.swing.Timer;
0103:        import javax.swing.event.InternalFrameAdapter;
0104:        import javax.swing.event.InternalFrameEvent;
0105:        import javax.swing.event.InternalFrameListener;
0106:        import javax.swing.event.MenuEvent;
0107:        import javax.swing.event.PopupMenuEvent;
0108:        import javax.swing.event.PopupMenuListener;
0109:
0110:        /**
0111:         * This class is responsible for the main window of the JUMP application.
0112:         */
0113:        public class WorkbenchFrame extends JFrame implements 
0114:                LayerViewPanelContext, ViewportListener {
0115:            BorderLayout borderLayout1 = new BorderLayout();
0116:            JLabel coordinateLabel = new JLabel();
0117:            JMenuBar menuBar = new JMenuBar();
0118:            JMenu fileMenu = (JMenu) FeatureInstaller.installMnemonic(
0119:                    new JMenu(MenuNames.FILE), menuBar);
0120:            JMenuItem exitMenuItem = FeatureInstaller
0121:                    .installMnemonic(new JMenuItem(I18N
0122:                            .get("ui.WorkbenchFrame.exit")), fileMenu);
0123:            GridBagLayout gridBagLayout1 = new GridBagLayout();
0124:            JLabel messageLabel = new JLabel();
0125:            JPanel statusPanel = new JPanel();
0126:            JLabel timeLabel = new JLabel();
0127:            //<<TODO:FEATURE>> Before JUMP Workbench closes, prompt the user to save
0128:            // any
0129:            //unsaved layers [Jon Aquino]
0130:            WorkbenchToolBar toolBar;
0131:            JMenu windowMenu = (JMenu) FeatureInstaller.installMnemonic(
0132:                    new JMenu(MenuNames.WINDOW), menuBar);
0133:
0134:            private DecimalFormat memoryFormat = new DecimalFormat("###,###");
0135:
0136:            private TitledPopupMenu categoryPopupMenu = new TitledPopupMenu() {
0137:                {
0138:                    addPopupMenuListener(new PopupMenuListener() {
0139:                        public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
0140:                            LayerNamePanel panel = ((LayerNamePanelProxy) getActiveInternalFrame())
0141:                                    .getLayerNamePanel();
0142:                            setTitle((panel.selectedNodes(Category.class)
0143:                                    .size() != 1) ? ("("
0144:                                    + panel.selectedNodes(Category.class)
0145:                                            .size() + " categories selected)")
0146:                                    : ((Category) panel.selectedNodes(
0147:                                            Category.class).iterator().next())
0148:                                            .getName());
0149:                        }
0150:
0151:                        public void popupMenuWillBecomeInvisible(
0152:                                PopupMenuEvent e) {
0153:                        }
0154:
0155:                        public void popupMenuCanceled(PopupMenuEvent e) {
0156:                        }
0157:                    });
0158:                }
0159:            };
0160:            private JDesktopPane desktopPane = new JDesktopPane() {
0161:                {
0162:                    // Simple workaround for the following JUMP bug: if you maximize one JInternalFrame, then all
0163:                    // JInternalFrames get maximized (including attribute windows, undesirably). The workaround is
0164:                    // to use the DefaultDesktopManager instead of the one installed by the Windows L&F
0165:                    // (the WindowsDesktopManager). (Uwe Dalluege noticed that the problem occurred with the
0166:                    // Windows L&F but not the Metal L&F -- this observation led me to the solution).
0167:                    // [Jon Aquino 2005-07-04]
0168:                    setDesktopManager(new DefaultDesktopManager());
0169:                }
0170:            };
0171:            //<<TODO:REMOVE>> Actually we're not using the three optimization
0172:            // parameters
0173:            //below. Remove. [Jon Aquino]
0174:            private int envelopeRenderingThreshold = 500;
0175:            private HTMLFrame outputFrame = new HTMLFrame(this ) {
0176:                public void setTitle(String title) {
0177:                    //Don't allow the title of the output frame to be changed.
0178:                }
0179:
0180:                {
0181:                    super .setTitle(I18N.get("ui.WorkbenchFrame.output"));
0182:                }
0183:            };
0184:            private ImageIcon icon;
0185:            private TitledPopupMenu layerNamePopupMenu = new TitledPopupMenu() {
0186:                {
0187:                    addPopupMenuListener(new PopupMenuListener() {
0188:                        public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
0189:                            LayerNamePanel panel = ((LayerNamePanelProxy) getActiveInternalFrame())
0190:                                    .getLayerNamePanel();
0191:                            setTitle((panel.selectedNodes(Layer.class).size() != 1) ? ("("
0192:                                    + panel.selectedNodes(Layer.class).size()
0193:                                    + " "
0194:                                    + I18N
0195:                                            .get("ui.WorkbenchFrame.layers-selected") + ")")
0196:                                    : ((Layerable) panel.selectedNodes(
0197:                                            Layer.class).iterator().next())
0198:                                            .getName());
0199:                        }
0200:
0201:                        public void popupMenuWillBecomeInvisible(
0202:                                PopupMenuEvent e) {
0203:                        }
0204:
0205:                        public void popupMenuCanceled(PopupMenuEvent e) {
0206:                        }
0207:                    });
0208:                }
0209:            };
0210:            private TitledPopupMenu wmsLayerNamePopupMenu = new TitledPopupMenu() {
0211:                {
0212:                    addPopupMenuListener(new PopupMenuListener() {
0213:                        public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
0214:                            LayerNamePanel panel = ((LayerNamePanelProxy) getActiveInternalFrame())
0215:                                    .getLayerNamePanel();
0216:                            setTitle((panel.selectedNodes(WMSLayer.class)
0217:                                    .size() != 1) ? ("("
0218:                                    + panel.selectedNodes(WMSLayer.class)
0219:                                            .size()
0220:                                    + " "
0221:                                    + I18N
0222:                                            .get("ui.WorkbenchFrame.wms-layers-selected") + ")")
0223:                                    : ((Layerable) panel.selectedNodes(
0224:                                            WMSLayer.class).iterator().next())
0225:                                            .getName());
0226:                        }
0227:
0228:                        public void popupMenuWillBecomeInvisible(
0229:                                PopupMenuEvent e) {
0230:                        }
0231:
0232:                        public void popupMenuCanceled(PopupMenuEvent e) {
0233:                        }
0234:                    });
0235:                }
0236:            };
0237:            private LayerNamePanelListener layerNamePanelListener = new LayerNamePanelListener() {
0238:                public void layerSelectionChanged() {
0239:                    toolBar.updateEnabledState();
0240:                }
0241:            };
0242:            //Here is a small patch to JUMP to avoid creating a StringBuffer every
0243:            //coordinate change (which could be many thoustands). Replace the innter
0244:            //class in WorkbenchFrame.java with the following. I am assuming only one
0245:            //thread can call the listener at a time. If that is untrue please
0246:            // synchronize
0247:            //cursorPositionChanged().
0248:            //
0249:            //Sheldon Young 2004-01-30
0250:            private LayerViewPanelListener layerViewPanelListener = new LayerViewPanelListener() {
0251:                // Avoid creating an expensive StringBuffer when the cursor position
0252:                // changes.
0253:                private StringBuffer positionStatusBuf = new StringBuffer("(");
0254:
0255:                public void cursorPositionChanged(String x, String y) {
0256:                    positionStatusBuf.setLength(1);
0257:                    positionStatusBuf.append(x).append(", ").append(y).append(
0258:                            ")");
0259:                    coordinateLabel.setText(positionStatusBuf.toString());
0260:                }
0261:
0262:                public void selectionChanged() {
0263:                    toolBar.updateEnabledState();
0264:                }
0265:
0266:                public void fenceChanged() {
0267:                    toolBar.updateEnabledState();
0268:                }
0269:
0270:                public void painted(Graphics graphics) {
0271:                }
0272:            };
0273:            //<<TODO:NAMING>> This name is not clear [Jon Aquino]
0274:            private int maximumFeatureExtentForEnvelopeRenderingInPixels = 10;
0275:            //<<TODO:NAMING>> This name is not clear [Jon Aquino]
0276:            private int minimumFeatureExtentForAnyRenderingInPixels = 2;
0277:            private StringBuffer log = new StringBuffer();
0278:            private int taskSequence = 1;
0279:            private WorkbenchContext workbenchContext;
0280:            private JLabel memoryLabel = new JLabel();
0281:            private String lastStatusMessage = "";
0282:            private Set choosableStyleClasses = new HashSet();
0283:            private JLabel wmsLabel = new JLabel();
0284:            private ArrayList easyKeyListeners = new ArrayList();
0285:            private Map nodeClassToLayerNamePopupMenuMap = CollectionUtil
0286:                    .createMap(new Object[] { Layer.class, layerNamePopupMenu,
0287:                            WMSLayer.class, wmsLayerNamePopupMenu,
0288:                            Category.class, categoryPopupMenu });
0289:            private int positionIndex = -1;
0290:            private int primaryInfoFrameIndex = -1;
0291:
0292:            public WorkbenchFrame(String title, ImageIcon icon,
0293:                    final WorkbenchContext workbenchContext) throws Exception {
0294:                setTitle(title);
0295:                new Timer(1000, new ActionListener() {
0296:                    public void actionPerformed(ActionEvent e) {
0297:                        memoryLabel
0298:                                .setText(getMBCommittedMemory()
0299:                                        + " MB "
0300:                                        + I18N
0301:                                                .get("ui.WorkbenchFrame.committed-memory"));
0302:                        memoryLabel.setToolTipText(LayerManager
0303:                                .layerManagerCount()
0304:                                + " "
0305:                                + I18N.get("ui.WorkbenchFrame.layer-manager")
0306:                                + StringUtil
0307:                                        .s(LayerManager.layerManagerCount()));
0308:                    }
0309:                }).start();
0310:                this .workbenchContext = workbenchContext;
0311:                this .icon = icon;
0312:                toolBar = new WorkbenchToolBar(workbenchContext);
0313:                toolBar.setTaskMonitorManager(new TaskMonitorManager());
0314:                try {
0315:                    jbInit();
0316:                    configureStatusLabel(messageLabel, 300);
0317:                    configureStatusLabel(coordinateLabel, 150);
0318:                    configureStatusLabel(timeLabel, 200);
0319:                    configureStatusLabel(wmsLabel, 100);
0320:                } catch (Exception e) {
0321:                    e.printStackTrace();
0322:                }
0323:                new RecursiveKeyListener(this ) {
0324:                    public void keyTyped(KeyEvent e) {
0325:                        for (Iterator i = easyKeyListeners.iterator(); i
0326:                                .hasNext();) {
0327:                            KeyListener l = (KeyListener) i.next();
0328:                            l.keyTyped(e);
0329:                        }
0330:                    }
0331:
0332:                    public void keyPressed(KeyEvent e) {
0333:                        for (Iterator i = new ArrayList(easyKeyListeners)
0334:                                .iterator(); i.hasNext();) {
0335:                            KeyListener l = (KeyListener) i.next();
0336:                            l.keyPressed(e);
0337:                        }
0338:                    }
0339:
0340:                    public void keyReleased(KeyEvent e) {
0341:                        for (Iterator i = new ArrayList(easyKeyListeners)
0342:                                .iterator(); i.hasNext();) {
0343:                            KeyListener l = (KeyListener) i.next();
0344:                            l.keyReleased(e);
0345:                        }
0346:                    }
0347:                };
0348:                installKeyboardShortcutListener();
0349:            }
0350:
0351:            /**
0352:             * Unlike #add(KeyListener), listeners registered using this method are
0353:             * notified when KeyEvents occur on this frame's child components. Note:
0354:             * Bug: KeyListeners registered using this method may receive events
0355:             * multiple times.
0356:             * 
0357:             * @see #addKeyboardShortcut
0358:             */
0359:            public void addEasyKeyListener(KeyListener l) {
0360:                easyKeyListeners.add(l);
0361:            }
0362:
0363:            public void removeEasyKeyListener(KeyListener l) {
0364:                easyKeyListeners.remove(l);
0365:            }
0366:
0367:            public String getMBCommittedMemory() {
0368:                long totalMemory = Runtime.getRuntime().totalMemory();
0369:                long freeMemory = Runtime.getRuntime().freeMemory();
0370:                long usedMemory = totalMemory - freeMemory;
0371:                double usedMemoryInMB = usedMemory / (1024 * 1024d);
0372:                String memoryStr = memoryFormat.format(usedMemoryInMB);
0373:                return memoryStr;
0374:            }
0375:
0376:            /**
0377:             * @param newEnvelopeRenderingThreshold
0378:             *                  the number of on-screen features above which envelope
0379:             *                  rendering should occur
0380:             */
0381:            public void setEnvelopeRenderingThreshold(
0382:                    int newEnvelopeRenderingThreshold) {
0383:                envelopeRenderingThreshold = newEnvelopeRenderingThreshold;
0384:            }
0385:
0386:            public void setMaximumFeatureExtentForEnvelopeRenderingInPixels(
0387:                    int newMaximumFeatureExtentForEnvelopeRenderingInPixels) {
0388:                maximumFeatureExtentForEnvelopeRenderingInPixels = newMaximumFeatureExtentForEnvelopeRenderingInPixels;
0389:            }
0390:
0391:            public void log(String message) {
0392:                log.append(new Date() + "  " + message
0393:                        + System.getProperty("line.separator"));
0394:            }
0395:
0396:            public String getLog() {
0397:                return log.toString();
0398:            }
0399:
0400:            public void setMinimumFeatureExtentForAnyRenderingInPixels(
0401:                    int newMinimumFeatureExtentForAnyRenderingInPixels) {
0402:                minimumFeatureExtentForAnyRenderingInPixels = newMinimumFeatureExtentForAnyRenderingInPixels;
0403:            }
0404:
0405:            public void displayLastStatusMessage() {
0406:                setStatusMessage(lastStatusMessage);
0407:            }
0408:
0409:            public void setStatusMessage(String message) {
0410:                lastStatusMessage = message;
0411:                setStatusBarText(message);
0412:                setStatusBarTextHighlighted(false, null);
0413:            }
0414:
0415:            private void setStatusBarText(String message) {
0416:                //<<TODO:IMPROVE>> Treat null messages like "" [Jon Aquino]
0417:                messageLabel.setText((message == "") ? " " : message);
0418:                messageLabel.setToolTipText(message);
0419:                //Make message at least a space so that status bar won't collapse [Jon
0420:                // Aquino]
0421:            }
0422:
0423:            /**
0424:             * To highlight a message, call #warnUser.
0425:             */
0426:            private void setStatusBarTextHighlighted(boolean highlighted,
0427:                    Color color) {
0428:                //Use #coordinateLabel rather than (unattached) dummy label because
0429:                //dummy label's background does not change when L&F changes. [Jon
0430:                // Aquino]
0431:                messageLabel.setForeground(highlighted ? Color.black
0432:                        : coordinateLabel.getForeground());
0433:                messageLabel.setBackground(highlighted ? color
0434:                        : coordinateLabel.getBackground());
0435:            }
0436:
0437:            public void setTimeMessage(String message) {
0438:                //<<TODO:IMPROVE>> Treat null messages like "" [Jon Aquino]
0439:                timeLabel.setText((message == "") ? " " : message);
0440:                //Make message at least a space so that status bar won't collapse [Jon
0441:                // Aquino]
0442:            }
0443:
0444:            public JInternalFrame getActiveInternalFrame() {
0445:                return desktopPane.getSelectedFrame();
0446:            }
0447:
0448:            public JInternalFrame[] getInternalFrames() {
0449:                return desktopPane.getAllFrames();
0450:            }
0451:
0452:            public TitledPopupMenu getCategoryPopupMenu() {
0453:                return categoryPopupMenu;
0454:            }
0455:
0456:            public WorkbenchContext getContext() {
0457:                return workbenchContext;
0458:            }
0459:
0460:            public JDesktopPane getDesktopPane() {
0461:                return desktopPane;
0462:            }
0463:
0464:            public int getEnvelopeRenderingThreshold() {
0465:                return envelopeRenderingThreshold;
0466:            }
0467:
0468:            public TitledPopupMenu getLayerNamePopupMenu() {
0469:                return layerNamePopupMenu;
0470:            }
0471:
0472:            public TitledPopupMenu getWMSLayerNamePopupMenu() {
0473:                return wmsLayerNamePopupMenu;
0474:            }
0475:
0476:            public LayerViewPanelListener getLayerViewPanelListener() {
0477:                return layerViewPanelListener;
0478:            }
0479:
0480:            public Map getNodeClassToPopupMenuMap() {
0481:                return nodeClassToLayerNamePopupMenuMap;
0482:            }
0483:
0484:            public LayerNamePanelListener getLayerNamePanelListener() {
0485:                return layerNamePanelListener;
0486:            }
0487:
0488:            public int getMaximumFeatureExtentForEnvelopeRenderingInPixels() {
0489:                return maximumFeatureExtentForEnvelopeRenderingInPixels;
0490:            }
0491:
0492:            public int getMinimumFeatureExtentForAnyRenderingInPixels() {
0493:                return minimumFeatureExtentForAnyRenderingInPixels;
0494:            }
0495:
0496:            public HTMLFrame getOutputFrame() {
0497:                return outputFrame;
0498:            }
0499:
0500:            public WorkbenchToolBar getToolBar() {
0501:                return toolBar;
0502:            }
0503:
0504:            public void activateFrame(JInternalFrame frame) {
0505:                try {
0506:                    if (frame.isIcon()) {
0507:                        frame.setIcon(false);
0508:                    }
0509:                    frame.moveToFront();
0510:                    frame.requestFocus();
0511:                    frame.setSelected(true);
0512:                    if (!(frame instanceof  TaskFrame)) {
0513:                        frame.setMaximum(false);
0514:                    }
0515:                } catch (PropertyVetoException e) {
0516:                    warnUser(StringUtil.stackTrace(e));
0517:                }
0518:            }
0519:
0520:            /**
0521:             * If internalFrame is a LayerManagerProxy, the close behaviour will be
0522:             * altered so that the user is prompted if it is the last window on the
0523:             * LayerManager.
0524:             */
0525:            public void addInternalFrame(final JInternalFrame internalFrame) {
0526:                addInternalFrame(internalFrame, false, true);
0527:            }
0528:
0529:            public void addInternalFrame(final JInternalFrame internalFrame,
0530:                    boolean alwaysOnTop, boolean autoUpdateToolBar) {
0531:                if (internalFrame instanceof  LayerManagerProxy) {
0532:                    setClosingBehaviour((LayerManagerProxy) internalFrame);
0533:                    installTitleBarModifiedIndicator((LayerManagerProxy) internalFrame);
0534:                }
0535:                //<<TODO:IMPROVE>> Listen for when the frame closes, and when it does,
0536:                //activate the topmost frame. Because Swing does not seem to do this
0537:                //automatically. [Jon Aquino]
0538:                internalFrame.setFrameIcon(icon);
0539:                //Call JInternalFrame#setVisible before JDesktopPane#add; otherwise,
0540:                // the
0541:                //TreeLayerNamePanel starts too narrow (100 pixels or so) for some
0542:                // reason.
0543:                //<<TODO>>Investigate. [Jon Aquino]
0544:                internalFrame.setVisible(true);
0545:                desktopPane.add(internalFrame,
0546:                        alwaysOnTop ? JLayeredPane.PALETTE_LAYER
0547:                                : JLayeredPane.DEFAULT_LAYER);
0548:                if (autoUpdateToolBar) {
0549:                    internalFrame
0550:                            .addInternalFrameListener(new InternalFrameListener() {
0551:                                public void internalFrameActivated(
0552:                                        InternalFrameEvent e) {
0553:                                    toolBar.updateEnabledState();
0554:                                    //Associate current cursortool with the new frame [Jon
0555:                                    // Aquino]
0556:                                    toolBar.reClickSelectedCursorToolButton();
0557:                                }
0558:
0559:                                public void internalFrameClosed(
0560:                                        InternalFrameEvent e) {
0561:                                    toolBar.updateEnabledState();
0562:                                }
0563:
0564:                                public void internalFrameClosing(
0565:                                        InternalFrameEvent e) {
0566:                                    toolBar.updateEnabledState();
0567:                                }
0568:
0569:                                public void internalFrameDeactivated(
0570:                                        InternalFrameEvent e) {
0571:                                    toolBar.updateEnabledState();
0572:                                }
0573:
0574:                                public void internalFrameDeiconified(
0575:                                        InternalFrameEvent e) {
0576:                                    toolBar.updateEnabledState();
0577:                                }
0578:
0579:                                public void internalFrameIconified(
0580:                                        InternalFrameEvent e) {
0581:                                    toolBar.updateEnabledState();
0582:                                }
0583:
0584:                                public void internalFrameOpened(
0585:                                        InternalFrameEvent e) {
0586:                                    toolBar.updateEnabledState();
0587:                                }
0588:                            });
0589:                    //Call #activateFrame *after* adding the listener. [Jon Aquino]
0590:                    activateFrame(internalFrame);
0591:                    position(internalFrame);
0592:                }
0593:            }
0594:
0595:            private void installTitleBarModifiedIndicator(
0596:                    final LayerManagerProxy internalFrame) {
0597:                final JInternalFrame i = (JInternalFrame) internalFrame;
0598:                new Block() {
0599:                    //Putting updatingTitle in a Block is better than making it an
0600:                    //instance variable, because this way there is one updatingTitle
0601:                    // for each
0602:                    //internal frame, rather than one for all internal frames. [Jon
0603:                    // Aquino]
0604:                    private boolean updatingTitle = false;
0605:
0606:                    private void updateTitle() {
0607:                        if (updatingTitle) {
0608:                            return;
0609:                        }
0610:                        updatingTitle = true;
0611:                        try {
0612:                            String newTitle = i.getTitle();
0613:                            if (newTitle.charAt(0) == '*') {
0614:                                newTitle = newTitle.substring(1);
0615:                            }
0616:                            if (!internalFrame.getLayerManager()
0617:                                    .getLayersWithModifiedFeatureCollections()
0618:                                    .isEmpty()) {
0619:                                newTitle = '*' + newTitle;
0620:                            }
0621:                            i.setTitle(newTitle);
0622:                        } finally {
0623:                            updatingTitle = false;
0624:                        }
0625:                    }
0626:
0627:                    public Object yield() {
0628:                        internalFrame.getLayerManager().addLayerListener(
0629:                                new LayerListener() {
0630:                                    public void layerChanged(LayerEvent e) {
0631:                                        if ((e.getType() == LayerEventType.METADATA_CHANGED)
0632:                                                || (e.getType() == LayerEventType.REMOVED)) {
0633:                                            updateTitle();
0634:                                        }
0635:                                    }
0636:
0637:                                    public void categoryChanged(CategoryEvent e) {
0638:                                    }
0639:
0640:                                    public void featuresChanged(FeatureEvent e) {
0641:                                    }
0642:                                });
0643:                        i.addPropertyChangeListener(
0644:                                JInternalFrame.TITLE_PROPERTY,
0645:                                new PropertyChangeListener() {
0646:                                    public void propertyChange(
0647:                                            PropertyChangeEvent e) {
0648:                                        updateTitle();
0649:                                    }
0650:                                });
0651:                        return null;
0652:                    }
0653:                }.yield();
0654:            }
0655:
0656:            private void setClosingBehaviour(final LayerManagerProxy proxy) {
0657:                final JInternalFrame internalFrame = (JInternalFrame) proxy;
0658:                internalFrame
0659:                        .setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
0660:                internalFrame
0661:                        .addInternalFrameListener(new InternalFrameAdapter() {
0662:                            public void internalFrameClosing(
0663:                                    InternalFrameEvent e) {
0664:                                internalFrameCloseHandler.close(internalFrame);
0665:                            }
0666:                        });
0667:            }
0668:
0669:            private Collection getInternalFramesAssociatedWith(
0670:                    LayerManager layerManager) {
0671:                ArrayList internalFramesAssociatedWithLayerManager = new ArrayList();
0672:                JInternalFrame[] internalFrames = getInternalFrames();
0673:                for (int i = 0; i < internalFrames.length; i++) {
0674:                    if (internalFrames[i] instanceof  LayerManagerProxy
0675:                            && (((LayerManagerProxy) internalFrames[i])
0676:                                    .getLayerManager() == layerManager)) {
0677:                        internalFramesAssociatedWithLayerManager
0678:                                .add(internalFrames[i]);
0679:                    }
0680:                }
0681:                return internalFramesAssociatedWithLayerManager;
0682:            }
0683:
0684:            // added by [mmichaud 2007-06-03]
0685:            // Return TaskFrame s using the same layerManager
0686:            private Collection getTaskFramesAssociatedWith(
0687:                    LayerManager layerManager) {
0688:                ArrayList taskFramesAssociatedWithLayerManager = new ArrayList();
0689:                JInternalFrame[] internalFrames = getInternalFrames();
0690:                for (int i = 0; i < internalFrames.length; i++) {
0691:                    if (internalFrames[i] instanceof  TaskFrame
0692:                            && (((TaskFrame) internalFrames[i])
0693:                                    .getLayerManager() == layerManager)) {
0694:                        taskFramesAssociatedWithLayerManager
0695:                                .add(internalFrames[i]);
0696:                    }
0697:                }
0698:                return taskFramesAssociatedWithLayerManager;
0699:            }
0700:
0701:            // added by [mmichaud 2007-06-03]
0702:            // Return every InternalFrame associated with taskFrame (taskFrame is excluded)
0703:            private Collection getInternalFramesAssociatedWith(
0704:                    TaskFrame taskFrame) {
0705:                ArrayList internalFramesAssociatedWithTaskFrame = new ArrayList();
0706:                JInternalFrame[] internalFrames = getInternalFrames();
0707:                for (int i = 0; i < internalFrames.length; i++) {
0708:                    if (internalFrames[i] instanceof  TaskFrameProxy
0709:                            && (((TaskFrameProxy) internalFrames[i])
0710:                                    .getTaskFrame() == taskFrame)
0711:                            && internalFrames[i] != taskFrame) {
0712:                        internalFramesAssociatedWithTaskFrame
0713:                                .add(internalFrames[i]);
0714:                    }
0715:                }
0716:                return internalFramesAssociatedWithTaskFrame;
0717:            }
0718:
0719:            public TaskFrame addTaskFrame() {
0720:                TaskFrame f = addTaskFrame(createTask());
0721:                return f;
0722:            }
0723:
0724:            public Task createTask() {
0725:                Task task = new Task();
0726:                //LayerManager shouldn't automatically add categories in its
0727:                // constructor.
0728:                //Sometimes we want to create a LayerManager with no categories
0729:                //(e.g. in OpenProjectPlugIn). [Jon Aquino]
0730:                task.getLayerManager().addCategory(
0731:                        StandardCategoryNames.WORKING);
0732:                task.getLayerManager()
0733:                        .addCategory(StandardCategoryNames.SYSTEM);
0734:                task.setName(I18N.get("ui.WorkbenchFrame.task") + " "
0735:                        + taskSequence++);
0736:                return task;
0737:            }
0738:
0739:            public TaskFrame addTaskFrame(Task task) {
0740:                return addTaskFrame(new TaskFrame(task, workbenchContext));
0741:            }
0742:
0743:            public TaskFrame addTaskFrame(TaskFrame taskFrame) {
0744:                taskFrame.getTask().getLayerManager().addLayerListener(
0745:                        new LayerListener() {
0746:                            public void featuresChanged(FeatureEvent e) {
0747:                            }
0748:
0749:                            public void categoryChanged(CategoryEvent e) {
0750:                                toolBar.updateEnabledState();
0751:                            }
0752:
0753:                            public void layerChanged(LayerEvent layerEvent) {
0754:                                toolBar.updateEnabledState();
0755:                            }
0756:                        });
0757:                addInternalFrame(taskFrame);
0758:                taskFrame.getLayerViewPanel().getLayerManager()
0759:                        .getUndoableEditReceiver().add(
0760:                                new UndoableEditReceiver.Listener() {
0761:                                    public void undoHistoryChanged() {
0762:                                        toolBar.updateEnabledState();
0763:                                    }
0764:
0765:                                    public void undoHistoryTruncated() {
0766:                                        toolBar.updateEnabledState();
0767:                                        log(I18N
0768:                                                .get("ui.WorkbenchFrame.undo-history-was-truncated"));
0769:                                    }
0770:                                });
0771:                return taskFrame;
0772:            }
0773:
0774:            public void flash(final HTMLFrame frame) {
0775:                final Color originalColor = frame.getBackgroundColor();
0776:                new Timer(100, new ActionListener() {
0777:                    private int tickCount = 0;
0778:
0779:                    public void actionPerformed(ActionEvent e) {
0780:                        try {
0781:                            tickCount++;
0782:                            frame
0783:                                    .setBackgroundColor(((tickCount % 2) == 0) ? originalColor
0784:                                            : Color.yellow);
0785:                            if (tickCount == 2) {
0786:                                Timer timer = (Timer) e.getSource();
0787:                                timer.stop();
0788:                            }
0789:                        } catch (Throwable t) {
0790:                            handleThrowable(t);
0791:                        }
0792:                    }
0793:                }).start();
0794:            }
0795:
0796:            private void flashStatusMessage(final String message,
0797:                    final Color color) {
0798:                new Timer(100, new ActionListener() {
0799:                    private int tickCount = 0;
0800:
0801:                    public void actionPerformed(ActionEvent e) {
0802:                        tickCount++;
0803:                        //This message is important, so overwrite whatever is on the
0804:                        // status bar. [Jon Aquino]
0805:                        setStatusBarText(message);
0806:                        setStatusBarTextHighlighted((tickCount % 2) == 0, color);
0807:                        if (tickCount == 4) {
0808:                            Timer timer = (Timer) e.getSource();
0809:                            timer.stop();
0810:                        }
0811:                    }
0812:                }).start();
0813:            }
0814:
0815:            /**
0816:             * Can be called regardless of whether the current thread is the AWT event
0817:             * dispatch thread.
0818:             *
0819:             * @param t
0820:             *                  Description of the Parameter
0821:             */
0822:            public void handleThrowable(final Throwable t) {
0823:                log(StringUtil.stackTrace(t));
0824:                Component parent = this ;
0825:                Window[] ownedWindows = getOwnedWindows();
0826:                for (int i = 0; i < ownedWindows.length; i++) {
0827:                    if (ownedWindows[i] instanceof  Dialog
0828:                            && ownedWindows[i].isVisible()
0829:                            && ((Dialog) ownedWindows[i]).isModal()) {
0830:                        parent = ownedWindows[i];
0831:                        break;
0832:                    }
0833:                }
0834:                handleThrowable(t, parent);
0835:            }
0836:
0837:            public static void handleThrowable(final Throwable t,
0838:                    final Component parent) {
0839:                t.printStackTrace(System.err);
0840:                SwingUtilities.invokeLater(new Runnable() {
0841:                    public void run() {
0842:                        ErrorDialog.show(parent, StringUtil.toFriendlyName(t
0843:                                .getClass().getName()), toMessage(t),
0844:                                StringUtil.stackTrace(t));
0845:                    }
0846:                });
0847:            }
0848:
0849:            private ArrayList lastFiveThrowableDates = new ArrayList() {
0850:                public boolean add(Object o) {
0851:                    if (size() == 5) {
0852:                        remove(0);
0853:                    }
0854:                    return super .add(o);
0855:                }
0856:            };
0857:
0858:            public static String toMessage(Throwable t) {
0859:                String message;
0860:                if (t.getLocalizedMessage() == null) {
0861:                    message = I18N
0862:                            .get("ui.WorkbenchFrame.no-description-was-provided");
0863:                } else if (t.getLocalizedMessage().toLowerCase().indexOf(
0864:                        I18N.get("ui.WorkbenchFrame.side-location-conflict")) > -1) {
0865:                    message = t.getLocalizedMessage()
0866:                            + " -- "
0867:                            + I18N
0868:                                    .get("ui.WorkbenchFrame.check-for-invalid-geometries");
0869:                } else {
0870:                    message = t.getLocalizedMessage();
0871:                }
0872:                return message + " ("
0873:                        + StringUtil.toFriendlyName(t.getClass().getName())
0874:                        + ")";
0875:            }
0876:
0877:            public boolean hasInternalFrame(JInternalFrame internalFrame) {
0878:                JInternalFrame[] frames = desktopPane.getAllFrames();
0879:                for (int i = 0; i < frames.length; i++) {
0880:                    if (frames[i] == internalFrame) {
0881:                        return true;
0882:                    }
0883:                }
0884:                return false;
0885:            }
0886:
0887:            public void removeInternalFrame(JInternalFrame internalFrame) {
0888:                //Looks like #closeFrame is the proper way to remove an internal
0889:                // frame.
0890:                //It will activate the next frame. [Jon Aquino]
0891:                desktopPane.getDesktopManager().closeFrame(internalFrame);
0892:            }
0893:
0894:            public void warnUser(String warning) {
0895:                log(I18N.get("ui.WorkbenchFrame.warning") + ": " + warning);
0896:                flashStatusMessage(warning, Color.yellow);
0897:            }
0898:
0899:            public void zoomChanged(Envelope modelEnvelope) {
0900:                toolBar.updateEnabledState();
0901:            }
0902:
0903:            void exitMenuItem_actionPerformed(ActionEvent e) {
0904:                closeApplication();
0905:            }
0906:
0907:            void this _componentShown(ComponentEvent e) {
0908:                try {
0909:                    //If the first internal frame is not a TaskWindow (as may be the
0910:                    // case in
0911:                    //custom workbenches), #updateEnabledState() will ensure that the
0912:                    //cursor-tool buttons are disabled. [Jon Aquino]
0913:                    toolBar.updateEnabledState();
0914:                } catch (Throwable t) {
0915:                    handleThrowable(t);
0916:                }
0917:            }
0918:
0919:            void this _windowClosing(WindowEvent e) {
0920:                closeApplication();
0921:            }
0922:
0923:            void windowMenu_menuSelected(MenuEvent e) {
0924:                //<<TODO:MAINTAINABILITY>> This algorithm is not robust. It assumes
0925:                // the Window
0926:                //menu has exactly one "regular" menu item (newWindowMenuItem). [Jon
0927:                // Aquino]
0928:                int addedMenuItems = 3; //[sstein: new menus: options + log + separator]
0929:                int allItems = windowMenu.getItemCount();
0930:                String t = windowMenu.getItem(addedMenuItems).getText();
0931:                String name = AbstractPlugIn
0932:                        .createName(CloneWindowPlugIn.class);
0933:                boolean isWindowCloneClass = t.equals(name);
0934:                if (windowMenu.getItemCount() > addedMenuItems
0935:                        && windowMenu.getItem(addedMenuItems) != null
0936:                        && isWindowCloneClass) {
0937:                    JMenuItem newWindowMenuItem = windowMenu
0938:                            .getItem(addedMenuItems);
0939:                    //windowMenu.removeAll();
0940:                    int loopsdone = 0;
0941:                    for (int itemIdx = addedMenuItems; itemIdx < allItems; itemIdx++) {
0942:                        //-- subtract since number of window-menu-items shrinks				
0943:                        try {
0944:                            //String tt = windowMenu.getItem(itemIdx-loopsdone).getText();
0945:                            //-- [sstein:] an exception for the line above is thrown if the item is a separator
0946:                            //             then, getText seems not to work 
0947:                            windowMenu.remove(itemIdx - loopsdone);
0948:                            loopsdone = loopsdone + 1;
0949:                        } catch (Exception exc) {
0950:                            //eat -- should be thrown caused by a separator
0951:                            System.out
0952:                                    .println("WorkbenchFrame: exception in windowMenu_Selected() ");
0953:                        }
0954:                    }
0955:                    windowMenu.add(newWindowMenuItem);
0956:                    windowMenu.addSeparator();
0957:                } else {
0958:                    //ezLink doesn't have a Clone Window menu [Jon Aquino]
0959:                    windowMenu.removeAll();
0960:                }
0961:                final JInternalFrame[] frames = desktopPane.getAllFrames();
0962:                for (int i = 0; i < frames.length; i++) {
0963:                    JMenuItem menuItem = new JMenuItem();
0964:                    //Increase truncation threshold from 20 to 40, for eziLink [Jon
0965:                    // Aquino]
0966:                    menuItem.setText(GUIUtil.truncateString(frames[i]
0967:                            .getTitle(), 40));
0968:                    associate(menuItem, frames[i]);
0969:                    windowMenu.add(menuItem);
0970:                }
0971:                if (windowMenu.getItemCount() == addedMenuItems) {
0972:                    //For ezLink [Jon Aquino]
0973:                    windowMenu.add(new JMenuItem("("
0974:                            + I18N.get("ui.WorkbenchFrame.no-windows") + ")"));
0975:                }
0976:            }
0977:
0978:            private void associate(JMenuItem menuItem,
0979:                    final JInternalFrame frame) {
0980:                menuItem.addActionListener(new ActionListener() {
0981:                    public void actionPerformed(ActionEvent e) {
0982:                        try {
0983:                            activateFrame(frame);
0984:                        } catch (Throwable t) {
0985:                            handleThrowable(t);
0986:                        }
0987:                    }
0988:                });
0989:            }
0990:
0991:            private void closeApplication() {
0992:                applicationExitHandler.exitApplication(this );
0993:            }
0994:
0995:            private Collection getLayersWithModifiedFeatureCollections() {
0996:                ArrayList layersWithModifiedFeatureCollections = new ArrayList();
0997:                for (Iterator i = getLayerManagers().iterator(); i.hasNext();) {
0998:                    LayerManager layerManager = (LayerManager) i.next();
0999:                    layersWithModifiedFeatureCollections.addAll(layerManager
1000:                            .getLayersWithModifiedFeatureCollections());
1001:                }
1002:                return layersWithModifiedFeatureCollections;
1003:            }
1004:
1005:            private Collection getLayerManagers() {
1006:                //Multiple windows may point to the same LayerManager, so use
1007:                //a Set. [Jon Aquino]
1008:                HashSet layerManagers = new HashSet();
1009:                JInternalFrame[] internalFrames = getInternalFrames();
1010:                for (int i = 0; i < internalFrames.length; i++) {
1011:                    if (internalFrames[i] instanceof  LayerManagerProxy) {
1012:                        layerManagers
1013:                                .add(((LayerManagerProxy) internalFrames[i])
1014:                                        .getLayerManager());
1015:                    }
1016:                }
1017:                return layerManagers;
1018:            }
1019:
1020:            private void configureStatusLabel(JLabel label, int width) {
1021:                label.setMinimumSize(new Dimension(width, (int) label
1022:                        .getMinimumSize().getHeight()));
1023:                label.setMaximumSize(new Dimension(width, (int) label
1024:                        .getMaximumSize().getHeight()));
1025:                label.setPreferredSize(new Dimension(width, (int) label
1026:                        .getPreferredSize().getHeight()));
1027:            }
1028:
1029:            private void jbInit() throws Exception {
1030:                setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
1031:                this .setIconImage(icon.getImage());
1032:                this 
1033:                        .addComponentListener(new java.awt.event.ComponentAdapter() {
1034:                            public void componentShown(ComponentEvent e) {
1035:                                this _componentShown(e);
1036:                            }
1037:                        });
1038:                this .getContentPane().setLayout(borderLayout1);
1039:                this .addWindowListener(new java.awt.event.WindowAdapter() {
1040:                    public void windowClosing(WindowEvent e) {
1041:                        this _windowClosing(e);
1042:                    }
1043:                });
1044:                this .setJMenuBar(menuBar);
1045:                //This size is chosen so that when the user hits the Info tool, the
1046:                // window
1047:                //fits between the lower edge of the TaskFrame and the lower edge of
1048:                // the
1049:                //WorkbenchFrame. See the call to #setSize in InfoFrame. [Jon Aquino]
1050:                setSize(900, 665);
1051:                //OUTLINE_DRAG_MODE is excruciatingly slow in JDK 1.4.1, so don't use
1052:                // it.
1053:                //(although it's supposed to be fixed in 1.4.2, which has not yet been
1054:                //released). (see Sun Java Bug ID 4665237). [Jon Aquino]
1055:                //desktopPane.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
1056:                messageLabel.setOpaque(true);
1057:                memoryLabel.setText("jLabel1");
1058:                wmsLabel.setHorizontalAlignment(SwingConstants.LEFT);
1059:                wmsLabel.setText(" ");
1060:                this .getContentPane().add(statusPanel, BorderLayout.SOUTH);
1061:                exitMenuItem
1062:                        .addActionListener(new java.awt.event.ActionListener() {
1063:                            public void actionPerformed(ActionEvent e) {
1064:                                exitMenuItem_actionPerformed(e);
1065:                            }
1066:                        });
1067:                windowMenu
1068:                        .addMenuListener(new javax.swing.event.MenuListener() {
1069:                            public void menuCanceled(MenuEvent e) {
1070:                            }
1071:
1072:                            public void menuDeselected(MenuEvent e) {
1073:                            }
1074:
1075:                            public void menuSelected(MenuEvent e) {
1076:                                windowMenu_menuSelected(e);
1077:                            }
1078:                        });
1079:                coordinateLabel.setBorder(BorderFactory
1080:                        .createLoweredBevelBorder());
1081:                wmsLabel.setBorder(BorderFactory.createLoweredBevelBorder());
1082:                coordinateLabel.setText(" ");
1083:                statusPanel.setLayout(gridBagLayout1);
1084:                statusPanel.setBorder(BorderFactory.createRaisedBevelBorder());
1085:                messageLabel
1086:                        .setBorder(BorderFactory.createLoweredBevelBorder());
1087:                messageLabel.setText(" ");
1088:                timeLabel.setBorder(BorderFactory.createLoweredBevelBorder());
1089:                timeLabel.setText(" ");
1090:                memoryLabel.setBorder(BorderFactory.createLoweredBevelBorder());
1091:                memoryLabel.setText(" ");
1092:                menuBar.add(fileMenu);
1093:                menuBar.add(windowMenu);
1094:                getContentPane().add(toolBar, BorderLayout.NORTH);
1095:                getContentPane().add(desktopPane, BorderLayout.CENTER);
1096:                fileMenu.addSeparator();
1097:                fileMenu.add(exitMenuItem);
1098:                statusPanel.add(coordinateLabel, new GridBagConstraints(5, 1,
1099:                        1, 1, 0.0, 0.0, GridBagConstraints.WEST,
1100:                        GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0),
1101:                        0, 0));
1102:                statusPanel.add(timeLabel, new GridBagConstraints(2, 1, 1, 1,
1103:                        0.0, 0.0, GridBagConstraints.CENTER,
1104:                        GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0),
1105:                        0, 0));
1106:                statusPanel.add(messageLabel, new GridBagConstraints(1, 1, 1,
1107:                        1, 0.0, 0.0, GridBagConstraints.CENTER,
1108:                        GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0),
1109:                        0, 0));
1110:                //Give memoryLabel the 1.0 weight. All the rest should have their
1111:                // sizes
1112:                //configured using #configureStatusLabel. [Jon Aquino]
1113:                statusPanel.add(memoryLabel, new GridBagConstraints(3, 1, 1, 1,
1114:                        1.0, 0.0, GridBagConstraints.CENTER,
1115:                        GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0),
1116:                        0, 0));
1117:                statusPanel.add(wmsLabel, new GridBagConstraints(4, 1, 1, 1,
1118:                        0.0, 0.0, GridBagConstraints.WEST,
1119:                        GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
1120:            }
1121:
1122:            private void position(JInternalFrame internalFrame) {
1123:                final int STEP = 5;
1124:                GUIUtil.Location location = null;
1125:                if (internalFrame instanceof  PrimaryInfoFrame) {
1126:                    primaryInfoFrameIndex++;
1127:                    int offset = (primaryInfoFrameIndex % 3) * STEP;
1128:                    location = new GUIUtil.Location(offset, true, offset, true);
1129:                } else {
1130:                    positionIndex++;
1131:                    int offset = (positionIndex % 5) * STEP;
1132:                    location = new GUIUtil.Location(offset, false, offset,
1133:                            false);
1134:                }
1135:                GUIUtil.setLocation(internalFrame, location, desktopPane);
1136:            }
1137:
1138:            /**
1139:             * Fundamental Style classes (like BasicStyle, VertexStyle, and LabelStyle)
1140:             * cannot be removed, and are thus excluded from the choosable Style
1141:             * classes.
1142:             */
1143:            public Set getChoosableStyleClasses() {
1144:                return Collections.unmodifiableSet(choosableStyleClasses);
1145:            }
1146:
1147:            public void addChoosableStyleClass(Class choosableStyleClass) {
1148:                Assert.isTrue(ChoosableStyle.class
1149:                        .isAssignableFrom(choosableStyleClass));
1150:                choosableStyleClasses.add(choosableStyleClass);
1151:            }
1152:
1153:            private HashMap keyCodeAndModifiersToPlugInAndEnableCheckMap = new HashMap();
1154:
1155:            /**
1156:             * Adds a keyboard shortcut for a plugin. logs plugin exceptions.
1157:             *
1158:             * note - attaching to keyCode 'a', modifiers =1 will detect shift-A
1159:             * events. It will *not* detect caps-lock-'a'. This is due to
1160:             * inconsistencies in java.awt.event.KeyEvent. In the unlikely event you
1161:             * actually do want to also also attach to caps-lock-'a', then make two
1162:             * shortcuts - one to keyCode 'a' and modifiers =1 (shift-A) and one to
1163:             * keyCode 'A' and modifiers=0 (caps-lock A).
1164:             *
1165:             * For more details, see the java.awt.event.KeyEvent class - it has a full
1166:             * explaination.
1167:             *
1168:             * @param keyCode
1169:             *                  What key to attach to (See java.awt.event.KeyEvent)
1170:             * @param modifiers 0=
1171:             *                  none, 1=shift, 2= cntrl, 8=alt, 3=shift+cntrl, etc... See the
1172:             *                  modifier mask constants in the Event class
1173:             * @param plugIn
1174:             *                  What plugin to execute
1175:             * @param enableCheck
1176:             *                  Is the key enabled at the moment?
1177:             */
1178:            public void addKeyboardShortcut(final int keyCode,
1179:                    final int modifiers, final PlugIn plugIn,
1180:                    final EnableCheck enableCheck) {
1181:                //Overwrite existing shortcut [Jon Aquino]
1182:                keyCodeAndModifiersToPlugInAndEnableCheckMap.put(keyCode + ":"
1183:                        + modifiers, new Object[] { plugIn, enableCheck });
1184:            }
1185:
1186:            private void installKeyboardShortcutListener() {
1187:                addEasyKeyListener(new KeyListener() {
1188:                    public void keyTyped(KeyEvent e) {
1189:                    }
1190:
1191:                    public void keyReleased(KeyEvent e) {
1192:                    }
1193:
1194:                    public void keyPressed(KeyEvent e) {
1195:                        Object[] plugInAndEnableCheck = (Object[]) keyCodeAndModifiersToPlugInAndEnableCheckMap
1196:                                .get(e.getKeyCode() + ":" + e.getModifiers());
1197:                        if (plugInAndEnableCheck == null) {
1198:                            return;
1199:                        }
1200:                        PlugIn plugIn = (PlugIn) plugInAndEnableCheck[0];
1201:                        EnableCheck enableCheck = (EnableCheck) plugInAndEnableCheck[1];
1202:                        if (enableCheck != null
1203:                                && enableCheck.check(null) != null) {
1204:                            return;
1205:                        }
1206:                        //#toActionListener handles checking if the plugIn is a
1207:                        // ThreadedPlugIn,
1208:                        //and making calls to UndoableEditReceiver if necessary. [Jon
1209:                        // Aquino 10/15/2003]
1210:                        AbstractPlugIn.toActionListener(plugIn,
1211:                                workbenchContext, new TaskMonitorManager())
1212:                                .actionPerformed(null);
1213:                    }
1214:                });
1215:            }
1216:
1217:            //==========================================================================
1218:            // Applications (such as EziLink) want to override the default JUMP
1219:            // frame closing behaviour and application exit behaviour with their own
1220:            // behaviours.
1221:            //
1222:            InternalFrameCloseHandler internalFrameCloseHandler = new DefaultInternalFrameCloser();
1223:            ApplicationExitHandler applicationExitHandler = new DefaultApplicationExitHandler();
1224:
1225:            public InternalFrameCloseHandler getInternalFrameCloseHandler() {
1226:                return internalFrameCloseHandler;
1227:            }
1228:
1229:            public void setInternalFrameCloseHandler(
1230:                    InternalFrameCloseHandler value) {
1231:                internalFrameCloseHandler = value;
1232:            }
1233:
1234:            public ApplicationExitHandler getApplicationExitHandler() {
1235:                return applicationExitHandler;
1236:            }
1237:
1238:            public void setApplicationExitHandler(ApplicationExitHandler value) {
1239:                applicationExitHandler = value;
1240:            }
1241:
1242:            private class DefaultInternalFrameCloser implements 
1243:                    InternalFrameCloseHandler {
1244:                public void close(JInternalFrame internalFrame) {
1245:                    if (internalFrame instanceof  TaskFrame) {
1246:                        closeTaskFrame((TaskFrame) internalFrame);
1247:                    } else {
1248:                        GUIUtil.dispose(internalFrame, desktopPane);
1249:                    }
1250:                    SwingUtilities.invokeLater(new Runnable() {
1251:                        public void run() {
1252:                            System.runFinalization();
1253:                            System.gc();
1254:                        }
1255:                    });
1256:                }
1257:            }
1258:
1259:            private class DefaultApplicationExitHandler implements 
1260:                    ApplicationExitHandler {
1261:                public void exitApplication(JFrame mainFrame) {
1262:                    if (confirmClose(I18N.get("ui.WorkbenchFrame.exit-jump"),
1263:                            getLayersWithModifiedFeatureCollections())) {
1264:                        //PersistentBlackboardPlugIn listens for when the workbench is
1265:                        // hidden [Jon Aquino]
1266:                        setVisible(false);
1267:                        //Invoke System#exit after all pending GUI events have been
1268:                        // fired
1269:                        //(e.g. the hiding of this WorkbenchFrame) [Jon Aquino]
1270:                        SwingUtilities.invokeLater(new Runnable() {
1271:                            public void run() {
1272:                                System.exit(0);
1273:                            }
1274:                        });
1275:                    }
1276:                }
1277:            }
1278:
1279:            // Method completed by [mmichaud 2007-06-03] to close properly
1280:            // internal frames depending on a TaskFrame.
1281:            // Maybe this method should take place in TaskFrame instead...
1282:            private void closeTaskFrame(TaskFrame taskFrame) {
1283:                LayerManager layerManager = taskFrame.getLayerManager();
1284:                Collection associatedFrames = getInternalFramesAssociatedWith(taskFrame);
1285:                boolean lastTaskFrame = getTaskFramesAssociatedWith(
1286:                        layerManager).size() == 1;
1287:                if (lastTaskFrame) {
1288:                    Collection modifiedItems = layerManager
1289:                            .getLayersWithModifiedFeatureCollections();
1290:                    if (confirmClose(I18N.get("ui.WorkbenchFrame.close-task"),
1291:                            modifiedItems)) {
1292:                        // There are other internal frames associated with this task
1293:                        if (associatedFrames.size() != 0) {
1294:                            // Confirm you want to close them first
1295:                            if (confirmClose(
1296:                                    StringUtil
1297:                                            .split(
1298:                                                    I18N
1299:                                                            .get("ui.WorkbenchFrame.other-internal-frames-depend-on-this-task-frame")
1300:                                                            + " "
1301:                                                            + I18N
1302:                                                                    .get("ui.WorkbenchFrame.do-you-want-to-close-them-also"),
1303:                                                    60), I18N
1304:                                            .get("ui.WorkbenchFrame.close-all"))) {
1305:                                for (java.util.Iterator it = associatedFrames
1306:                                        .iterator(); it.hasNext();) {
1307:                                    GUIUtil.dispose((JInternalFrame) it.next(),
1308:                                            desktopPane);
1309:                                }
1310:
1311:                            } else
1312:                                return; // finally, I don't want to close
1313:                        }
1314:                        layerManager.dispose();
1315:                        taskFrame.getLayerViewPanel().dispose();
1316:                        taskFrame.getLayerNamePanel().dispose();
1317:                        GUIUtil.dispose(taskFrame, desktopPane);
1318:                    } else
1319:                        return; // finally, I don't want to close
1320:                } else {
1321:                    // There are other internal frames associated with this task
1322:                    if (associatedFrames.size() != 0) {
1323:                        // Confirm you want to close them first
1324:                        if (confirmClose(
1325:                                StringUtil
1326:                                        .split(
1327:                                                I18N
1328:                                                        .get("ui.WorkbenchFrame.other-internal-frames-depend-on-this-task-frame")
1329:                                                        + " "
1330:                                                        + I18N
1331:                                                                .get("ui.WorkbenchFrame.do-you-want-to-close-them-also"),
1332:                                                60), I18N
1333:                                        .get("ui.WorkbenchFrame.close-all"))) {
1334:                            for (java.util.Iterator it = associatedFrames
1335:                                    .iterator(); it.hasNext();) {
1336:                                GUIUtil.dispose((JInternalFrame) it.next(),
1337:                                        desktopPane);
1338:                            }
1339:                        } else
1340:                            return; // finally, I don't want to close
1341:                    }
1342:                    taskFrame.getLayerViewPanel().dispose();
1343:                    taskFrame.getLayerNamePanel().dispose();
1344:                    GUIUtil.dispose(taskFrame, desktopPane);
1345:                }
1346:            }
1347:
1348:            private boolean confirmClose(String action,
1349:                    Collection modifiedLayers) {
1350:                if (modifiedLayers.isEmpty()) {
1351:                    return true;
1352:                }
1353:                JOptionPane pane = new JOptionPane(
1354:                        StringUtil
1355:                                .split(
1356:                                        modifiedLayers.size()
1357:                                                + " "
1358:                                                + I18N
1359:                                                        .get("ui.WorkbenchFrame.dataset")
1360:                                                + StringUtil.s(modifiedLayers
1361:                                                        .size())
1362:                                                + " "
1363:                                                + ((modifiedLayers.size() > 1) ? I18N
1364:                                                        .get("ui.WorkbenchFrame.have-been-modified")
1365:                                                        : I18N
1366:                                                                .get("ui.WorkbenchFrame.has-been-modified"))
1367:                                                + " ("
1368:                                                + ((modifiedLayers.size() > 3) ? "e.g. "
1369:                                                        : "")
1370:                                                + StringUtil
1371:                                                        .toCommaDelimitedString(new ArrayList(
1372:                                                                modifiedLayers)
1373:                                                                .subList(
1374:                                                                        0,
1375:                                                                        Math
1376:                                                                                .min(
1377:                                                                                        3,
1378:                                                                                        modifiedLayers
1379:                                                                                                .size())))
1380:                                                + "). "
1381:                                                + I18N
1382:                                                        .get("ui.WorkbenchFrame.continue")
1383:                                                + "?", 80),
1384:                        JOptionPane.WARNING_MESSAGE);
1385:                pane.setOptions(new String[] { action,
1386:                        I18N.get("ui.WorkbenchFrame.cancel") });
1387:                pane.createDialog(this , "JUMP").setVisible(true);
1388:                return pane.getValue().equals(action);
1389:            }
1390:
1391:            private boolean confirmClose(String question, String action) {
1392:                javax.swing.JOptionPane pane = new javax.swing.JOptionPane(
1393:                        question, javax.swing.JOptionPane.WARNING_MESSAGE);
1394:                pane.setOptions(new String[] {
1395:                        action,
1396:                        com.vividsolutions.jump.I18N
1397:                                .get("ui.WorkbenchFrame.cancel") });
1398:                pane.createDialog(this , "JUMP").setVisible(true);
1399:                return pane.getValue().equals(action);
1400:            }
1401:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.