Source Code Cross Referenced for Element.java in  » Web-Framework » rife-1.6.1 » com » uwyn » rife » gui » old » 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 » Web Framework » rife 1.6.1 » com.uwyn.rife.gui.old 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
0003:         * Distributed under the terms of either:
0004:         * - the common development and distribution license (CDDL), v1.0; or
0005:         * - the GNU Lesser General Public License, v2.1 or later
0006:         * $Id: Element.java 3634 2007-01-08 21:42:24Z gbevin $
0007:         */
0008:        package com.uwyn.rife.gui.old;
0009:
0010:        import java.awt.*;
0011:        import java.awt.event.MouseEvent;
0012:        import java.awt.event.MouseListener;
0013:        import java.awt.event.MouseMotionListener;
0014:        import java.awt.font.LineMetrics;
0015:        import java.awt.geom.*;
0016:        import java.awt.image.BufferedImage;
0017:        import java.util.ArrayList;
0018:
0019:        import javax.swing.JComponent;
0020:        import javax.swing.JMenu;
0021:        import javax.swing.JMenuItem;
0022:        import javax.swing.JPopupMenu;
0023:
0024:        import com.uwyn.rife.config.Config;
0025:        import com.uwyn.rife.gui.Rife;
0026:        import com.uwyn.rife.swing.JDialogSystemError;
0027:        import com.uwyn.rife.tools.ExceptionUtils;
0028:        import com.uwyn.rife.tools.Localization;
0029:
0030:        public class Element extends JComponent implements  MouseListener,
0031:                MouseMotionListener {
0032:            private boolean mSelected = false;
0033:
0034:            private Color mTitleBackgroundColor = new Color(220, 220, 220);
0035:            private StructurePanel mStructurePanel = null;
0036:            private ElementStyle mElementStyleOrig = null;
0037:            private ElementStyle mElementStyleScaled = null;
0038:
0039:            private ArrayList<ElementListener> mElementListeners = null;
0040:            private ArrayList<ElementProperty> mElementProperties = null;
0041:
0042:            private float mXOrig = -1f;
0043:            private float mYOrig = -1f;
0044:            private float mWidthOrig = -1f;
0045:            private float mHeightOrig = -1f;
0046:            private float mBodyXOffsetOrig = -1f;
0047:            private float mBodyYOffsetOrig = -1f;
0048:            private Area mBoundingOrig = null;
0049:            private Area mBodyAreaOutsideOrig = null;
0050:            private Area mBodyAreaInsideOrig = null;
0051:            private GeneralPath mUsedParameterLinesOrig = null;
0052:            private Area mTitleRectangleOutsideOrig = null;
0053:            private Area mTitleRectangleInsideOrig = null;
0054:
0055:            private float mScaleFactor = 1f;
0056:
0057:            private float mXScaled = -1f;
0058:            private float mYScaled = -1f;
0059:            private float mWidthScaled = -1f;
0060:            private float mHeightScaled = -1f;
0061:            private Area mBoundingScaled = null;
0062:            private Area mBodyAreaOutsideScaled = null;
0063:            private Area mBodyAreaInsideScaled = null;
0064:            private GeneralPath mUsedParameterLinesScaled = null;
0065:            private Area mTitleRectangleOutsideScaled = null;
0066:            private Area mTitleRectangleInsideScaled = null;
0067:
0068:            private boolean mDragActive = false;
0069:            private Point mDragStartPoint = null;
0070:            private BufferedImage mDragBufferedImage = null;
0071:
0072:            private boolean mIsTransparent = false;
0073:
0074:            public Element(StructurePanel structurePanel,
0075:                    ElementStyle styleOrig, ElementStyle styleScaled) {
0076:                this (structurePanel, "", styleOrig, styleScaled);
0077:            }
0078:
0079:            public Element(StructurePanel structurePanel, String title,
0080:                    ElementStyle styleOrig, ElementStyle styleScaled) {
0081:                super ();
0082:
0083:                mStructurePanel = structurePanel;
0084:                mElementStyleOrig = styleOrig;
0085:                mElementStyleScaled = styleScaled;
0086:
0087:                mElementListeners = new ArrayList<ElementListener>();
0088:                mElementProperties = new ArrayList<ElementProperty>();
0089:                addProperty(ElementPropertyTitle.class, title);
0090:
0091:                setOpaque(false);
0092:                setLayout(null);
0093:            }
0094:
0095:            public StructurePanel getStructurePanel() {
0096:                return mStructurePanel;
0097:            }
0098:
0099:            public int getWidth() {
0100:                if (mWidthScaled == -1) {
0101:                    createPrecalculatedAreas();
0102:                }
0103:                return (int) mWidthScaled;
0104:            }
0105:
0106:            public int getHeight() {
0107:                if (mHeightScaled == -1) {
0108:                    createPrecalculatedAreas();
0109:                }
0110:                return (int) mHeightScaled;
0111:            }
0112:
0113:            public Area getBoundingAreaOrig() {
0114:                return mBoundingOrig;
0115:            }
0116:
0117:            public Area getBoundingAreaScaled() {
0118:                return mBoundingScaled;
0119:            }
0120:
0121:            public Area getTitleRectangleOutside() {
0122:                return mTitleRectangleOutsideScaled;
0123:            }
0124:
0125:            public Area getTitleRectangleInside() {
0126:                return mTitleRectangleInsideScaled;
0127:            }
0128:
0129:            public void setLocation(Point p) {
0130:                setLocation(p.x, p.y);
0131:            }
0132:
0133:            public void setLocation(int x, int y) {
0134:                setBounds(x, y, getWidth(), getHeight());
0135:            }
0136:
0137:            public void setBounds(Rectangle r) {
0138:                setBounds(r.x, r.x, r.width, r.height);
0139:            }
0140:
0141:            public void setBounds(int x, int y, int width, int height) {
0142:                mXOrig = x / mScaleFactor;
0143:                mYOrig = y / mScaleFactor;
0144:                if (Config.getRepInstance().getBool("GRID_SNAP")) {
0145:                    int grid_size = Config.getRepInstance().getInt("GRID_SIZE");
0146:                    mXOrig = mXOrig - ((mXOrig + mBodyXOffsetOrig) % grid_size);
0147:                    mYOrig = mYOrig - ((mYOrig + mBodyYOffsetOrig) % grid_size);
0148:                }
0149:                mXScaled = mXOrig * mScaleFactor;
0150:                mYScaled = mYOrig * mScaleFactor;
0151:                super .setBounds((int) mXScaled, (int) mYScaled, width, height);
0152:            }
0153:
0154:            public int getX() {
0155:                return (int) mXScaled;
0156:            }
0157:
0158:            public int getY() {
0159:                return (int) mYScaled;
0160:            }
0161:
0162:            public Rectangle getBounds(Rectangle rv) {
0163:                if (rv == null) {
0164:                    rv = new Rectangle();
0165:                }
0166:
0167:                rv.x = getX();
0168:                rv.y = getY();
0169:                rv.width = getWidth();
0170:                rv.height = getHeight();
0171:
0172:                return rv;
0173:            }
0174:
0175:            public void setElementColor(Color bodyColor) {
0176:                mTitleBackgroundColor = bodyColor;
0177:                repaint();
0178:            }
0179:
0180:            public void selectElement() {
0181:                if (!mSelected) {
0182:                    mSelected = true;
0183:                }
0184:            }
0185:
0186:            public void deselectElement() {
0187:                if (mSelected) {
0188:                    mSelected = false;
0189:                }
0190:            }
0191:
0192:            public boolean isSelected() {
0193:                return mSelected;
0194:            }
0195:
0196:            public ElementStyle getElementStyleScaled() {
0197:                return mElementStyleScaled;
0198:            }
0199:
0200:            protected void resetPrecalculatedAreas() {
0201:                mWidthOrig = -1f;
0202:                mHeightOrig = -1f;
0203:                mBodyXOffsetOrig = -1f;
0204:                mBodyYOffsetOrig = -1f;
0205:                mBoundingOrig = null;
0206:                mBodyAreaOutsideOrig = null;
0207:                mBodyAreaInsideOrig = null;
0208:                mUsedParameterLinesOrig = null;
0209:
0210:                mWidthScaled = -1f;
0211:                mHeightScaled = -1f;
0212:                mBoundingScaled = null;
0213:                mBodyAreaOutsideScaled = null;
0214:                mBodyAreaInsideScaled = null;
0215:                mUsedParameterLinesScaled = null;
0216:            }
0217:
0218:            ElementProperty createProperty(Class propertyClass, String name) {
0219:                ElementProperty property = null;
0220:                try {
0221:                    property = (ElementProperty) propertyClass.getConstructor(
0222:                            new Class[] { Element.class, String.class })
0223:                            .newInstance(new Object[] { this , name });
0224:                } catch (Throwable e) {
0225:                    JDialogSystemError dialog = new JDialogSystemError(
0226:                            Rife.getMainFrame(),
0227:                            "Element.createProperty() : Error while creating an element property with name '"
0228:                                    + name
0229:                                    + "' and class '"
0230:                                    + propertyClass.getName()
0231:                                    + "': "
0232:                                    + ExceptionUtils.getExceptionStackTrace(e));
0233:                    dialog.setVisible(true);
0234:                    Rife.quit();
0235:                }
0236:
0237:                return property;
0238:            }
0239:
0240:            ElementProperty getProperty(Class propertyClass, String name) {
0241:                int index = mElementProperties.indexOf(createProperty(
0242:                        propertyClass, name));
0243:                if (index == -1) {
0244:                    return null;
0245:                } else {
0246:                    return mElementProperties.get(index);
0247:                }
0248:            }
0249:
0250:            ElementProperty addProperty(Class propertyClass, String name) {
0251:                ElementProperty property = createProperty(propertyClass, name);
0252:
0253:                if (property != null) {
0254:                    if (!mElementProperties.contains(property)) {
0255:                        mElementProperties.add(property);
0256:                        resetPrecalculatedAreas();
0257:                        return property;
0258:                    }
0259:                }
0260:
0261:                return null;
0262:            }
0263:
0264:            boolean removeProperty(ElementProperty property) {
0265:                if (mElementProperties.remove(property)) {
0266:                    resetPrecalculatedAreas();
0267:                    return true;
0268:                } else {
0269:                    return false;
0270:                }
0271:            }
0272:
0273:            boolean renameProperty(ElementProperty property, String newName) {
0274:                if (mElementProperties.contains(property)) {
0275:                    if (property.isValidName(newName)) {
0276:                        property.setName(newName);
0277:                        resetPrecalculatedAreas();
0278:                        return true;
0279:                    } else {
0280:                        return false;
0281:                    }
0282:                }
0283:
0284:                return false;
0285:            }
0286:
0287:            ElementPropertyExit addExit(String name) {
0288:                return (ElementPropertyExit) addProperty(
0289:                        ElementPropertyExit.class, name);
0290:            }
0291:
0292:            ElementPropertyParameterConsumed addConsumedParameter(String name) {
0293:                return (ElementPropertyParameterConsumed) addProperty(
0294:                        ElementPropertyParameterConsumed.class, name);
0295:            }
0296:
0297:            ElementPropertyParameterUsed addUsedParameter(String name) {
0298:                return (ElementPropertyParameterUsed) addProperty(
0299:                        ElementPropertyParameterUsed.class, name);
0300:            }
0301:
0302:            ElementPropertyParameterAdded addAddedParameter(String name) {
0303:                return (ElementPropertyParameterAdded) addProperty(
0304:                        ElementPropertyParameterAdded.class, name);
0305:            }
0306:
0307:            ElementProperty getTitle() {
0308:                return getProperties(ElementPropertyTitle.class).get(0);
0309:            }
0310:
0311:            ArrayList<ElementProperty> getExits() {
0312:                return getProperties(ElementPropertyExit.class);
0313:            }
0314:
0315:            ArrayList<ElementProperty> getConsumedParameters() {
0316:                return getProperties(ElementPropertyParameterConsumed.class);
0317:            }
0318:
0319:            ArrayList<ElementProperty> getUsedParameters() {
0320:                return getProperties(ElementPropertyParameterUsed.class);
0321:            }
0322:
0323:            ArrayList<ElementProperty> getAddedParameters() {
0324:                return getProperties(ElementPropertyParameterAdded.class);
0325:            }
0326:
0327:            ArrayList<ElementProperty> getProperties(Class propertyClass) {
0328:                ArrayList<ElementProperty> result = new ArrayList<ElementProperty>();
0329:
0330:                for (ElementProperty property : mElementProperties) {
0331:                    if (propertyClass.isInstance(property)) {
0332:                        result.add(property);
0333:                    }
0334:                }
0335:                return result;
0336:            }
0337:
0338:            int countExits() {
0339:                return countProperties(ElementPropertyExit.class);
0340:            }
0341:
0342:            int countConsumedParameters() {
0343:                return countProperties(ElementPropertyParameterConsumed.class);
0344:            }
0345:
0346:            int countUsedParameters() {
0347:                return countProperties(ElementPropertyParameterUsed.class);
0348:            }
0349:
0350:            int countAddedParameters() {
0351:                return countProperties(ElementPropertyParameterAdded.class);
0352:            }
0353:
0354:            private int countProperties(Class propertyClass) {
0355:                int result = 0;
0356:
0357:                for (ElementProperty property : mElementProperties) {
0358:                    if (propertyClass.isInstance(property)) {
0359:                        result++;
0360:                    }
0361:                }
0362:                return result;
0363:            }
0364:
0365:            public Dimension getMinimumSize() {
0366:                return new Dimension((int) mWidthScaled, (int) mHeightScaled);
0367:            }
0368:
0369:            public Dimension getPreferredSize() {
0370:                return getMinimumSize();
0371:            }
0372:
0373:            public Dimension getMaximumSize() {
0374:                return getMinimumSize();
0375:            }
0376:
0377:            public boolean contains(int x, int y) {
0378:                if (mBoundingScaled != null && x >= 0 && y >= 0
0379:                        && x < mWidthScaled && y < mHeightScaled
0380:                        && mBoundingScaled.contains(x, y)) {
0381:                    return true;
0382:                } else {
0383:                    return false;
0384:                }
0385:            }
0386:
0387:            public synchronized void scalePrecalculatedAreas(float multiplier) {
0388:                mScaleFactor *= multiplier;
0389:
0390:                mXScaled = mXOrig * mScaleFactor;
0391:                mYScaled = mYOrig * mScaleFactor;
0392:                mWidthScaled = mWidthOrig * mScaleFactor;
0393:                mHeightScaled = mHeightOrig * mScaleFactor;
0394:
0395:                AffineTransform scale_transform = AffineTransform
0396:                        .getScaleInstance(mScaleFactor, mScaleFactor);
0397:                mBoundingScaled = mBoundingOrig
0398:                        .createTransformedArea(scale_transform);
0399:                mBodyAreaOutsideScaled = mBodyAreaOutsideOrig
0400:                        .createTransformedArea(scale_transform);
0401:                mBodyAreaInsideScaled = mBodyAreaInsideOrig
0402:                        .createTransformedArea(scale_transform);
0403:                mTitleRectangleOutsideScaled = mTitleRectangleOutsideOrig
0404:                        .createTransformedArea(scale_transform);
0405:                mTitleRectangleInsideScaled = mTitleRectangleInsideOrig
0406:                        .createTransformedArea(scale_transform);
0407:                mUsedParameterLinesScaled = (GeneralPath) mUsedParameterLinesOrig
0408:                        .clone();
0409:                mUsedParameterLinesScaled.transform(scale_transform);
0410:
0411:                for (ElementProperty property : mElementProperties) {
0412:                    property.scale(multiplier);
0413:                }
0414:
0415:                super .setBounds((int) mXScaled, (int) mYScaled,
0416:                        (int) mWidthScaled, (int) mHeightScaled);
0417:            }
0418:
0419:            private synchronized void createPrecalculatedAreas() {
0420:                int grid_size = Config.getRepInstance().getInt("GRID_SIZE");
0421:                LineMetrics line_metrics = null;
0422:                Rectangle2D string_bounds = null;
0423:                Rectangle2D name_bounds = null;
0424:                Area hotspot = null;
0425:
0426:                //
0427:                // calculate parameters dimensions
0428:                //
0429:                line_metrics = mElementStyleOrig.mParamFont.getLineMetrics("M",
0430:                        mElementStyleOrig.mFontRenderContext);
0431:                float parameter_text_width = (float) (mElementStyleOrig.mParamFont
0432:                        .getStringBounds("M",
0433:                                mElementStyleOrig.mFontRenderContext)
0434:                        .getHeight());
0435:                float parameter_text_middle = line_metrics.getDescent()
0436:                        - line_metrics.getStrikethroughOffset();
0437:
0438:                // calculate the parameter rectangle width, this is the distance that one parameter needs to draw its components
0439:                // and to be aligned to the grid
0440:                float parameter_rectangle_width_minimum = parameter_text_width
0441:                        + (mElementStyleOrig.mParamMarginWidth * 2)
0442:                        + mElementStyleOrig.mParamLineWidth;
0443:                float parameter_rectangle_width_unit = grid_size * 2;
0444:                float parameter_rectangle_width = parameter_rectangle_width_unit;
0445:                if (parameter_rectangle_width_minimum > parameter_rectangle_width_unit) {
0446:                    parameter_rectangle_width = (float) (Math
0447:                            .ceil(parameter_rectangle_width_minimum
0448:                                    / parameter_rectangle_width_unit) * parameter_rectangle_width_unit);
0449:                }
0450:
0451:                // calculate to FINAL WIDTH of the complete consumed parameters rectangle
0452:                float consumed_parameters_rectangle_width = 0;
0453:                float number_of_consumed_parameters = countConsumedParameters();
0454:                if (number_of_consumed_parameters > 0) {
0455:                    consumed_parameters_rectangle_width = (number_of_consumed_parameters * parameter_rectangle_width)
0456:                            + ((number_of_consumed_parameters + 1) * (parameter_rectangle_width / 2));
0457:                }
0458:
0459:                // calculate to FINAL WIDTH of the complete used parameters rectangle
0460:                float used_parameters_rectangle_width = 0;
0461:                float number_of_used_parameters = countUsedParameters();
0462:                if (number_of_used_parameters > 0) {
0463:                    used_parameters_rectangle_width = (number_of_used_parameters * parameter_rectangle_width)
0464:                            + ((number_of_used_parameters + 1) * (parameter_rectangle_width / 2));
0465:
0466:                    if (number_of_consumed_parameters == 0) {
0467:                        used_parameters_rectangle_width += mElementStyleOrig.mElementBorderWidth;
0468:                    }
0469:                }
0470:
0471:                // calculate to FINAL WIDTH of the complete added parameters rectangle
0472:                float added_parameters_rectangle_width = 0;
0473:                float number_of_added_parameters = countAddedParameters();
0474:                if (number_of_added_parameters > 0) {
0475:                    added_parameters_rectangle_width = number_of_added_parameters
0476:                            * parameter_rectangle_width
0477:                            + number_of_added_parameters
0478:                            * (parameter_rectangle_width / 2);
0479:                }
0480:
0481:                //
0482:                // calculate title dimensions
0483:                //
0484:                line_metrics = mElementStyleOrig.mTitleFont.getLineMetrics("M",
0485:                        mElementStyleOrig.mFontRenderContext);
0486:                Rectangle2D name_text_bounds = mElementStyleOrig.mTitleFont
0487:                        .getStringBounds(getTitle().getName(),
0488:                                mElementStyleOrig.mFontRenderContext);
0489:                float title_text_height = (float) (name_text_bounds.getHeight());
0490:                float title_text_width = (float) (name_text_bounds.getWidth());
0491:
0492:                // calculate the MINIMAL WIDTH of the TITLE RECTANGLE so that it contains at least the title text
0493:                float name_rectangle_width = title_text_width
0494:                        + mElementStyleOrig.mElementBorderWidth * 2
0495:                        + mElementStyleOrig.mTitleMarginWidth * 2;
0496:                // snap it to grid units
0497:                name_rectangle_width = (float) (Math.ceil(name_rectangle_width
0498:                        / grid_size) * grid_size);
0499:                // calculate the FINAL HEIGHT of the TITLE RECTANGLE
0500:                float name_rectangle_height = title_text_height
0501:                        + mElementStyleOrig.mElementBorderWidth * 2
0502:                        + mElementStyleOrig.mTitleMarginHeight * 2;
0503:                // snap it to grid units
0504:                name_rectangle_height = (float) (Math
0505:                        .ceil(name_rectangle_height / grid_size) * grid_size);
0506:
0507:                // calculate the temporary width of the complete element rectangle and take space for the right edge
0508:                float element_rectangle_width = consumed_parameters_rectangle_width
0509:                        + used_parameters_rectangle_width
0510:                        + parameter_rectangle_width
0511:                        + name_rectangle_width
0512:                        + mElementStyleOrig.mElementBorderWidth;
0513:
0514:                // calculate the FINAL X OFFSET to start the TITLE BOX immediatly right of the used parameters rectangle
0515:                float name_rectangle_x_offset = element_rectangle_width
0516:                        - name_rectangle_width;
0517:
0518:                //
0519:                // make sure that the element is wide enough to contain all the parameters and exit widths
0520:                //
0521:
0522:                // calculate the maximum width of all the exit texts
0523:                float exits_width = 0;
0524:                float exit_string_width = 0;
0525:
0526:                for (ElementProperty exit : getExits()) {
0527:                    exit_string_width = (float) (mElementStyleOrig.mExitFont
0528:                            .getStringBounds(exit.getName(),
0529:                                    mElementStyleOrig.mFontRenderContext)
0530:                            .getWidth());
0531:                    if (exit_string_width > exits_width) {
0532:                        exits_width = exit_string_width;
0533:                    }
0534:                }
0535:
0536:                // calculate the minimal body rectangle width to known what size has to be at least available to display all the items
0537:                // inside the body (consumed parameter texts, used parameter texts and lines, added parameters texts, exit texts)
0538:                float minimal_body_rectangle_width = consumed_parameters_rectangle_width
0539:                        + used_parameters_rectangle_width
0540:                        + added_parameters_rectangle_width
0541:                        + parameter_rectangle_width
0542:                        + mElementStyleOrig.mExitMarginWidth
0543:                        + exits_width
0544:                        + mElementStyleOrig.mExitMarginWidth;
0545:                // snap yhe minimal body rectangle width to grid units and take space for the right edge
0546:                minimal_body_rectangle_width = (float) (Math
0547:                        .ceil(minimal_body_rectangle_width / grid_size) * grid_size)
0548:                        + mElementStyleOrig.mElementBorderWidth;
0549:
0550:                if (element_rectangle_width < minimal_body_rectangle_width) {
0551:                    // calculate the FINAL WIDTH of the ELEMENT RECTANGLE
0552:                    element_rectangle_width = minimal_body_rectangle_width;
0553:                    // calculate the FINAL WIDTH of the TITLE RECTANGLE so that it's wide enough to fill all the space
0554:                    // right of the used parameters rectangle
0555:                    name_rectangle_width = element_rectangle_width
0556:                            - (consumed_parameters_rectangle_width
0557:                                    + used_parameters_rectangle_width
0558:                                    + parameter_rectangle_width + mElementStyleOrig.mElementBorderWidth);
0559:                }
0560:
0561:                //
0562:                // calculate body dimensions
0563:                //
0564:                line_metrics = mElementStyleOrig.mExitFont.getLineMetrics("M",
0565:                        mElementStyleOrig.mFontRenderContext);
0566:                float exit_text_height = (float) (mElementStyleOrig.mExitFont
0567:                        .getStringBounds("M",
0568:                                mElementStyleOrig.mFontRenderContext)
0569:                        .getHeight());
0570:                // calculate the exit rectangle height, this is the distance that one exit needs to draw its text and rectangle
0571:                float exit_rectangle_height = exit_text_height
0572:                        + (mElementStyleOrig.mElementBorderWidth * 2)
0573:                        + (mElementStyleOrig.mExitMarginHeight * 2);
0574:                // snap it to grid units
0575:                exit_rectangle_height = (float) (Math
0576:                        .ceil(exit_rectangle_height / grid_size) * grid_size);
0577:                // calculate the width of the exit rectangle
0578:                float exit_rectangle_width = grid_size * 4
0579:                        + mElementStyleOrig.mElementBorderWidth;
0580:                // calculate the vertical offset from one exit to the next one
0581:                float exit_rectangle_y_interval = exit_rectangle_height
0582:                        + (exit_rectangle_height / 2);
0583:                // take space for the bottom edge
0584:                exit_rectangle_height += mElementStyleOrig.mElementBorderWidth;
0585:
0586:                // calculate the MINIMUM HEIGHT of the BODY RECTANGLE
0587:                float body_rectangle_height = name_rectangle_height * 2;
0588:                // calculate the FINAL WIDTH of the BODY RECTANGLE
0589:                float body_rectangle_width = element_rectangle_width;
0590:                // calculate the temporary height of the body rectangle, this is large enough to display the title and all the exits
0591:                float number_of_exits = countExits();
0592:                if (number_of_exits > 0) {
0593:                    body_rectangle_height = name_rectangle_height
0594:                            + number_of_exits * exit_rectangle_y_interval
0595:                            + exit_rectangle_y_interval / 3;
0596:                }
0597:
0598:                //
0599:                // make sure that the body is high enough to contain all the parameters in height
0600:                //
0601:
0602:                // calculate the maximum height of all the consumed parameter texts
0603:                float parameters_height = 0;
0604:                float parameter_string_width = 0;
0605:
0606:                for (ElementProperty parameter : getConsumedParameters()) {
0607:                    parameter_string_width = (float) (mElementStyleOrig.mParamFont
0608:                            .getStringBounds(parameter.getName(),
0609:                                    mElementStyleOrig.mFontRenderContext)
0610:                            .getWidth());
0611:                    if (parameter_string_width > parameters_height) {
0612:                        parameters_height = parameter_string_width;
0613:                    }
0614:                }
0615:                // calculate the minimal body rectangle height that is required to correctly display the longest consumed parameter
0616:                float minimal_body_rectangle_height_for_parameters = mElementStyleOrig.mParamLineLength
0617:                        + mElementStyleOrig.mParamMarginHeight
0618:                        + parameters_height
0619:                        + (mElementStyleOrig.mElementBorderWidth * 2);
0620:                // calculate the height of the body rectangle and make it at least as big as the previously calculated minimal body height
0621:                if (body_rectangle_height < minimal_body_rectangle_height_for_parameters) {
0622:                    body_rectangle_height = minimal_body_rectangle_height_for_parameters;
0623:                }
0624:
0625:                // calculate the maximum height of all the used parameter texts
0626:                parameters_height = 0;
0627:                parameter_string_width = 0;
0628:
0629:                for (ElementProperty parameter : getUsedParameters()) {
0630:                    parameter_string_width = (float) (mElementStyleOrig.mParamFont
0631:                            .getStringBounds(parameter.getName(),
0632:                                    mElementStyleOrig.mFontRenderContext)
0633:                            .getWidth());
0634:                    if (parameter_string_width > parameters_height) {
0635:                        parameters_height = parameter_string_width;
0636:                    }
0637:                }
0638:                // calculate the minimal body rectangle height that is required to correctly display the longest used parameter
0639:                minimal_body_rectangle_height_for_parameters = mElementStyleOrig.mParamLineLength
0640:                        + mElementStyleOrig.mParamMarginHeight
0641:                        + parameters_height
0642:                        + (mElementStyleOrig.mElementBorderWidth * 2);
0643:                // calculate the height of the body rectangle and make it at least as big as the previously calculated minimal body height
0644:                if (body_rectangle_height < minimal_body_rectangle_height_for_parameters) {
0645:                    body_rectangle_height = minimal_body_rectangle_height_for_parameters;
0646:                }
0647:
0648:                // calculate the maximum height of all the added parameter texts
0649:                parameters_height = 0;
0650:
0651:                for (ElementProperty parameter : getAddedParameters()) {
0652:                    parameter_string_width = (float) (mElementStyleOrig.mParamFont
0653:                            .getStringBounds(parameter.getName(),
0654:                                    mElementStyleOrig.mFontRenderContext)
0655:                            .getWidth());
0656:                    if (parameter_string_width > parameters_height) {
0657:                        parameters_height = parameter_string_width;
0658:                    }
0659:                }
0660:                // calculate the minimal body rectangle height that is required to correctly display the longest added parameter
0661:                minimal_body_rectangle_height_for_parameters = name_rectangle_height
0662:                        + (mElementStyleOrig.mParamLineLength / 2)
0663:                        + parameters_height
0664:                        + mElementStyleOrig.mParamMarginHeight
0665:                        + (mElementStyleOrig.mElementBorderWidth * 2);
0666:                // calculate the height of the body rectangle and make it at least as big as the previously calculated minimal body height
0667:                if (body_rectangle_height < minimal_body_rectangle_height_for_parameters) {
0668:                    body_rectangle_height = minimal_body_rectangle_height_for_parameters;
0669:                }
0670:                // snap the height of the body to grid units and take space for the bottom edge
0671:                body_rectangle_height = (float) (Math
0672:                        .ceil(body_rectangle_height / grid_size) * grid_size)
0673:                        + mElementStyleOrig.mElementBorderWidth;
0674:
0675:                //
0676:                // calculate the width and height of the buffered image
0677:                //
0678:                mBodyXOffsetOrig = 0;
0679:                mBodyYOffsetOrig = 0;
0680:                // calculate the required vertical offset that is needed for the optional top parameter handles (consumed and used)
0681:                if (number_of_consumed_parameters > 0
0682:                        || number_of_used_parameters > 0) {
0683:                    mBodyYOffsetOrig += mElementStyleOrig.mParamLineLength / 2;
0684:                }
0685:                // calculate the body width, taking into account the existance of exits
0686:                if (number_of_exits > 0) {
0687:                    mWidthOrig = element_rectangle_width + exit_rectangle_width
0688:                            + 1;
0689:                } else {
0690:                    mWidthOrig = element_rectangle_width + 1;
0691:                }
0692:                // calculate the body height, taking into account the space taken by optional parameter handles
0693:                if (number_of_consumed_parameters > 0
0694:                        || number_of_used_parameters > 0
0695:                        || number_of_added_parameters > 0) {
0696:                    mHeightOrig = body_rectangle_height
0697:                            + mElementStyleOrig.mParamLineLength + 1;
0698:                } else {
0699:                    mHeightOrig = body_rectangle_height + 1;
0700:                }
0701:
0702:                //
0703:                // precalculate the body shape
0704:                //
0705:
0706:                // create the body area, including the outside stroke
0707:                Area body_area_outside = new Area(new Rectangle2D.Float(
0708:                        mBodyXOffsetOrig, mBodyYOffsetOrig,
0709:                        body_rectangle_width, body_rectangle_height));
0710:                // create the body area, excluding the outside stroke
0711:                Area body_area_inside = new Area(new Rectangle2D.Float(
0712:                        mBodyXOffsetOrig
0713:                                + mElementStyleOrig.mElementBorderWidth,
0714:                        mBodyYOffsetOrig
0715:                                + mElementStyleOrig.mElementBorderWidth,
0716:                        body_rectangle_width
0717:                                - mElementStyleOrig.mElementBorderWidth * 2,
0718:                        body_rectangle_height
0719:                                - mElementStyleOrig.mElementBorderWidth * 2));
0720:                // if there are exits, add them to the body shape
0721:                if (number_of_exits > 0) {
0722:                    // create the base exit shape, including the outside stroke
0723:                    Area exit_area_outside = new Area(new Rectangle2D.Float(
0724:                            mBodyXOffsetOrig + element_rectangle_width
0725:                                    - mElementStyleOrig.mElementBorderWidth,
0726:                            mBodyYOffsetOrig + name_rectangle_height
0727:                                    + exit_rectangle_y_interval / 3,
0728:                            exit_rectangle_width, exit_rectangle_height));
0729:                    // create the base exit shape, excluding the outside stroke
0730:                    Area exit_area_inside = new Area(
0731:                            new Rectangle2D.Float(
0732:                                    mBodyXOffsetOrig
0733:                                            + element_rectangle_width
0734:                                            - mElementStyleOrig.mElementBorderWidth,
0735:                                    mBodyYOffsetOrig
0736:                                            + name_rectangle_height
0737:                                            + exit_rectangle_y_interval
0738:                                            / 3
0739:                                            + mElementStyleOrig.mElementBorderWidth,
0740:                                    exit_rectangle_width
0741:                                            - mElementStyleOrig.mElementBorderWidth,
0742:                                    exit_rectangle_height
0743:                                            - mElementStyleOrig.mElementBorderWidth
0744:                                            * 2));
0745:                    // create the transformation that will translate the previous exit shape to make it suit for the next one
0746:                    AffineTransform next_exit_transform = AffineTransform
0747:                            .getTranslateInstance(0, exit_rectangle_y_interval);
0748:                    // process each exit, add its shapes to the body shapes and transform the exit shapes for the optional next exit
0749:
0750:                    Rectangle2D exit_area_outside_bounds = null;
0751:                    float hotspot_width = exits_width
0752:                            + mElementStyleOrig.mExitMarginWidth * 2;
0753:                    if (hotspot_width < exit_rectangle_width) {
0754:                        hotspot_width = exit_rectangle_width;
0755:                    }
0756:                    float hotspot_x = mWidthOrig
0757:                            - mElementStyleOrig.mElementBorderWidth * 2
0758:                            - hotspot_width;
0759:                    for (ElementProperty exit : getExits()) {
0760:                        body_area_outside.add(exit_area_outside);
0761:                        body_area_inside.add(exit_area_inside);
0762:                        exit_area_outside_bounds = exit_area_outside
0763:                                .getBounds2D();
0764:                        exit.setHotSpot(new Rectangle2D.Float(hotspot_x,
0765:                                (float) exit_area_outside_bounds.getY(),
0766:                                hotspot_width, (float) exit_area_outside_bounds
0767:                                        .getHeight()));
0768:                        exit_area_outside = exit_area_outside
0769:                                .createTransformedArea(next_exit_transform);
0770:                        exit_area_inside = exit_area_inside
0771:                                .createTransformedArea(next_exit_transform);
0772:                    }
0773:                }
0774:
0775:                // create the bounding area by stroking the body area
0776:                mBoundingOrig = new Area((new BasicStroke(1))
0777:                        .createStrokedShape(body_area_outside));
0778:                mBoundingOrig.add(body_area_outside);
0779:
0780:                // store the body areas and create the outside shape so that it only contains what is needed to draw the stroke
0781:                mBodyAreaInsideOrig = body_area_inside;
0782:                mBodyAreaOutsideOrig = (Area) body_area_outside.clone();
0783:                mBodyAreaOutsideOrig.subtract(mBodyAreaInsideOrig);
0784:
0785:                //
0786:                // precalculate exit name texts
0787:                //
0788:                if (number_of_exits > 0) {
0789:                    // calculate the base location for the first exit text
0790:                    float base_exit_text_x_offset = mBodyXOffsetOrig
0791:                            + element_rectangle_width + exit_rectangle_width
0792:                            - mElementStyleOrig.mExitMarginWidth * 2
0793:                            - mElementStyleOrig.mElementBorderWidth;
0794:                    float base_exit_text_y_offset = mBodyYOffsetOrig
0795:                            + name_rectangle_height + exit_rectangle_y_interval
0796:                            / 3 + mElementStyleOrig.mElementBorderWidth
0797:                            + mElementStyleOrig.mExitMarginHeight
0798:                            + exit_text_height;
0799:                    // iterate over all the exit texts
0800:                    for (ElementProperty exit : getExits()) {
0801:                        // store each exit text with it's precalculated location in a dedicated glyph vector
0802:                        string_bounds = mElementStyleOrig.mExitFont
0803:                                .getStringBounds(exit.getName(),
0804:                                        mElementStyleOrig.mFontRenderContext);
0805:                        exit
0806:                                .setNameBounds(new Rectangle2D.Float(
0807:                                        (float) (base_exit_text_x_offset - string_bounds
0808:                                                .getWidth()),
0809:                                        (float) (base_exit_text_y_offset - string_bounds
0810:                                                .getHeight()),
0811:                                        (float) string_bounds.getWidth(),
0812:                                        (float) string_bounds.getHeight()));
0813:
0814:                        // move the vertical position downwards
0815:                        base_exit_text_y_offset += exit_rectangle_y_interval;
0816:                    }
0817:                }
0818:
0819:                //
0820:                // precalculate title shape
0821:                //
0822:                mTitleRectangleOutsideOrig = new Area(new Rectangle2D.Float(
0823:                        mBodyXOffsetOrig + name_rectangle_x_offset,
0824:                        mBodyYOffsetOrig, name_rectangle_width,
0825:                        name_rectangle_height));
0826:                mTitleRectangleInsideOrig = new Area(new Rectangle2D.Float(
0827:                        mBodyXOffsetOrig + name_rectangle_x_offset
0828:                                + mElementStyleOrig.mElementBorderWidth,
0829:                        mBodyYOffsetOrig
0830:                                + mElementStyleOrig.mElementBorderWidth,
0831:                        name_rectangle_width
0832:                                - mElementStyleOrig.mElementBorderWidth * 2,
0833:                        name_rectangle_height
0834:                                - mElementStyleOrig.mElementBorderWidth * 2));
0835:                mBodyAreaOutsideOrig.add(mTitleRectangleOutsideOrig);
0836:                mBodyAreaOutsideOrig.subtract(mTitleRectangleInsideOrig);
0837:                mBodyAreaInsideOrig.subtract(mTitleRectangleOutsideOrig);
0838:
0839:                //
0840:                // precalculate consumed parameters and texts
0841:                //
0842:
0843:                // set the initial horizontal offset for the drawing of the parameter handles, this is both used by all parameters
0844:                float parameter_x_cursor = mBodyXOffsetOrig
0845:                        + (parameter_rectangle_width / 2);
0846:                if (number_of_consumed_parameters > 0) {
0847:                    // move the initial parameter line offset to the position for consumed parameters
0848:                    parameter_x_cursor += parameter_rectangle_width;
0849:                    // calculate the vertical start and end positions of the top parameter handles
0850:                    float consumed_parameter_handle_top_y1 = mBodyYOffsetOrig
0851:                            - (mElementStyleOrig.mParamLineLength / 2);
0852:                    float consumed_parameter_handle_top_y2 = mBodyYOffsetOrig
0853:                            + (mElementStyleOrig.mParamLineLength / 2);
0854:                    // create the first parameter handle area
0855:                    Area consumed_parameter_handle_top_area = new Area(
0856:                            new Rectangle2D.Float(parameter_x_cursor
0857:                                    - (mElementStyleOrig.mParamLineWidth / 2),
0858:                                    consumed_parameter_handle_top_y1,
0859:                                    mElementStyleOrig.mParamLineWidth,
0860:                                    mElementStyleOrig.mParamLineLength));
0861:
0862:                    // calculate the horizontal interval between the parameters and create the transform object to perform the translation
0863:                    float consumed_parameter_x_interval = parameter_rectangle_width
0864:                            + (parameter_rectangle_width / 2);
0865:                    AffineTransform next_consumed_parameter_transform = AffineTransform
0866:                            .getTranslateInstance(
0867:                                    consumed_parameter_x_interval, 0);
0868:
0869:                    // process all the consumed parameters
0870:                    for (ElementProperty parameter : getConsumedParameters()) {
0871:                        // add the consumed parameter handle to the body area and bounding area
0872:                        mBodyAreaOutsideOrig
0873:                                .add(consumed_parameter_handle_top_area);
0874:                        mBoundingOrig.add(consumed_parameter_handle_top_area);
0875:
0876:                        // add the consumed parameter texts together with their locations as glyph vectors to the collection of parameter glyph vectors
0877:                        string_bounds = mElementStyleOrig.mParamFont
0878:                                .getStringBounds(parameter.getName(),
0879:                                        mElementStyleOrig.mFontRenderContext);
0880:                        name_bounds = new Rectangle2D.Float(
0881:                                (float) (parameter_x_cursor
0882:                                        + parameter_text_middle - string_bounds
0883:                                        .getHeight()),
0884:                                consumed_parameter_handle_top_y2
0885:                                        + mElementStyleOrig.mParamMarginHeight,
0886:                                (float) string_bounds.getHeight(),
0887:                                (float) string_bounds.getWidth());
0888:                        parameter.setNameBounds(name_bounds);
0889:                        hotspot = new Area(new Rectangle2D.Float(
0890:                                (float) name_bounds.getX(),
0891:                                consumed_parameter_handle_top_y1,
0892:                                (float) name_bounds.getWidth(),
0893:                                (float) (name_bounds.getY() + name_bounds
0894:                                        .getHeight())));
0895:                        hotspot.intersect(mBoundingOrig);
0896:                        parameter.setHotSpot(hotspot);
0897:
0898:                        // update the horizontal offset and translate the parameter handle area
0899:                        parameter_x_cursor += consumed_parameter_x_interval;
0900:                        consumed_parameter_handle_top_area = consumed_parameter_handle_top_area
0901:                                .createTransformedArea(next_consumed_parameter_transform);
0902:                    }
0903:                } else {
0904:                    // adapt the initial horizontal offset in case there are no consumed parameters to make the used parameters appear
0905:                    // on the correct location
0906:                    parameter_x_cursor += parameter_rectangle_width / 2;
0907:                }
0908:
0909:                //
0910:                // precalculate used parameters lines and texts
0911:                //
0912:                mUsedParameterLinesOrig = new GeneralPath();
0913:                if (number_of_used_parameters > 0) {
0914:                    // move the initial parameter line offset to the position for used parameters
0915:                    parameter_x_cursor += parameter_rectangle_width / 2;
0916:                    // calculate the vertical start and end positions of the top and bottom parameter handles
0917:                    float used_parameter_handle_top_y1 = mBodyYOffsetOrig
0918:                            - (mElementStyleOrig.mParamLineLength / 2);
0919:                    float used_parameter_handle_top_y2 = mBodyYOffsetOrig
0920:                            + (mElementStyleOrig.mParamLineLength / 2);
0921:                    float used_parameter_handle_bottom_y1 = used_parameter_handle_top_y1
0922:                            + body_rectangle_height;
0923:                    float used_parameter_handle_bottom_y2 = used_parameter_handle_top_y2
0924:                            + body_rectangle_height;
0925:                    // create the first parameter top and bottom handle areas with their connection line
0926:                    Area used_parameter_handle_top_area = new Area(
0927:                            new Rectangle2D.Float(parameter_x_cursor
0928:                                    - (mElementStyleOrig.mParamLineWidth / 2),
0929:                                    used_parameter_handle_top_y1,
0930:                                    mElementStyleOrig.mParamLineWidth,
0931:                                    mElementStyleOrig.mParamLineLength));
0932:                    Area used_parameter_handle_bottom_area = new Area(
0933:                            new Rectangle2D.Float(parameter_x_cursor
0934:                                    - (mElementStyleOrig.mParamLineWidth / 2),
0935:                                    used_parameter_handle_bottom_y1,
0936:                                    mElementStyleOrig.mParamLineWidth,
0937:                                    mElementStyleOrig.mParamLineLength));
0938:                    Line2D used_parameter_handle_connect = new Line2D.Float(
0939:                            parameter_x_cursor, used_parameter_handle_top_y2,
0940:                            parameter_x_cursor, used_parameter_handle_bottom_y1);
0941:
0942:                    // calculate the horizontal interval between the parameters and create the transform object to perform the translation
0943:                    float used_parameter_x_interval = parameter_rectangle_width
0944:                            + (parameter_rectangle_width / 2);
0945:                    AffineTransform next_used_parameter_transform = AffineTransform
0946:                            .getTranslateInstance(used_parameter_x_interval, 0);
0947:
0948:                    // process all the used parameters
0949:                    for (ElementProperty parameter : getUsedParameters()) {
0950:                        // add the used parameter top and bottom handles to the body area and bounding area
0951:                        mBodyAreaOutsideOrig
0952:                                .add(used_parameter_handle_top_area);
0953:                        mBodyAreaOutsideOrig
0954:                                .add(used_parameter_handle_bottom_area);
0955:                        mBoundingOrig.add(used_parameter_handle_top_area);
0956:                        mBoundingOrig.add(used_parameter_handle_bottom_area);
0957:
0958:                        // add the connection line between handles to the collection of used parameter connection lines
0959:                        mUsedParameterLinesOrig.moveTo(parameter_x_cursor,
0960:                                used_parameter_handle_top_y2);
0961:                        mUsedParameterLinesOrig.lineTo(parameter_x_cursor,
0962:                                used_parameter_handle_bottom_y1);
0963:
0964:                        // add the used parameter texts together with their locations as glyph vectors to the collection of parameter glyph vectors
0965:                        string_bounds = mElementStyleOrig.mParamFont
0966:                                .getStringBounds(parameter.getName(),
0967:                                        mElementStyleOrig.mFontRenderContext);
0968:                        name_bounds = new Rectangle2D.Float(
0969:                                (float) (parameter_x_cursor
0970:                                        - mElementStyleOrig.mParamMarginWidth - string_bounds
0971:                                        .getHeight()),
0972:                                used_parameter_handle_top_y2
0973:                                        + mElementStyleOrig.mParamMarginHeight,
0974:                                (float) string_bounds.getHeight(),
0975:                                (float) string_bounds.getWidth());
0976:                        parameter.setNameBounds(name_bounds);
0977:                        hotspot = new Area(
0978:                                new Rectangle2D.Float(
0979:                                        (float) name_bounds.getX(),
0980:                                        used_parameter_handle_top_y1,
0981:                                        (float) (parameter_x_cursor
0982:                                                + mElementStyleOrig.mParamLineWidth - name_bounds
0983:                                                .getX()),
0984:                                        used_parameter_handle_bottom_y2
0985:                                                - used_parameter_handle_top_y1));
0986:                        hotspot.intersect(mBoundingOrig);
0987:                        parameter.setHotSpot(hotspot);
0988:
0989:                        // update the horizontal offset and translate the parameter top and bottom handle areas and their connection line
0990:                        parameter_x_cursor += used_parameter_x_interval;
0991:                        used_parameter_handle_top_area = used_parameter_handle_top_area
0992:                                .createTransformedArea(next_used_parameter_transform);
0993:                        used_parameter_handle_bottom_area = used_parameter_handle_bottom_area
0994:                                .createTransformedArea(next_used_parameter_transform);
0995:                        used_parameter_handle_connect.setLine(
0996:                                parameter_x_cursor,
0997:                                used_parameter_handle_top_y2,
0998:                                parameter_x_cursor,
0999:                                used_parameter_handle_bottom_y1);
1000:                    }
1001:                }
1002:
1003:                //
1004:                // precalculate added parameters lines and texts
1005:                //
1006:                if (number_of_added_parameters > 0) {
1007:                    // move the initial parameter line offset to the position for added parameters
1008:                    parameter_x_cursor += parameter_rectangle_width / 2;
1009:                    // calculate the vertical start and end positions of the bottom parameter handles
1010:                    float added_parameter_line_y1 = mBodyYOffsetOrig
1011:                            + body_rectangle_height
1012:                            - (mElementStyleOrig.mParamLineLength / 2);
1013:                    float added_parameter_line_y2 = mBodyYOffsetOrig
1014:                            + body_rectangle_height
1015:                            + (mElementStyleOrig.mParamLineLength / 2);
1016:                    // create the first parameter handle area
1017:                    Area added_parameter_line_area = new Area(
1018:                            new Rectangle2D.Float(parameter_x_cursor
1019:                                    - (mElementStyleOrig.mParamLineWidth / 2),
1020:                                    added_parameter_line_y1,
1021:                                    mElementStyleOrig.mParamLineWidth,
1022:                                    mElementStyleOrig.mParamLineLength));
1023:
1024:                    // calculate the horizontal interval between the parameters and create the transform object to perform the translation
1025:                    float added_parameter_x_interval = parameter_rectangle_width
1026:                            + (parameter_rectangle_width / 2);
1027:                    AffineTransform next_added_parameter_transform = AffineTransform
1028:                            .getTranslateInstance(added_parameter_x_interval, 0);
1029:
1030:                    // process all the added parameters
1031:                    for (ElementProperty parameter : getAddedParameters()) {
1032:                        // add the added parameter handle to the body area and bounding area
1033:                        mBodyAreaOutsideOrig.add(added_parameter_line_area);
1034:                        mBoundingOrig.add(added_parameter_line_area);
1035:
1036:                        // add the added parameter texts together with their locations as glyph vectors to the collection of parameter glyph vectors
1037:                        string_bounds = mElementStyleOrig.mParamFont
1038:                                .getStringBounds(parameter.getName(),
1039:                                        mElementStyleOrig.mFontRenderContext);
1040:                        name_bounds = new Rectangle2D.Float(
1041:                                (float) (parameter_x_cursor
1042:                                        + parameter_text_middle - string_bounds
1043:                                        .getHeight()),
1044:                                (float) (added_parameter_line_y1
1045:                                        - mElementStyleOrig.mParamMarginHeight - string_bounds
1046:                                        .getWidth()), (float) string_bounds
1047:                                        .getHeight(), (float) string_bounds
1048:                                        .getWidth());
1049:                        parameter.setNameBounds(name_bounds);
1050:                        hotspot = new Area(new Rectangle2D.Float(
1051:                                (float) name_bounds.getX(), (float) name_bounds
1052:                                        .getY(),
1053:                                (float) name_bounds.getWidth(),
1054:                                (float) (added_parameter_line_y2 - name_bounds
1055:                                        .getY())));
1056:                        hotspot.intersect(mBoundingOrig);
1057:                        parameter.setHotSpot(hotspot);
1058:
1059:                        // update the horizontal offset and translate the parameter handle area
1060:                        parameter_x_cursor += added_parameter_x_interval;
1061:                        added_parameter_line_area = added_parameter_line_area
1062:                                .createTransformedArea(next_added_parameter_transform);
1063:                    }
1064:                }
1065:
1066:                //
1067:                // precalculate name text
1068:                //
1069:                ElementProperty title = getTitle();
1070:                title.setNameBounds(new Rectangle2D.Float(mBodyXOffsetOrig
1071:                        + name_rectangle_x_offset
1072:                        + (name_rectangle_width - title_text_width) / 2,
1073:                        mBodyYOffsetOrig + mElementStyleOrig.mTitleMarginHeight
1074:                                + mElementStyleOrig.mElementBorderWidth,
1075:                        title_text_width, title_text_height));
1076:                title.setHotSpot(mTitleRectangleOutsideOrig);
1077:
1078:                //
1079:                // create the scaled version, keeping the current scale factor
1080:                //
1081:                scalePrecalculatedAreas(1);
1082:            }
1083:
1084:            public void drawElement(Graphics2D g2d) {
1085:                Rectangle clip = g2d.getClipBounds();
1086:
1087:                if (mBoundingScaled == null) {
1088:                    createPrecalculatedAreas();
1089:                }
1090:
1091:                if (clip == null || mBoundingScaled.intersects(clip)) {
1092:                    boolean drag_outline = Config.getRepInstance().getBool(
1093:                            "DRAG_OUTLINE");
1094:                    boolean scrolling_fast = Config.getRepInstance().getBool(
1095:                            "SCROLLING_FAST");
1096:                    boolean scrolling_outline = Config.getRepInstance()
1097:                            .getBool("SCROLLING_OUTLINE");
1098:                    boolean scroll_active = ((StructurePanel) getParent())
1099:                            .isScrollActive();
1100:
1101:                    if ((!mDragActive && !scroll_active)
1102:                            || (mDragActive && !drag_outline)
1103:                            || (scroll_active && !scrolling_outline)) {
1104:                        if (!mSelected) {
1105:                            g2d
1106:                                    .setColor(mElementStyleScaled.mBodyBackgroundColor);
1107:                        } else {
1108:                            g2d
1109:                                    .setColor(mElementStyleScaled.mBodyBackgroundColorSelected);
1110:                        }
1111:                        g2d.fill(mBodyAreaInsideScaled);
1112:                    }
1113:                    g2d.setColor(mElementStyleScaled.mElementBorderColor);
1114:                    g2d.fill(mBodyAreaOutsideScaled);
1115:
1116:                    if ((!mDragActive && !scroll_active)
1117:                            || (mDragActive && !drag_outline)
1118:                            || (scroll_active && !scrolling_outline)) {
1119:                        if (!scrolling_fast || !scroll_active) {
1120:                            g2d
1121:                                    .setColor(mElementStyleScaled.mElementBorderColor);
1122:                            g2d
1123:                                    .setStroke(mElementStyleScaled.mParamLineDashedStroke);
1124:                            g2d.draw(mUsedParameterLinesScaled);
1125:                        }
1126:                        if (clip == null
1127:                                || mTitleRectangleInsideScaled.intersects(clip)) {
1128:                            g2d.setColor(mTitleBackgroundColor);
1129:                            g2d.fill(mTitleRectangleInsideScaled);
1130:                        }
1131:                        getTitle().draw(g2d);
1132:                        if (!scrolling_fast || !scroll_active) {
1133:                            for (ElementProperty property : mElementProperties) {
1134:                                if (!(property instanceof  ElementPropertyTitle)) {
1135:                                    property.draw(g2d);
1136:                                }
1137:                            }
1138:                        }
1139:
1140:                        mStructurePanel.drawHighlightedProperty(this , g2d);
1141:                    }
1142:                }
1143:            }
1144:
1145:            public void paintComponent(Graphics g) {
1146:                super .paintComponent(g);
1147:
1148:                Graphics2D g2d = (Graphics2D) g;
1149:
1150:                if (mDragBufferedImage == null) {
1151:                    g2d = (Graphics2D) g2d.create();
1152:                    ElementStyle.setRenderingHints(g2d, mScaleFactor);
1153:                    drawElement(g2d);
1154:                } else {
1155:                    if (mIsTransparent) {
1156:                        g2d.setComposite(AlphaComposite.getInstance(
1157:                                AlphaComposite.SRC_OVER, 0.5f));
1158:                    }
1159:
1160:                    g2d.drawImage(mDragBufferedImage, null, 0, 0);
1161:                }
1162:            }
1163:
1164:            public BufferedImage getDragBufferedImage() {
1165:                return mDragBufferedImage;
1166:            }
1167:
1168:            public void addElementListener(ElementListener listener) {
1169:                mElementListeners.add(listener);
1170:            }
1171:
1172:            public void removeElementListener(ElementListener listener) {
1173:                mElementListeners.remove(listener);
1174:            }
1175:
1176:            protected void fireElementRepositioned() {
1177:                for (ElementListener listener : mElementListeners) {
1178:                    listener.elementRepositioned(this );
1179:                }
1180:            }
1181:
1182:            protected void fireElementRaised() {
1183:                for (ElementListener listener : mElementListeners) {
1184:                    listener.elementRaised(this );
1185:                }
1186:            }
1187:
1188:            protected void fireElementSelected(int modifiers) {
1189:                for (ElementListener listener : mElementListeners) {
1190:                    listener.elementSelected(this , modifiers);
1191:                }
1192:            }
1193:
1194:            protected void fireElementDeselected(int modifiers) {
1195:                for (ElementListener listener : mElementListeners) {
1196:                    listener.elementDeselected(this , modifiers);
1197:                }
1198:            }
1199:
1200:            protected void fireElementDragged(int x, int y) {
1201:                for (ElementListener listener : mElementListeners) {
1202:                    listener.elementDragged(this , x, y);
1203:                }
1204:            }
1205:
1206:            protected void fireElementDragStart(Point dragStartPoint) {
1207:                for (ElementListener listener : mElementListeners) {
1208:                    listener.elementDragStart(this , dragStartPoint);
1209:                }
1210:            }
1211:
1212:            protected void fireElementDragEnd() {
1213:                for (ElementListener listener : mElementListeners) {
1214:                    listener.elementDragEnd();
1215:                }
1216:            }
1217:
1218:            protected void fireElementPropertyHighlighted(
1219:                    ElementProperty property) {
1220:                for (ElementListener listener : mElementListeners) {
1221:                    listener.elementPropertyHighlighted(property);
1222:                }
1223:            }
1224:
1225:            protected void repositionElementDuringDrag(int offsetX, int offsetY) {
1226:                setLocation(offsetX + getX(), offsetY + getY());
1227:            }
1228:
1229:            protected void startDrag() {
1230:                mDragActive = true;
1231:                mDragBufferedImage = new BufferedImage((int) mWidthScaled,
1232:                        (int) mHeightScaled, BufferedImage.TYPE_INT_ARGB);
1233:                Graphics2D g2d = mDragBufferedImage.createGraphics();
1234:                ElementStyle.setRenderingHints(g2d, mScaleFactor);
1235:                drawElement(g2d);
1236:                fireElementRaised();
1237:                if (Config.getRepInstance().getBool("DRAG_TRANSPARENT")) {
1238:                    mIsTransparent = true;
1239:                }
1240:            }
1241:
1242:            protected void endDrag() {
1243:                mDragBufferedImage = null;
1244:                mDragActive = false;
1245:                if (Config.getRepInstance().getBool("DRAG_TRANSPARENT")) {
1246:                    mIsTransparent = false;
1247:                }
1248:                fireElementRepositioned();
1249:            }
1250:
1251:            private ElementProperty locateElementProperty(Point location) {
1252:                Shape hotspot = null;
1253:                for (ElementProperty property : mElementProperties) {
1254:                    hotspot = property.getHotSpot();
1255:                    if (hotspot.contains(location)) {
1256:                        return property;
1257:                    }
1258:                }
1259:
1260:                return null;
1261:            }
1262:
1263:            private void triggerPopup(Point location) {
1264:                fireElementRaised();
1265:                ElementProperty property = locateElementProperty(location);
1266:                if (property != null) {
1267:                    property.showPopupMenu(location);
1268:                } else {
1269:                    JPopupMenu popup = new JPopupMenu();
1270:                    DynamicMenuBuilder menu_builder = new DynamicMenuBuilder();
1271:                    JMenu menu_add = menu_builder
1272:                            .addMenu(
1273:                                    popup,
1274:                                    Localization
1275:                                            .getString("rife.element.popupmenu.add"),
1276:                                    Localization
1277:                                            .getChar("rife.element.popupmenu.add.mnemonic"));
1278:                    menu_builder
1279:                            .addMenuItem(
1280:                                    menu_add,
1281:                                    Localization
1282:                                            .getString("rife.element.popupmenu.add.exit"),
1283:                                    new AddExit(location),
1284:                                    Localization
1285:                                            .getChar("rife.element.popupmenu.add.exit.mnemonic"));
1286:                    menu_builder
1287:                            .addMenuItem(
1288:                                    menu_add,
1289:                                    Localization
1290:                                            .getString("rife.element.popupmenu.add.consumedparameter"),
1291:                                    new AddConsumedParameter(location),
1292:                                    Localization
1293:                                            .getChar("rife.element.popupmenu.add.consumedparameter.mnemonic"));
1294:                    menu_builder
1295:                            .addMenuItem(
1296:                                    menu_add,
1297:                                    Localization
1298:                                            .getString("rife.element.popupmenu.add.usedparameter"),
1299:                                    new AddUsedParameter(location),
1300:                                    Localization
1301:                                            .getChar("rife.element.popupmenu.add.usedparameter.mnemonic"));
1302:                    menu_builder
1303:                            .addMenuItem(
1304:                                    menu_add,
1305:                                    Localization
1306:                                            .getString("rife.element.popupmenu.add.addedparameter"),
1307:                                    new AddAddedParameter(location),
1308:                                    Localization
1309:                                            .getChar("rife.element.popupmenu.add.addedparameter.mnemonic"));
1310:                    menu_builder
1311:                            .addMenuItem(
1312:                                    popup,
1313:                                    Localization
1314:                                            .getString("rife.element.popupmenu.delete"),
1315:                                    new Delete(),
1316:                                    Localization
1317:                                            .getChar("rife.element.popupmenu.delete.mnemonic"));
1318:
1319:                    popup.show(this , location.x, location.y);
1320:                    popup.addPopupMenuListener(getStructurePanel());
1321:                }
1322:            }
1323:
1324:            protected class AddExit implements  DynamicMenuAction {
1325:                private Point mClickedPoint = null;
1326:
1327:                public AddExit(Point clickedPoint) {
1328:                    mClickedPoint = clickedPoint;
1329:                }
1330:
1331:                public void execute(JMenuItem menuItem) {
1332:                    ElementPropertyExit exit = addExit("");
1333:                    createPrecalculatedAreas();
1334:                    getStructurePanel()
1335:                            .editElementProperty(exit, mClickedPoint);
1336:                }
1337:            }
1338:
1339:            protected class AddConsumedParameter implements  DynamicMenuAction {
1340:                private Point mClickedPoint = null;
1341:
1342:                public AddConsumedParameter(Point clickedPoint) {
1343:                    mClickedPoint = clickedPoint;
1344:                }
1345:
1346:                public void execute(JMenuItem menuItem) {
1347:                    ElementPropertyParameterConsumed parameter = addConsumedParameter("");
1348:                    createPrecalculatedAreas();
1349:                    getStructurePanel().editElementProperty(parameter,
1350:                            mClickedPoint);
1351:                }
1352:            }
1353:
1354:            protected class AddUsedParameter implements  DynamicMenuAction {
1355:                private Point mClickedPoint = null;
1356:
1357:                public AddUsedParameter(Point clickedPoint) {
1358:                    mClickedPoint = clickedPoint;
1359:                }
1360:
1361:                public void execute(JMenuItem menuItem) {
1362:                    ElementPropertyParameterUsed parameter = addUsedParameter("");
1363:                    createPrecalculatedAreas();
1364:                    getStructurePanel().editElementProperty(parameter,
1365:                            mClickedPoint);
1366:                }
1367:            }
1368:
1369:            protected class AddAddedParameter implements  DynamicMenuAction {
1370:                private Point mClickedPoint = null;
1371:
1372:                public AddAddedParameter(Point clickedPoint) {
1373:                    mClickedPoint = clickedPoint;
1374:                }
1375:
1376:                public void execute(JMenuItem menuItem) {
1377:                    ElementPropertyParameterAdded parameter = addAddedParameter("");
1378:                    createPrecalculatedAreas();
1379:                    getStructurePanel().editElementProperty(parameter,
1380:                            mClickedPoint);
1381:                }
1382:            }
1383:
1384:            protected class Delete implements  DynamicMenuAction {
1385:                public void execute(JMenuItem menuItem) {
1386:                    JComponent parent = (JComponent) Element.this .getParent();
1387:                    if (parent instanceof  StructurePanel) {
1388:                        ((StructurePanel) parent).removeElement(Element.this );
1389:                    }
1390:                }
1391:            }
1392:
1393:            private void updateHighlightedProperty(Point location) {
1394:                ElementProperty property = locateElementProperty(location);
1395:                fireElementPropertyHighlighted(property);
1396:            }
1397:
1398:            public void mouseClicked(MouseEvent e) {
1399:                if ((e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) {
1400:                    if (e.getClickCount() == 2) {
1401:                        ElementProperty property = locateElementProperty(e
1402:                                .getPoint());
1403:                        if (property != null) {
1404:                            getStructurePanel().editElementProperty(property,
1405:                                    e.getPoint());
1406:                        }
1407:                    }
1408:                }
1409:            }
1410:
1411:            public void mousePressed(MouseEvent e) {
1412:                getStructurePanel().removeElementPropertyEditor();
1413:
1414:                if (e.isPopupTrigger()) {
1415:                    triggerPopup(e.getPoint());
1416:                } else if ((e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) {
1417:                    mDragStartPoint = e.getPoint();
1418:                    if (!mSelected) {
1419:                        fireElementSelected(e.getModifiers());
1420:                    } else {
1421:                        fireElementDeselected(e.getModifiers());
1422:                    }
1423:                }
1424:            }
1425:
1426:            public void mouseReleased(MouseEvent e) {
1427:                if (e.isPopupTrigger()) {
1428:                    triggerPopup(e.getPoint());
1429:                } else if ((e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) {
1430:                    mDragStartPoint = null;
1431:                    if (mDragActive) {
1432:                        fireElementDragEnd();
1433:                    }
1434:                }
1435:            }
1436:
1437:            public void mouseEntered(MouseEvent e) {
1438:                updateHighlightedProperty(e.getPoint());
1439:            }
1440:
1441:            public void mouseExited(MouseEvent e) {
1442:                if (!mStructurePanel.isDragActive()
1443:                        && !mStructurePanel.isElementPropertyBeingEdited()
1444:                        && !mStructurePanel.isPopupMenuActive()) {
1445:                    updateHighlightedProperty(new Point(-1, -1));
1446:                }
1447:                if (mDragActive) {
1448:                    fireElementDragged(e.getPoint().x, e.getPoint().y);
1449:                }
1450:            }
1451:
1452:            public void mouseDragged(MouseEvent e) {
1453:                if (e.getComponent() == this ) {
1454:                    if ((e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) {
1455:                        if (mSelected) {
1456:                            if (!mDragActive) {
1457:                                fireElementDragStart(mDragStartPoint);
1458:                            } else {
1459:                                fireElementDragged(e.getPoint().x,
1460:                                        e.getPoint().y);
1461:                            }
1462:                        }
1463:                    }
1464:                }
1465:            }
1466:
1467:            public void mouseMoved(MouseEvent e) {
1468:                updateHighlightedProperty(e.getPoint());
1469:            }
1470:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.