001: /**
002: * ========================================
003: * JFreeReport : a free Java report library
004: * ========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
009: *
010: * This library is free software; you can redistribute it and/or modify it under the terms
011: * of the GNU Lesser General Public License as published by the Free Software Foundation;
012: * either version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: * See the GNU Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License along with this
019: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: *
022: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023: * in the United States and other countries.]
024: *
025: * ------------
026: * $Id: ComponentDrawable.java 3525 2007-10-16 11:43:48Z tmorgner $
027: * ------------
028: * (C) Copyright 2000-2005, by Object Refinery Limited.
029: * (C) Copyright 2005-2007, by Pentaho Corporation.
030: */package org.jfree.report.util;
031:
032: import java.awt.Component;
033: import java.awt.Dimension;
034: import java.awt.Graphics2D;
035: import java.awt.Window;
036: import java.awt.geom.Rectangle2D;
037: import javax.swing.JComponent;
038: import javax.swing.JFrame;
039: import javax.swing.JPanel;
040: import javax.swing.RepaintManager;
041: import javax.swing.SwingUtilities;
042:
043: import org.jfree.ui.ExtendedDrawable;
044: import org.jfree.util.Log;
045:
046: /**
047: * Creation-Date: 11.10.2005, 14:03:15
048: *
049: * @author Thomas Morgner
050: */
051: public class ComponentDrawable implements ExtendedDrawable {
052: private class PainterRunnable implements Runnable {
053: private Rectangle2D area;
054: private Graphics2D graphics;
055:
056: private PainterRunnable() {
057: }
058:
059: public Graphics2D getGraphics() {
060: return graphics;
061: }
062:
063: public void setGraphics(final Graphics2D graphics) {
064: this .graphics = graphics;
065: }
066:
067: public Rectangle2D getArea() {
068: return area;
069: }
070:
071: public void setArea(final Rectangle2D area) {
072: this .area = area;
073: }
074:
075: public void run() {
076: if (component instanceof Window) {
077: component.addNotify();
078: } else if (isOwnPeerConnected()) {
079: final Window w = getWindowAncestor(component);
080: w.validate();
081: } else {
082: peerSupply.pack();
083: contentPane.add(component);
084: }
085:
086: component.setBounds((int) area.getX(), (int) area.getY(),
087: (int) area.getWidth(), (int) area.getHeight());
088: component.validate();
089: component.paint(graphics);
090:
091: }
092: }
093:
094: private boolean preserveAspectRatio;
095: private Component component;
096: private JFrame peerSupply;
097: private JPanel contentPane;
098: private PainterRunnable runnable;
099: private boolean paintSynchronously;
100: private boolean allowOwnPeer;
101:
102: public ComponentDrawable() {
103: peerSupply = new JFrame();
104: peerSupply.pack(); // add a peer ...
105: contentPane = new JPanel();
106: contentPane.setLayout(null);
107: peerSupply.setContentPane(contentPane);
108: runnable = new PainterRunnable();
109: }
110:
111: public boolean isAllowOwnPeer() {
112: return allowOwnPeer;
113: }
114:
115: public void setAllowOwnPeer(final boolean allowOwnPeer) {
116: this .allowOwnPeer = allowOwnPeer;
117: }
118:
119: public boolean isPaintSynchronously() {
120: return paintSynchronously;
121: }
122:
123: public void setPaintSynchronously(final boolean paintSynchronously) {
124: this .paintSynchronously = paintSynchronously;
125: }
126:
127: private void cleanUp() {
128: if (component instanceof JComponent
129: && isOwnPeerConnected() == false) {
130: final JComponent jc = (JComponent) component;
131: RepaintManager.currentManager(jc)
132: .removeInvalidComponent(jc);
133: RepaintManager.currentManager(jc).markCompletelyClean(jc);
134: }
135: contentPane.removeAll();
136: RepaintManager.currentManager(contentPane)
137: .removeInvalidComponent(contentPane);
138: RepaintManager.currentManager(contentPane).markCompletelyClean(
139: contentPane);
140: peerSupply.dispose();
141: }
142:
143: public Component getComponent() {
144: return component;
145: }
146:
147: public void setComponent(final Component component) {
148: this .component = component;
149: prepareComponent(component);
150: }
151:
152: public synchronized Dimension getPreferredSize() {
153: if (component == null) {
154: return new Dimension(0, 0);
155: }
156: if (component instanceof Window == false
157: && isOwnPeerConnected() == false) {
158: peerSupply.pack();
159: contentPane.add(component);
160: contentPane.validate();
161: component.validate();
162: } else if (isOwnPeerConnected()) {
163: return component.getSize();
164: } else {
165: component.validate();
166: }
167: final Dimension retval = component.getPreferredSize();
168: cleanUp();
169: return retval;
170: }
171:
172: private boolean isOwnPeerConnected() {
173: if (allowOwnPeer == false) {
174: return false;
175: }
176: final Window windowAncestor = getWindowAncestor(component);
177: return (windowAncestor != null && windowAncestor != peerSupply);
178: }
179:
180: protected static Window getWindowAncestor(final Component component) {
181: Component parent = component.getParent();
182: while (parent != null) {
183: if (parent instanceof Window) {
184: return (Window) parent;
185: }
186: parent = parent.getParent();
187: }
188: return null;
189: }
190:
191: public void setPreserveAspectRatio(final boolean preserveAspectRatio) {
192: this .preserveAspectRatio = preserveAspectRatio;
193: }
194:
195: public boolean isPreserveAspectRatio() {
196: return preserveAspectRatio;
197: }
198:
199: public synchronized void draw(final Graphics2D g2,
200: final Rectangle2D area) {
201: if (component == null) {
202: return;
203: }
204:
205: runnable.setArea(area);
206: runnable.setGraphics(g2);
207:
208: if (SwingUtilities.isEventDispatchThread()
209: || paintSynchronously == false) {
210: runnable.run();
211: } else {
212: try {
213: SwingUtilities.invokeAndWait(runnable);
214: } catch (Exception e) {
215: Log.warn("Failed to redraw the component.");
216: }
217: }
218:
219: cleanUp();
220: }
221:
222: private void prepareComponent(final Component c) {
223: if (c instanceof JComponent) {
224: final JComponent jc = (JComponent) c;
225: jc.setDoubleBuffered(false);
226: final Component[] childs = jc.getComponents();
227: for (int i = 0; i < childs.length; i++) {
228: final Component child = childs[i];
229: prepareComponent(child);
230: }
231: }
232: }
233: }
|