001: /*
002: * uDig - User Friendly Desktop Internet GIS client
003: * http://udig.refractions.net
004: * (C) 2004, Refractions Research Inc.
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package net.refractions.udig.printing.ui.internal.editor.figures;
018:
019: import java.awt.Graphics2D;
020: import java.awt.image.BufferedImage;
021: import java.awt.image.RenderedImage;
022:
023: import net.refractions.udig.printing.model.Box;
024: import net.refractions.udig.ui.PlatformGIS;
025: import net.refractions.udig.ui.graphics.SWTGraphics;
026:
027: import org.eclipse.core.runtime.IProgressMonitor;
028: import org.eclipse.core.runtime.IStatus;
029: import org.eclipse.core.runtime.Status;
030: import org.eclipse.core.runtime.jobs.IJobChangeEvent;
031: import org.eclipse.core.runtime.jobs.IJobChangeListener;
032: import org.eclipse.core.runtime.jobs.Job;
033: import org.eclipse.core.runtime.jobs.JobChangeAdapter;
034: import org.eclipse.draw2d.Figure;
035: import org.eclipse.draw2d.Graphics;
036: import org.eclipse.draw2d.Label;
037: import org.eclipse.draw2d.RectangleFigure;
038: import org.eclipse.draw2d.geometry.Rectangle;
039: import org.eclipse.swt.SWT;
040: import org.eclipse.swt.graphics.Color;
041: import org.eclipse.swt.graphics.Image;
042: import org.eclipse.swt.widgets.Display;
043: import org.eclipse.ui.PlatformUI;
044:
045: /**
046: * Draws LabelBoxes
047: *
048: * @author Richard Gould
049: * @since 0.3
050: */
051: public class BoxFigure extends Figure {
052: private Box box;
053:
054: private RectangleFigure rectangleFigure;
055: private Label label;
056:
057: public BoxFigure() {
058: this .rectangleFigure = new RectangleFigure();
059: this .label = new Label();
060: this .add(rectangleFigure);
061: this .add(label);
062: setOpaque(false);
063: }
064:
065: public String getText() {
066: return this .label.getText();
067: }
068:
069: public Rectangle getTextBounds() {
070: return this .label.getTextBounds();
071: }
072:
073: public void setName(String name) {
074: this .label.setText(name);
075: this .repaint();
076: }
077:
078: public void setBox(Box box) {
079: this .box = box;
080: this .repaint();
081: }
082:
083: public void setBounds(Rectangle rect) {
084: super .setBounds(rect);
085: this .rectangleFigure.setBounds(rect);
086: this .label.setBounds(rect);
087: }
088:
089: protected void paintFigure(Graphics graphics) {
090: super .paintFigure(graphics);
091: }
092:
093: PreviewJob drawJob = new PreviewJob();
094:
095: boolean rendering = false;
096: private IJobChangeListener listener = new JobChangeAdapter() {
097:
098: @Override
099: public void scheduled(IJobChangeEvent event) {
100: rendering = true;
101: }
102:
103: public void done(IJobChangeEvent event) {
104: rendering = false;
105: if (PlatformUI.getWorkbench().isClosing())
106: return;
107:
108: Display.getDefault().asyncExec(new Runnable() {
109: public void run() {
110: repaint();
111: }
112: });
113: }
114: };
115:
116: protected void paintClientArea(Graphics graphics) {
117: if (box.getSize().width < 1 || box.getSize().height < 1)
118: return;
119:
120: drawJob.addJobChangeListener(listener);
121: graphics.translate(this .getLocation().x, this .getLocation().y);
122:
123: if (box.getBoxPrinter() == null)
124: return;
125:
126: if ((!box.getBoxPrinter().isNewPreviewNeeded() && drawJob
127: .getCacheImage() != null)
128: || (drawJob.getDraws() > 5 && drawJob.getCacheImage() != null)) {
129: drawJob.setDraws(0);
130: // on the Draw2D graphics context
131: graphics.drawImage(drawJob.getCacheImage(), 0, 0);
132: } else {
133: // gets the Graphics2D context
134: if (!rendering) {
135: drawJob.clearCache();
136: drawJob.setDisplay(Display.getCurrent());
137: drawJob.setBox(box);
138: drawJob.schedule();
139: }
140: String message = "Rendering Preview";
141: Color color = graphics.getBackgroundColor();
142: graphics.setBackgroundColor(Display.getCurrent()
143: .getSystemColor(SWT.COLOR_GRAY));
144: graphics.fillRectangle(0, 0, box.getSize().width - 1, box
145: .getSize().height - 1);
146: graphics.setBackgroundColor(color);
147: graphics.setForegroundColor(Display.getCurrent()
148: .getSystemColor(SWT.COLOR_BLACK));
149: graphics.drawRectangle(0, 0, box.getSize().width - 1, box
150: .getSize().height - 1);
151: int fontHeight = graphics.getFontMetrics().getHeight();
152: int fontWidth = graphics.getFontMetrics()
153: .getAverageCharWidth()
154: * message.length();
155: graphics.drawText(message, box.getSize().width / 2
156: - fontWidth, box.getSize().height / 2 - fontHeight);
157: }
158:
159: }
160:
161: private static class PreviewJob extends Job {
162:
163: private Box box;
164: private Display display;
165: private Image cacheImage;
166: private int draws = 0;
167:
168: public synchronized void setBox(Box box) {
169: this .box = box;
170: }
171:
172: public void clearCache() {
173: if (cacheImage != null)
174: cacheImage.dispose();
175: cacheImage = null;
176: }
177:
178: PreviewJob() {
179: super ("Preview Job");
180: }
181:
182: public synchronized void setDisplay(Display display2) {
183: this .display = display2;
184: }
185:
186: public synchronized Image getCacheImage() {
187: return cacheImage;
188: }
189:
190: protected IStatus run(IProgressMonitor monitor) {
191: int width = box.getSize().width;
192: int height = box.getSize().height;
193: BufferedImage image = new BufferedImage(width, height,
194: BufferedImage.TYPE_3BYTE_BGR);
195: // does the Java 2D painting
196: Graphics2D createGraphics = image.createGraphics();
197: createGraphics.setBackground(java.awt.Color.WHITE);
198: createGraphics.clearRect(0, 0, width, height);
199: box.getBoxPrinter().createPreview(createGraphics, monitor);
200:
201: ImageRunnable runnable = new ImageRunnable();
202: runnable.image = image;
203:
204: PlatformGIS.syncInDisplayThread(runnable);
205:
206: synchronized (this ) {
207: this .cacheImage = runnable.swtImage;
208: draws++;
209: }
210: return Status.OK_STATUS;
211: }
212:
213: private class ImageRunnable implements Runnable {
214:
215: Image swtImage;
216: private RenderedImage image;
217:
218: public void run() {
219: swtImage = SWTGraphics.createSWTImage(image, true);
220: }
221:
222: }
223:
224: /**
225: * @return Returns the draws.
226: */
227: public synchronized int getDraws() {
228: return draws;
229: }
230:
231: /**
232: * @param draws The draws to set.
233: */
234: public synchronized void setDraws(int draws) {
235: this.draws = draws;
236: }
237:
238: }
239:
240: }
|