Source Code Cross Referenced for FieldWidget.java in  » Report » datavision-1.1.0 » jimm » datavision » gui » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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


001:        package jimm.datavision.gui;
002:
003:        import jimm.datavision.*;
004:        import jimm.datavision.field.Field;
005:        import jimm.datavision.layout.swing.AbstractSwingField;
006:        import jimm.datavision.layout.swing.SwingTextField;
007:        import jimm.util.I18N;
008:        import java.awt.*;
009:        import java.awt.event.*;
010:        import java.awt.dnd.*;
011:        import java.util.Observable;
012:        import java.util.Observer;
013:        import java.util.HashMap;
014:        import javax.swing.*;
015:        import javax.swing.event.MouseInputListener;
016:
017:        /**
018:         * A field widget is the visual representation of a text-based report field.
019:         *
020:         * @author Jim Menard, <a href="mailto:jimm@io.com">jimm@io.com</a>
021:         */
022:        public class FieldWidget implements  MouseInputListener,
023:                DropTargetListener, ActionListener, KeyListener, Observer {
024:
025:            protected static final int GRAB_EDGE_WIDTH = 4;
026:
027:            protected static final int ACTION_INACTION = 0;
028:            protected static final int ACTION_MOVE = 1;
029:            protected static final int ACTION_STRETCH_LEFT = 2;
030:            protected static final int ACTION_STRETCH_RIGHT = 3;
031:            protected static final int ACTION_STRETCH_TOP = 4;
032:            protected static final int ACTION_STRETCH_BOTTOM = 5;
033:            protected static final int ACTION_POPPING_UP_MENU = 6;
034:
035:            /** Minimum field with and height. */
036:            protected static final int MIN_SIZE = 2;
037:
038:            protected static final Font POPUP_FONT = new Font("Serif",
039:                    Font.PLAIN, 10);
040:
041:            protected static HashMap componentMap = new HashMap();
042:
043:            protected AbstractSwingField swingField;
044:            protected SectionWidget sectionWidget;
045:            protected int action;
046:            protected boolean actionStartedYet;
047:            protected boolean selected;
048:            protected boolean mouseChangedSelectedState;
049:            protected PreMoveInfo preMoveInfo;
050:            protected PreStretchInfo preStretchInfo;
051:            protected JPopupMenu popup;
052:            protected JMenu alignSubmenu;
053:            protected JMenu sizeSubmenu;
054:            protected JMenuItem nameItem;
055:            protected JMenuItem showOrHide;
056:            protected JMenuItem formatMenuItem;
057:            protected JMenuItem aggregatesMenuItem;
058:
059:            /**
060:             * Returns the field widget that owns a particular visual component.
061:             *
062:             * @return a field widget or <code>null</code>
063:             */
064:            static FieldWidget findFieldWidgetOwning(Object c) {
065:                return (FieldWidget) componentMap.get(c);
066:            }
067:
068:            /**
069:             * Constructor.
070:             *
071:             * @param sw section widget in which the field's new widget will reside
072:             * @param field a report field
073:             */
074:            public FieldWidget(SectionWidget sw, Field field) {
075:                this (sw, new SwingTextField(field, field.designLabel()));
076:            }
077:
078:            /**
079:             * Constructor.
080:             *
081:             * @param sw section widget in which the field's new widget will reside
082:             * @param asf an abstract swing field
083:             */
084:            protected FieldWidget(SectionWidget sw, AbstractSwingField asf) {
085:                sectionWidget = sw;
086:                swingField = asf;
087:                action = ACTION_INACTION;
088:
089:                jimm.datavision.field.Rectangle b = getField().getBounds();
090:                getComponent().setBounds((int) b.x, (int) b.y, (int) b.width,
091:                        (int) b.height);
092:
093:                getComponent().setBorder(new FWBorder(this ));
094:                getComponent().addMouseListener(this );
095:                getComponent().addMouseMotionListener(this );
096:                getComponent().addKeyListener(this ); // Frank W. Zammetti
097:                buildPopupMenu();
098:
099:                // Allow drops. All we do is pass them on to our parent.
100:                new DropTarget(this .getComponent(),
101:                        DnDConstants.ACTION_COPY_OR_MOVE, // actions
102:                        this ); // DropTargetListener
103:
104:                // Set color, etc. based on field's visiblity
105:                setVisibilityLook();
106:
107:                // Start observing field changes
108:                getField().addObserver(this );
109:
110:                // Add to the class's map so we can find this widget later, given
111:                // a GUI component.
112:                componentMap.put(getComponent(), this );
113:            }
114:
115:            /**
116:             * Builds the popup menu.
117:             */
118:            protected void buildPopupMenu() {
119:                popup = new JPopupMenu();
120:                popup.setFont(POPUP_FONT);
121:
122:                nameItem = MenuUtils.addToMenu(this , popup,
123:                        "FieldWidget.popup_dummy_title", POPUP_FONT);
124:                nameItem.setText(getPopupNameText()); // Overwrite dummy title
125:                nameItem.setEnabled(false);
126:                popup.addSeparator();
127:
128:                addCustomPopupItems();
129:
130:                showOrHide = MenuUtils.addToMenu(this , popup,
131:                        "FieldWidget.popup_hide", POPUP_FONT);
132:                MenuUtils.addToMenu(this , popup, "FieldWidget.popup_delete",
133:                        POPUP_FONT);
134:                popup.addSeparator();
135:                formatMenuItem = MenuUtils.addToMenu(this , popup,
136:                        "FieldWidget.popup_format", POPUP_FONT);
137:                MenuUtils.addToMenu(this , popup, "FieldWidget.popup_border",
138:                        POPUP_FONT);
139:                MenuUtils.addToMenu(this , popup, "FieldWidget.popup_bounds",
140:                        POPUP_FONT);
141:                popup.addSeparator();
142:                aggregatesMenuItem = MenuUtils.addToMenu(this , popup,
143:                        "FieldWidget.popup_aggr", POPUP_FONT);
144:                popup.addSeparator();
145:
146:                alignSubmenu = MenuUtils.buildAlignMenu(this , POPUP_FONT);
147:                alignSubmenu.setFont(POPUP_FONT);
148:                popup.add(alignSubmenu); // Add Align submenu to popup menu
149:
150:                sizeSubmenu = MenuUtils.buildSizeMenu(this , POPUP_FONT);
151:                sizeSubmenu.setFont(POPUP_FONT);
152:                popup.add(sizeSubmenu); // Add Size submenu to popup menu
153:            }
154:
155:            /**
156:             * This hook lets subclasses customize the popup menu. By default,
157:             * nothing happens.
158:             */
159:            protected void addCustomPopupItems() {
160:            }
161:
162:            protected void finalize() throws Throwable {
163:                getField().deleteObserver(this );
164:            }
165:
166:            public void update(Observable obj, Object arg) {
167:                swingField.format(); // Redo font, style, etc.
168:                jimm.datavision.field.Rectangle b = getField().getBounds();
169:                JTextPane textPane = (JTextPane) getComponent();
170:
171:                double width = b.width;
172:                if (width < MIN_SIZE)
173:                    width = MIN_SIZE;
174:                double height = b.height;
175:                if (height < MIN_SIZE)
176:                    height = MIN_SIZE;
177:
178:                textPane.setBounds((int) b.x, (int) b.y, (int) width,
179:                        (int) height);
180:                textPane.setText(getField().designLabel());
181:            }
182:
183:            /**
184:             * Returns <code>true</code> if this field can be formatted.
185:             *
186:             * @return <code>true</code> if this field can be formatted
187:             */
188:            public boolean usesFormat() {
189:                return true;
190:            }
191:
192:            /**
193:             * Returns string to use for popup menu's first item, the (disabled)
194:             * name of this field.
195:             */
196:            protected String getPopupNameText() {
197:                return getField().designLabel();
198:            }
199:
200:            /**
201:             * Returns the section widget containing this field widget.
202:             *
203:             * @return the section widget containing this field widget
204:             */
205:            public SectionWidget getSectionWidget() {
206:                return sectionWidget;
207:            }
208:
209:            /**
210:             * Returns <code>true</code> if the field is selected.
211:             *
212:             * @return <code>true</code> if the field is selected
213:             */
214:            boolean isSelected() {
215:                return selected;
216:            }
217:
218:            /**
219:             * Align this field in relation to <i>prototype</i>.
220:             *
221:             * @param which one of the <code>Designer.ALIGN_*</code> constants
222:             * @param prototype the field to which this one should be aligned
223:             */
224:            public void align(int which, Field prototype) {
225:                jimm.datavision.field.Rectangle b = getField().getBounds();
226:                jimm.datavision.field.Rectangle pb = prototype.getBounds();
227:                switch (which) {
228:                case Designer.ALIGN_TOP:
229:                    b.setY(pb.y);
230:                    break;
231:                case Designer.ALIGN_MIDDLE:
232:                    double middle = pb.y + pb.height / 2;
233:                    b.setY(middle - b.height / 2);
234:                    break;
235:                case Designer.ALIGN_BOTTOM:
236:                    b.setY(pb.y + pb.height - b.height);
237:                    break;
238:                case Designer.ALIGN_LEFT:
239:                    b.setX(pb.x);
240:                    break;
241:                case Designer.ALIGN_CENTER:
242:                    double center = pb.x + pb.width / 2;
243:                    b.setX(center - b.width / 2);
244:                    break;
245:                case Designer.ALIGN_RIGHT:
246:                    b.setX(pb.x + pb.width - b.width);
247:                    break;
248:                case Designer.ALIGN_SNAP_TO_GRID:
249:                    sectionWidget.snapToGrid(b);
250:                    break;
251:                }
252:            }
253:
254:            /**
255:             * Resize this field in relation to <var>prototype</var>.
256:             *
257:             * @param which one of the <code>Designer.SIZE_SAME_*</code> constants
258:             * @param prototype the field from which this one should take sizes
259:             */
260:            public void size(int which, Field prototype) {
261:                jimm.datavision.field.Rectangle b = getField().getBounds();
262:                jimm.datavision.field.Rectangle pb = prototype.getBounds();
263:                switch (which) {
264:                case Designer.SIZE_SAME_WIDTH:
265:                    b.setWidth(pb.width);
266:                    break;
267:                case Designer.SIZE_SAME_HEIGHT:
268:                    b.setHeight(pb.height);
269:                    break;
270:                case Designer.SIZE_SAME_SIZE:
271:                    b.setWidth(pb.width);
272:                    b.setHeight(pb.height);
273:                    break;
274:                }
275:            }
276:
277:            /**
278:             * Selects this field. If the shift key is down (we don't want to deselect
279:             * other fields), toggles the selection state instead. If
280:             * <i>deselectOthers</i> is <code>true</code>, do so. Eventually
281:             * {@link #doSelect} will be called.
282:             *
283:             * @param deselectOthers if <code>true</code>, do so
284:             */
285:            void select(boolean deselectOthers) {
286:                sectionWidget.select(this , !selected, deselectOthers);
287:            }
288:
289:            /**
290:             * Performs whatever is necessary to select or deselct self. Called by
291:             * {@link Designer#select}.
292:             *
293:             * @param makeSelected new selection state
294:             */
295:            void doSelect(boolean makeSelected) {
296:                // For some reason, characters between the original selection click and
297:                // a deselection click get selected. Un-select all characters.
298:                JTextPane textPane = (JTextPane) getComponent();
299:                textPane.setCaretPosition(0);
300:                textPane.moveCaretPosition(0);
301:
302:                if (selected != makeSelected) {
303:                    selected = makeSelected;
304:                    textPane.repaint(); // Reflect border changes
305:                }
306:            }
307:
308:            /**
309:             * If the user is placing a new text field, pass it on to the section
310:             * widget; else do nothing.
311:             *
312:             * @param e mousevent
313:             */
314:            public void mouseClicked(MouseEvent e) {
315:                if (sectionWidget.designer.isPlacingNewTextField())
316:                    sectionWidget.createNewTextField(e);
317:                else {
318:                    if (!mouseChangedSelectedState) {
319:                        select(!e.isShiftDown());
320:                    }
321:                }
322:            }
323:
324:            /**
325:             * Asks section to drag (move, resize) all selected widgets together. (The
326:             * section, in turn, asks the window to do the same.)
327:             *
328:             * @param e mouse event
329:             */
330:            public void mouseDragged(MouseEvent e) {
331:                if (action == ACTION_INACTION
332:                        || action == ACTION_POPPING_UP_MENU)
333:                    return;
334:
335:                if (!selected) {
336:                    select(!e.isShiftDown());
337:                    mouseChangedSelectedState = true;
338:                }
339:
340:                // Set ePos to screen position of click
341:                java.awt.Point screenMousePos = e.getPoint();
342:                java.awt.Point screenPos = getComponent().getLocationOnScreen();
343:                screenMousePos.translate(screenPos.x, screenPos.y);
344:
345:                if (!actionStartedYet) {
346:                    actionStartedYet = true;
347:                    switch (action) {
348:                    case ACTION_MOVE:
349:                        // will eventually call our pickUp()
350:                        sectionWidget.pickUp(screenMousePos);
351:                        break;
352:                    case ACTION_STRETCH_LEFT:
353:                    case ACTION_STRETCH_RIGHT:
354:                    case ACTION_STRETCH_TOP:
355:                    case ACTION_STRETCH_BOTTOM:
356:                        // will eventually call our startStretching()
357:                        sectionWidget.startStretching(screenMousePos);
358:                        break;
359:                    }
360:                }
361:
362:                sectionWidget.dragSelectedWidgets(action, screenMousePos);
363:            }
364:
365:            /**
366:             * Changes cursor if this widget is selected.
367:             *
368:             * @param e mouse event
369:             */
370:            public void mouseEntered(MouseEvent e) {
371:                if (selected && !sectionWidget.designer.isPlacingNewTextField())
372:                    cursorForPosition(e);
373:            }
374:
375:            /**
376:             * Changes cursor if this widget is selected.
377:             *
378:             * @param e mouse event
379:             */
380:            public void mouseExited(MouseEvent e) {
381:                if (selected && !sectionWidget.designer.isPlacingNewTextField())
382:                    resetCursor();
383:            }
384:
385:            /**
386:             * Changes cursor if this widget is selected.
387:             *
388:             * @param e mouse event
389:             */
390:            public void mouseMoved(MouseEvent e) {
391:                if (selected && !sectionWidget.designer.isPlacingNewTextField())
392:                    cursorForPosition(e);
393:            }
394:
395:            /**
396:             * When the mouse is pressed, do the Right Thing(tm). Handles popup menu,
397:             * selecting, shift-selecting, and prepping for movement.
398:             *
399:             * @param e mouse event
400:             */
401:            public void mousePressed(MouseEvent e) {
402:                mouseChangedSelectedState = false;
403:
404:                if (mousePressReleaseCommon(e))
405:                    return;
406:
407:                cursorForPosition(e);
408:                action = actionFromPosition(e);
409:
410:                actionStartedYet = false; // Used to detect start of moves and stretches
411:            }
412:
413:            /**
414:             * When the mouse is released and we have been dragging this field,
415:             * drop this one and all others that are being dragged.
416:             *
417:             * @param e mouse event
418:             */
419:            public void mouseReleased(MouseEvent e) {
420:                if (mousePressReleaseCommon(e))
421:                    return;
422:
423:                switch (action) {
424:                case ACTION_MOVE:
425:                    if (actionStartedYet) {
426:                        // Put down this and all selected fields.
427:                        // Set mousePos to screen position of mouse.
428:                        java.awt.Point screenMousePos = e.getPoint();
429:                        java.awt.Point screenPos = getComponent()
430:                                .getLocationOnScreen();
431:                        screenMousePos.translate(screenPos.x, screenPos.y);
432:
433:                        // Put all selected widgets down. Might not be put down in same
434:                        // section.
435:                        sectionWidget.putDown(this , preMoveInfo.screenPos,
436:                                screenMousePos);
437:                    }
438:                    break;
439:                case ACTION_STRETCH_LEFT:
440:                case ACTION_STRETCH_RIGHT:
441:                case ACTION_STRETCH_TOP:
442:                case ACTION_STRETCH_BOTTOM:
443:                    if (actionStartedYet) {
444:                        // Stop stretching all selected widgets down.
445:                        sectionWidget.stopStretching(this ,
446:                                preStretchInfo.origBounds);
447:                    }
448:                    break;
449:                }
450:
451:                action = ACTION_INACTION;
452:            }
453:
454:            /**
455:             * Performs checks and behaviors common to both mouse presses and mouse
456:             * release events. Returns <code>true</code> if the event was handled by
457:             * this method and should be ignored by the caller.
458:             *
459:             * @param e the mouse event
460:             * @return <code>true</code> if the event was handled by this method and
461:             * should be ignored by the caller
462:             */
463:            protected boolean mousePressReleaseCommon(MouseEvent e) {
464:                if (sectionWidget.designer.isPlacingNewTextField()) {
465:                    sectionWidget.createNewTextField(e);
466:                    return true;
467:                }
468:
469:                if (e.isPopupTrigger()) {
470:                    showPopupMenu(e);
471:                    return true;
472:                }
473:
474:                return false;
475:            }
476:
477:            /**
478:             * Returns the information we saved before starting to move this widget.
479:             *
480:             * @return an object containing the information we saved before starting
481:             * to move this widget
482:             */
483:            public PreMoveInfo getPreMoveInfo() {
484:                return preMoveInfo;
485:            }
486:
487:            /**
488:             * Prepares for movement by remembering where we are now and removing
489:             * ourself from the section view widget (but not the section model).
490:             */
491:            public void pickUp(java.awt.Point mouseScreenPos) {
492:                preMoveInfo = new PreMoveInfo(this , mouseScreenPos);
493:
494:                // Remove from section view widget, but not section model in report.
495:                sectionWidget.removeField(this );
496:            }
497:
498:            /**
499:             * Place this field into a section widget. Our bounds rectangle is in
500:             * window coordinates; translate to section coordinates.
501:             */
502:            public void putDown(SectionWidget sw) {
503:                // Recalculate bounds
504:                jimm.datavision.field.Rectangle b = getField().getBounds();
505:                b.setBounds(b.x - SectionWidget.LHS_WIDTH, b.y
506:                        - sw.getBounds().y, b.width, b.height);
507:
508:                // Move model and view to new section
509:                moveToSection(sw);
510:
511:                preMoveInfo = null;
512:            }
513:
514:            /**
515:             * Move back to original location in original section widget.
516:             */
517:            void snapBack() {
518:                getField().getBounds().setBounds(preMoveInfo.origBounds);
519:                moveToSection(preMoveInfo.sectionWidget);
520:            }
521:
522:            /**
523:             * Prepares for stretching by creating a <code>PreStretchInfo</code>.
524:             *
525:             * @param mouseScreenPos the location of the mouse in screen coordinates
526:             */
527:            public void startStretching(java.awt.Point mouseScreenPos) {
528:                preStretchInfo = new PreStretchInfo(this , mouseScreenPos);
529:            }
530:
531:            /**
532:             * Stop stretching.
533:             */
534:            public void stopStretching() {
535:                preStretchInfo = null;
536:            }
537:
538:            /**
539:             * Displays popup menu, after enabling/disabling the appropriate items.
540:             */
541:            protected void showPopupMenu(MouseEvent e) {
542:                showOrHide.setText(getField().isVisible() ? I18N.get(
543:                        I18N.MENU_FILE_PREFIX, "FieldWidget.popup_hide") : I18N
544:                        .get(I18N.MENU_FILE_PREFIX, "FieldWidget.popup_show"));
545:
546:                enableMenuItems();
547:
548:                action = ACTION_POPPING_UP_MENU;
549:                popup.show(e.getComponent(), e.getX(), e.getY());
550:            }
551:
552:            /**
553:             * Enables or disables popup menu items based on field and window state.
554:             */
555:            protected void enableMenuItems() {
556:                boolean canFormat = usesFormat()
557:                        || sectionWidget.designer.someSelectedFieldUsesFormat();
558:                formatMenuItem.setEnabled(canFormat);
559:
560:                int numSelectedFields = sectionWidget.designer
561:                        .countSelectedFields();
562:                if (numSelectedFields >= 2) {
563:                    // More than two fields selected.
564:                    for (int i = 0; i < alignSubmenu.getItemCount(); ++i)
565:                        alignSubmenu.getItem(i).setEnabled(true);
566:                    sizeSubmenu.setEnabled(true);
567:                    aggregatesMenuItem.setEnabled(false);
568:                } else {
569:                    // Only one item selected or this item is not selected.
570:                    for (int i = 0; i < alignSubmenu.getItemCount() - 1; ++i)
571:                        alignSubmenu.getItem(i).setEnabled(false);
572:                    sizeSubmenu.setEnabled(false);
573:
574:                    // Ask the AggregateField class if we can aggregate this field.
575:                    aggregatesMenuItem.setEnabled(getField().canBeAggregated());
576:                }
577:            }
578:
579:            /**
580:             * Given a mouse event, returns the <code>ACTION_*</code> constant
581:             * associated with the mouse position within the field.
582:             */
583:            protected int actionFromPosition(MouseEvent e) {
584:                int ex = e.getX();
585:                int ey = e.getY();
586:                if (ex <= GRAB_EDGE_WIDTH)
587:                    return ACTION_STRETCH_LEFT;
588:                else if (ex >= getField().getBounds().width - GRAB_EDGE_WIDTH)
589:                    return ACTION_STRETCH_RIGHT;
590:                else if (ey <= GRAB_EDGE_WIDTH)
591:                    return ACTION_STRETCH_TOP;
592:                else if (ey >= getField().getBounds().height - GRAB_EDGE_WIDTH)
593:                    return ACTION_STRETCH_BOTTOM;
594:                else
595:                    return ACTION_MOVE;
596:            }
597:
598:            /**
599:             * If this field is selected, sets the cursor based on the current mouse
600:             * position in the widget. If the field is unselected, resets the cursor.
601:             *
602:             * @param e a mouse event
603:             */
604:            protected void cursorForPosition(MouseEvent e) {
605:                if (!selected) {
606:                    resetCursor();
607:                    return;
608:                }
609:
610:                switch (action == ACTION_INACTION ? actionFromPosition(e)
611:                        : action) {
612:                case ACTION_MOVE:
613:                    getComponent().setCursor(
614:                            Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
615:                    break;
616:                case ACTION_STRETCH_LEFT:
617:                    getComponent().setCursor(
618:                            Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
619:                    break;
620:                case ACTION_STRETCH_RIGHT:
621:                    getComponent().setCursor(
622:                            Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
623:                    break;
624:                case ACTION_STRETCH_TOP:
625:                    getComponent().setCursor(
626:                            Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
627:                    break;
628:                case ACTION_STRETCH_BOTTOM:
629:                    getComponent().setCursor(
630:                            Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
631:                    break;
632:                }
633:            }
634:
635:            /**
636:             * Resets the cursor to its default.
637:             */
638:            protected void resetCursor() {
639:                getComponent().setCursor(null);
640:            }
641:
642:            /**
643:             * Performs a drag or a stretch. Called from {@link
644:             * Designer#dragSelectedWidgets}.
645:             *
646:             * @param action a <code>ACTION_*</code> constant
647:             * @param mouseScreenPos the location of the mouse in screen coordinates
648:             * @see Designer#dragSelectedWidgets
649:             */
650:            void doDrag(int action, java.awt.Point mouseScreenPos) {
651:                jimm.datavision.field.Rectangle b = getField().getBounds();
652:
653:                if (action == ACTION_MOVE) {
654:                    int dx = mouseScreenPos.x
655:                            - preMoveInfo.startMouseScreenPos.x;
656:                    int dy = mouseScreenPos.y
657:                            - preMoveInfo.startMouseScreenPos.y;
658:                    // Must take into account the fact that we are floating on the
659:                    // section container. See Designer.pickUp.
660:                    b.setBounds(preMoveInfo.origBounds.x + dx
661:                            + SectionWidget.LHS_WIDTH, preMoveInfo.origBounds.y
662:                            + dy + sectionWidget.getBounds().y,
663:                            preMoveInfo.origBounds.width,
664:                            preMoveInfo.origBounds.height);
665:                    return;
666:                }
667:
668:                int dx = mouseScreenPos.x
669:                        - preStretchInfo.startMouseScreenPos.x;
670:                int dy = mouseScreenPos.y
671:                        - preStretchInfo.startMouseScreenPos.y;
672:                java.awt.Rectangle newBounds;
673:
674:                switch (action) {
675:                case ACTION_STRETCH_LEFT:
676:                    newBounds = new java.awt.Rectangle(
677:                            (int) preStretchInfo.origBounds.x + dx,
678:                            (int) preStretchInfo.origBounds.y,
679:                            (int) preStretchInfo.origBounds.width - dx,
680:                            (int) preStretchInfo.origBounds.height);
681:                    break;
682:                case ACTION_STRETCH_RIGHT:
683:                    newBounds = new java.awt.Rectangle(
684:                            (int) preStretchInfo.origBounds.x,
685:                            (int) preStretchInfo.origBounds.y,
686:                            (int) preStretchInfo.origBounds.width + dx,
687:                            (int) preStretchInfo.origBounds.height);
688:                    break;
689:                case ACTION_STRETCH_TOP:
690:                    newBounds = new java.awt.Rectangle(
691:                            (int) preStretchInfo.origBounds.x,
692:                            (int) preStretchInfo.origBounds.y + dy,
693:                            (int) preStretchInfo.origBounds.width,
694:                            (int) preStretchInfo.origBounds.height - dy);
695:                    break;
696:                case ACTION_STRETCH_BOTTOM:
697:                    newBounds = new java.awt.Rectangle(
698:                            (int) preStretchInfo.origBounds.x,
699:                            (int) preStretchInfo.origBounds.y,
700:                            (int) preStretchInfo.origBounds.width,
701:                            (int) preStretchInfo.origBounds.height + dy);
702:                    break;
703:                default:
704:                    return;
705:                }
706:
707:                // Make sure new bounds fit within the section
708:                newBounds = newBounds
709:                        .intersection(preStretchInfo.sectionBounds);
710:
711:                // Make sure new bounds are not too small.
712:                switch (action) {
713:                case ACTION_STRETCH_LEFT:
714:                    if (newBounds.width < MIN_SIZE) {
715:                        dx = MIN_SIZE - newBounds.width;
716:                        newBounds.x -= dx;
717:                        newBounds.width = MIN_SIZE;
718:                    }
719:                    break;
720:                case ACTION_STRETCH_RIGHT:
721:                    if (newBounds.width < MIN_SIZE)
722:                        newBounds.width = MIN_SIZE;
723:                    break;
724:                case ACTION_STRETCH_TOP:
725:                    if (newBounds.height < MIN_SIZE) {
726:                        dy = MIN_SIZE - newBounds.height;
727:                        newBounds.y -= dy;
728:                        newBounds.height = MIN_SIZE;
729:                    }
730:                    break;
731:                case ACTION_STRETCH_BOTTOM:
732:                    if (newBounds.height < MIN_SIZE)
733:                        newBounds.height = MIN_SIZE;
734:                    break;
735:                default:
736:                    return;
737:                }
738:
739:                b.setBounds(newBounds);
740:            }
741:
742:            /**
743:             * Asks the window delete this field and all selected fields.
744:             */
745:            protected void delete() {
746:                sectionWidget.designer.deleteSelectedFieldsAnd(this );
747:            }
748:
749:            /**
750:             * Deletes this field from its section. Deletes the report field from the
751:             * report section (the model) and the field widget from the parent widget
752:             * (the view/controller).
753:             */
754:            public void doDelete() {
755:                getField().getSection().removeField(getField());
756:                getComponent().getParent().remove(getComponent());
757:            }
758:
759:            /**
760:             * Moves both field view and model to a new section. Technically, moves
761:             * model to a new section and adds view to section widget.
762:             *
763:             * @param sw a section widget
764:             */
765:            public void moveToSection(SectionWidget sw) {
766:                // Bounds are already relative to new section widget
767:
768:                Section currSection = getField().getSection();
769:                Section newSection = sw.section;
770:                if (newSection != currSection) {
771:                    if (currSection != null)
772:                        currSection.removeField(getField());
773:                    newSection.addField(getField());
774:                }
775:
776:                // Always move to new section widget, because the act of dragging
777:                // lifted this widget from that section widget. (That's why we don't
778:                // need to remove it from the current section widget).
779:                sw.addField(this );
780:
781:                // Not sure why this is necessary, but sometimes it is.
782:                getComponent().repaint();
783:            }
784:
785:            /**
786:             * Handles drop of a dragged field. Passes request on to parent view.
787:             *
788:             * @param e drop event
789:             * @see SectionFieldPanel#drop
790:             */
791:            public void drop(DropTargetDropEvent e) {
792:                ((DropTargetListener) getComponent().getParent()).drop(e);
793:            }
794:
795:            public void dragEnter(DropTargetDragEvent e) {
796:            }
797:
798:            public void dragExit(DropTargetEvent e) {
799:            }
800:
801:            public void dragOver(DropTargetDragEvent e) {
802:            }
803:
804:            public void dropActionChanged(DropTargetDragEvent e) {
805:            }
806:
807:            /**
808:             * Performs some action based on the action command string (the menu
809:             * item text).
810:             */
811:            public void actionPerformed(ActionEvent e) {
812:                String command = e.getActionCommand();
813:                if (command == null)
814:                    return;
815:
816:                Designer designer = sectionWidget.designer;
817:
818:                if ("hide".equals(command) || "show".equals(command))
819:                    toggleVisibility();
820:                else if ("delete".equals(command))
821:                    delete();
822:
823:                else if ("align_top".equals(command))
824:                    designer.align(Designer.ALIGN_TOP);
825:                else if ("align_middle".equals(command))
826:                    designer.align(Designer.ALIGN_MIDDLE);
827:                else if ("align_bottom".equals(command))
828:                    designer.align(Designer.ALIGN_BOTTOM);
829:                else if ("align_left".equals(command))
830:                    designer.align(Designer.ALIGN_LEFT);
831:                else if ("align_center".equals(command))
832:                    designer.align(Designer.ALIGN_CENTER);
833:                else if ("align_right".equals(command))
834:                    designer.align(Designer.ALIGN_RIGHT);
835:                else if ("snap_to_grid".equals(command)) {
836:                    if (designer.countSelectedFields() > 0)
837:                        designer.align(Designer.ALIGN_SNAP_TO_GRID);
838:                    else
839:                        align(Designer.ALIGN_SNAP_TO_GRID, getField());
840:                }
841:
842:                else if ("size_width".equals(command))
843:                    designer.size(Designer.SIZE_SAME_WIDTH);
844:                else if ("size_height".equals(command))
845:                    designer.size(Designer.SIZE_SAME_HEIGHT);
846:                else if ("size_size".equals(command))
847:                    designer.size(Designer.SIZE_SAME_SIZE);
848:
849:                else if ("format".equals(command))
850:                    new FormatWin(designer, this .getField(), 0);
851:                else if ("border".equals(command))
852:                    new FormatWin(designer, this .getField(), 1);
853:                else if ("bounds".equals(command))
854:                    new BoundsWin(designer, this .getField());
855:                else if ("aggregates".equals(command))
856:                    new AggregatesWin(designer, this );
857:            }
858:
859:            public String toString() {
860:                return getField().designLabel();
861:            }
862:
863:            /**
864:             * Toggles the visiblity of this field and all selected fields.
865:             */
866:            void toggleVisibility() {
867:                boolean newVisibility = !getField().isVisible();
868:                sectionWidget.setFieldVisibility(newVisibility, this );
869:            }
870:
871:            /**
872:             * Sets the visiblity of this field. Called directly and/or indirectly
873:             * from <code>toggleVisibility</code>.
874:             */
875:            public void doSetVisibility(boolean newVisibility) {
876:                getField().setVisible(newVisibility);
877:                setVisibilityLook();
878:            }
879:
880:            /**
881:             * Sets the look of the field based on the current visiblity flag value. The
882:             * {@link jimm.datavision.layout.swing.AbstractSwingField} does all the work.
883:             * We just ask our <var>swingField</var> to re-format itself.
884:             */
885:            protected void setVisibilityLook() {
886:                swingField.format();
887:            }
888:
889:            Color getColor() {
890:                return swingField.getColor();
891:            }
892:
893:            public Field getField() {
894:                return swingField.getField();
895:            }
896:
897:            public JComponent getComponent() {
898:                return swingField.getComponent();
899:            }
900:
901:            /* This code fixes the delete key not working. Basically, I discovered, for
902:             * reasons I frankly don't get at the moment, attaching the KeyListener to the
903:             * frame in DesignWin wasn't working (I'm beting it's some sort of event
904:             * bubbling issue with which I am unfamiliar). So, it had to be attached at
905:             * the widget level. So, putting here in FieldWidget applies it to all other
906:             * widgets. The keyPressed and keyTyped events we want to basically ignore, as
907:             * they only apply to TextFieldWidgets, and in that case, that class will
908:             * override keyTyped, which is what it's interested in. So, we implement the
909:             * delete code that was previously an anonymous inner class in DesignWin, and
910:             * we're good!
911:             * <p>
912:             * Frank W. Zammetti
913:             */
914:
915:            public void keyPressed(KeyEvent ke) {
916:                return;
917:            }
918:
919:            public void keyTyped(KeyEvent ke) {
920:                return;
921:            }
922:
923:            public void keyReleased(KeyEvent ke) {
924:                if (!sectionWidget.designer.ignoreKeys) {
925:                    int code = ke.getKeyCode();
926:                    if (code == KeyEvent.VK_BACK_SPACE
927:                            || code == KeyEvent.VK_DELETE)
928:                        sectionWidget.designer.deleteSelectedFields();
929:                }
930:            }
931:
932:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.