001: /*
002: * Gruntspud
003: *
004: * Copyright (C) 2002 Brett Smith.
005: *
006: * Written by: Brett Smith <t_magicthize@users.sourceforge.net>
007: *
008: * This program is free software; you can redistribute it and/or modify it under
009: * the terms of the GNU Library General Public License as published by the Free
010: * Software Foundation; either version 2 of the License, or (at your option) any
011: * later version. This program is distributed in the hope that it will be
012: * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
014: * General Public License for more details.
015: *
016: * You should have received a copy of the GNU Library General Public License
017: * along with this program; if not, write to the Free Software Foundation, Inc.,
018: * 675 Mass Ave, Cambridge, MA 02139, USA.
019: */
020: package gruntspud.ui;
021:
022: import gruntspud.Constants;
023: import gruntspud.Gruntspud;
024: import gruntspud.GruntspudContext;
025: import gruntspud.actions.DefaultGruntspudAction;
026: import gruntspud.actions.GruntspudAction;
027: import gruntspud.ui.icons.*;
028: import java.awt.BorderLayout;
029: import java.awt.Color;
030: import java.awt.Component;
031: import java.awt.Container;
032: import java.awt.Dimension;
033: import java.awt.GridBagConstraints;
034: import java.awt.GridBagLayout;
035: import java.awt.Image;
036: import java.awt.Insets;
037: import java.awt.Rectangle;
038: import java.awt.Toolkit;
039: import java.awt.event.ActionListener;
040: import java.awt.image.FilteredImageSource;
041: import java.awt.image.ImageFilter;
042: import java.awt.image.ImageProducer;
043: import java.lang.reflect.Method;
044: import java.net.URL;
045: import java.util.HashMap;
046: import javax.swing.Action;
047: import javax.swing.Icon;
048: import javax.swing.ImageIcon;
049: import javax.swing.JButton;
050: import javax.swing.JComponent;
051: import javax.swing.JMenuItem;
052: import javax.swing.JTabbedPane;
053: import javax.swing.JTable;
054: import javax.swing.JToolBar;
055: import javax.swing.SwingConstants;
056: import javax.swing.UIManager;
057:
058: /**
059: * Description of the Class
060: *
061: *@author magicthize
062: *@created 26 May 2002
063: */
064: public class UIUtil implements SwingConstants {
065: public final static Insets EMPTY_INSETS = new Insets(0, 0, 0, 0);
066:
067: public final static Icon EMPTY_SMALL_ICON = new EmptyIcon(16, 16);
068:
069: public final static Icon EMPTY_LARGE_ICON = new EmptyIcon(48, 48);
070:
071: public final static Icon EMPTY_ICON = new EmptyIcon(24, 24);
072:
073: public final static Color TRANSPARENT_RED = new Color(255, 0, 0, 96);
074:
075: public final static Color TRANSPARENT_BLUE = new Color(0, 0, 255,
076: 96);
077:
078: private static ImageFilter imageFilter;
079:
080: // Private statics
081: private final static HashMap iconCache = new HashMap();
082:
083: public static void setImageFilter(ImageFilter imageFilter) {
084: UIUtil.imageFilter = imageFilter;
085: }
086:
087: /**
088: * Return the position of a tool bar given the panel that it rotates around.
089: * Returns the same constants that are used for BorderLayout
090: *
091: * @param toolBar Description of the Parameter
092: * @param center Description of the Parameter
093: * @return position
094: */
095: public static String getToolBarPosition(JToolBar toolBar,
096: Container center) {
097: Constants.UI_LOG
098: .debug("Toolbar orientation = "
099: + (toolBar.getOrientation() == JToolBar.HORIZONTAL ? "Horizontal"
100: : "Vertical")
101: + " Position on screen = "
102: + toolBar.getLocationOnScreen()
103: + " Position in parent = "
104: + toolBar.getLocation()
105: + " Container location = "
106: + center.getLocationOnScreen());
107: if (toolBar.getOrientation() == JToolBar.HORIZONTAL) {
108: // Horizontal, so it must be either north or south
109: return (toolBar.getLocationOnScreen().y <= center
110: .getLocationOnScreen().y) ? BorderLayout.NORTH
111: : BorderLayout.SOUTH;
112: }
113: // Vertial, so it must be either east or west
114: else {
115: return (toolBar.getLocationOnScreen().x <= center
116: .getLocationOnScreen().x) ? BorderLayout.WEST
117: : BorderLayout.EAST;
118: }
119: }
120:
121: /**
122: * Save table column positions and sizes. Note, the table must have its auto
123: * resize mode set to off, i.e.
124: *
125: * @param table
126: * @param registry prefix
127: * @param table name
128: */
129: public static void saveTableMetrics(JTable table,
130: String propertyName, GruntspudContext context) {
131: for (int i = 0; i < table.getColumnModel().getColumnCount(); i++) {
132: int w = table.getColumnModel().getColumn(i).getWidth();
133: // Constants.UI_LOG.debug("Saving table " + propertyName + ", column " + i
134: // + "=" +
135: // table.getColumnModel().getColumn(i).getHeaderValue() + " as " + w);
136: context.getHost().setProperty(
137: propertyName + ".column." + i + ".width",
138: String.valueOf(w));
139: context.getHost().setProperty(
140: propertyName + ".column." + i + ".position",
141: String.valueOf(table.convertColumnIndexToModel(i)));
142: }
143: }
144:
145: /**
146: * Restore table column positions and sizes. Note, the table must have its
147: * auto resize mode set to off, i.e.
148: *
149: * @param table
150: * @param registry prefix
151: * @param table name
152: * @param default column widths
153: */
154: public static void restoreTableMetrics(JTable table,
155: String propertyName, int[] defaultWidths,
156: GruntspudContext context) {
157: // Check the table columns may be resized correctly
158: if (table.getAutoResizeMode() != JTable.AUTO_RESIZE_OFF) {
159: throw new IllegalArgumentException(
160: "Table AutoResizeMode must be JTable.AUTO_RESIZE_OFF");
161: }
162: // Restore the table column widths and positions
163: for (int i = 0; i < table.getColumnModel().getColumnCount(); i++) {
164: try {
165: table.moveColumn(table.convertColumnIndexToView(Integer
166: .parseInt(context.getHost().getProperty(
167: propertyName + ".column." + i
168: + ".position",
169: String.valueOf(i)))), i);
170: int w = Integer
171: .parseInt(context
172: .getHost()
173: .getProperty(
174: propertyName + ".column." + i
175: + ".width",
176: String
177: .valueOf((defaultWidths == null) ? table
178: .getColumnModel()
179: .getColumn(i)
180: .getPreferredWidth()
181: : defaultWidths[i])));
182: // Constants.UI_LOG.debug("Restoring table " + propertyName + " column "
183: // + i + " width to " + w);
184: table.getColumnModel().getColumn(i)
185: .setPreferredWidth(w);
186: } catch (NumberFormatException nfe) {
187: }
188: }
189: }
190:
191: /**
192: * Utility common in use with GridBagLayout. Adds a component to the specified
193: * grid width position
194: *
195: * @param parent container
196: * @param constraints object
197: * @param componentToAdd Description of the Parameter
198: * @param pos Description of the Parameter
199: * @throws IllegalArgumentException if parent is not a JComponent
200: */
201: public static void jGridBagAdd(JComponent parent,
202: JComponent componentToAdd, GridBagConstraints constraints,
203: int pos) {
204: // Test and get the parents layout
205: if (!(parent.getLayout() instanceof GridBagLayout)) {
206: throw new IllegalArgumentException(
207: "parent must have a GridBagLayout");
208: }
209: GridBagLayout layout = (GridBagLayout) parent.getLayout();
210: //
211: constraints.gridwidth = pos;
212: layout.setConstraints(componentToAdd, constraints);
213: parent.add(componentToAdd);
214: }
215:
216: /**
217: * Description of the Method
218: *
219: * @param s Description of the Parameter
220: * @param s1 Description of the Parameter
221: * @param l Description of the Parameter
222: * @return Description of the Return Value
223: */
224: public static JButton createButton(String s, String s1,
225: ActionListener l) {
226: JButton jbutton = new JButton((s == null) ? null
227: : getCachedIcon(s)) {
228: public boolean isFocusTraversable() {
229: return false;
230: }
231:
232: public Insets getMargin() {
233: return EMPTY_INSETS;
234: }
235:
236: public boolean isRequestFocusEnabled() {
237: return false;
238: }
239: };
240: jbutton.setToolTipText(s1);
241: if (l != null) {
242: jbutton.addActionListener(l);
243: // jbutton.setFocusable(false);
244: }
245: return jbutton;
246: }
247:
248: /**
249: * Description of the Method
250: *
251: * @param a Description of the Parameter
252: * @param showText Description of the Parameter
253: * @return Description of the Return Value
254: */
255: public static JButton createButton(Action a, boolean showText,
256: boolean smallIcon) {
257: JButton b = new JButton(a) {
258: public Insets getMargin() {
259: return EMPTY_INSETS;
260: }
261:
262: public boolean isRequestFocusEnabled() {
263: return false;
264: }
265:
266: public boolean isFocusTraversable() {
267: return false;
268: }
269: };
270: if (smallIcon) {
271: b.setIcon((Icon) a
272: .getValue(DefaultGruntspudAction.SMALL_ICON));
273: } else {
274: b.setIcon((Icon) a.getValue(DefaultGruntspudAction.ICON));
275: }
276: showText = showText
277: && Boolean.TRUE.equals(a
278: .getValue(GruntspudAction.SHOW_NAME));
279: if (!showText) {
280: b.setText(null);
281: // b.setMargin(EMPTY_INSETS);
282: // b.setRequestFocusEnabled(false);
283: }
284: return b;
285: }
286:
287: /**
288: * Description of the Method
289: *
290: * @param a Description of the Parameter
291: * @param showText Description of the Parameter
292: * @return Description of the Return Value
293: */
294: public static JMenuItem createMenuItem(Action a) {
295: JMenuItem m = new JMenuItem(a);
296: boolean hideMenuItems = "true".equals(System.getProperty(
297: "gruntspud.hideMenuIcons", "false"));
298: if (hideMenuItems) {
299: m.setIcon(null);
300: } else {
301: if (a.getValue(DefaultGruntspudAction.SMALL_ICON) != null) {
302: m.setIcon((Icon) a
303: .getValue(DefaultGruntspudAction.SMALL_ICON));
304: } else {
305: m.setIcon(new EmptyIcon(16, 16));
306: }
307: }
308: return m;
309: }
310:
311: /**
312: * Description of the Method
313: *
314: * @param p Description of the Parameter
315: * @param c Description of the Parameter
316: */
317: public static void positionComponent(int p, Component c) {
318: Rectangle r = c.getGraphicsConfiguration().getBounds();
319: Dimension d = new Dimension(r.width, r.height);
320: //Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
321: if (p == NORTH_WEST) {
322: c.setLocation(0, 0);
323: } else {
324: if (p == NORTH) {
325: c.setLocation(
326: r.x + ((d.width - c.getSize().width) / 2), r.y);
327: } else {
328: if (p == NORTH_EAST) {
329: c.setLocation(r.x + (d.width - c.getSize().width),
330: r.y);
331: } else {
332: if (p == WEST) {
333: c
334: .setLocation(
335: r.x,
336: r.y
337: + ((d.height - c
338: .getSize().height) / 2));
339: } else {
340: if (p == SOUTH_WEST) {
341: c.setLocation(r.x, r.y
342: + (d.height - c.getSize().height));
343: } else {
344: if (p == EAST) {
345: c
346: .setLocation(
347: r.x
348: + d.width
349: - c.getSize().width,
350: r.y
351: + ((d.height - c
352: .getSize().height) / 2));
353: } else {
354: if (p == SOUTH_EAST) {
355: c
356: .setLocation(
357: r.x
358: + (d.width - c
359: .getSize().width),
360: r.y
361: + (d.height - c
362: .getSize().height)
363: - 30);
364: } else {
365: if (p == CENTER) {
366: c
367: .setLocation(
368: r.x
369: + ((d.width - c
370: .getSize().width) / 2),
371: r.y
372: + ((d.height - c
373: .getSize().height) / 2));
374: }
375: }
376: }
377: }
378: }
379: }
380: }
381: }
382: }
383:
384: /**
385: * Description of the Method
386: *
387: * @param resource Description of the Parameter
388: * @return Description of the Return Value
389: */
390: public static Icon loadIconForResource(String resource) {
391: URL res = UIUtil.class.getClassLoader().getResource(resource);
392: ImageIcon icon = new ImageIcon(res, res.toExternalForm());
393: if (imageFilter != null) {
394: Image img = icon.getImage();
395: if (img != null) {
396: ImageProducer producer = new FilteredImageSource(img
397: .getSource(), imageFilter);
398: Image bwImage = Toolkit.getDefaultToolkit()
399: .createImage(producer);
400: icon = new ImageIcon(bwImage, res.toExternalForm());
401: }
402: }
403: return icon;
404: }
405:
406: /**
407: * Gets the cachedIcon attribute of the UIUtil class
408: *
409: * @param key Description of the Parameter
410: * @return The cachedIcon value
411: */
412: public static Icon getCachedIcon(String key) {
413: return (Icon) iconCache.get(key);
414: }
415:
416: /**
417: * Description of the Method
418: *
419: * @param key Description of the Parameter
420: * @param resource Description of the Parameter
421: */
422: public static void cacheIcon(String key, String resource) {
423: cacheIcon(key, loadIconForResource(resource));
424: }
425:
426: /**
427: * Description of the Method
428: *
429: * @param key Description of the Parameter
430: * @param icon Description of the Parameter
431: */
432: public static void cacheIcon(String key, Icon icon) {
433: iconCache.put(key, icon);
434: }
435:
436: /**
437: * DOCUMENT ME!
438: *
439: * @param tabs DOCUMENT ME!
440: * @param policy DOCUMENT ME!
441: */
442: public static void setTabLayoutPolicy(JTabbedPane tabs, int policy) {
443: // Hack to stop the great looking compiere look and feel complaining under
444: // 1.4.1-beta1
445: if (Gruntspud.is14()
446: && !UIManager
447: .getLookAndFeel()
448: .getClass()
449: .getName()
450: .equals("org.compiere.plaf.CompiereLookAndFeel")) {
451: try {
452: Method tabplace = tabs.getClass()
453: .getMethod("setTabLayoutPolicy",
454: new Class[] { int.class });
455: tabplace.invoke(tabs, new Integer[] { new Integer(
456: policy) });
457: } catch (Exception e) {
458: }
459: }
460: }
461: }
|