001: /*
002: * Copyright (C) 2005 Jeff Tassin
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018:
019: package com.jeta.swingbuilder.codegen.builder;
020:
021: import java.util.HashMap;
022: import java.util.Iterator;
023:
024: import com.jeta.forms.gui.common.FormSpecAdapter;
025: import com.jeta.forms.gui.common.FormUtils;
026: import com.jeta.forms.store.memento.BeanMemento;
027: import com.jeta.forms.store.memento.CellConstraintsMemento;
028: import com.jeta.forms.store.memento.ComponentMemento;
029: import com.jeta.forms.store.memento.FormGroupSet;
030: import com.jeta.forms.store.memento.FormMemento;
031: import com.jeta.forms.store.memento.PropertiesMemento;
032: import com.jeta.swingbuilder.gui.utils.FormDesignerUtils;
033: import com.jgoodies.forms.layout.CellConstraints;
034: import com.jgoodies.forms.layout.ColumnSpec;
035: import com.jgoodies.forms.layout.FormLayout;
036: import com.jgoodies.forms.layout.RowSpec;
037: import com.jgoodies.forms.layout.Sizes;
038:
039: /**
040: * Builds the Java Source for a form and all its child forms.
041: *
042: * @author Jeff Tassin
043: */
044: public class PanelWriter {
045: private CellConstraints m_default_cc = new CellConstraints();
046:
047: public PanelWriter() {
048: }
049:
050: public MethodWriter createPanel(DeclarationManager decl_mgr,
051: FormMemento fm) {
052: decl_mgr.addImport("javax.swing.JPanel");
053: decl_mgr.addImport("com.jgoodies.forms.layout.CellConstraints");
054: decl_mgr.addImport("com.jgoodies.forms.layout.FormLayout");
055:
056: PropertiesMemento pm = fm.getPropertiesMemento();
057:
058: MethodWriter method_writer = new MethodWriter(decl_mgr, null,
059: getSuggestedMethodName(pm.getComponentName()));
060: BeanWriter form_bean_writer = new BeanWriter(method_writer, pm);
061: method_writer.setReturnResult(form_bean_writer);
062:
063: LocalVariableDeclaration layout = new LocalVariableDeclaration(
064: method_writer,
065: com.jgoodies.forms.layout.FormLayout.class);
066: layout.addParameter(new StringExpression(fm.getColumnSpecs()));
067: layout.addParameter(new StringExpression(fm.getRowSpecs()));
068:
069: /** we need this to get the row/column count */
070: FormLayout formlayout = new FormLayout(FormSpecAdapter
071: .fixupSpecs(fm.getColumnSpecs()), FormSpecAdapter
072: .fixupSpecs(fm.getRowSpecs()));
073:
074: method_writer.addStatements(form_bean_writer.getStatements());
075:
076: method_writer.addStatement(layout);
077:
078: /** set the column and row groups */
079: setGroups(method_writer, layout.getVariable(), fm, true);
080: setGroups(method_writer, layout.getVariable(), fm, false);
081:
082: LocalVariableDeclaration ccvar = new LocalVariableDeclaration(
083: method_writer,
084: com.jgoodies.forms.layout.CellConstraints.class, "cc");
085: method_writer.addStatement(ccvar);
086:
087: /** add the panel declaration/ctor to the method */
088: MethodStatement ss = new MethodStatement(form_bean_writer
089: .getBeanVariable(), "setLayout");
090: ss.addParameter(new BasicExpression(layout.getVariable()));
091: method_writer.addStatement(ss);
092:
093: decl_mgr.addMethod(method_writer);
094:
095: /** puts a newline between beans */
096: method_writer.addStatement(new BasicStatement(""));
097:
098: HashMap row_cache = new HashMap();
099: HashMap col_cache = new HashMap();
100:
101: Iterator iter = fm.iterator();
102: while (iter.hasNext()) {
103: ComponentMemento cm = (ComponentMemento) iter.next();
104: CellConstraintsMemento ccm = cm.getCellConstraintsMemento();
105: CellConstraints cc = ccm.createCellConstraints();
106:
107: try {
108: if (cm instanceof FormMemento) {
109: FormMemento cfm = (FormMemento) cm;
110: MethodWriter subpanel = createPanel(method_writer,
111: cfm);
112: method_writer
113: .addStatement(createAddComponentStatement(
114: form_bean_writer.getBeanVariable(),
115: subpanel.getMethodName() + "()",
116: ccvar.getVariable(), cc));
117:
118: } else if (cm instanceof BeanMemento) {
119: BeanMemento bm = (BeanMemento) cm;
120: Integer icol = new Integer(cc.gridX);
121: Integer irow = new Integer(cc.gridY);
122:
123: if (bm.getBeanClass() == null) {
124: /** found an empty component */
125: if (col_cache.get(icol) == null)
126: col_cache.put(icol, new FillMarker(bm,
127: formlayout.getColumnSpec(icol
128: .intValue())));
129:
130: if (row_cache.get(irow) == null)
131: row_cache.put(irow, new FillMarker(bm,
132: formlayout.getRowSpec(irow
133: .intValue())));
134:
135: } else if (bm.getProperties() != null) {
136: String beanclass = bm.getBeanClass();
137: if (beanclass.indexOf("GridView") > 0
138: || beanclass.indexOf("JETALabel") > 0
139: || decl_mgr.isIncludeNonStandard()
140: || beanclass.indexOf("com.jeta") < 0) {
141:
142: BeanWriter bw = new BeanWriter(
143: method_writer, bm.getProperties());
144: method_writer.addStatements(bw
145: .getStatements());
146:
147: method_writer
148: .addStatement(createAddComponentStatement(
149: form_bean_writer
150: .getBeanVariable(),
151: bw.getResultVariable(),
152: ccvar.getVariable(), cc));
153: /** puts a newline between beans */
154: method_writer
155: .addStatement(new BasicStatement(""));
156:
157: if (icol.intValue() == 1)
158: row_cache.put(irow, new FillMarker(bm,
159: formlayout.getRowSpec(irow
160: .intValue())));
161:
162: if (irow.intValue() == 1)
163: col_cache.put(icol, new FillMarker(bm,
164: formlayout.getColumnSpec(icol
165: .intValue())));
166: }
167:
168: }
169: } else {
170: assert (false);
171: }
172: } catch (Exception e) {
173:
174: }
175: }
176:
177: MethodStatement addseps = new MethodStatement(
178: "addFillComponents");
179: addseps.addParameter(form_bean_writer.getBeanVariable());
180: addseps.addParameter(createFillArray(col_cache, formlayout
181: .getColumnCount()));
182: addseps.addParameter(createFillArray(row_cache, formlayout
183: .getRowCount()));
184: method_writer.addStatement(addseps);
185:
186: return method_writer;
187: }
188:
189: private Statement createAddComponentStatement(String formVariable,
190: String beanVariable, String ccVar, CellConstraints cc) {
191: MethodStatement ms = new MethodStatement(formVariable, "add");
192: ms.addParameter(beanVariable);
193:
194: if (cc.hAlign == m_default_cc.hAlign
195: && cc.vAlign == m_default_cc.vAlign) {
196: if (cc.gridWidth == 1 && cc.gridHeight == 1) {
197: MethodExpression ccme = new MethodExpression(ccVar,
198: "xy");
199: ccme.addParameter(String.valueOf(cc.gridX));
200: ccme.addParameter(String.valueOf(cc.gridY));
201: ms.addParameter(ccme);
202: } else {
203: MethodExpression ccme = new MethodExpression(ccVar,
204: "xywh");
205: ccme.addParameter(String.valueOf(cc.gridX));
206: ccme.addParameter(String.valueOf(cc.gridY));
207: ccme.addParameter(String.valueOf(cc.gridWidth));
208: ccme.addParameter(String.valueOf(cc.gridHeight));
209: ms.addParameter(ccme);
210: }
211: } else {
212: MethodExpression ccme = new MethodExpression(
213: "new CellConstraints");
214: ccme.addParameter(String.valueOf(cc.gridX));
215: ccme.addParameter(String.valueOf(cc.gridY));
216: ccme.addParameter(String.valueOf(cc.gridWidth));
217: ccme.addParameter(String.valueOf(cc.gridHeight));
218: ccme.addParameter("CellConstraints."
219: + FormUtils.fromAlignment(cc.hAlign));
220: ccme.addParameter("CellConstraints."
221: + FormUtils.fromAlignment(cc.vAlign));
222: ms.addParameter(ccme);
223: }
224: return ms;
225: }
226:
227: /**
228: * Creates an array of column or row indices that correspond to cells in the
229: * first row or column that require empty filler components. This is
230: * required to keep the spacing of the grid consistent with the view in the
231: * editor.
232: *
233: * @param indexes
234: * a map of Integer indexes to ComponentMememeto objects.
235: */
236: private String createFillArray(HashMap indexes, int count) {
237: StringBuffer sbuff = null;
238: for (int index = 1; index <= count; index++) {
239: Integer ival = new Integer(index);
240: FillMarker fm = (FillMarker) indexes.get(ival);
241: if (fm == null || fm.isFillable()) {
242: /** we have an empty row/column */
243: if (sbuff == null) {
244: sbuff = new StringBuffer("new int[]{ ");
245: sbuff.append(String.valueOf(index));
246: } else {
247: sbuff.append(',');
248: sbuff.append(String.valueOf(index));
249: }
250: }
251: }
252:
253: if (sbuff == null) {
254: return "new int[0]";
255: } else {
256: sbuff.append(" }");
257: return sbuff.toString();
258: }
259: }
260:
261: private String getSuggestedMethodName(String mname) {
262: mname = FormDesignerUtils.fastTrim(mname);
263: if (mname.length() == 0)
264: mname = "createPanel";
265: else
266: mname = "create" + mname;
267: return mname;
268: }
269:
270: private void setGroups(MethodWriter method_writer,
271: String layoutVariable, FormMemento fm, boolean colGroups) {
272: StringBuffer group_params = null;
273: FormGroupSet grpset = fm.getColumnGroups();
274: if (colGroups)
275: grpset = fm.getColumnGroups();
276: else
277: grpset = fm.getRowGroups();
278:
279: if (grpset != null) {
280: int[][] grps = grpset.toArray();
281: for (int index = 0; index < grps.length; index++) {
282: int[] group = grps[index];
283: if (group != null && group.length > 0) {
284: if (group_params == null)
285: group_params = new StringBuffer();
286: else
287: group_params.append(", ");
288:
289: group_params.append("{");
290: for (int gindex = 0; gindex < group.length; gindex++) {
291: if (gindex != 0)
292: group_params.append(",");
293: group_params.append(String
294: .valueOf(group[gindex]));
295: }
296: group_params.append("}");
297: }
298: }
299:
300: if (group_params != null) {
301: group_params.insert(0, "new int[][]{ ");
302: group_params.append(" }");
303:
304: MethodStatement setgroup = null;
305: if (colGroups)
306: setgroup = new MethodStatement(layoutVariable,
307: "setColumnGroups");
308: else
309: setgroup = new MethodStatement(layoutVariable,
310: "setRowGroups");
311:
312: setgroup.addParameter(group_params.toString());
313: method_writer.addStatement(setgroup);
314: }
315: }
316: }
317:
318: private static class FillMarker {
319: private BeanMemento m_memento;
320: private Object m_spec;
321:
322: public FillMarker(BeanMemento memento, ColumnSpec spec) {
323: m_memento = memento;
324: m_spec = spec;
325: }
326:
327: public FillMarker(BeanMemento memento, RowSpec spec) {
328: m_memento = memento;
329: m_spec = spec;
330: }
331:
332: public boolean isFillable() {
333: if (m_spec instanceof RowSpec)
334: return isFillable((RowSpec) m_spec);
335: else if (m_spec instanceof ColumnSpec)
336: return isFillable((ColumnSpec) m_spec);
337: else {
338: assert (false);
339: return false;
340: }
341: }
342:
343: public boolean isFillable(ColumnSpec spec) {
344: return (m_memento == null || m_memento.getBeanClass() == null
345: && (spec.getSize() == Sizes.DEFAULT || spec
346: .getSize() == Sizes.PREFERRED));
347:
348: }
349:
350: public boolean isFillable(RowSpec spec) {
351: return (m_memento == null || m_memento.getBeanClass() == null
352: && (spec.getSize() == Sizes.DEFAULT || spec
353: .getSize() == Sizes.PREFERRED));
354: }
355: }
356: }
|