Visual Color Imbalance Detector: Reconstructed project directories and files
[VistaCID.git] / org / tjworld / components / PowerAction.java
1 /*\r
2         * PowerAction.java\r
3  *\r
4         * Created on 10 October 2001, 01:59\r
5         * $Header: $\r
6         * \r
7         * $History: $\r
8 */\r
9 package org.tjworld.components;\r
10 \r
11 import javax.swing.Icon;\r
12 import javax.swing.Action;\r
13 import java.io.Serializable;\r
14 import java.lang.Cloneable;\r
15 import java.util.Locale;\r
16 import java.util.ResourceBundle;\r
17 import javax.swing.event.SwingPropertyChangeSupport;\r
18 \r
19 /**\r
20  * <code>PowerAction</code> enhances <code>AbstractAction</code> by addding support for\r
21         * additional properties of components, such as alternate icons \r
22         * (dimmed, rollover, selected, pressed).\r
23         *\r
24         * It is used with Power implementations of several swing components such as\r
25         * <code>PowerButton, PowerMenuItem, PowerLabel, PowerTextField</code>.\r
26         *\r
27         * It can be used with <code>JButton, JMenuItem, JLabel, JTextField</code> directly\r
28         * to support more properties than just <code>name</code> and <code>icon</code> that\r
29         * <code>AbstractAction</code> supports.\r
30         *\r
31         * These new components are named <code>PowerButton, PowerMenuItem,</code> and so on.\r
32         *\r
33         * They provide additional methods for setting and getting a PowerAction on the\r
34         * component.\r
35         * \r
36         * Implementations of PowerAction need only subclass this abstract class and\r
37  * define the <code>actionPerformed</code> method. \r
38         *\r
39         * @author  TJ\r
40  * @version 1.0 10 Oct 2001 \r
41         * @since 1.4\r
42         * @see Action, AbstractAction\r
43  */\r
44 public abstract class PowerAction extends javax.swing.AbstractAction {\r
45  /** Useful constants supporting Locale-sensitive values */\r
46         public static final String LOC_KEY_NAME = "     LOC_KEY_NAME";\r
47         public static final String LOC_KEY_SHORT_DESCRIPTION = "LOC_KEY_SD";\r
48         public static final String LOC_KEY_LONG_DESCRIPTION = "LOC_KEY_LD";\r
49         public static final String LOC_KEY_ACTION_COMMAND_KEY = "LOC_KEY_AC";\r
50         public static final String LOC_KEY_MNEMONIC_KEY = "LOC_KEY_MNEM";\r
51         public static final String LOC_KEY_ACCELERATOR_KEY = "LOC_KEY_ACCEL";\r
52 \r
53  /** Flag masks for blocking selected PropertyChangeEvents */\r
54         public static final long MASK_NAME                                                                                                                      = 0x80000000;\r
55         public static final long MASK_ICON                                                                                                                      = 0x40000000;\r
56         public static final long MASK_SHORT_DESCRIPTION         = 0x20000000;\r
57         public static final long MASK_LONG_DESCRIPTION                  = 0x10000000;\r
58         public static final long MASK_ACTION_COMMAND_KEY = 0x08000000;\r
59         public static final long MASK_MNEMONIC_KEY                                                      = 0x04000000;\r
60         public static final long MASK_ACCELERATOR_KEY                           = 0x02000000;\r
61  \r
62         public static final long MASK_LOC_NAME                                                                                                                  = 0x00008000;\r
63         public static final long MASK_LOC_ICON                                                                                                                  = 0x00004000;\r
64         public static final long MASK_LOC_SHORT_DESCRIPTION             = 0x00002000;\r
65         public static final long MASK_LOC_LONG_DESCRIPTION                      = 0x00001000;\r
66         public static final long MASK_LOC_ACTION_COMMAND_KEY = 0x00000800;\r
67         public static final long MASK_LOC_MNEMONIC                                                                                      = 0x00000400;\r
68         public static final long MASK_LOC_ACCELERATOR_KEY                               = 0x00000200;\r
69         \r
70         /** frequently used masks */\r
71         public static final long MASK_ALL                                                                                                       = 0xFFFFFFFF; // everything enabled\r
72         public static final long MASK_JMENUITEM                                                 = 0xFFFFFFFF; // everything enabled\r
73         public static final long MASK_JBUTTON                                                                   = 0xFDFFFFFF; // no accelerator\r
74         public static final long MASK_JTOOLBAR_BUTTON   = 0x75FFFFFF; // no name, action command, accelerator\r
75         public static final long MASK_NONE                                                                                              = 0x00000000; // nothing enabled\r
76         \r
77         /** current mask flags */\r
78         protected long maskFlags = 0xFFFFFFFF;\r
79         \r
80         /** Keep track of the state of the Property Change Listener interface */\r
81         protected boolean firePropertyChangeEnabled = true;\r
82         \r
83         /** A copy of the original change support object */\r
84  protected SwingPropertyChangeSupport oldChangeSupport;\r
85         \r
86         /** make the action Locale-sensitive */\r
87         protected Locale currentLocale = null;\r
88 \r
89         /** Creates new default PowerAction */\r
90  public PowerAction() {\r
91                 super(); // nothing special for the default constructor to do, so let super class do it's thing\r
92  }\r
93                                 \r
94         /** Create a new PowerAction that supports just the properties that <code>javax.swing.AbstractButton</code> uses.\r
95                 *\r
96                 * @param name The Text or Title of a component using this action\r
97                 * @param icon The Icon associated with this action\r
98                 * @param tooltip The popup tooltip associated with <code>JComponent</code>\r
99                 * @param longDesc The longer description associated with this action (for use in help services, etc.)\r
100                 * @param actionCommand The action command name (e.g: New, Save, Delete. etc.)\r
101                 * @param mnemonic The character in <code>name</code> used as a quick-key (gets underlined in menu's and buttons)\r
102                 * @param accelerator The key-combination required to activate this action from the parent window or frame\r
103                 *\r
104                 * @see AbstractButton#configurePropertiesFromAction\r
105                 */\r
106  public PowerAction(String name, Icon icon, String tooltip, String longDesc, String actionCommand, int mnemonic, javax.swing.KeyStroke accelerator) {\r
107                 super(name, icon); // let super add these, don't duplicate code\r
108                 \r
109                 // add key-value pairs ONLY if the received value is not 'empty'\r
110                 if(tooltip != null) putValue(Action.SHORT_DESCRIPTION, tooltip);\r
111                 if(longDesc != null) putValue(Action.LONG_DESCRIPTION, longDesc);\r
112                 if(actionCommand != null) putValue(Action.ACTION_COMMAND_KEY, actionCommand);\r
113                 if(mnemonic > 0) putValue(Action.MNEMONIC_KEY, new Integer(mnemonic));\r
114                 if(accelerator != null) putValue(Action.ACCELERATOR_KEY, accelerator);\r
115         }\r
116         \r
117         /** Create a new PowerAction that supports locale-sensitive values\r
118                 *\r
119                 * The <code>ResourceBundle</code> keys that indentify the values used by the action\r
120                 * are stored as Key/Values along with the standard <code>Action</code> key/value pairs.\r
121                 *\r
122                 * Hereafter, a simple call to <code>setLocale(loc, res)</code> allows the action to update\r
123                 * itself with locale-sensitive values.\r
124                 *\r
125                 * @param name The Text or Title of a component using this action\r
126                 * @param icon The Icon associated with this action\r
127                 * @param tooltip The popup tooltip associated with <code>JComponent</code>\r
128                 * @param longDesc The longer description associated with this action (for use in help services, etc.)\r
129                 * @param actionCommand The action command name (e.g: New, Save, Delete. etc.)\r
130                 * @param mnemonic The character in <code>name</code> used as a quick-key (gets underlined in menu's and buttons)\r
131                 * @param accelerator The key-combination required to activate this action from the parent window or frame\r
132                 * @param loc The Locale currently assigned to this action\r
133                 * @param locName The <code>ResourceBundle</code> key used to identify the NAME value\r
134                 * @param locTooltip The <code>ResourceBundle</code> key used to identify the SHORT_DESCRIPTION value\r
135                 * @param locLongDesc The <code>ResourceBundle</code> key used to identify the LONG_DESCRIPTION value\r
136                 * @param locActionCommand The <code>ResourceBundle</code> key used to identify the ACTION_COMMAND value\r
137                 * @param locMnemonic The <code>ResourceBundle</code> key used to identify the MNEMONIC value\r
138                 * @param locAccelerator The <code>ResourceBundle</code> key used to identify the ACCELERATOR value\r
139                 *\r
140                 * @see ResourceBundle\r
141                 * @see Action\r
142                 * @see PowerAction#setLocale\r
143                 */\r
144  public PowerAction(String name, Icon icon, String tooltip, String longDesc, String actionCommand, int mnemonic, javax.swing.KeyStroke accelerator,\r
145   java.util.Locale loc, String locName, String locTooltip, String locLongDesc, String locActionCommand, String locMnemonic, String locAccelerator) {\r
146                 this(name, icon, tooltip, longDesc, actionCommand, mnemonic, accelerator); // don't duplicate code\r
147                 \r
148                 // add Locale-sensitve key-value pairs ONLY if the received value is not 'empty'\r
149                 if(locName != null) putValue(LOC_KEY_NAME, locName);\r
150                 if(locTooltip != null) putValue(LOC_KEY_SHORT_DESCRIPTION, locTooltip);\r
151                 if(locLongDesc != null) putValue(LOC_KEY_LONG_DESCRIPTION, locLongDesc);\r
152                 if(locActionCommand != null) putValue(LOC_KEY_ACTION_COMMAND_KEY, locActionCommand);\r
153                 if(locMnemonic != null) putValue(LOC_KEY_MNEMONIC_KEY, locMnemonic);\r
154                 if(locAccelerator != null) putValue(LOC_KEY_ACCELERATOR_KEY, locAccelerator);\r
155                 \r
156                 if(loc != null) // set the Locale\r
157                         currentLocale = loc;\r
158                 else\r
159                         currentLocale = Locale.getDefault();\r
160         }\r
161 \r
162         /** Are PropertyChangeEvents enabled?\r
163                 *\r
164                 * @returns true is they are, false otherwise\r
165                 */\r
166  public boolean isFirePropertyChangeEnabled() {\r
167                 return firePropertyChangeEnabled;\r
168         }\r
169         \r
170         public void setPropertyChangeMask(long mask) {\r
171                 maskFlags = mask; // update the enabled PropertyChange events           \r
172         }\r
173         \r
174         public long getPropertyChangeMask() {\r
175                 return maskFlags;\r
176         }\r
177         \r
178         /** Enable or Disable PropertyChangeEvent notifications\r
179                 *\r
180                 * @param enabled true to enable, false to disable\r
181                 */\r
182  public void setFirePropertyChangeEnabled(boolean enabled) {\r
183                 if(enabled) { // return the underlying AbstractAction.changeSupport to it's original state\r
184                         if(changeSupport == null && oldChangeSupport != null) // don't mes it up if it's not null\r
185                                 changeSupport = oldChangeSupport; // allow AbstractAction.firePropertyChange() to work again\r
186                 }       else { // disable AbstractAction.firePropertyChange()\r
187                         oldChangeSupport = changeSupport; // keep a copy, ready for re-enabling\r
188                         changeSupport = null; // clear the change support\r
189                 }\r
190                         \r
191                 firePropertyChangeEnabled = enabled; // update the flag\r
192         }\r
193                 \r
194         /** Update the locale, alter strings if necessary\r
195                 *\r
196                 * For each <code>Action</code> key/value pair that has an associated <code>ResourceBundle</code>\r
197                 * key specified, the value will be updated from the specified <code>ResourceBundle</code>\r
198                 *\r
199                 * @param loc The new locale\r
200                 * @param res The resource bundle to get new strings from\r
201                 */\r
202         public void setLocale(Locale loc, ResourceBundle res) {\r
203                 // make sure locale is valid, in use, and not already changed; otherwise ignore it\r
204   if(loc != null && currentLocale != null && loc != currentLocale) { \r
205                         currentLocale = loc; // update locale\r
206                         if(res != null) { // make sure the resource bundle is good too\r
207 \r
208                                 /* for each potential Action key/value pair, only update if the Locale-Key\r
209                                         * is in the collection of key/value pairs\r
210                                         *\r
211                                         * would be cleaner source to do this in an iteration - maybe need to create\r
212                                         * an array to store the static constant key names from Action and PowerAction??\r
213                                         */\r
214                                 String locKeyName = null;\r
215                                 Object actValue = null;\r
216                                 Object locValue = null;\r
217 \r
218                                 if((actValue = getValue(Action.NAME)) != null) { // there is a key/value pair that might need updating\r
219                                 if((locKeyName = (String)getValue(LOC_KEY_NAME)) != null) { // a locale-sensitive resource key has been stored...\r
220                                         locValue = res.getObject(locKeyName); // ...so request it's value from the resource bundle\r
221                                                 if(locValue != null) { // don't try to replace a good value with an empty one\r
222                                                         if((maskFlags & MASK_NAME) == MASK_NAME) // disable PropertyChangeEvents if mask is set\r
223                                                                 setFirePropertyChangeEnabled(false);\r
224 \r
225                                                         putValue(Action.NAME, locValue); // change the value\r
226                                                         setFirePropertyChangeEnabled(true); // ensure PropertyChangeEvents are enabled\r
227                                                 }\r
228                                 }\r
229                                 }\r
230 \r
231                                 if((actValue = getValue(Action.SHORT_DESCRIPTION)) != null) { // there is a key/value pair that might need updating\r
232                                 if((locKeyName = (String)getValue(LOC_KEY_SHORT_DESCRIPTION)) != null) { // a locale-sensitive resource key has been stored...\r
233                                         locValue = res.getObject(locKeyName); // ...so request it's value from the resource bundle\r
234                                                 if(locValue != null) { // don't try to replace a good value with an empty one\r
235                                                         if((maskFlags & MASK_SHORT_DESCRIPTION) == MASK_SHORT_DESCRIPTION) // disable PropertyChangeEvents if mask is set\r
236                                                                 setFirePropertyChangeEnabled(false);\r
237 \r
238                                          putValue(Action.SHORT_DESCRIPTION, locValue);\r
239                                                         setFirePropertyChangeEnabled(true); // ensure PropertyChangeEvents are enabled\r
240                                                 }\r
241                                 }\r
242                                 }\r
243 \r
244                                 if((actValue = getValue(Action.LONG_DESCRIPTION)) != null) { // there is a key/value pair that might need updating\r
245                                 if((locKeyName = (String)getValue(LOC_KEY_LONG_DESCRIPTION)) != null) { // a locale-sensitive resource key has been stored...\r
246                                         locValue = res.getObject(locKeyName); // ...so request it's value from the resource bundle\r
247                                                 if(locValue != null) { // don't try to replace a good value with an empty one\r
248                                                         if((maskFlags & MASK_LONG_DESCRIPTION) == MASK_LONG_DESCRIPTION) // disable PropertyChangeEvents if mask is set\r
249                                                                 setFirePropertyChangeEnabled(false);\r
250                                                 \r
251                                                         putValue(Action.LONG_DESCRIPTION, locValue);\r
252                                                         setFirePropertyChangeEnabled(true); // ensure PropertyChangeEvents are enabled\r
253                                                 }\r
254                                 }\r
255                                 }\r
256 \r
257                                 if((actValue = getValue(Action.ACTION_COMMAND_KEY)) != null) { // there is a key/value pair that might need updating\r
258                                 if((locKeyName = (String)getValue(LOC_KEY_ACTION_COMMAND_KEY)) != null) { // a locale-sensitive resource key has been stored...\r
259                                         locValue = res.getObject(locKeyName); // ...so request it's value from the resource bundle\r
260                                                 if(locValue != null) { // don't try to replace a good value with an empty one\r
261                                                         if((maskFlags & MASK_ACTION_COMMAND_KEY) == MASK_ACTION_COMMAND_KEY) // disable PropertyChangeEvents if mask is set\r
262                                                                 setFirePropertyChangeEnabled(false);\r
263                                         putValue(Action.ACTION_COMMAND_KEY, locValue);\r
264                                                         setFirePropertyChangeEnabled(true); // ensure PropertyChangeEvents are enabled\r
265                                                 }\r
266                                 }\r
267                                 }\r
268 \r
269                                 if((actValue = getValue(Action.MNEMONIC_KEY)) != null) { // there is a key/value pair that might need updating\r
270                                 if((locKeyName = (String)getValue(LOC_KEY_MNEMONIC_KEY)) != null) { // a locale-sensitive resource key has been stored...\r
271                                         locValue = res.getObject(locKeyName); // ...so request it's value from the resource bundle\r
272                                                 if(locValue != null) { // don't try to replace a good value with an empty one\r
273                                                         if((maskFlags & MASK_MNEMONIC_KEY) == MASK_MNEMONIC_KEY) // disable PropertyChangeEvents if mask is set\r
274                                                                 setFirePropertyChangeEnabled(false); // ensure PropertyChangeEvents are enabled\r
275 \r
276                                                         putValue(Action.MNEMONIC_KEY, locValue);\r
277                                                         setFirePropertyChangeEnabled(true); // ensure PropertyChangeEvents are enabled\r
278                                                 }\r
279                                 }\r
280                                 }\r
281 \r
282                                 if((actValue = getValue(Action.ACCELERATOR_KEY)) != null) { // there is a key/value pair that might need updating\r
283                                 if((locKeyName = (String)getValue(LOC_KEY_ACCELERATOR_KEY)) != null) { // a locale-sensitive resource key has been stored...\r
284                                         locValue = res.getObject(locKeyName); // ...so request it's value from the resource bundle\r
285                                                 if(locValue != null) { // don't try to replace a good value with an empty one\r
286                                                  if((maskFlags & MASK_ACCELERATOR_KEY) == MASK_ACCELERATOR_KEY) // disable PropertyChangeEvents if mask is set\r
287                                                                 setFirePropertyChangeEnabled(false);\r
288                                                                 \r
289                                                  putValue(Action.ACCELERATOR_KEY, locValue);\r
290                                                         setFirePropertyChangeEnabled(true); // ensure PropertyChangeEvents are enabled\r
291                                                 }\r
292                                 }\r
293                                 }\r
294                         }\r
295                 }                               \r
296         }\r
297         \r
298         /** Get the current Locale of the Action\r
299                 *\r
300                 * @returns The current locale\r
301                 */\r
302  public Locale getLocale() {\r
303                 return currentLocale;\r
304         }\r
305 }\r