1:
31:
32: package ;
33:
34: import ;
35: import ;
36: import ;
37: import ;
38: import ;
39: import ;
40: import ;
41: import ;
42: import ;
43: import ;
44:
45: import ;
46: import ;
47:
48:
53: public class ComponentDrawable implements ExtendedDrawable
54: {
55: private class PainterRunnable implements Runnable
56: {
57: private Rectangle2D area;
58: private Graphics2D graphics;
59:
60: private PainterRunnable()
61: {
62: }
63:
64: public Graphics2D getGraphics()
65: {
66: return graphics;
67: }
68:
69: public void setGraphics(final Graphics2D graphics)
70: {
71: this.graphics = graphics;
72: }
73:
74: public Rectangle2D getArea()
75: {
76: return area;
77: }
78:
79: public void setArea(final Rectangle2D area)
80: {
81: this.area = area;
82: }
83:
84: public void run()
85: {
86: if (component instanceof Window)
87: {
88: component.addNotify();
89: }
90: else if (isOwnPeerConnected())
91: {
92: final Window w = getWindowAncestor(component);
93: w.validate();
94: }
95: else
96: {
97: peerSupply.pack();
98: contentPane.add(component);
99: }
100:
101: component.setBounds
102: ((int) area.getX(), (int) area.getY(),
103: (int) area.getWidth(), (int) area.getHeight());
104: component.validate();
105: component.paint(graphics);
106:
107: }
108: }
109:
110: private boolean preserveAspectRatio;
111: private Component component;
112: private JFrame peerSupply;
113: private JPanel contentPane;
114: private PainterRunnable runnable;
115: private boolean paintSynchronously;
116: private boolean allowOwnPeer;
117:
118: public ComponentDrawable()
119: {
120: peerSupply = new JFrame();
121: peerSupply.pack();
122: contentPane = new JPanel();
123: contentPane.setLayout(null);
124: peerSupply.setContentPane(contentPane);
125: runnable = new PainterRunnable();
126: }
127:
128: public boolean isAllowOwnPeer()
129: {
130: return allowOwnPeer;
131: }
132:
133: public void setAllowOwnPeer(final boolean allowOwnPeer)
134: {
135: this.allowOwnPeer = allowOwnPeer;
136: }
137:
138: public boolean isPaintSynchronously()
139: {
140: return paintSynchronously;
141: }
142:
143: public void setPaintSynchronously(final boolean paintSynchronously)
144: {
145: this.paintSynchronously = paintSynchronously;
146: }
147:
148: private void cleanUp ()
149: {
150: if (component instanceof JComponent && isOwnPeerConnected() == false)
151: {
152: final JComponent jc = (JComponent) component;
153: RepaintManager.currentManager(jc).removeInvalidComponent(jc);
154: RepaintManager.currentManager(jc).markCompletelyClean(jc);
155: }
156: contentPane.removeAll();
157: RepaintManager.currentManager(contentPane).removeInvalidComponent(contentPane);
158: RepaintManager.currentManager(contentPane).markCompletelyClean(contentPane);
159: peerSupply.dispose();
160: }
161:
162: public Component getComponent()
163: {
164: return component;
165: }
166:
167: public void setComponent(final Component component)
168: {
169: this.component = component;
170: prepareComponent(component);
171: }
172:
173: public synchronized Dimension getPreferredSize()
174: {
175: if (component == null)
176: {
177: return new Dimension(0,0);
178: }
179: if (component instanceof Window == false &&
180: isOwnPeerConnected() == false)
181: {
182: peerSupply.pack();
183: contentPane.add(component);
184: contentPane.validate();
185: component.validate();
186: }
187: else if (isOwnPeerConnected())
188: {
189: return component.getSize();
190: }
191: else
192: {
193: component.validate();
194: }
195: final Dimension retval = component.getPreferredSize();
196: cleanUp();
197: return retval;
198: }
199:
200: private boolean isOwnPeerConnected()
201: {
202: if (allowOwnPeer == false)
203: {
204: return false;
205: }
206: final Window windowAncestor = getWindowAncestor(component);
207: return (windowAncestor != null && windowAncestor != peerSupply);
208: }
209:
210: protected static Window getWindowAncestor(final Component component)
211: {
212: Component parent = component.getParent();
213: while (parent != null)
214: {
215: if (parent instanceof Window)
216: {
217: return (Window) parent;
218: }
219: parent = parent.getParent();
220: }
221: return null;
222: }
223:
224: public void setPreserveAspectRatio(final boolean preserveAspectRatio)
225: {
226: this.preserveAspectRatio = preserveAspectRatio;
227: }
228:
229: public boolean isPreserveAspectRatio()
230: {
231: return preserveAspectRatio;
232: }
233:
234: public synchronized void draw(final Graphics2D g2, final Rectangle2D area)
235: {
236: if (component == null)
237: {
238: return;
239: }
240:
241: runnable.setArea(area);
242: runnable.setGraphics(g2);
243:
244: if (SwingUtilities.isEventDispatchThread() || paintSynchronously == false)
245: {
246: runnable.run();
247: }
248: else
249: {
250: try
251: {
252: SwingUtilities.invokeAndWait(runnable);
253: }
254: catch (Exception e)
255: {
256: Log.warn ("Failed to redraw the component.");
257: }
258: }
259:
260: cleanUp();
261: }
262:
263: private void prepareComponent (final Component c)
264: {
265: if (c instanceof JComponent)
266: {
267: final JComponent jc = (JComponent) c;
268: jc.setDoubleBuffered(false);
269: final Component[] childs = jc.getComponents();
270: for (int i = 0; i < childs.length; i++)
271: {
272: final Component child = childs[i];
273: prepareComponent(child);
274: }
275: }
276: }
277: }