Source Code Cross Referenced for JGraphpadLibraryPane.java in  » Graphic-Library » jgraphpad » com » jgraph » pad » factory » 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 » Graphic Library » jgraphpad » com.jgraph.pad.factory 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* 
002:         * $Id: JGraphpadLibraryPane.java,v 1.8 2007/07/27 14:15:59 gaudenz Exp $
003:         * Copyright (c) 2001-2005, Gaudenz Alder
004:         * 
005:         * All rights reserved.
006:         * 
007:         * See LICENSE file for license details. If you are unable to locate
008:         * this file please contact info (at) jgraph (dot) com.
009:         */
010:        package com.jgraph.pad.factory;
011:
012:        import java.awt.Component;
013:        import java.awt.Dimension;
014:        import java.awt.Graphics;
015:        import java.awt.Graphics2D;
016:        import java.awt.Rectangle;
017:        import java.awt.RenderingHints;
018:        import java.awt.Shape;
019:        import java.awt.datatransfer.DataFlavor;
020:        import java.awt.datatransfer.Transferable;
021:        import java.awt.event.MouseEvent;
022:        import java.awt.geom.Rectangle2D;
023:        import java.util.ArrayList;
024:        import java.util.Hashtable;
025:        import java.util.List;
026:        import java.util.Map;
027:
028:        import javax.swing.CellRendererPane;
029:        import javax.swing.JComponent;
030:        import javax.swing.JInternalFrame;
031:        import javax.swing.JTabbedPane;
032:        import javax.swing.SwingUtilities;
033:        import javax.swing.TransferHandler;
034:        import javax.swing.event.TreeModelEvent;
035:
036:        import org.jgraph.JGraph;
037:        import org.jgraph.event.GraphModelEvent;
038:        import org.jgraph.event.GraphModelListener;
039:        import org.jgraph.event.GraphSelectionEvent;
040:        import org.jgraph.event.GraphSelectionListener;
041:        import org.jgraph.graph.CellView;
042:        import org.jgraph.graph.ConnectionSet;
043:        import org.jgraph.graph.DefaultGraphCell;
044:        import org.jgraph.graph.GraphModel;
045:        import org.jgraph.graph.GraphTransferHandler;
046:        import org.jgraph.graph.ParentMap;
047:        import org.w3c.dom.Node;
048:
049:        import com.jgraph.JGraphEditor;
050:        import com.jgraph.editor.JGraphEditorAction;
051:        import com.jgraph.editor.JGraphEditorFactory;
052:        import com.jgraph.editor.factory.JGraphEditorFactoryMethod;
053:        import com.jgraph.pad.JGraphpadLibrary;
054:        import com.jgraph.pad.graph.JGraphpadVertexRenderer;
055:        import com.jgraph.pad.util.JGraphpadMouseAdapter;
056:        import com.jgraph.pad.util.JGraphpadTreeModelAdapter;
057:
058:        /**
059:         * Displays groups in a {@link JGraphpadLibrary} as a list of entries. Allows to
060:         * drag and drop entries to/from {@link JGraph}.
061:         */
062:        public class JGraphpadLibraryPane extends JComponent {
063:
064:            /**
065:             * Node name for the library popup menu configuration.
066:             */
067:            public static final String NODENAME_LIBRARYPOPUPMENU = "librarypopupmenu";
068:
069:            /**
070:             * Node name for the library popup menu configuration.
071:             */
072:            public static final String NODENAME_ENTRYPOPUPMENU = "entrypopupmenu";
073:
074:            /**
075:             * Defines the preferred width which is used to find the best number of
076:             * columns.
077:             */
078:            public static int PREFERRED_WIDTH = 100;
079:
080:            /**
081:             * References the library.
082:             */
083:            protected JGraphpadLibrary library;
084:
085:            /**
086:             * References the enclosing editor.
087:             */
088:            protected JGraphEditor editor;
089:
090:            /**
091:             * Defines geometry and spacing.
092:             */
093:            protected int entrywidth = 60, entryheight = 40, hgap = 10,
094:                    vgap = 10;
095:
096:            protected CellRendererPane rendererPane = new CellRendererPane();
097:
098:            /**
099:             * Holds the backing graph for rendering. Makes sure the cell renderer pane
100:             * is actually inserted into a valid component.
101:             */
102:            protected JGraph backingGraph = new JGraph();
103:
104:            /**
105:             * Automatically groups cells on drop and ungroups cells on drag. Default is
106:             * true.
107:             */
108:            protected boolean autoBoxing = true;
109:
110:            /**
111:             * Specifies whether to use antialiasing to render the entries.
112:             */
113:            protected boolean antiAliased = true;
114:
115:            /**
116:             * Specifies whether the library can be changed.
117:             */
118:            protected boolean isReadOnly = false;
119:
120:            /**
121:             * Internal variable to block drag and drop if the operation was initiated
122:             * from here. This variable is true during drag operations that started
123:             * here.
124:             */
125:            protected transient boolean dragging = false;
126:
127:            /**
128:             * Constructs a new repository pane for the specified library.
129:             * 
130:             * @param library
131:             *            The library that contains the cells.
132:             */
133:            public JGraphpadLibraryPane(final JGraphEditor editor,
134:                    JGraphpadLibrary library) {
135:                setTransferHandler(new LibraryTransferHandler());
136:                this .editor = editor;
137:                this .library = library;
138:                this .isReadOnly = library.isReadOnly();
139:
140:                // Disables the folding icon in the backing graph
141:                backingGraph
142:                        .putClientProperty(
143:                                JGraphpadVertexRenderer.CLIENTPROPERTY_SHOWFOLDINGICONS,
144:                                new Boolean(false));
145:
146:                // Configures the backing graph
147:                GraphTransferHandler transferHandler = new LibraryGraphTransferHandler();
148:                transferHandler.setAlwaysReceiveAsCopyAction(true);
149:                backingGraph.setTransferHandler(transferHandler);
150:                backingGraph.setGraphLayoutCache(library.getGraphLayoutCache());
151:                backingGraph.setDragEnabled(true);
152:                backingGraph.setDoubleBuffered(false);
153:
154:                // Starts dragging the entry under the mouse pointer
155:                addMouseListener(new JGraphpadMouseAdapter(editor,
156:                        NODENAME_LIBRARYPOPUPMENU) {
157:
158:                    /**
159:                     * Selects the entry under the mouse pointer.
160:                     */
161:                    public void mousePressed(MouseEvent event) {
162:                        int index = getIndexAt(event.getX(), event.getY());
163:
164:                        // Selects cell at index and starts dragging
165:                        if (index >= 0) {
166:                            getBackingGraph().setSelectionCell(
167:                                    getBackingGraph().getModel().getRootAt(
168:                                            index));
169:                            if (!SwingUtilities.isRightMouseButton(event))
170:                                getTransferHandler().exportAsDrag(
171:                                        getBackingGraph(), event,
172:                                        TransferHandler.COPY);
173:                        }
174:
175:                        // Clear selection if no cell found
176:                        else {
177:                            getBackingGraph().clearSelection();
178:                        }
179:                        requestFocus();
180:                    }
181:
182:                    /**
183:                     * Overrides the parent implementation to return a different config
184:                     * if the selection is not empty.
185:                     */
186:                    public String getConfigName() {
187:                        return (!isSelectionEmpty()) ? NODENAME_ENTRYPOPUPMENU
188:                                : super .getConfigName();
189:                    }
190:
191:                });
192:
193:                // Repaints and revalidates on model changes
194:                backingGraph.getModel().addGraphModelListener(
195:                        new GraphModelListener() {
196:                            public void graphChanged(GraphModelEvent e) {
197:                                revalidate();
198:                                repaint();
199:                            }
200:                        });
201:
202:                // Repaints on selection changes
203:                backingGraph.getSelectionModel().addGraphSelectionListener(
204:                        new GraphSelectionListener() {
205:                            public void valueChanged(GraphSelectionEvent e) {
206:                                repaint();
207:                            }
208:                        });
209:
210:                add(rendererPane);
211:            }
212:
213:            /**
214:             * Returns true if the library contains no entries.
215:             * 
216:             * @return Returns true if the library is empty.
217:             */
218:            public boolean isEmpty() {
219:                return backingGraph.getModel().getRootCount() == 0;
220:            }
221:
222:            /**
223:             * Returns true if the library contains no selectio entries.
224:             * 
225:             * @return Returns true if the selection is empty.
226:             */
227:            public boolean isSelectionEmpty() {
228:                return backingGraph.isSelectionEmpty();
229:            }
230:
231:            /**
232:             * Removes the selection entry from the library.
233:             */
234:            public void removeEntry() {
235:                if (!backingGraph.isSelectionEmpty()) {
236:                    Object[] cells = backingGraph.getDescendants(backingGraph
237:                            .getSelectionCells());
238:                    backingGraph.getModel().remove(cells);
239:                }
240:            }
241:
242:            /**
243:             * Brings the selection entry to front (start of list).
244:             */
245:            public void bringEntryToFront() {
246:                if (!backingGraph.isSelectionEmpty())
247:                    backingGraph.getModel().toFront(
248:                            backingGraph.getSelectionCells());
249:            }
250:
251:            /**
252:             * Sends the selection entry to back (end of list).
253:             */
254:            public void sendEntryToBack() {
255:                if (!backingGraph.isSelectionEmpty())
256:                    backingGraph.getModel().toBack(
257:                            backingGraph.getSelectionCells());
258:            }
259:
260:            /**
261:             * Returns the bounds of the entry at <code>index</code>. This returns a
262:             * value regardless of whether an entry at index actually exists.
263:             * 
264:             * @param index
265:             *            The index that specifies the entry.
266:             * @return Returns the bounds for the entry at <code>index</code>.
267:             */
268:            public Rectangle getBounds(int index) {
269:                Rectangle outer = getBounds();
270:                int cols = Math.max(outer.width / (entrywidth + hgap), 1);
271:                int col = index % cols;
272:                int row = index / cols;
273:                int x = hgap + col * (entrywidth + hgap);
274:                int y = vgap + row * (entryheight + vgap);
275:                return new Rectangle(x, y, entrywidth, entryheight);
276:            }
277:
278:            /**
279:             * Returns the index of the entry at the specified location. If no entry
280:             * exists at the specified location then -1 is returned.
281:             * 
282:             * @param x
283:             *            The x position.
284:             * @param y
285:             *            The y position.
286:             * @return Returns the index for the specified location or -1.
287:             */
288:            public int getIndexAt(int x, int y) {
289:                Rectangle outer = getBounds();
290:                int cols = Math.max(outer.width / (entrywidth + hgap), 1);
291:                int col = x / (entrywidth + hgap);
292:                int row = y / (entryheight + vgap);
293:                int index = row * cols + col;
294:                if (index >= 0
295:                        && index < backingGraph.getModel().getRootCount())
296:                    return index;
297:                return -1;
298:
299:            }
300:
301:            /**
302:             * Paints the library pane.
303:             * 
304:             * @param g
305:             *            The graphics to paint the library pane to.
306:             */
307:            public void paint(Graphics g) {
308:                super .paint(g);
309:                Graphics2D g2 = (Graphics2D) g;
310:                if (antiAliased)
311:                    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
312:                            RenderingHints.VALUE_ANTIALIAS_ON);
313:                Shape clip = g.getClip();
314:                CellView[] entries = backingGraph.getGraphLayoutCache()
315:                        .getRoots();
316:                for (int i = 0; i < entries.length; i++) {
317:
318:                    // Computes the scale to draw the entry width
319:                    Rectangle2D bounds = entries[i].getBounds();
320:                    double scale = Math.min(entrywidth / bounds.getWidth(),
321:                            entryheight / bounds.getHeight());
322:                    Rectangle rect = getBounds(i);
323:                    Rectangle frame = new Rectangle((int) rect.getX() - 2,
324:                            (int) rect.getY() - 2, entrywidth + 4,
325:                            entryheight + 4);
326:
327:                    // Translates and renders the entry using the backing graph
328:                    if (clip.intersects(frame)) {
329:                        g2.scale(scale, scale);
330:                        g.translate(
331:                                (int) (rect.getX() / scale - bounds.getX()),
332:                                (int) (rect.getY() / scale - bounds.getY()));
333:
334:                        // Since the backing graph has not been added to a component
335:                        // hierarchy we have to use our own cell renderer pane here.
336:                        paintView(g, entries[i]);
337:                        g.translate(
338:                                -(int) (rect.getX() / scale - bounds.getX()),
339:                                -(int) (rect.getY() / scale - bounds.getY()));
340:                        g2.scale(1 / scale, 1 / scale);
341:                        if (getBackingGraph().isCellSelected(
342:                                entries[i].getCell())) {
343:                            g.setColor(backingGraph.getHandleColor());
344:                            g.drawRect(frame.x, frame.y, frame.width,
345:                                    frame.height);
346:                        }
347:                    }
348:                }
349:            }
350:
351:            /**
352:             * Paints the specified cell view on the local cell renderer pane.
353:             * 
354:             * @param g
355:             * @param view
356:             */
357:            protected void paintView(Graphics g, CellView view) {
358:                // Paint parent
359:                Component component = view.getRendererComponent(backingGraph,
360:                        false, false, false);
361:                Rectangle2D bounds = view.getBounds();
362:                component.setBounds(0, 0, (int) bounds.getWidth(), (int) bounds
363:                        .getHeight());
364:                rendererPane.paintComponent(g, component, this , (int) bounds
365:                        .getX(), (int) bounds.getY(), (int) bounds.getWidth(),
366:                        (int) bounds.getHeight(), true);
367:
368:                // Paint children recursively
369:                CellView[] children = view.getChildViews();
370:                for (int i = 0; i < children.length; i++) {
371:                    paintView(g, children[i]); // recurse
372:                }
373:            }
374:
375:            /**
376:             * Overrides the parent method to contain all entries in a matrix with as
377:             * many columns as fit into {@link #PREFERRED_WIDTH} with the current
378:             * {@link #entrywidth}.
379:             * 
380:             * @return Returns the preferred size.
381:             */
382:            public Dimension preferredSize() {
383:                int rootCount = getBackingGraph().getModel().getRootCount();
384:                int cols = Math.max(1, PREFERRED_WIDTH / (entrywidth + vgap));
385:                return new Dimension(cols * (entrywidth + vgap), (Math.max(
386:                        (rootCount + 1) / cols, 1) * (entryheight + hgap)));
387:            }
388:
389:            /**
390:             * Overrides the parent method to contain a single entry.
391:             * 
392:             * @return Returns the minimum size.
393:             */
394:            public Dimension getMinimumSize() {
395:                return new Dimension(entrywidth + vgap, entryheight + hgap);
396:            }
397:
398:            /**
399:             * Returns the backing graph used for rendering entries.
400:             * 
401:             * @return Returns the backing graph.
402:             */
403:            public JGraph getBackingGraph() {
404:                return backingGraph;
405:            }
406:
407:            /**
408:             * Sets the backing graph to be used to render entries.
409:             * 
410:             * @param backingGraph
411:             *            The backing graph to set.
412:             */
413:            public void setBackingGraph(JGraph backingGraph) {
414:                this .backingGraph = backingGraph;
415:            }
416:
417:            /**
418:             * Returns the library associated with the library pane.
419:             * 
420:             * @return Returns the library.
421:             */
422:            public JGraphpadLibrary getLibrary() {
423:                return library;
424:            }
425:
426:            /**
427:             * Sets the library associated with the library pane.
428:             * 
429:             * @param library
430:             *            The library to set.
431:             */
432:            public void setLibrary(JGraphpadLibrary library) {
433:                this .library = library;
434:            }
435:
436:            /**
437:             * Returns true if the library uses autoboxing.
438:             * 
439:             * @return Returns the autoBoxing.
440:             */
441:            public boolean isAutoBoxing() {
442:                return autoBoxing;
443:            }
444:
445:            /**
446:             * Sets if the library should use autoboxing.
447:             * 
448:             * @param autoBoxing
449:             *            The autoBoxing to set.
450:             */
451:            public void setAutoBoxing(boolean autoBoxing) {
452:                this .autoBoxing = autoBoxing;
453:            }
454:
455:            /**
456:             * Returns the height to draw entries.
457:             * 
458:             * @return Returns the entryheight.
459:             */
460:            public int getEntryheight() {
461:                return entryheight;
462:            }
463:
464:            /**
465:             * Sets the height to draw entries.
466:             * 
467:             * @param entryheight
468:             *            The entryheight to set.
469:             */
470:            public void setEntryheight(int entryheight) {
471:                this .entryheight = entryheight;
472:            }
473:
474:            /**
475:             * Returns the width to draw entries.
476:             * 
477:             * @return Returns the entrywidth.
478:             */
479:            public int getEntrywidth() {
480:                return entrywidth;
481:            }
482:
483:            /**
484:             * Sets the width to draw entries.
485:             * 
486:             * @param entrywidth
487:             *            The entrywidth to set.
488:             */
489:            public void setEntrywidth(int entrywidth) {
490:                this .entrywidth = entrywidth;
491:            }
492:
493:            /**
494:             * Returns the horizontal gap between entries.
495:             * 
496:             * @return Returns the hgap.
497:             */
498:            public int getHgap() {
499:                return hgap;
500:            }
501:
502:            /**
503:             * Sets the horizontal gap between entries.
504:             * 
505:             * @param hgap
506:             *            The hgap to set.
507:             */
508:            public void setHgap(int hgap) {
509:                this .hgap = hgap;
510:            }
511:
512:            /**
513:             * Returns the vertical gap between entries.
514:             * 
515:             * @return Returns the vgap.
516:             */
517:            public int getVgap() {
518:                return vgap;
519:            }
520:
521:            /**
522:             * Sets the vertical gap between entries.
523:             * 
524:             * @param vgap
525:             *            The vgap to set.
526:             */
527:            public void setVgap(int vgap) {
528:                this .vgap = vgap;
529:            }
530:
531:            /**
532:             * Returns true if rendering should be antialiased.
533:             * 
534:             * @return Returns the antiAliased.
535:             */
536:            public boolean isAntiAliased() {
537:                return antiAliased;
538:            }
539:
540:            /**
541:             * Sets if the rendering should be antialiased.
542:             * 
543:             * @param antiAliased
544:             *            The antiAliased to set.
545:             */
546:            public void setAntiAliased(boolean antiAliased) {
547:                this .antiAliased = antiAliased;
548:            }
549:
550:            /**
551:             * @return Returns the readOnly.
552:             */
553:            public boolean isReadOnly() {
554:                return isReadOnly;
555:            }
556:
557:            /**
558:             * @param readOnly
559:             *            The readOnly to set.
560:             */
561:            public void setReadOnly(boolean readOnly) {
562:                this .isReadOnly = readOnly;
563:            }
564:
565:            /**
566:             * Returns the parent library pane of the specified component or the
567:             * component itself if it is a library pane.
568:             * 
569:             * @return Returns the parent library pane.
570:             */
571:            public static JGraphpadLibraryPane getParentLibraryPane(
572:                    Component component) {
573:                while (component != null) {
574:                    if (component instanceof  JGraphpadLibraryPane)
575:                        return (JGraphpadLibraryPane) component;
576:                    component = component.getParent();
577:                }
578:                return null;
579:            }
580:
581:            /**
582:             * Utility class to implement autoboxing and to set the {@link #dragging}
583:             * flag.
584:             */
585:            public class LibraryGraphTransferHandler extends
586:                    GraphTransferHandler {
587:
588:                /**
589:                 * Only allows importing data if the enclosing library is not read-only.
590:                 */
591:                public boolean canImport(JComponent component,
592:                        DataFlavor[] flavors) {
593:                    return !isReadOnly;
594:                }
595:
596:                /**
597:                 * Overrides the parent method to set the dragging flag and replaces the
598:                 * selection group with its children if autoboxing is turned on.
599:                 * 
600:                 * @param c
601:                 *            The component to perform the opeation in.
602:                 */
603:                protected Transferable createTransferable(JComponent c) {
604:                    dragging = true;
605:
606:                    // Creates a transferable that contains the children
607:                    // of the autobox cell (selection cell) and returns them.
608:                    if (c instanceof  JGraph) {
609:                        JGraph graph = (JGraph) c;
610:                        if (!graph.isSelectionEmpty()) {
611:                            Object cell = graph.getSelectionCell();
612:                            GraphModel model = graph.getModel();
613:                            if (cell instanceof  AutoBoxCell) {
614:                                int childCount = model.getChildCount(cell);
615:                                List children = new ArrayList(childCount);
616:                                for (int i = 0; i < childCount; i++)
617:                                    children.add(model.getChild(cell, i));
618:                                Object[] cells = graph.getDescendants(graph
619:                                        .order(children.toArray()));
620:                                return createTransferable(graph, cells); // exit
621:                            }
622:                        }
623:                    }
624:                    return super .createTransferable(c);
625:                }
626:
627:                /**
628:                 * Overrides the parent method to reset the dragging flag in order to
629:                 * accept external drops.
630:                 */
631:                protected void exportDone(JComponent source, Transferable data,
632:                        int action) {
633:                    dragging = false;
634:                    super .exportDone(source, data, action);
635:                }
636:
637:                /**
638:                 * Overrides the parent method to add a group to the dropped cells if
639:                 * autoboxing is turned on.
640:                 * 
641:                 * @param graph
642:                 *            The graph to perform the operation in.
643:                 * @param cells
644:                 *            The cells to be inserted into the library.
645:                 * @param nested
646:                 *            The attributes to be assigned to the cells.
647:                 * @param cs
648:                 *            The connections to be established between the cells.
649:                 * @param pm
650:                 *            The parent map that describes the parent-child relations.
651:                 * @param dx
652:                 *            The x-offset to translate the cells with.
653:                 * @param dy
654:                 *            The y-offset to translate the cells with.
655:                 */
656:                protected void handleExternalDrop(JGraph graph, Object[] cells,
657:                        Map nested, ConnectionSet cs, ParentMap pm, double dx,
658:                        double dy) {
659:                    if (autoBoxing) {
660:                        // Adds a new autoboxcell as the parent cell to all inserted
661:                        // cells which have no parent in the transfer data.
662:                        DefaultGraphCell parent = new AutoBoxCell();
663:                        List tmp = new ArrayList(cells.length + 1);
664:                        tmp.add(parent);
665:                        for (int i = 0; i < cells.length; i++) {
666:                            if (!(cells[i] instanceof  AutoBoxCell)) {
667:                                tmp.add(cells[i]);
668:                                Object oldParent = graph.getModel().getParent(
669:                                        cells[i]);
670:                                if (oldParent == null
671:                                        || !pm.getChangedNodes().contains(
672:                                                oldParent))
673:                                    pm.addEntry(cells[i], parent);
674:                            }
675:                        }
676:                        cells = tmp.toArray();
677:                    }
678:                    super .handleExternalDrop(graph, cells, nested, cs, pm, dx,
679:                            dy);
680:                }
681:
682:            }
683:
684:            /**
685:             * Utility class to redirect transfer events from the library pane to the
686:             * backing graph if the dragging flag is not set.
687:             * 
688:             */
689:            public class LibraryTransferHandler extends TransferHandler {
690:
691:                /*
692:                 * (non-Javadoc)
693:                 */
694:                public int getSourceActions(JComponent c) {
695:                    return COPY;
696:                }
697:
698:                /*
699:                 * (non-Javadoc)
700:                 */
701:                public boolean canImport(JComponent comp, DataFlavor[] flavors) {
702:                    return !dragging
703:                            && getBackingGraph().getTransferHandler()
704:                                    .canImport(comp, flavors);
705:                }
706:
707:                /*
708:                 * (non-Javadoc)
709:                 */
710:                public boolean importData(JComponent comp, Transferable t) {
711:                    return getBackingGraph().getTransferHandler().importData(
712:                            getBackingGraph(), t);
713:                }
714:
715:            }
716:
717:            /**
718:             * Utility class to establish a listener in a editor's document model and
719:             * update the library panes in a tabbed pane.
720:             */
721:            public static class LibraryTracker extends
722:                    JGraphpadTreeModelAdapter {
723:
724:                /**
725:                 * References the enclosing editor.
726:                 */
727:                protected JGraphEditor editor;
728:
729:                /**
730:                 * References the tabbed pane to be updated.
731:                 */
732:                protected JTabbedPane tabPane;
733:
734:                /**
735:                 * Holds library, component pairs to find the respective tabs.
736:                 */
737:                protected Map tabs = new Hashtable();
738:
739:                /**
740:                 * Constructs a new library tracker for updating the specified tabPane
741:                 * using factory to create required components. The library tracker must
742:                 * be added as a tree model listener to an editor's document model.
743:                 * 
744:                 * @param tabPane
745:                 *            The pane to be updated on document model changes.
746:                 * @param editor
747:                 *            The enclosing editor.
748:                 */
749:                public LibraryTracker(JTabbedPane tabPane, JGraphEditor editor) {
750:                    this .tabPane = tabPane;
751:                    this .editor = editor;
752:                }
753:
754:                /**
755:                 * Creates a new {@link JGraphpadLibraryPane}, wraps it up in a scroll
756:                 * pane using {@link JGraphEditorFactory#createScrollPane(Component)}
757:                 * and adds it as a tab to {@link #tabPane} using the library's toString
758:                 * method to set the tab's title.
759:                 * 
760:                 * @param arg0
761:                 *            The object that describes the event.
762:                 */
763:                public void treeNodesInserted(TreeModelEvent arg0) {
764:                    JGraphpadPane padPane = JGraphEditorAction
765:                            .getJGraphpadPane();
766:
767:                    Object[] children = arg0.getChildren();
768:                    for (int i = 0; i < children.length; i++) {
769:
770:                        if (children[i] instanceof  JGraphpadLibrary) {
771:                            JGraphpadLibrary library = (JGraphpadLibrary) children[i];
772:
773:                            JInternalFrame frame = null;
774:
775:                            if (padPane != null) {
776:                                frame = padPane.getInternalFrame(library
777:                                        .getParent());
778:                            }
779:
780:                            if (frame == null || frame.isAncestorOf(tabPane)) {
781:                                final JGraphpadLibraryPane libraryPane = new JGraphpadLibraryPane(
782:                                        editor, library);
783:                                Component pane = editor.getFactory()
784:                                        .createScrollPane(libraryPane);
785:                                tabPane.addTab(getTitle(library), pane);
786:                                tabPane.setSelectedComponent(pane);
787:                                tabs.put(children[i], pane);
788:
789:                                // Transfers the focus to the new library pane
790:                                // after the component hierarchy has been revalidated.
791:                                SwingUtilities.invokeLater(new Runnable() {
792:                                    public void run() {
793:                                        libraryPane.requestFocus();
794:                                    }
795:                                });
796:                            }
797:                        }
798:                    }
799:                }
800:
801:                /**
802:                 * Removes the tabs for the removed libraries from the tab pane.
803:                 */
804:                public void treeNodesRemoved(TreeModelEvent arg0) {
805:                    Object[] children = arg0.getChildren();
806:                    for (int i = 0; i < children.length; i++) {
807:                        if (children[i] instanceof  JGraphpadLibrary) {
808:
809:                            // Finds the tab with the scrollpane that contains
810:                            // the library pane for the removed library and
811:                            // removes it.
812:                            Object tab = tabs.remove(children[i]);
813:                            if (tab instanceof  Component)
814:                                tabPane.remove((Component) tab);
815:                        }
816:                    }
817:                }
818:
819:                /**
820:                 * Calls {@link #updateTabTitle(JGraphpadLibrary)} for all libraries
821:                 * that have changed in the tree.
822:                 * 
823:                 * @param arg0
824:                 *            The object that describes the event.
825:                 */
826:                public void treeNodesChanged(TreeModelEvent arg0) {
827:                    Object[] children = arg0.getChildren();
828:                    for (int i = 0; i < children.length; i++)
829:                        if (children[i] instanceof  JGraphpadLibrary)
830:                            updateTabTitle((JGraphpadLibrary) children[i]);
831:                }
832:
833:                /**
834:                 * Invoked to update the title for the tab of the specified library.
835:                 * 
836:                 * @param library
837:                 *            The library who's title needs to be updated.
838:                 */
839:                protected void updateTabTitle(JGraphpadLibrary library) {
840:                    Object tab = tabs.get(library);
841:                    if (tab instanceof  Component) {
842:                        String title = getTitle(library);
843:                        int index = tabPane.indexOfComponent((Component) tab);
844:                        tabPane.setTitleAt(index, title);
845:                    }
846:                }
847:
848:                /**
849:                 * Hook for subclassers to return the tab title to be used for the
850:                 * specified library. This implementation returns the filename-part of a
851:                 * path.
852:                 * 
853:                 * @param library
854:                 *            The library to return the title for.
855:                 * @return Returns a title for <code>library</code>.
856:                 */
857:                protected String getTitle(JGraphpadLibrary library) {
858:                    String state = (library.isModified()) ? " *" : "";
859:                    return String.valueOf(library) + state;
860:                }
861:
862:            }
863:
864:            /**
865:             * Utility class to identify autoboxing cells.
866:             */
867:            public static class AutoBoxCell extends DefaultGraphCell {
868:                // empty
869:            }
870:
871:            /**
872:             * Provides a factory method to construct a library pane.
873:             */
874:            public static class FactoryMethod extends JGraphEditorFactoryMethod {
875:
876:                /**
877:                 * Defines the default name for factory methods of this kind.
878:                 */
879:                public static String NAME = "createLibraryPane";
880:
881:                /**
882:                 * References the enclosing editor.
883:                 */
884:                protected JGraphEditor editor;
885:
886:                /**
887:                 * Constructs a new factory method for the specified enclosing editor
888:                 * using {@link #NAME}.
889:                 * 
890:                 * @param editor
891:                 *            The editor that contains the factory method.
892:                 */
893:                public FactoryMethod(JGraphEditor editor) {
894:                    super (NAME);
895:                    this .editor = editor;
896:                }
897:
898:                /*
899:                 * (non-Javadoc)
900:                 */
901:                public Component createInstance(Node configuration) {
902:                    JTabbedPane tabPane = editor.getFactory().createTabbedPane(
903:                            JTabbedPane.BOTTOM);
904:                    tabPane.addMouseListener(new JGraphpadMouseAdapter(editor,
905:                            JGraphpadPane.NODENAME_DESKTOPPOPUPMENU));
906:                    LibraryTracker tracker = new LibraryTracker(tabPane, editor);
907:                    editor.getModel().addTreeModelListener(tracker);
908:                    return tabPane;
909:                }
910:
911:            }
912:
913:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.