001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.form.fakepeer;
043:
044: import java.awt.*;
045: import java.awt.peer.ButtonPeer;
046: import java.awt.peer.CanvasPeer;
047: import java.awt.peer.CheckboxPeer;
048: import java.awt.peer.ChoicePeer;
049: import java.awt.peer.ComponentPeer;
050: import java.awt.peer.ContainerPeer;
051: import java.awt.peer.LabelPeer;
052: import java.awt.peer.ListPeer;
053: import java.awt.peer.PanelPeer;
054: import java.awt.peer.ScrollPanePeer;
055: import java.awt.peer.ScrollbarPeer;
056: import java.awt.peer.TextAreaPeer;
057: import java.awt.peer.TextComponentPeer;
058: import java.awt.peer.TextFieldPeer;
059: import java.lang.reflect.*;
060:
061: /**
062: *
063: * @author Tran Duc Trung
064: */
065:
066: public class FakePeerSupport {
067: private FakePeerSupport() {
068: }
069:
070: public static boolean attachFakePeer(Component comp) {
071: if (comp == null || comp.isDisplayable()
072: || comp instanceof javax.swing.JComponent
073: || comp instanceof javax.swing.RootPaneContainer)
074: return false;
075:
076: FakePeer peer = null;
077:
078: if (comp instanceof Label)
079: peer = getFakePeer(LabelPeer.class, new FakeLabelPeer(
080: (Label) comp));
081: else if (comp instanceof Button)
082: peer = getFakePeer(ButtonPeer.class, new FakeButtonPeer(
083: (Button) comp));
084: else if (comp instanceof Panel)
085: peer = getFakePeer(new Class[] { ContainerPeer.class,
086: PanelPeer.class }, new FakePanelPeer((Panel) comp));
087: else if (comp instanceof TextField)
088: peer = getFakePeer(new Class[] { TextFieldPeer.class,
089: TextComponentPeer.class }, new FakeTextFieldPeer(
090: (TextField) comp));
091: else if (comp instanceof TextArea)
092: peer = getFakePeer(new Class[] { TextAreaPeer.class,
093: TextComponentPeer.class }, new FakeTextAreaPeer(
094: (TextArea) comp));
095: else if (comp instanceof TextComponent)
096: peer = getFakePeer(TextComponentPeer.class,
097: new FakeTextComponentPeer((TextComponent) comp));
098: else if (comp instanceof Checkbox)
099: peer = getFakePeer(CheckboxPeer.class,
100: new FakeCheckboxPeer((Checkbox) comp));
101: else if (comp instanceof Choice)
102: peer = getFakePeer(ChoicePeer.class, new FakeChoicePeer(
103: (Choice) comp));
104: else if (comp instanceof List)
105: peer = getFakePeer(ListPeer.class, new FakeListPeer(
106: (List) comp));
107: else if (comp instanceof Scrollbar)
108: peer = getFakePeer(ScrollbarPeer.class,
109: new FakeScrollbarPeer((Scrollbar) comp));
110: else if (comp instanceof ScrollPane)
111: peer = getFakePeer(new Class[] { ContainerPeer.class,
112: ScrollPanePeer.class }, new FakeScrollPanePeer(
113: (ScrollPane) comp));
114: else if (comp instanceof Canvas)
115: peer = getFakePeer(CanvasPeer.class, new FakeCanvasPeer(
116: (Canvas) comp));
117: else
118: return false;
119:
120: attachFakePeer(comp, peer);
121: return true;
122: }
123:
124: private static FakePeer getFakePeer(Class fakePeerInterfaces,
125: FakeComponentPeer compPeer) {
126: return getFakePeer(new Class[] { fakePeerInterfaces }, compPeer);
127: }
128:
129: private static FakePeer getFakePeer(Class[] fakePeerInterfaces,
130: FakeComponentPeer compPeer) {
131:
132: // FakePeer.class and java.awt.peer.LightweightPeer.class interfaces
133: // should be implemented for each FakeComponentPeer
134: Class[] interfaces = new Class[fakePeerInterfaces.length + 2];
135: System.arraycopy(fakePeerInterfaces, 0, interfaces, 0,
136: fakePeerInterfaces.length);
137: interfaces[fakePeerInterfaces.length] = FakePeer.class;
138: interfaces[fakePeerInterfaces.length + 1] = java.awt.peer.LightweightPeer.class;
139:
140: Class proxyClass = Proxy.getProxyClass(compPeer.getClass()
141: .getClassLoader(), interfaces);
142: FakePeerInvocationHandler handler = new FakePeerInvocationHandler(
143: compPeer);
144: try {
145: return (FakePeer) proxyClass.getConstructor(
146: new Class[] { InvocationHandler.class })
147: .newInstance(new Object[] { handler });
148: } catch (Exception e) {
149: org.openide.ErrorManager.getDefault().notify(e);
150: }
151: return null;
152: }
153:
154: public static void attachFakePeer(Component comp, ComponentPeer peer) {
155: try {
156: Field f = Component.class.getDeclaredField("peer"); // NOI18N
157: f.setAccessible(true);
158: f.set(comp, peer);
159: } catch (Exception ex) {
160: org.openide.ErrorManager.getDefault().notify(
161: org.openide.ErrorManager.INFORMATIONAL, ex);
162: }
163: }
164:
165: public static void attachFakePeerRecursively(Container container) {
166: Component components[] = getComponents(container);
167: for (int i = 0; i < components.length; i++) {
168: Component comp = components[i];
169: attachFakePeer(comp);
170: if (comp instanceof Container)
171: attachFakePeerRecursively((Container) comp);
172: }
173: }
174:
175: static Component[] getComponents(Container container) {
176: // hack for the case some "smart" containers delegate getComponents()
177: // to some subcontainer (which becomes inaccessible then)
178: try {
179: Field f = Container.class.getDeclaredField("component"); // NOI18N
180: f.setAccessible(true);
181: return (Component[]) f.get(container);
182: } catch (Exception ex) {
183: org.openide.ErrorManager.getDefault().notify(
184: org.openide.ErrorManager.INFORMATIONAL, ex);
185: }
186: return container.getComponents();
187: }
188:
189: public static ComponentPeer detachFakePeer(Component comp) {
190: try {
191: Field f = Component.class.getDeclaredField("peer"); // NOI18N
192: f.setAccessible(true);
193: Object peer = (ComponentPeer) f.get(comp);
194: if (peer instanceof FakePeer) {
195: f.set(comp, null);
196: return (FakePeer) peer;
197: }
198: } catch (Exception ex) {
199: org.openide.ErrorManager.getDefault().notify(
200: org.openide.ErrorManager.INFORMATIONAL, ex);
201: }
202: return null;
203: }
204:
205: public static Font getDefaultAWTFont() {
206: if (defaultFont == null) {
207: defaultFont = org.openide.windows.WindowManager
208: .getDefault().getMainWindow().getFont();
209: if (defaultFont == null)
210: defaultFont = new Font("Dialog", Font.PLAIN, 12); // NOI18N
211: }
212: return defaultFont;
213: }
214:
215: private static Font defaultFont;
216: }
|