001: package discRack;
002:
003: import java.awt.*;
004: import java.awt.event.*;
005: import java.beans.*;
006: import java.net.URL;
007: import java.util.*;
008: import java.io.*;
009:
010: import javax.swing.*;
011: import javax.swing.undo.*;
012: import javax.swing.event.*;
013: import javax.swing.tree.*;
014:
015: /**
016: * Implements the static methods that are used to implement
017: * multilanguage support, and to create some resources as
018: * menubar, toolbars and button panels.
019: *
020: * @author Sasa Bojanic
021: * @version 1.0
022: */
023: public class BarFactory extends JPanel {
024: /** Suffix applied to the key used in resource file lookups for an image. */
025: public static final String imageSuffix = "Image";
026: /** Suffix applied to the key used in resource file lookups for a label. */
027: public static final String labelSuffix = "Label";
028: /** Suffix applied to the key used in resource file lookups for an action. */
029: public static final String actionSuffix = "Action";
030: /** Suffix applied to the key used in resource file lookups for a submenu. */
031: public static final String menuSuffix = "Menu";
032: /** Suffix applied to the key used in resource file lookups for a menuitem (instead of action). */
033: public static final String accelSuffix = "Accel";
034: /** Suffix applied to the key used in resource file lookups for a menuitem (instead of action) */
035: public static final String mnemonicSuffix = "Mnemonic";
036: /** Suffix applied to the key used in resource file lookups for tooltip text. */
037: public static final String tipSuffix = "Tooltip";
038:
039: //********************** CREATE TOOLBARS AND THEIR COMPONENTS *****************
040: /**
041: * Creates application's toolbars. Reads resource to find out which
042: * toolbars to create. The toolbars are put into the tabbed pane.
043: * NOTE: this method is modified to accept a creation of a button
044: * after toolbars.
045: * @see #createToolbar
046: */
047: public static Component createToolBars(String toolbarToLoad,
048: Map actions) {
049: String[] toolBars = Utils.tokenize(ResourceManager
050: .getResourceString(toolbarToLoad), " ");
051: JPanel lastPanel = new JPanel();
052: lastPanel.setLayout(new BorderLayout());
053: JTabbedPane tabbedPane = new JTabbedPane();
054: int i;
055: for (i = 0; i < toolBars.length; i++) {
056: // if I found "-" it means that button will be created
057: if (!toolBars[i].equals("-")) {
058: String label = ResourceManager
059: .getResourceString(toolBars[i] + labelSuffix);
060: final JPanel panel = new JPanel();
061: panel.setLayout(new BorderLayout());
062: final Component c = createToolbar(toolBars[i], actions);
063: panel.add(BorderLayout.WEST, c);
064: panel.add(c);
065: ImageIcon icon = null;
066: URL url = ResourceManager.getResource(toolBars[i]
067: + imageSuffix);
068: if (url != null) {
069: icon = new ImageIcon(url);
070: }
071: tabbedPane.addTab(label, icon, panel, label);
072: } else {
073: break;
074: }
075: }
076: tabbedPane.setPreferredSize(new Dimension(500, 60));
077: tabbedPane.setSelectedIndex(i - 1);
078:
079: lastPanel.add(BorderLayout.WEST, tabbedPane);
080: if (i < toolBars.length - 1) {
081: Component c = createButton(toolBars[i + 1], actions, false);
082: lastPanel.add(BorderLayout.EAST, c);
083: }
084:
085: return lastPanel;
086: }
087:
088: /**
089: * Create the toolbar. By default this reads the
090: * resource file for the definition of the toolbar.
091: * @see #createButton
092: */
093: public static Component createToolbar(String key, Map actions) {
094: String label = ResourceManager.getResourceString(key
095: + labelSuffix);
096: JToolBar toolbar = new JToolBar(label);
097: toolbar.putClientProperty("JToolBar.isRollover", Boolean.TRUE);
098: toolbar.setFloatable(false);
099: String[] toolKeys = Utils.tokenize(ResourceManager
100: .getResourceString(key), " ");
101: for (int i = 0; i < toolKeys.length; i++) {
102: if (toolKeys[i].equals("-")) {
103: toolbar.add(Box.createHorizontalStrut(10));
104: } else {
105: toolbar.add(createButton(toolKeys[i], actions, false));
106: }
107: }
108: toolbar.add(Box.createHorizontalGlue());
109: return toolbar;
110: }
111:
112: /**
113: * Hook through which every toolbar item is created.
114: * Creates a button to go inside of the toolbar. By default this
115: * will load an image resource. The image filename is relative to
116: * the classpath (including the '.' directory if its a part of the
117: * classpath), and may either be in a JAR file or a separate file.
118: *
119: * @param key The key in the resource file to serve as the basis
120: * of lookups.
121: */
122: public static Component createButton(String key, Map actions,
123: boolean setText) {
124: AbstractButton b = null;
125: URL url = ResourceManager.getResource(key + imageSuffix);
126: if (url != null) {
127: b = new JButton(new ImageIcon(url)) {
128: public float getAlignmentY() {
129: return 0.5f;
130: }
131: };
132: if (setText) {
133: b.setText(ResourceManager.getResourceString(key
134: + labelSuffix));
135: }
136: } else {
137: b = new JButton(ResourceManager.getResourceString(key
138: + labelSuffix)) {
139: public float getAlignmentY() {
140: return 0.5f;
141: }
142: };
143: }
144:
145: b.setMargin(new Insets(1, 1, 1, 1));
146: b.setRequestFocusEnabled(false);
147:
148: String astr = ResourceManager.getResourceString(key
149: + actionSuffix);
150: if (astr == null) {
151: astr = key;
152: }
153: Action a = (Action) actions.get(astr);
154: if (a != null) {
155: b.setActionCommand(astr);
156: b.addActionListener(a);
157: a.addPropertyChangeListener(createActionChangeListener(b));
158: b.setEnabled(a.isEnabled());
159: } else {
160: b.setEnabled(false);
161: }
162:
163: String tip = ResourceManager.getResourceString(key + tipSuffix);
164: if (tip != null) {
165: b.setToolTipText(tip);
166: }
167: return b;
168:
169: }
170:
171: //********************* CREATING MENUBAR AND IT'S COMPONENTS ******************
172: /**
173: * Create the menubar for the app. By default this pulls the
174: * definition of the menu from the associated resource file.
175: */
176: public static JMenuBar createMenubar(String menubarToLoad,
177: Map actions) {
178: JMenuItem mi;
179: JMenuBar mb = new JMenuBar();
180:
181: String[] menuKeys = Utils.tokenize(ResourceManager
182: .getResourceString(menubarToLoad), " ");
183: for (int i = 0; i < menuKeys.length; i++) {
184: String[] itemKeys = Utils.tokenize(ResourceManager
185: .getResourceString(menuKeys[i]), " ");
186: JMenu m = createMenu(menuKeys[i], itemKeys, actions);
187: if (m != null) {
188: mb.add(m);
189: }
190: }
191:
192: return mb;
193: }
194:
195: /**
196: * Create a menu for the app.
197: */
198: public static JMenu createMenu(String key, String[] itemKeys,
199: Map actions) {
200: JMenu menu = new JMenu(ResourceManager.getResourceString(key
201: + labelSuffix));
202: for (int i = 0; i < itemKeys.length; i++) {
203: if (itemKeys[i].equals("-")) {
204: menu.addSeparator();
205: } else {
206: JMenuItem mi = createMenuItem(itemKeys[i], actions);
207: menu.add(mi);
208: }
209: }
210: URL url = ResourceManager.getResource(key + imageSuffix);
211: if (url != null) {
212: menu.setHorizontalTextPosition(JButton.RIGHT);
213: menu.setIcon(new ImageIcon(url));
214: }
215:
216: setMnemonic(menu, ResourceManager.getResourceString(key
217: + mnemonicSuffix));
218:
219: menu.setActionCommand(key);
220: return menu;
221: }
222:
223: /**
224: * This is the hook through which all menu items are
225: * created.
226: */
227: public static JMenuItem createMenuItem(String cmd, Map actions) {
228: String subMenu = ResourceManager.getResourceString(cmd
229: + menuSuffix);
230: if (subMenu != null) {
231: String[] itemKeys = Utils.tokenize(subMenu, " ");
232: JMenu mn = createMenu(cmd, itemKeys, actions);
233: return mn;
234: } else {
235: JMenuItem mi;
236: mi = new JMenuItem(ResourceManager.getResourceString(cmd
237: + labelSuffix));
238: URL url = ResourceManager.getResource(cmd + imageSuffix);
239: if (url != null) {
240: mi.setHorizontalTextPosition(JButton.RIGHT);
241: mi.setIcon(new ImageIcon(url));
242: }
243: setAccelerator(mi, ResourceManager.getResourceString(cmd
244: + accelSuffix));
245: setMnemonic(mi, ResourceManager.getResourceString(cmd
246: + mnemonicSuffix));
247:
248: String astr = ResourceManager.getResourceString(cmd
249: + actionSuffix);
250: if (astr == null) {
251: astr = cmd;
252: }
253: mi.setActionCommand(astr);
254: Action a = (Action) actions.get(astr);
255: if (a != null) {
256: mi.addActionListener(a);
257: a
258: .addPropertyChangeListener(createActionChangeListener(mi));
259: mi.setEnabled(a.isEnabled());
260: }
261: return mi;
262: }
263: }
264:
265: public static void setMnemonic(JMenuItem mi, String mnemonic) {
266: if (mnemonic != null && mnemonic.length() > 0) {
267: mi.setMnemonic(mnemonic.charAt(0));
268: }
269: }
270:
271: public static void setAccelerator(JMenuItem mi, String accel) {
272: if (accel != null) {
273: try {
274: int mask = 0;
275: if (accel.startsWith("CTRL")) {
276: mask += ActionEvent.CTRL_MASK;
277: accel = accel.substring(5);
278: }
279: if (accel.startsWith("SHIFT")) {
280: mask += ActionEvent.SHIFT_MASK;
281: accel = accel.substring(6);
282: }
283: if (accel.startsWith("ALT")) {
284: mask += ActionEvent.ALT_MASK;
285: accel = accel.substring(4);
286: }
287: int key = KeyEvent.class.getField("VK_" + accel)
288: .getInt(null);
289: mi.setAccelerator(KeyStroke.getKeyStroke(key, mask));
290: } catch (Exception e) {
291: System.err
292: .println("Error while assigning accelerator !!!");
293: }
294: }
295: }
296:
297: //********************* CREATING BUTTONPANEL ******************
298: /**
299: * Create the button panel. By default this reads the
300: * resource file for the definition of the panel.
301: */
302: public static Component createButtonPanel(String key, Map actions) {
303: String label = ResourceManager.getResourceString(key
304: + labelSuffix);
305: JPanel p = new JPanel();
306: String[] buttonKeys = Utils.tokenize(ResourceManager
307: .getResourceString(key), " ");
308: for (int i = 0; i < buttonKeys.length; i++) {
309: if (buttonKeys[i].equals("-")) {
310: p.add(Box.createHorizontalStrut(5));
311: } else {
312: p.add(createButton(buttonKeys[i], actions, true));
313: }
314: }
315: return p;
316: }
317:
318: //************************* ACTIONCHANGEDLISTENER CLASS **********************
319: // Yarked from JMenu, ideally this would be public.
320: /**
321: * Class used to change enable state of buttons.
322: */
323: private static class ActionChangedListener implements
324: PropertyChangeListener {
325: AbstractButton button;
326:
327: ActionChangedListener(AbstractButton b) {
328: super ();
329: button = b;
330: }
331:
332: public void propertyChange(PropertyChangeEvent e) {
333: String propertyName = e.getPropertyName();
334: if (e.getPropertyName().equals(Action.NAME)
335: && button instanceof JMenuItem) {
336: String text = (String) e.getNewValue();
337: button.setText(text);
338: } else {
339: if (propertyName.equals("enabled")) {
340: Boolean enabledState = (Boolean) e.getNewValue();
341: button.setEnabled(enabledState.booleanValue());
342: }
343: }
344: }
345: }
346:
347: //********************* END OF ACTIONCHANGEDLISTENER CLASS ********************
348: /**
349: * Creates ActionChangeListener object.
350: */
351: private static PropertyChangeListener createActionChangeListener(
352: AbstractButton b) {
353: return new BarFactory.ActionChangedListener(b);
354: }
355:
356: }
|