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.gui.utils;
020:
021: import java.awt.Component;
022: import java.awt.Dimension;
023: import java.io.BufferedInputStream;
024: import java.io.BufferedOutputStream;
025: import java.io.BufferedWriter;
026: import java.io.File;
027: import java.io.FileInputStream;
028: import java.io.FileOutputStream;
029: import java.io.IOException;
030: import java.io.ObjectOutputStream;
031: import java.io.OutputStreamWriter;
032: import java.io.Writer;
033: import java.util.Arrays;
034: import java.util.Hashtable;
035: import java.util.LinkedList;
036: import java.util.List;
037: import java.util.Map;
038:
039: import javax.swing.ImageIcon;
040: import javax.swing.JOptionPane;
041:
042: import com.jeta.forms.gui.form.ComponentConstraints;
043: import com.jeta.forms.gui.form.GridComponent;
044: import com.jeta.forms.gui.form.GridView;
045: import com.jeta.forms.gui.form.ReadOnlyConstraints;
046: import com.jeta.forms.store.jml.JMLException;
047: import com.jeta.forms.store.jml.JMLUtils;
048: import com.jeta.forms.store.jml.dom.JMLNode;
049: import com.jeta.forms.store.memento.FormPackage;
050: import com.jeta.forms.store.xml.writer.XMLWriter;
051: import com.jeta.open.i18n.I18N;
052: import com.jeta.open.registry.JETARegistry;
053: import com.jeta.swingbuilder.gui.commands.CommandUtils;
054: import com.jeta.swingbuilder.gui.commands.SetConstraintsCommand;
055: import com.jeta.swingbuilder.gui.editor.FormEditor;
056: import com.jeta.swingbuilder.interfaces.resources.ResourceLoader;
057:
058: /**
059: * Some common utilities used by the form designer.
060: *
061: * @author Jeff Tassin
062: */
063: public class FormDesignerUtils {
064: private static Object[] ENV_VARS = null;
065:
066: /** cache of images */
067: private static Hashtable m_imagecache = new Hashtable();
068:
069: /**
070: * Checks if the span can be set to the given values for the given
071: * component.
072: */
073: public static boolean checkSpan(GridComponent gc, int colspan,
074: int rowspan) {
075: if (gc == null)
076: return false;
077:
078: int rowstart = gc.getRow();
079: int colstart = gc.getColumn();
080:
081: GridView parentview = gc.getParentView();
082: /**
083: * Make sure that the component will not overlay any other components
084: */
085: for (int row = rowstart; row <= (rowstart + rowspan - 1); row++) {
086: for (int col = colstart; col <= (colstart + colspan - 1); col++) {
087: if (row != rowstart || col != colstart) {
088: GridComponent gc_existing = parentview
089: .getGridComponent(col, row);
090: assert (gc_existing != gc);
091: if (gc_existing.hasBean()) {
092: String msg = I18N.format(
093: "Components_would_overlap_at_cell_2",
094: new Integer(col), new Integer(row));
095: String title = I18N
096: .getLocalizedMessage("Error");
097: JOptionPane.showMessageDialog(gc, msg, title,
098: JOptionPane.ERROR_MESSAGE);
099: return false;
100: }
101: }
102: }
103: }
104:
105: return true;
106: }
107:
108: public static void copyFile(String dest_path, String src_path)
109: throws IOException {
110: if (dest_path == null)
111: return;
112:
113: try {
114: File f1 = new File(dest_path);
115: File f2 = new File(src_path);
116:
117: if (f1.getCanonicalPath().equals(f2.getCanonicalPath())) {
118: System.err
119: .println("FormsDesignerUtils.copyFile dest and src are same.");
120: return;
121: }
122: } catch (Exception e) {
123: e.printStackTrace();
124: }
125:
126: FileInputStream fis = new FileInputStream(src_path);
127: FileOutputStream fos = new FileOutputStream(dest_path);
128:
129: BufferedInputStream bis = new BufferedInputStream(fis);
130: BufferedOutputStream bos = new BufferedOutputStream(fos);
131:
132: byte[] buff = new byte[1024];
133: int numread = bis.read(buff);
134: while (numread > 0) {
135: bos.write(buff, 0, numread);
136: numread = bis.read(buff);
137: }
138:
139: bos.flush();
140: bos.close();
141: bis.close();
142: }
143:
144: /**
145: * Converts dialog units in the x and y to pixels. This is used for
146: * providing a consistent initial window size for growable panels.
147: */
148: public static Dimension getWindowDimension(Component window,
149: int dluX, int dluY) {
150: Units units = Units.getInstance();
151: return new Dimension(units.dialogUnitXAsPixel(dluX, window),
152: units.dialogUnitYAsPixel(dluY, window));
153: }
154:
155: /**
156: * Performs a fast trim on a string. Note: if the string does not need
157: * triming, then a copy is NOT created and the original string is returned.
158: * Null is never returned from this method. If null is passed, an empty
159: * string is returned.
160: */
161: public static String fastTrim(String str) {
162: if (str == null)
163: return "";
164:
165: int len = str.length();
166: if (len == 0)
167: return str;
168:
169: if (str.charAt(0) == ' ' || str.charAt(len - 1) == ' ')
170: return str.trim();
171: else
172: return str; // no leading/trailing spaces so just return the
173: // original
174: // string
175: }
176:
177: /**
178: * Loads an image from disk. The image is loaded relative to the application
179: * directory.
180: *
181: * @todo we need to cache these images
182: */
183: public static ImageIcon loadImage(String imageName) {
184: if (imageName != null) {
185: ImageIcon icon = (ImageIcon) m_imagecache.get(imageName);
186: if (icon == null) {
187: try {
188: ResourceLoader loader = (ResourceLoader) JETARegistry
189: .lookup(ResourceLoader.COMPONENT_ID);
190: assert (loader != null);
191: icon = loader.loadImage(imageName);
192: } catch (Exception e) {
193: e.printStackTrace();
194: }
195:
196: if (icon == null) {
197: icon = new ImageIcon();
198: }
199: m_imagecache.put(imageName, icon);
200: }
201: return icon;
202: } else {
203: assert (false);
204: return new ImageIcon();
205: }
206: }
207:
208: /**
209: * Sets the span on the given component
210: */
211: public static void setSpan(GridComponent gc, int colspan,
212: int rowspan) {
213: if (gc == null || colspan < 1 || rowspan < 1)
214: return;
215:
216: if (gc.getBeanDelegate() == null)
217: return;
218:
219: GridView parentview = gc.getParentView();
220: ComponentConstraints cc = gc.getConstraints();
221:
222: int rowstart = gc.getRow();
223: int colstart = gc.getColumn();
224:
225: /**
226: * Make sure the span does not force the component past the end of the
227: * grid.
228: */
229: colspan = calculateValidColumnSpan(gc, colspan);
230: rowspan = calculateValidRowSpan(gc, rowspan);
231:
232: if (rowspan == cc.getRowSpan() && colspan == cc.getColumnSpan())
233: return;
234:
235: if (checkSpan(gc, colspan, rowspan)) {
236: ReadOnlyConstraints rocc = new ReadOnlyConstraints(
237: colstart, rowstart, colspan, rowspan, cc
238: .getHorizontalAlignment(), cc
239: .getVerticalAlignment(), cc.getInsets());
240:
241: SetConstraintsCommand cmd = new SetConstraintsCommand(
242: parentview.getParentForm(), gc, rocc);
243: CommandUtils.invoke(cmd, FormEditor.getEditor(gc));
244: }
245: }
246:
247: /**
248: * Checks if the column span can be set on the given grid component. If the
249: * component would extend off the form, then the resulting span that is
250: * returned is trimed to fit.
251: */
252: public static int calculateValidColumnSpan(GridComponent gc,
253: int colspan) {
254: if (gc == null || colspan < 1)
255: return 1;
256:
257: GridView parentview = gc.getParentView();
258: ComponentConstraints cc = gc.getConstraints();
259:
260: int colstart = gc.getColumn();
261:
262: /**
263: * Make sure the span does not force the component past the end of the
264: * grid.
265: */
266: return Math.min(colspan, parentview.getColumnCount() - colstart
267: + 1);
268: }
269:
270: /**
271: * Checks if the row span can be set on the given grid component. If the
272: * component would extend off the form, then the resulting span that is
273: * returned is trimed to fit.
274: */
275: public static int calculateValidRowSpan(GridComponent gc,
276: int rowspan) {
277: if (gc == null || rowspan < 1)
278: return 1;
279:
280: GridView parentview = gc.getParentView();
281: ComponentConstraints cc = gc.getConstraints();
282:
283: int rowstart = gc.getRow();
284:
285: /**
286: * Make sure the span does not force the component past the end of the
287: * grid.
288: */
289: return Math.min(rowspan, parentview.getRowCount() - rowstart
290: + 1);
291: }
292:
293: /**
294: * Testing flag
295: */
296: public static boolean isTest() {
297: try {
298: String result = System.getProperty("jeta1.test");
299: return (result != null && result.equals("true"));
300: } catch (Exception e) {
301:
302: }
303: return false;
304: }
305:
306: /**
307: * Debugging flag
308: */
309: public static boolean isDebug() {
310: try {
311: String result = System.getProperty("jeta1.debug");
312: return (result != null && result.equals("true"));
313: } catch (Exception e) {
314:
315: }
316: return false;
317: }
318:
319: /**
320: * Saves the specified form to the specified file. If the file name ends in
321: * .xml, the form is stored in xml format. Otherwise, it is stored in binary
322: * form.
323: *
324: * @param fpackage
325: * @param file
326: * @throws IOException
327: * @throws JMLException
328: */
329: public static void saveForm(FormPackage fpackage, File file)
330: throws IOException, JMLException {
331: if (file.getName().endsWith(".xml")
332: || file.getName().endsWith(".XML")) {
333: JMLNode node = JMLUtils.writeObject(fpackage);
334: Writer writer = new BufferedWriter(new OutputStreamWriter(
335: new FileOutputStream(file), "UTF8"));
336: new XMLWriter().write(writer, node);
337: writer.write('\n');
338: writer.flush();
339: writer.close();
340: } else {
341: FileOutputStream fos = new FileOutputStream(file);
342: ObjectOutputStream current_stream = new ObjectOutputStream(
343: fos);
344: current_stream.writeObject(fpackage);
345: current_stream.close();
346: }
347: }
348:
349: public static Object[] getEnvVars(boolean refresh) {
350: if ((ENV_VARS == null) || (refresh)) {
351: List envVarDirs = new LinkedList();
352: if (refresh) {
353: EnvUtils.getInstance().refresh();
354: }
355: Map map = EnvUtils.getInstance().getEnvVars();
356: Object[] envVars = map.keySet().toArray();
357: Arrays.sort(envVars);
358: for (int index = 0; index < envVars.length; index++) {
359: String envVar = (String) envVars[index];
360:
361: String value = EnvUtils.getInstance().getEnvVar(envVar);
362: try {
363: File file = new File(value);
364: if (file.exists() && file.isDirectory()) {
365: envVarDirs.add(envVar);
366: }
367: } catch (Exception e) {
368: }
369:
370: }
371:
372: ENV_VARS = envVarDirs.toArray();
373: Arrays.sort(ENV_VARS);
374: }
375: return ENV_VARS;
376: }
377: }
|