001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019: package org.netbeans.modules.bpel.design.model.elements;
020:
021: import java.awt.Color;
022: import java.awt.Dimension;
023: import java.awt.Font;
024: import java.awt.FontMetrics;
025: import java.awt.GradientPaint;
026: import java.awt.Graphics2D;
027: import java.awt.Point;
028: import java.awt.Rectangle;
029: import java.awt.Paint;
030: import java.awt.RenderingHints;
031: import java.awt.font.FontRenderContext;
032: import java.awt.font.LineBreakMeasurer;
033: import java.awt.font.TextLayout;
034: import java.awt.geom.AffineTransform;
035: import java.awt.geom.Rectangle2D;
036: import java.awt.image.BufferedImage;
037: import java.util.ArrayList;
038: import java.util.List;
039: import javax.swing.JLabel;
040: import org.netbeans.modules.bpel.design.DesignView;
041: import org.netbeans.modules.bpel.design.geometry.FBounds;
042: import org.netbeans.modules.bpel.design.geometry.FPoint;
043: import org.netbeans.modules.bpel.design.geometry.FShape;
044: import org.netbeans.modules.bpel.design.ViewProperties;
045: import org.netbeans.modules.bpel.design.decoration.Decoration;
046: import org.netbeans.modules.bpel.design.decoration.TextstyleDescriptor;
047: import org.netbeans.modules.bpel.design.geometry.FBounds;
048: import org.netbeans.modules.bpel.design.geometry.FShape;
049: import org.netbeans.modules.bpel.design.model.connections.Connection;
050: import org.netbeans.modules.bpel.design.model.patterns.Pattern;
051:
052: /**
053: *
054: * @author anjeleevich
055: */
056: public abstract class VisualElement {
057:
058: protected FShape shape;
059: private FBounds textBounds;
060: private List<Connection> inputConnections = new ArrayList<Connection>();
061: private List<Connection> outputConnections = new ArrayList<Connection>();
062: private String text;
063: private Pattern pattern;
064:
065: public VisualElement(FShape shape) {
066: this .shape = shape;
067: }
068:
069: public void setPattern(Pattern newPattern) {
070: pattern = newPattern;
071: }
072:
073: public Pattern getPattern() {
074: return pattern;
075: }
076:
077: public boolean hasPattern() {
078: return pattern != null;
079: }
080:
081: public void addInputConnection(Connection c) {
082: inputConnections.add(c);
083: }
084:
085: public void addOutputConnection(Connection c) {
086: outputConnections.add(c);
087: }
088:
089: public void removeInputConnection(Connection c) {
090: inputConnections.remove(c);
091: }
092:
093: public void removeOutputConnection(Connection c) {
094: outputConnections.remove(c);
095: }
096:
097: public List<Connection> getIncomingConnections() {
098: return inputConnections;
099: }
100:
101: public List<Connection> getOutcomingConnections() {
102: return outputConnections;
103: }
104:
105: public void setLabelText(String text) {
106: this .text = text;
107: }
108:
109: public String getLabelText() {
110: return text;
111: }
112:
113: public abstract void paint(Graphics2D g2);
114:
115: public abstract void paintThumbnail(Graphics2D g2);
116:
117: public FShape getShape() {
118: return shape;
119: }
120:
121: public FBounds getBounds() {
122: return shape;
123: }
124:
125: public void translate(double tx, double ty) {
126: shape = shape.translate(tx, ty);
127: }
128:
129: public void setLocation(double x0, double y0) {
130: shape = shape.move(x0, y0);
131: }
132:
133: public void setCenter(double cx, double cy) {
134: shape = shape.moveCenter(cx, cy);
135: }
136:
137: public double getX() {
138: return shape.getX();
139: }
140:
141: public double getY() {
142: return shape.getY();
143: }
144:
145: public double getCenterX() {
146: return shape.getCenterX();
147: }
148:
149: public double getCenterY() {
150: return shape.getCenterY();
151: }
152:
153: public double getMinX() {
154: return shape.getMinX();
155: }
156:
157: public double getMinY() {
158: return shape.getMinY();
159: }
160:
161: public double getMaxX() {
162: return shape.getMaxX();
163: }
164:
165: public double getMaxY() {
166: return shape.getMaxY();
167: }
168:
169: public double getWidth() {
170: return shape.getWidth();
171: }
172:
173: public double getHeight() {
174: return shape.getHeight();
175: }
176:
177: public boolean textContains(double x, double y) {
178: return (textBounds != null) && textBounds.contains(x, y);
179: }
180:
181: public boolean contains(double x, double y) {
182: return textContains(x, y) || shape.contains(x, y);
183: }
184:
185: public String getText() {
186: return text;
187: }
188:
189: public void setText(String newText) {
190: text = (newText != null) ? newText.trim() : null;
191: }
192:
193: public boolean isEmptyText() {
194: return (text == null) || (text.length() == 0);
195: }
196:
197: public boolean isTextElement() {
198: return (getPattern() == null) ? false : getPattern()
199: .isTextElement(this );
200: }
201:
202: public boolean isPaintText() {
203: return !isEmptyText();
204: }
205:
206: public Color getTextColor() {
207: Pattern p = getPattern();
208: Decoration decoration = p.getModel().getView().getDecoration(p);
209:
210: TextstyleDescriptor textStyle = (decoration == null) ? null
211: : decoration.getTextstyle();
212:
213: boolean editable = isTextElement();
214:
215: if (textStyle == null) {
216: return (editable) ? ViewProperties.EDITABLE_TEXT_COLOR
217: : ViewProperties.UNEDITABLE_TEXT_COLOR;
218: } else {
219: return (editable) ? textStyle.getEditableTextColor()
220: : textStyle.getNotEditableTextColor();
221: }
222: }
223:
224: protected void drawString(Graphics2D g2, String string, double x,
225: double y, double width) {
226: if (string == null || string.length() == 0) {
227: setTextBounds(null);
228: }
229:
230: string = clipString(string, g2, width);
231:
232: Rectangle2D bounds = g2.getFont().getStringBounds(string,
233: g2.getFontRenderContext());
234:
235: double w = bounds.getWidth();
236: double h = bounds.getHeight();
237:
238: double tx = x - bounds.getX();
239: double ty = y - bounds.getY();
240:
241: g2.translate(tx, ty);
242: g2.drawString(string, 0, 0);
243: g2.translate(-tx, -ty);
244:
245: setTextBounds(new FBounds(tx, ty + bounds.getY(), w, h));
246: }
247:
248: protected void drawXCenteredString(Graphics2D g2, String string,
249: double cx, double y, double width) {
250: if (string == null || string.length() == 0) {
251: setTextBounds(null);
252: }
253:
254: string = clipString(string, g2, width);
255:
256: Rectangle2D bounds = g2.getFont().getStringBounds(string,
257: g2.getFontRenderContext());
258:
259: double w = bounds.getWidth();
260: double h = bounds.getHeight();
261:
262: double tx = cx - w / 2.0 - bounds.getX();
263: double ty = y - bounds.getY();
264:
265: g2.translate(tx, ty);
266: g2.drawString(string, 0, 0);
267: g2.translate(-tx, -ty);
268:
269: setTextBounds(new FBounds(tx, ty + bounds.getY(), w, h));
270: }
271:
272: protected void drawCenteredString(Graphics2D g2, String string,
273: double cx, double cy, double width) {
274: if (string == null || string.length() == 0) {
275: setTextBounds(null);
276: }
277:
278: string = clipString(string, g2, width);
279:
280: Rectangle2D bounds = g2.getFont().getStringBounds(string,
281: g2.getFontRenderContext());
282:
283: double w = bounds.getWidth();
284: double h = bounds.getHeight();
285:
286: double tx = cx - w / 2.0 - bounds.getX();
287: double ty = cy - h / 2.0 - bounds.getY();
288:
289: g2.translate(tx, ty);
290: g2.drawString(string, 0, 0);
291: g2.translate(-tx, -ty);
292:
293: setTextBounds(new FBounds(tx, ty + bounds.getY(), w, h));
294: }
295:
296: private static String clipString(String string, Graphics2D g2,
297: double clipWidth) {
298: Font font = g2.getFont();
299: FontRenderContext frc = g2.getFontRenderContext();
300:
301: double stringWidth = font.getStringBounds(string, frc)
302: .getWidth();
303:
304: if (stringWidth <= clipWidth) {
305: return string;
306: }
307:
308: clipWidth -= font.getStringBounds("...", frc).getWidth();
309:
310: if (clipWidth <= 0.0) {
311: return "...";
312: }
313:
314: int i = string.length();
315:
316: do {
317: i--;
318: stringWidth -= font.getStringBounds(
319: string.substring(i, i + 1), frc).getWidth();
320: } while (stringWidth > clipWidth && i > 0);
321:
322: return string.substring(0, i) + "...";
323: }
324:
325: public static double getScale(AffineTransform at) {
326: if (at == null) {
327: return 1.0;
328: }
329:
330: double coords[] = { 1, 1 };
331: at.deltaTransform(coords, 0, coords, 0, 1);
332:
333: double x = coords[0];
334: double y = coords[1];
335:
336: return Math.sqrt(x * x + y * y) / 2.0;
337: }
338:
339: private static final double COS_45 = Math.sqrt(2.0) / 2.0;
340: public static final Color GRADIENT_TEXTURE_COLOR = new Color(
341: 0xE7ECF4);
342: public static final BufferedImage GRADIENT_TEXTURE;
343: static {
344: double[] percents = { 0, 0.0843, 0.1798, 0.7416, 0.9045, 1.0674 };
345: int[] rgbColors = { 0xA9CDE8, 0xDDEBF6, 0xFFFFFF, 0xDCE3EF,
346: 0xE7F1F9, 0xDCE3EF };
347:
348: final int height = 100;
349:
350: BufferedImage image = new BufferedImage(1, height,
351: BufferedImage.TYPE_INT_RGB);
352:
353: Graphics2D g2 = (Graphics2D) image.getGraphics();
354:
355: g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
356: RenderingHints.VALUE_ANTIALIAS_ON);
357:
358: Rectangle2D.Float rect = new Rectangle2D.Float(0, 0, 1, height);
359:
360: for (int i = 1; i < percents.length; i++) {
361: float y0 = (float) (percents[i - 1] * height - 0.5);
362: float y1 = (float) (percents[i] * height + 0.5);
363:
364: rect.y = y0;
365: rect.height = y1 - y0;
366:
367: Paint p = new GradientPaint(0, y0, new Color(
368: rgbColors[i - 1]), 0, y1, new Color(rgbColors[i]));
369:
370: g2.setPaint(p);
371: g2.fill(rect);
372: }
373:
374: GRADIENT_TEXTURE = image;
375: }
376:
377: public FBounds getTextBounds() {
378: if (isEmptyText()) {
379: return null;
380: }
381: return textBounds;
382: }
383:
384: protected void setTextBounds(FBounds textBounds) {
385: this .textBounds = textBounds;
386: }
387:
388: public List<Connection> getAllConnections() {
389: List<Connection> result = new ArrayList<Connection>();
390: result.addAll(inputConnections);
391: result.addAll(outputConnections);
392: return result;
393: }
394: /*
395: public void scrollTo() {
396: DesignView view = getPattern().getModel().getView();
397: FBounds bounds = getTextBounds();
398: Rectangle rect;
399: Point p1,
400: p2;
401:
402: if (bounds == null) {
403: FShape shape = getShape();
404: rect = view.getVisibleRect();
405: double y0;
406: double y1;
407: double x;
408:
409: if (this instanceof ContentElement) {
410: y0 = shape.getMaxY();
411: y1 = y0 + 24;
412: x = shape.getCenterX();
413: p1 = view.convertDiagramToScreen(new FPoint(x, y0));
414: p2 = view.convertDiagramToScreen(new FPoint(x, y1));
415: rect.x = p1.x - rect.width / 2;
416: rect.y = p1.y;
417: rect.height = p2.y - p1.y;
418: } else if (this instanceof ProcessBorder) {
419: y0 = shape.getY();
420: y1 = y0 + 32;
421: x = shape.getCenterX();
422: p1 = view.convertDiagramToScreen(new FPoint(x, y0));
423: p2 = view.convertDiagramToScreen(new FPoint(x, y1));
424: rect.x = p1.x - rect.width / 2;
425: rect.y = p1.y;
426: rect.height = p2.y - p1.y;
427: } else {
428: y0 = shape.getY();
429: y1 = y0 + 24;
430: x = shape.getX();
431: p1 = view.convertDiagramToScreen(new FPoint(x, y0));
432: p2 = view.convertDiagramToScreen(new FPoint(x, y1));
433: rect.x = p1.x - 24;
434: rect.y = p1.y;
435: rect.height = p2.y - p1.y;
436: }
437: } else {
438: p1 = view.convertDiagramToScreen(bounds.getTopLeft());
439: p2 = view.convertDiagramToScreen(bounds.getBottomRight());
440: int width = p2.x - p1.x + 48;
441: int height = p2.y - p1.y;
442: rect = new Rectangle(p1.x - 24, p1.y, width, height);
443: }
444: rect.y -= 24;
445: rect.height += 48;
446: view.scrollRectToVisible(rect);
447: }
448: */
449: }
|