001: /*
002: * Layout.java
003: *
004: * Copyright (c) 1997-2003 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package pnuts.awt;
010:
011: import java.lang.reflect.Method;
012: import java.util.Hashtable;
013: import java.awt.*;
014:
015: import javax.swing.JComboBox;
016: import javax.swing.JScrollPane;
017:
018: /**
019: * Manager class of Hierarchical Layout.
020: */
021: public abstract class Layout {
022: private static Hashtable mappingTable = new Hashtable();
023: private final static String swingPkgName = "javax.swing";
024:
025: static {
026: // default mapping
027: registerLayoutManager(BorderLayout.class,
028: BorderLayoutMapping.class);
029: registerLayoutManager(CardLayout.class, CardLayoutMapping.class);
030: registerLayoutManager(GridLayout.class, GridLayoutMapping.class);
031: registerLayoutManager(GridBagLayout.class,
032: GridBagLayoutMapping.class);
033: registerLayoutManager(FlowLayout.class, FlowLayoutMapping.class);
034: registerLayoutManager(PnutsLayout.class,
035: PnutsLayoutMapping.class);
036: }
037:
038: private static Class jpanelClass = null;
039: private static boolean jPanelFlg = false;
040:
041: private static Class findJPanelClass() {
042: if (!jPanelFlg) {
043: jPanelFlg = true;
044: try {
045: jpanelClass = Class.forName("javax.swing.JPanel");
046: return jpanelClass;
047: } catch (ClassNotFoundException e) { /* ignore */
048: }
049: }
050: return jpanelClass;
051: }
052:
053: /**
054: * Register a Layout Mapping
055: *
056: * @param clazz Class of the mapping
057: * @param layout The definition of the mapping
058: * This class should be subclass of Layout class.
059: */
060: public static void registerLayoutManager(Class clazz, Class layout) {
061: if (Layout.class.isAssignableFrom(layout)) {
062: mappingTable.put(clazz, layout);
063: }
064: }
065:
066: protected static boolean isArray(Object obj) {
067: return obj.getClass().isArray();
068: }
069:
070: protected Layout() {
071: }
072:
073: /**
074: * Define how to make a container.
075: * This class should be defined in a subclass of Layout class.
076: */
077: public abstract Container createContainer(Container container,
078: Object[] fmt);
079:
080: /**
081: * Layout components using format
082: */
083: public static Container layout(Object[] format) {
084: return layout(new Panel(), format);
085: }
086:
087: /**
088: * Layout components in the <em>container</em> using format fmt.
089: */
090: public static Container layout(Container container, Object[] fmt) {
091: if (container instanceof JScrollPane) {
092: Component view = ((JScrollPane) container).getViewport()
093: .getView();
094: if (view != null && view instanceof Container)
095: container = (Container) view;
096: }
097: if (fmt[0] instanceof Class) {
098: Layout layout = null;
099: try {
100: Object map = mappingTable.get(fmt[0]);
101: if (map instanceof Layout) {
102: return ((Layout) map).createContainer(container,
103: fmt);
104: } else if (map instanceof Class) {
105: layout = (Layout) ((Class) map).newInstance();
106: mappingTable.put(fmt[0], layout);
107: return layout.createContainer(container, fmt);
108: } else {
109: throw new LayoutException("Mapping not defined: "
110: + fmt[0]);
111: }
112: } catch (Exception ex) {
113: LayoutException layoutEx = new LayoutException(ex
114: .getClass().getName()
115: + ": " + ex.getMessage());
116: ex.printStackTrace();
117: layoutEx.initCause(ex);
118: throw layoutEx;
119: }
120: } else {
121: for (int i = 0; i < fmt.length; i++) {
122: Object c = fmt[i];
123: if (c instanceof Component) {
124: container.add((Component) c);
125: } else if (c instanceof Object[]) {
126: Object[] array = (Object[]) c;
127: if (!(array[0] instanceof Component))
128: throw new LayoutException(
129: "First element must be a Component: "
130: + c);
131: if (array.length > 1) {
132: container.add((Component) array[0], array[1]);
133: if (array.length > 2) {
134: if (!(array[0] instanceof Container))
135: throw new LayoutException(
136: "Component must be a Container when a third element is used: "
137: + array[0]);
138: if (!(array[2] instanceof Object[]))
139: throw new LayoutException(
140: "Third element must be an array: "
141: + array[2]);
142: Layout.layout((Container) array[0],
143: (Object[]) array[2]);
144: }
145: } else {
146: container.add((Component) array[0]);
147: }
148: } else {
149: throw new LayoutException(
150: "Element must be a Component or array: "
151: + c);
152: }
153: }
154: return container;
155: }
156: }
157:
158: protected static Container makePanel(Container prototype) {
159: try {
160: if (prototype == null) {
161: return new Panel();
162: }
163: Class cl = prototype.getClass();
164: int guiType = 0; // 0:AWT, 1:javax.swing
165: String name = cl.getName();
166: if (name.startsWith(swingPkgName)) {
167: guiType = 1;
168: }
169:
170: if (prototype instanceof Window) {
171: if (guiType == 1) {
172: cl = findJPanelClass();
173: if (cl == null) {
174: cl = Panel.class;
175: }
176: } else {
177: cl = Panel.class;
178: }
179: }
180: Container ret = (Container) cl.newInstance();
181: ret.setForeground(prototype.getForeground());
182: ret.setBackground(prototype.getBackground());
183: ret.setCursor(prototype.getCursor());
184: ret.setFont(prototype.getFont());
185: if (guiType == 1) {
186: Method m = null;
187: Class t_noarg[] = new Class[] {};
188: Object noarg[] = new Object[] {};
189: Class t_boolean[] = new Class[] { Boolean.TYPE };
190: Class t_string[] = new Class[] { String.class };
191: Class clazz = prototype.getClass();
192: Object val = null;
193:
194: m = clazz.getMethod("isDoubleBuffered", t_noarg);
195: val = m.invoke(prototype, noarg);
196: m = cl.getMethod("setDoubleBuffered", t_boolean);
197: m.invoke(ret, new Object[] { val });
198:
199: m = clazz.getMethod("getToolTipText", t_noarg);
200: val = m.invoke(prototype, noarg);
201: m = cl.getMethod("setToolTipText", t_string);
202: m.invoke(ret, new Object[] { val });
203:
204: m = clazz.getMethod("isOpaque", t_noarg);
205: val = m.invoke(prototype, noarg);
206: m = cl.getMethod("setOpaque", t_boolean);
207: m.invoke(ret, new Object[] { val });
208:
209: m = clazz.getMethod("getAutoscrolls", t_noarg);
210: val = m.invoke(prototype, noarg);
211: m = cl.getMethod("setAutoscrolls", t_boolean);
212: m.invoke(ret, new Object[] { val });
213: }
214: return ret;
215: } catch (Exception e) {
216: return new Panel();
217: }
218: }
219: }
|