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