Source Code Cross Referenced for ScriptTable.java in  » Testing » abbot-1.0.1 » abbot » editor » 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 » Testing » abbot 1.0.1 » abbot.editor 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package abbot.editor;
002:
003:        import java.awt.*;
004:        import java.awt.datatransfer.Transferable;
005:        import java.awt.dnd.*;
006:        import java.awt.event.*;
007:        import java.awt.image.BufferedImage;
008:        import java.net.URL;
009:        import java.util.*;
010:        import java.util.List;
011:
012:        import javax.swing.*;
013:        import javax.swing.plaf.basic.BasicTreeUI;
014:        import javax.swing.table.*;
015:
016:        import abbot.Log;
017:        import abbot.script.*;
018:
019:        /** Provides a component to edit a test script.  A cursor indicates where
020:         insertions will be positioned.  Supports drag & drop within the component
021:         itself.<p>
022:         Actions supported:<br>
023:         move-rows-up<br>
024:         move-rows-down<br>
025:         toggle<br>
026:         */
027:
028:        public class ScriptTable extends JTable implements  Autoscroll {
029:            private int cursorRow = 0;
030:            private Sequence cursorParent = null;
031:            private int cursorParentIndex = 0;
032:            private int cursorDepth = 0;
033:            private boolean isDragging = false;
034:
035:            private DragSource dragSource;
036:            private DragSourceListener dragSourceListener;
037:            private static Icon openIcon;
038:            private static Icon closedIcon;
039:            private static int baseIndent;
040:            private static final int MARGIN = 4;
041:
042:            static {
043:                URL url1 = ScriptTable.class
044:                        .getResource("icons/triangle-dn.gif");
045:                URL url2 = ScriptTable.class
046:                        .getResource("icons/triangle-rt.gif");
047:                if (url1 != null && url2 != null) {
048:                    openIcon = new ImageIcon(url1);
049:                    closedIcon = new ImageIcon(url2);
050:                } else {
051:                    BasicTreeUI ui = (BasicTreeUI) (new JTree().getUI());
052:                    openIcon = ui.getExpandedIcon();
053:                    closedIcon = ui.getCollapsedIcon();
054:                }
055:                baseIndent = openIcon.getIconWidth();
056:            }
057:
058:            private ScriptModel model;
059:
060:            public ScriptTable() {
061:                this (new ScriptModel());
062:            }
063:
064:            public ScriptTable(ScriptModel scriptModel) {
065:                super (scriptModel);
066:                setSelectionModel(new SelectionModel());
067:                model = scriptModel;
068:                TableCellRenderer cr = new ScriptTableCellRenderer();
069:                setDefaultRenderer(Object.class, cr);
070:                Dimension spacing = getIntercellSpacing();
071:                spacing.height = 2;
072:                setIntercellSpacing(spacing);
073:
074:                initDragDrop();
075:
076:                // Detect clicks on the table in order to position the cursor
077:                // and expand entries.
078:                MouseListener ml = new MouseAdapter() {
079:                    public void mouseClicked(MouseEvent me) {
080:                        if (me.getModifiers() != InputEvent.BUTTON1_MASK)
081:                            return;
082:                        if (me.getClickCount() == 2) {
083:                            int row = rowAtPoint(me.getPoint());
084:                            Log.debug("Toggling row at " + row);
085:                            toggle(row);
086:                        } else {
087:                            click(me.getPoint());
088:                        }
089:                    }
090:                };
091:                addMouseListener(ml);
092:                // Set up our custom actions; note that there are no default input
093:                // bindings 
094:                ActionMap map = getActionMap();
095:                map.put("move-rows-up", new AbstractAction() {
096:                    public void actionPerformed(ActionEvent ev) {
097:                        moveUp();
098:                    }
099:                });
100:                map.put("move-rows-down", new AbstractAction() {
101:                    public void actionPerformed(ActionEvent ev) {
102:                        moveDown();
103:                    }
104:                });
105:                map.put("toggle", new AbstractAction() {
106:                    public void actionPerformed(ActionEvent ev) {
107:                        int selRow = getSelectedRow();
108:                        if (selRow != -1) {
109:                            toggle(selRow);
110:                        }
111:                    }
112:                });
113:            }
114:
115:            /** Toggle the open/closed state of a sequence. */
116:            public void toggle(int row) {
117:                int[] rows = getSelectedRows();
118:                if (rows.length > 0) {
119:                    int anchor = getSelectionModel().getAnchorSelectionIndex();
120:                    Step first = model.getStepAt(rows[0]);
121:                    int lastRow = rows[rows.length - 1];
122:                    Step last = model.getStepAt(lastRow);
123:                    Step afterLast = lastRow < getRowCount() - 1 ? model
124:                            .getStepAt(lastRow + 1) : null;
125:                    clearSelection();
126:                    model.toggle(row);
127:                    int index0 = model.getRowOf(first);
128:                    int index1 = model.getRowOf(last);
129:                    // If the last step in the selection becomes hidden, change the
130:                    // selection and the cursor position. 
131:                    if (index1 == -1) {
132:                        index1 = afterLast == null ? row : model
133:                                .getRowOf(afterLast) - 1;
134:                    }
135:                    if (anchor == index0) {
136:                        Log.debug("Updating selection to " + index0 + " to "
137:                                + index1);
138:                        setRowSelectionInterval(index0, index1);
139:                    } else {
140:                        Log.debug("Updating selection to " + index1 + " to "
141:                                + index0);
142:                        setRowSelectionInterval(index1, index0);
143:                    }
144:                } else {
145:                    model.toggle(row);
146:                }
147:            }
148:
149:            /** Return the bounding for the given cell.  If the step at the given row
150:             * is contained within a sequence, the rect will be offset to the right.
151:             */
152:            public Rectangle getCellRect(int row, int col, boolean includeBorder) {
153:                Rectangle rect = super .getCellRect(row, col, includeBorder);
154:                int indent = getIndentation(row);
155:                rect.x += indent;
156:                rect.width -= indent;
157:                return rect;
158:            }
159:
160:            /** Return the number of pixels offset from the left edge of the table for
161:                the given row.
162:             */
163:            public int getIndentation(int row) {
164:                return getDepthIndentation(model.getNestingDepthAt(row));
165:            }
166:
167:            /** Return the number of pixels offset from the left edge of the table for
168:                the given level of indentation.
169:             */
170:            public int getDepthIndentation(int depth) {
171:                return baseIndent * depth;
172:            }
173:
174:            private void click(Point pt) {
175:                int row = rowAtPoint(pt);
176:                if (row == -1) {
177:                    clearSelection();
178:                    setCursorLocation(getRowCount());
179:                } else {
180:                    Rectangle rect = getCellRect(row, 0, true);
181:                    // If the click is on the open/close icon, then toggle
182:                    if ((model.getStepAt(row) instanceof  Sequence)
183:                            && pt.x >= rect.x
184:                            && pt.x < rect.x + baseIndent
185:                            && pt.y > rect.y + rect.height / MARGIN
186:                            && pt.y < rect.y + rect.height * (MARGIN - 1)
187:                                    / MARGIN) {
188:                        toggle(row);
189:                    } else {
190:                        setCursorLocation(pt);
191:                    }
192:                }
193:            }
194:
195:            private void initDragDrop() {
196:                int action = DnDConstants.ACTION_MOVE;
197:                dragSource = DragSource.getDefaultDragSource();
198:                DragGestureListener dgl = new DGListener();
199:                dragSource
200:                        .createDefaultDragGestureRecognizer(this , action, dgl);
201:                dragSourceListener = new DSListener();
202:
203:                DropTarget dt = new DropTarget(this , new DTListener());
204:                dt.setDefaultActions(DnDConstants.ACTION_MOVE);
205:            }
206:
207:            /** Determine what the background color for the given step should be. */
208:            protected Color getStepColor(Step step, boolean selected) {
209:                return selected ? getSelectionBackground() : getBackground();
210:            }
211:
212:            /** Returns the script context of the currently selected row. */
213:            public Script getScriptContext() {
214:                int row = getSelectedRow();
215:                if (row == -1)
216:                    return model.getScript();
217:                return model.getScriptOf(row);
218:            }
219:
220:            /** Returns the row number of the cursor.  The number of cursor locations
221:             * is one greater than the number of table 
222:             * entries.
223:             */
224:            public int getCursorRow() {
225:                return cursorRow;
226:            }
227:
228:            /** Returns the target parent of the current cursor location. */
229:            public Sequence getCursorParent() {
230:                return cursorParent;
231:            }
232:
233:            /** Returns the target index within the parent of the current cursor
234:                location. */
235:            public int getCursorParentIndex() {
236:                return cursorParentIndex;
237:            }
238:
239:            protected Rectangle getCursorBounds() {
240:                Insets insets = getInsets();
241:                Dimension d = getSize();
242:                Dimension m = getIntercellSpacing();
243:                if (m.height == 0)
244:                    m.height = 1;
245:                int width = d.width - insets.left - insets.right;
246:                int row = Math.min(cursorRow, getRowCount() - 1);
247:                Rectangle cellRect = super .getCellRect(row, 0, false);
248:                int y = cellRect.y;
249:                if (cursorRow == getRowCount())
250:                    y += cellRect.height + m.height;
251:                int indent = getDepthIndentation(cursorDepth);
252:                return new Rectangle(indent, y - m.height, width - indent,
253:                        m.height);
254:            }
255:
256:            /** Given an arbitrary point within the table, return the nearest valid
257:                row for the cursor to be placed.
258:             */
259:            private int getCursorRowAtPoint(Point where) {
260:                int row = rowAtPoint(where);
261:                if (row == -1) {
262:                    row = where.y < 0 ? 0 : getRowCount();
263:                } else {
264:                    Rectangle rect = super .getCellRect(row, 0, true);
265:                    if (where.getY() > rect.y + rect.height / 2)
266:                        ++row;
267:                }
268:                // When dragging, don't put the cursor somewhere which would produce
269:                // no effect, or which would be illegal.
270:                if (isDragging) {
271:                    int selStart = getSelectedRow();
272:                    int count = getSelectedRowCount();
273:                    if (row > selStart && row <= selStart + count) {
274:                        if (row > count / 2
275:                                && selStart + count + 1 < getRowCount()) {
276:                            row = selStart + count + 1;
277:                        } else {
278:                            row = selStart;
279:                        }
280:                    }
281:                }
282:
283:                return row;
284:            }
285:
286:            // FIXME sometimes the cursor row leads the selected row by two
287:            public void setCursorLocation(Point where) {
288:                int row = getCursorRowAtPoint(where);
289:                setCursorLocation(row, where.x);
290:            }
291:
292:            /** Set the cursor location, using the given indentation to determine the
293:             * appropriate target parent sequence.
294:             */
295:            private void setCursorLocation(int row, int indentation) {
296:                Rectangle oldRect = getCursorBounds();
297:                Script script = model.getScript();
298:                if (script == null)
299:                    return;
300:                // Can't position the cursor after a terminate step
301:                if (script.hasTerminate() && row == getRowCount())
302:                    --row;
303:                else if (script.hasLaunch() && row == 0)
304:                    ++row;
305:                cursorRow = row;
306:                Sequence parent = script;
307:                int index = row == getRowCount() ? parent.size() : parent
308:                        .indexOf(model.getStepAt(row));
309:                int depth = 0;
310:                if (row > 0) {
311:                    // Place the cursor based on the previous step
312:                    Step prev = model.getStepAt(row - 1);
313:                    if (model.isOpen(prev)) {
314:                        parent = (Sequence) prev;
315:                        index = 0;
316:                        // Depth is one greater than the depth of the parent
317:                        depth = model.getNestingDepthAt(row - 1) + 1;
318:                    } else {
319:                        parent = model.getParent(prev);
320:                        index = parent.indexOf(prev) + 1;
321:                        depth = model.getNestingDepthAt(row - 1);
322:                    }
323:                    int indent = getDepthIndentation(depth);
324:                    // Shift up the hierarchy until we reach the appropriate
325:                    // indentation level.
326:                    while (indent > indentation && parent != script) {
327:                        Sequence nextUp = model.getParent(parent);
328:                        index = nextUp.indexOf(parent) + 1;
329:                        parent = nextUp;
330:                        indent = getDepthIndentation(--depth);
331:                    }
332:                }
333:                cursorParent = parent;
334:                cursorParentIndex = index;
335:                cursorDepth = depth;
336:                if (oldRect != null)
337:                    repaint(oldRect);
338:                repaint(getCursorBounds());
339:            }
340:
341:            /** Set the cursor location to a reasonable target for the given row. */
342:            public void setCursorLocation(int row) {
343:                setCursorLocation(row, 0);
344:            }
345:
346:            protected void drawCursor(Graphics g, int row) {
347:                g.setColor(Color.green);
348:                ((Graphics2D) g).fill(getCursorBounds());
349:            }
350:
351:            /** We paint a cursor where insertions will take effect. */
352:            public void paint(Graphics g) {
353:                super .paint(g);
354:                drawCursor(g, cursorRow == getRowCount() ? cursorRow - 1
355:                        : cursorRow);
356:            }
357:
358:            public void autoscroll(Point pt) {
359:                Rectangle bounds = getBounds();
360:                Log.debug("autoscroll at " + pt + " bounds " + bounds);
361:
362:                // Figure out which row we're on.
363:                int row = rowAtPoint(pt);
364:                if (row < 0)
365:                    return;
366:
367:                if (pt.y + bounds.y <= AUTOSCROLL_MARGIN) {
368:                    if (row > 0)
369:                        --row;
370:                } else {
371:                    if (row < getRowCount() - 1)
372:                        ++row;
373:                }
374:                scrollRectToVisible(getCellRect(row, 0, true));
375:            }
376:
377:            private static final int AUTOSCROLL_MARGIN = 12;
378:
379:            public Insets getAutoscrollInsets() {
380:                // Calculate the insets for the JTree, not the viewport the tree is
381:                // in. 
382:                Rectangle tree = getBounds();
383:                Rectangle view = getParent().getBounds();
384:                return new Insets(view.y - tree.y + AUTOSCROLL_MARGIN, view.x
385:                        - tree.x + AUTOSCROLL_MARGIN, tree.height - view.height
386:                        - view.y + tree.y + AUTOSCROLL_MARGIN, tree.width
387:                        - view.width - view.x + tree.x + AUTOSCROLL_MARGIN);
388:            }
389:
390:            private class ScriptTableCellRenderer extends
391:                    DefaultTableCellRenderer {
392:                public Component getTableCellRendererComponent(JTable table,
393:                        Object value, boolean sel, boolean focus, int row,
394:                        int col) {
395:                    // We know that the default renderer for a JTable
396:                    // is a subclass of JLabel
397:                    JLabel renderer = (JLabel) super 
398:                            .getTableCellRendererComponent(table, value, sel,
399:                                    focus, row, col);
400:                    Step step = model.getStepAt(row);
401:                    Icon icon = null;
402:                    if (step instanceof  Sequence) {
403:                        icon = model.isOpen(row) ? openIcon : closedIcon;
404:                    }
405:                    renderer.setIcon(icon);
406:
407:                    super .setBackground(getStepColor(step, sel));
408:                    setOpaque(true);
409:
410:                    return renderer;
411:                }
412:            }
413:
414:            /** Return the first selected step. */
415:            public Step getSelectedStep() {
416:                return getSelectedRowCount() > 0 ? model
417:                        .getStepAt(getSelectedRow()) : null;
418:            }
419:
420:            /** Return the set of selected steps, restricted to siblings of the first
421:                selected row.
422:             */
423:            public List getSelectedSteps() {
424:                ArrayList list = new ArrayList();
425:                int[] rows = getSelectedRows();
426:                if (rows.length > 0) {
427:                    Step step = model.getStepAt(rows[0]);
428:                    Sequence parent = model.getParent(step);
429:                    for (int i = 0; i < rows.length; i++) {
430:                        step = model.getStepAt(rows[i]);
431:                        if (model.getParent(step) == parent) {
432:                            list.add(step);
433:                        }
434:                    }
435:                }
436:                return list;
437:            }
438:
439:            public boolean canMoveDown() {
440:                int[] rows = getSelectedRows();
441:                int max = getRowCount()
442:                        - (model.getScript().hasTerminate() ? 2 : 1);
443:                return rows[rows.length - 1] < max;
444:            }
445:
446:            public boolean canMoveUp() {
447:                int row = getSelectedRow();
448:                int min = model.getScript().hasLaunch() ? 1 : 0;
449:                return row > min
450:                        && !(model.getStepAt(row) instanceof  Terminate);
451:            }
452:
453:            /** Move the selected step(s) up.  If the previous row is part of an open
454:             * sequence, move to the end of the sequence.  Otherwise, switch places
455:             * with the step at the previous row.
456:             */
457:            public void moveUp() {
458:                if (!canMoveUp())
459:                    return;
460:                List list = getSelectedSteps();
461:                int leadRow = getSelectedRow();
462:                Step lead = (Step) list.get(0);
463:                Sequence parent = model.getParent(lead);
464:                Step prev = model.getStepAt(leadRow - 1);
465:                int targetIndex = 0;
466:                // If the previous row to the selection is its parent, move previous
467:                // to the parent.
468:                if (parent.indexOf(lead) == 0) {
469:                    Log.debug("Move out of sequence");
470:                    Sequence newParent = model.getParent(parent);
471:                    targetIndex = newParent.indexOf(parent);
472:                    parent = newParent;
473:                }
474:                // Is the previous step part of an open sequence?
475:                else if (model.isOpen(prev)) {
476:                    Log.debug("Move to previous empty open sequence");
477:                    parent = (Sequence) prev;
478:                    targetIndex = 0;
479:                } else if (model.getParent(prev) != parent) {
480:                    Log.debug("Move to previous open sequence");
481:                    parent = model.getParent(prev);
482:                    targetIndex = parent.indexOf(prev) + 1;
483:                } else {
484:                    Log.debug("Move previous");
485:                    targetIndex = parent.indexOf(prev);
486:                }
487:                moveSelectedRows(parent, targetIndex);
488:            }
489:
490:            /** Move the currently selected rows down one row. */
491:            public void moveDown() {
492:                if (!canMoveDown()) {
493:                    Log.warn("Unexpected move down state");
494:                    return;
495:                }
496:                List list = getSelectedSteps();
497:                Step lead = (Step) list.get(0);
498:                Sequence leadParent = model.getParent(lead);
499:                int[] rows = getSelectedRows();
500:                Step next = model.getStepAt(rows[rows.length - 1] + 1);
501:                Sequence parent = model.getParent(next);
502:                // Default behavior moves after the next step
503:                int targetIndex = parent.indexOf(next) + 1;
504:                // If the next step after the selection is not a sibling,
505:                // make the group a sibling to its old parent
506:                if (leadParent != parent) {
507:                    Sequence nextParent = model.getParent(leadParent);
508:                    targetIndex = nextParent.indexOf(leadParent) + 1;
509:                    parent = nextParent;
510:                }
511:                // If the next step is an open sequence, move into it
512:                else if (model.isOpen(next)) {
513:                    parent = (Sequence) next;
514:                    targetIndex = 0;
515:                }
516:                moveSelectedRows(parent, targetIndex);
517:            }
518:
519:            /** Move the currently selected rows into the given parent at the given
520:                index.
521:             */
522:            public void moveSelectedRows(Sequence parent, int index) {
523:                List steps = getSelectedSteps();
524:                Step first = (Step) steps.get(0);
525:                if (parent.indexOf(first) == index)
526:                    return;
527:
528:                ListSelectionModel lsm = getSelectionModel();
529:                boolean firstIsAnchor = getSelectedRow() == lsm
530:                        .getAnchorSelectionIndex();
531:                model.moveSteps(parent, steps, index);
532:                int firstRow = model.getRowOf(first);
533:                if (firstIsAnchor)
534:                    lsm.setSelectionInterval(firstRow, firstRow + steps.size()
535:                            - 1);
536:                else
537:                    lsm.setSelectionInterval(firstRow + steps.size() - 1,
538:                            firstRow);
539:            }
540:
541:            private class DGListener implements  DragGestureListener {
542:                public void dragGestureRecognized(DragGestureEvent e) {
543:                    Point where = e.getDragOrigin();
544:                    int firstRow = getSelectedRow();
545:                    if (firstRow == -1)
546:                        return;
547:                    if ((e.getDragAction() & DnDConstants.ACTION_MOVE) != 0) {
548:                        Transferable tf = getSelectedRowCount() > 1 ? new StepTransferable(
549:                                getSelectedSteps())
550:                                : new StepTransferable(getSelectedStep());
551:                        try {
552:                            Rectangle rect = getCellRect(firstRow, 0, true);
553:                            int count = getSelectedRowCount();
554:                            rect.height *= count;
555:                            Point offset = new Point(rect.x - where.x, rect.y
556:                                    - where.y);
557:                            rect.x = rect.y = 0;
558:                            BufferedImage image = new BufferedImage(rect.width,
559:                                    rect.height,
560:                                    BufferedImage.TYPE_INT_ARGB_PRE);
561:                            Graphics2D graphics = image.createGraphics();
562:
563:                            graphics.setColor(Color.gray);
564:                            --rect.width;
565:                            --rect.height;
566:                            graphics.draw(rect);
567:                            graphics.dispose();
568:
569:                            e.startDrag(DragSource.DefaultMoveDrop, image,
570:                                    offset, tf, dragSourceListener);
571:                            isDragging = true;
572:                        } catch (InvalidDnDOperationException exc) {
573:                            Log.warn(exc);
574:                        }
575:                    }
576:                }
577:            }
578:
579:            /** Listens to events coming from the source of the drag action. */
580:            private class DSListener implements  DragSourceListener {
581:                public void dragDropEnd(DragSourceDropEvent e) {
582:                    Log.debug("drag drop end " + e.getDropAction());
583:                    // OSX bug makes this fail, so do it in the target listener instead
584:                    if (!e.getDropSuccess()) {
585:                        Log.debug("drop failed");
586:                    }
587:                }
588:
589:                public void dragEnter(DragSourceDragEvent e) {
590:                    Log.debug("drag enter " + e.getDropAction());
591:                    DragSourceContext context = e.getDragSourceContext();
592:                    // intersection of the users selected action, and the source and
593:                    // target actions 
594:                    int action = e.getDropAction();
595:                    if ((action & DnDConstants.ACTION_MOVE) != 0) {
596:                        context.setCursor(DragSource.DefaultMoveDrop);
597:                    } else {
598:                        context.setCursor(DragSource.DefaultMoveNoDrop);
599:                    }
600:                }
601:
602:                public void dragOver(DragSourceDragEvent e) {
603:                }
604:
605:                public void dragExit(DragSourceEvent e) {
606:                }
607:
608:                public void dropActionChanged(DragSourceDragEvent e) {
609:                    Log.debug("action changed " + e.getDropAction());
610:                    DragSourceContext context = e.getDragSourceContext();
611:                    context.setCursor(DragSource.DefaultMoveNoDrop);
612:                }
613:            }
614:
615:            /** Listens to events coming from the target of the drag action. */
616:            private class DTListener implements  DropTargetListener {
617:                public void dragEnter(DropTargetDragEvent e) {
618:                    if (!isDragAcceptable(e)) {
619:                        e.rejectDrag();
620:                    } else {
621:                        e.acceptDrag(DnDConstants.ACTION_MOVE);
622:                    }
623:                }
624:
625:                public void dragExit(DropTargetEvent e) {
626:                }
627:
628:                public void dropActionChanged(DropTargetDragEvent e) {
629:                    if (!isDragAcceptable(e)) {
630:                        e.rejectDrag();
631:                    } else {
632:                        e.acceptDrag(DnDConstants.ACTION_MOVE);
633:                    }
634:                }
635:
636:                public void dragOver(DropTargetDragEvent e) {
637:                    Log.debug("drag over target " + e.getDropAction());
638:                    if (isDragAcceptable(e)) {
639:                        e.acceptDrag(DnDConstants.ACTION_MOVE);
640:                        Rectangle last = getCursorBounds();
641:                        setCursorLocation(e.getLocation());
642:                        Rectangle current = getCursorBounds();
643:                        paintImmediately(last);
644:                        paintImmediately(current);
645:                    } else {
646:                        e.rejectDrag();
647:                    }
648:                }
649:
650:                public void drop(DropTargetDropEvent e) {
651:                    Log.debug("drop successful " + e.getDropAction());
652:                    if (!isDropAcceptable(e)) {
653:                        e.rejectDrop();
654:                    } else {
655:                        e.acceptDrop(DnDConstants.ACTION_MOVE);
656:                        moveSelectedRows(cursorParent, cursorParentIndex);
657:                    }
658:                    e.dropComplete(true);
659:                }
660:
661:                public boolean isDragAcceptable(DropTargetDragEvent e) {
662:                    Log.debug("drag action is " + e.getDropAction());
663:                    return e
664:                            .isDataFlavorSupported(StepTransferable.STEP_FLAVOR);
665:                }
666:
667:                public boolean isDropAcceptable(DropTargetDropEvent e) {
668:                    Log.debug("drop action is " + e.getDropAction());
669:                    return e
670:                            .isDataFlavorSupported(StepTransferable.STEP_FLAVOR);
671:                }
672:            }
673:
674:            /** If any sub-steps of a sequence are selected, they <i>all</i> must be
675:                selected.  Also select all children when selecting an open sequence.
676:             */
677:            private class SelectionModel extends DefaultListSelectionModel {
678:                public SelectionModel() {
679:                    setSelectionMode(SINGLE_INTERVAL_SELECTION);
680:                }
681:
682:                private void fixSelection() {
683:                    if (getSelectedRowCount() == 0
684:                            || (getSelectedRowCount() == 1 && !model
685:                                    .isOpen(getSelectedRow()))) {
686:                        return;
687:                    }
688:                    // Ensure the first selection has at maximum the minimum depth
689:                    // Ensure the row after the last selection has at minimum the
690:                    // minimum depth.
691:                    int anchor = getAnchorSelectionIndex();
692:                    int lead = getLeadSelectionIndex();
693:                    int lo, hi;
694:                    if (anchor < lead) {
695:                        lo = anchor;
696:                        hi = lead;
697:                    } else {
698:                        lo = lead;
699:                        hi = anchor;
700:                    }
701:                    int loDepth = model.getNestingDepthAt(lo);
702:                    int minDepth = loDepth;
703:                    for (int i = lo + 1; i <= hi; i++) {
704:                        minDepth = Math.min(minDepth, model
705:                                .getNestingDepthAt(i));
706:                    }
707:                    if (loDepth > minDepth) {
708:                        for (int i = lo - 1; i >= 0; i--) {
709:                            if (model.getNestingDepthAt(i) == minDepth) {
710:                                Log.debug("Changing low end to " + i);
711:                                if (lo == anchor)
712:                                    setSelectionInterval(lo = i, hi);
713:                                else
714:                                    setSelectionInterval(hi, lo = i);
715:                                break;
716:                            }
717:                        }
718:                    }
719:                    int last = hi + 1;
720:                    while (last < getRowCount()
721:                            && model.getNestingDepthAt(last) > minDepth) {
722:                        ++last;
723:                    }
724:                    if (last > hi + 1) {
725:                        Log.debug("Changing hi end to " + (last - 1));
726:                        if (hi == lead)
727:                            setSelectionInterval(lo, last - 1);
728:                        else
729:                            setSelectionInterval(last - 1, lo);
730:                    }
731:                }
732:
733:                public void addSelectionInterval(int index0, int index1) {
734:                    super .addSelectionInterval(index0, index1);
735:                    fixSelection();
736:                }
737:
738:                public void removeSelectionInterval(int index0, int index1) {
739:                    super .removeSelectionInterval(index0, index1);
740:                    fixSelection();
741:                }
742:
743:                public void setAnchorSelectionIndex(int index) {
744:                    super .setAnchorSelectionIndex(index);
745:                    fixSelection();
746:                }
747:
748:                public void setLeadSelectionIndex(int index) {
749:                    super .setLeadSelectionIndex(index);
750:                    fixSelection();
751:                }
752:
753:                public void setSelectionInterval(int index0, int index1) {
754:                    super .setSelectionInterval(index0, index1);
755:                    fixSelection();
756:                }
757:
758:                public void insertIndexInterval(int index, int length,
759:                        boolean bfore) {
760:                    super .insertIndexInterval(index, length, bfore);
761:                    fixSelection();
762:                }
763:
764:                public void removeIndexInterval(int idx0, int idx1) {
765:                    super.removeIndexInterval(idx0, idx1);
766:                    fixSelection();
767:                }
768:            }
769:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.