001: package com.xoetrope.carousel.survey;
002:
003: import java.awt.Color;
004: import java.awt.Component;
005: import java.awt.Dimension;
006: import java.awt.Font;
007: import java.awt.Graphics;
008: import java.awt.Graphics2D;
009: import java.awt.Point;
010: import java.awt.RenderingHints;
011: import java.awt.Shape;
012: import java.awt.event.MouseEvent;
013: import java.awt.event.MouseListener;
014: import java.awt.event.MouseMotionListener;
015: import java.awt.geom.Rectangle2D;
016: import java.util.Observable;
017: import java.util.Observer;
018: import javax.swing.JComponent;
019: import javax.swing.JLayeredPane;
020: import javax.swing.JPopupMenu;
021: import net.xoetrope.xui.XProject;
022: import net.xoetrope.xui.XProjectManager;
023:
024: /**
025: * A super class for question view and condition view, handles dragging, changing scale, etc.
026: *
027: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
028: * the GNU Public License (GPL), please see license.txt for more details. If
029: * you make commercial use of this software you must purchase a commercial
030: * license from Xoetrope.</p>
031: * <p> $Revision: 1.5 $</p>
032: */
033: public abstract class XSurveyComponentSmall extends JComponent
034: implements MouseListener, MouseMotionListener {
035: public Color BACKGROUND_COLOR = Color.WHITE;
036: public Color BORDER_COLOR = Color.BLACK;
037: public Color SELECTED_COLOR = new Color(240, 240, 0);
038:
039: public static int WIDTH = 100;
040: public static int HEIGHT = 30;
041: public static int TOP_GAP = 2;
042: public static int BOTTOM_GAP = 2;
043: public static int LEFT_GAP = 2;
044: public static int RIGHT_GAP = 2;
045: public static int FONT_STYLE = 0;
046: public static int FONT_SIZE = 12;
047: public static String FONT_NAME = "Dialog";
048: public static Color FONT_COLOR = Color.BLACK;
049:
050: protected int width, height;
051: protected int leftGap, rightGap, topGap, bottomGap;
052: protected int posX, posY;
053: protected Color backgroundColor, borderColor, selectedColor;
054: protected Shape shape;
055: protected XRulesEditorPane editorPane;
056: protected XSurveyComponentBig owner;
057: protected XSurveyComponentBig prevOwner;
058: protected int prevPosition;
059: protected int fontStyle, fontSize;
060: protected String fontName;
061: protected Font font;
062: protected Color fontColor;
063: protected boolean isDragged;
064: protected MouseEvent firstMouseEvent;
065: protected JPopupMenu popupMenu;
066: protected XSurveyEditorFrame editorFrame;
067: protected boolean isSelected;
068: protected Observer selectionObserver;
069:
070: public XSurveyComponentSmall(XRulesEditorPane ep,
071: XSurveyComponentBig o) {
072: super ();
073: editorPane = ep;
074: selectionObserver = editorPane.getSelectionObserver();
075: owner = o;
076: popupMenu = null;
077: setLayout(null);
078: initVariables();
079: setSize();
080: editorPane.add(this , JLayeredPane.PALETTE_LAYER);
081: addMouseListener(this );
082: addMouseMotionListener(this );
083: addMouseListener(editorPane.getChangesSaver());
084: createPopupMenu();
085: moveToFront();
086: }
087:
088: public XSurveyComponentSmall(XRulesEditorPane ep) {
089: this (ep, null);
090: }
091:
092: protected abstract void createShape();
093:
094: protected abstract Class getOwnerClass();
095:
096: protected abstract void createPopupMenu();
097:
098: protected abstract void updateModel(XSurveyComponentBig oldOwner,
099: XSurveyComponentBig newOwner);
100:
101: protected boolean draggingAllowed(XSurveyComponentBig view) {
102: return view.isExpanded();
103: }
104:
105: public boolean isSelected() {
106: return isSelected;
107: }
108:
109: public void isSelected(boolean state) {
110: if (isSelected == state)
111: return;
112: isSelected = state;
113: if (isSelected())
114: selectionObserver.update(null, this );
115: }
116:
117: public void remove() {
118: if (owner != null)
119: owner.removeComponent(this );
120: editorPane.remove(this );
121: }
122:
123: protected double getScale() {
124: return XRulesEditorPane.SCALE;
125: }
126:
127: protected void showPopupMenu(Point p) {
128: if (popupMenu != null) {
129: popupMenu.show(this , p.x, p.y);
130: }
131: }
132:
133: protected void initVariables() {
134: XProject project = XProjectManager.getCurrentProject();
135: editorFrame = (XSurveyEditorFrame) project
136: .getObject("EditorFrame");
137:
138: width = WIDTH;
139: height = HEIGHT;
140: backgroundColor = BACKGROUND_COLOR;
141: borderColor = BORDER_COLOR;
142: shape = null;
143: isDragged = false;
144: fontName = FONT_NAME;
145: fontStyle = FONT_STYLE;
146: fontSize = FONT_SIZE;
147: fontColor = FONT_COLOR;
148: leftGap = LEFT_GAP;
149: rightGap = RIGHT_GAP;
150: topGap = TOP_GAP;
151: bottomGap = BOTTOM_GAP;
152: prevOwner = null;
153: prevPosition = -1;
154: posX = 0;
155: posY = 0;
156: selectedColor = SELECTED_COLOR;
157: }
158:
159: public void refresh() {
160: setSize();
161: repaint();
162: }
163:
164: protected void setSize() {
165: Dimension size = new Dimension(getWidth(), getHeight());
166: setSize(size);
167: setMinimumSize(size);
168: setPreferredSize(size);
169: createShape();
170: }
171:
172: protected void setLocation() {
173: int x = getPosX();
174: int y = getPosY();
175: super .setLocation(x, y);
176: }
177:
178: public boolean contains(int x, int y) {
179: return (shape != null && shape.contains(x, y));
180: }
181:
182: public Color getBackgroundColor() {
183: return (isSelected ? selectedColor : backgroundColor);
184: }
185:
186: public String getTruncatedText(String desc, int width,
187: Graphics2D g, Font font) {
188: String truncDesc = "";
189:
190: Rectangle2D rc = font.getStringBounds(desc, g
191: .getFontRenderContext());
192: if (rc.getWidth() > width) {
193: do {
194: int eidx = (desc.length() > 0 ? desc.length() - 1 : 0);
195: desc = desc.substring(0, eidx);
196: truncDesc = desc + "...";
197: rc = font.getStringBounds(truncDesc, g
198: .getFontRenderContext());
199: } while (rc.getWidth() > width && desc.length() > 0);
200: } else {
201: truncDesc = desc;
202: }
203: return truncDesc;
204: }
205:
206: public void setBackgroundColor(Color bc) {
207: backgroundColor = bc;
208: }
209:
210: public Color getBorderColor() {
211: return borderColor;
212: }
213:
214: public void setBorderColor(Color bc) {
215: borderColor = bc;
216: }
217:
218: public int getWidth() {
219: return (int) (getScale() * width);
220: }
221:
222: public void setWidth(int w) {
223: width = (int) ((double) w / getScale());
224: }
225:
226: public int getHeight() {
227: return (int) (getScale() * height);
228: }
229:
230: public void setHeight(int h) {
231: height = (int) ((double) h / getScale());
232: }
233:
234: public int getLeftGap() {
235: return (int) (getScale() * leftGap);
236: }
237:
238: public void setLeftGap(int lg) {
239: leftGap = (int) ((double) lg / getScale());
240: }
241:
242: public int getRightGap() {
243: return (int) (getScale() * rightGap);
244: }
245:
246: public void setRightGap(int rg) {
247: rightGap = (int) ((double) rg / getScale());
248: }
249:
250: public int getTopGap() {
251: return (int) (getScale() * topGap);
252: }
253:
254: public void setTopGap(int tg) {
255: topGap = (int) ((double) tg / getScale());
256: }
257:
258: public int getBottomGap() {
259: return (int) (getScale() * bottomGap);
260: }
261:
262: public void setBottomGap(int bg) {
263: bottomGap = (int) ((double) bg / getScale());
264: }
265:
266: public boolean isDragged() {
267: return isDragged;
268: }
269:
270: public int getFontStyle() {
271: return fontStyle;
272: }
273:
274: public void setFontStyle(int fs) {
275: fontStyle = fs;
276: }
277:
278: public int getFontSize() {
279: return (int) (getScale() * fontSize);
280: }
281:
282: public void setFontSize(int fs) {
283: fontSize = fs;
284: }
285:
286: public String getFontName() {
287: return fontName;
288: }
289:
290: public void setFontName(String fn) {
291: fontName = fn;
292: }
293:
294: public Color getFontColor() {
295: return fontColor;
296: }
297:
298: public void setFontColor(Color fc) {
299: fontColor = fc;
300: }
301:
302: public Font getFont() {
303: return new Font(getFontName(), getFontStyle(), getFontSize());
304: }
305:
306: public int getPosX() {
307: return (int) (getScale() * posX);
308: }
309:
310: public void setPosX(int px) {
311: posX = (int) ((double) px / getScale());
312: }
313:
314: public void setPosY(int py) {
315: posY = (int) ((double) py / getScale());
316: }
317:
318: public int getPosY() {
319: return (int) (getScale() * posY);
320: }
321:
322: public void paintShape(Graphics2D g) {
323: g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
324: RenderingHints.VALUE_ANTIALIAS_ON);
325: g.setColor(backgroundColor);
326: g.fill(shape);
327: g.setColor(borderColor);
328: g.draw(shape);
329: }
330:
331: public void moveToFront() {
332: editorPane.moveToFront(this );
333: }
334:
335: public void setLocation(int x, int y) {
336: setPosX(x);
337: setPosY(y);
338: super .setLocation(x, y);
339: }
340:
341: protected void startDragging(MouseEvent e) {
342: firstMouseEvent = e;
343: isDragged = true;
344: prevOwner = owner;
345: prevPosition = (owner != null ? owner.getComponentIdx(this )
346: : -1);
347: }
348:
349: protected void endDragging(MouseEvent e) {
350: if (!isDragged)
351: return;
352:
353: isDragged = false;
354: firstMouseEvent = null;
355:
356: if ((owner == null) && (prevOwner != null)
357: && (prevPosition >= 0)) {
358: owner = prevOwner;
359: owner.insertComponent(this , prevPosition);
360: owner.refreshComponents();
361: }
362:
363: if (owner != null)
364: owner.refreshComponents();
365: else if (owner == null)
366: remove();
367:
368: updateModel(prevOwner, owner);
369: }
370:
371: public void mouseClicked(MouseEvent e) {
372: }
373:
374: public void mousePressed(MouseEvent e) {
375: editorPane.selectAllComponents(false);
376: owner.isSelected(true);
377: isSelected(true);
378: owner.repaint();
379: repaint();
380: moveToFront();
381: firstMouseEvent = e;
382: if (e.getButton() == MouseEvent.BUTTON3)
383: showPopupMenu(e.getPoint());
384: }
385:
386: public void mouseReleased(MouseEvent e) {
387: endDragging(e);
388: }
389:
390: public void mouseEntered(MouseEvent e) {
391: }
392:
393: public void mouseExited(MouseEvent e) {
394: }
395:
396: public void setFirstMouseEvent(MouseEvent e) {
397: firstMouseEvent = e;
398: }
399:
400: protected void drag(MouseEvent e) {
401: if (firstMouseEvent == null)
402: return;
403:
404: if (!isDragged())
405: startDragging(e);
406:
407: int dx = (int) (e.getX() - firstMouseEvent.getX());
408: int dy = (int) (e.getY() - firstMouseEvent.getY());
409:
410: int x = getLocation().x + dx;
411: int y = getLocation().y + dy;
412: setLocation(x, y);
413:
414: Component c = editorPane.getIntersectedView(getBounds(),
415: getOwnerClass());
416: XSurveyComponentBig intersectedView = (XSurveyComponentBig) c;
417:
418: if (intersectedView != null
419: && !draggingAllowed(intersectedView))
420: intersectedView = null;
421:
422: if (intersectedView == null) {
423: if (owner != null) {
424: owner.removeComponent(this );
425: owner.refreshComponents();
426: }
427: owner = null;
428: } else if (!intersectedView.equals(owner)) {
429: if (owner != null) {
430: owner.removeComponent(this );
431: owner.refreshComponents();
432: }
433: owner = (intersectedView.insertComponent(this ) ? intersectedView
434: : null);
435: } else {
436: owner = (intersectedView.moveComponentView(this ) ? intersectedView
437: : null);
438: }
439: moveToFront();
440: }
441:
442: public void mouseDragged(MouseEvent e) {
443: drag(e);
444: }
445:
446: public void mouseMoved(MouseEvent e) {
447: }
448:
449: public Color getSelectedColor() {
450: return selectedColor;
451: }
452:
453: }
|