001: /*
002: #IFNDEF ALT_LICENSE
003: ThinWire(R) RIA Ajax Framework
004: Copyright (C) 2003-2007 Custom Credit Systems
005:
006: This library is free software; you can redistribute it and/or modify it under
007: the terms of the GNU Lesser General Public License as published by the Free
008: Software Foundation; either version 2.1 of the License, or (at your option) any
009: later version.
010:
011: This library is distributed in the hope that it will be useful, but WITHOUT ANY
012: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
013: PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
014:
015: You should have received a copy of the GNU Lesser General Public License along
016: with this library; if not, write to the Free Software Foundation, Inc., 59
017: Temple Place, Suite 330, Boston, MA 02111-1307 USA
018:
019: Users who would rather have a commercial license, warranty or support should
020: contact the following company who invented, built and supports the technology:
021:
022: Custom Credit Systems, Richardson, TX 75081, USA.
023: email: info@thinwire.com ph: +1 (888) 644-6405
024: http://www.thinwire.com
025: #ENDIF
026: [ v1.2_RC2 ]
027: */
028: package thinwire.ui.event;
029:
030: import java.util.Arrays;
031: import java.util.EventObject;
032:
033: import thinwire.ui.Component;
034:
035: /**
036: * @author Joshua J. Gertzen
037: */
038: public class KeyPressEvent extends EventObject {
039: private static final String[] specialKeyNames;
040: static {
041: specialKeyNames = new String[] { "Dash", "=", "`", "[", "]",
042: "\\", ";", "'", ",", ".", "/", "PageUp", "PageDown",
043: "End", "Home", "ArrowLeft", "ArrowRight", "ArrowDown",
044: "ArrowUp", "Space", "Enter", "Esc", "Tab", "BackSpace",
045: "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9",
046: "F10", "F11", "F12", "Del", "Ins", "Pause",
047: "ScrollLock", "NumLock", "Num0", "Num1", "Num2",
048: "Num3", "Num4", "Num5", "Num6", "Num7", "Num8", "Num9",
049: "Num*", "Num+", "NumDash", "Num/", "Num." };
050:
051: Arrays.sort(specialKeyNames, String.CASE_INSENSITIVE_ORDER);
052: }
053:
054: private static String getKeyName(String key) {
055: if (key.length() == 1 && key.matches("[A-Z0-9]"))
056: return key;
057:
058: if (key.length() == 1 && key.matches("[a-z]")) {
059: return key.toUpperCase();
060: } else {
061: if (key.indexOf('_') > 0)
062: key = key.replaceFirst("[_]", "");
063: int index = Arrays.binarySearch(specialKeyNames, key,
064: String.CASE_INSENSITIVE_ORDER);
065:
066: if (index >= 0) {
067: return specialKeyNames[index];
068: } else {
069: throw new IllegalArgumentException(
070: "Invalid key format:" + key);
071: }
072: }
073: }
074:
075: /**
076: * Combines the individual elements of a key press combination into a normalized string. The first part of the returned string
077: * contains the following key modifier string:
078: * <ul>
079: * <li>If <code>ctrl</code> is true, "Ctrl-" is the first part of the string.</li>
080: * <li>If <code>alt</code> is true, then "Alt-" is the first part of the string.</li>
081: * <li>If <code>shift</code> is true, then "Shift-" is the first part of the string.</li>
082: * <li>If any combination of <code>ctrl</code>, <code>alt</code> and <code>shift</code> is true, then the first part of
083: * the string will be a combination "Ctrl-", "Alt-" and "Shift-", in that order. Ex. If <code>ctrl</code> and
084: * <code>shift</code> are true, but <code>alt</code> is false, the first part of the string will be "Ctrl-Shift-".
085: * <li>If neither <code>ctrl</code>, <code>alt</code> or <code>shift</code> is true, then an empty value is the first
086: * part of the string.</li>
087: * </ul>
088: * The last part of the string is a result of the value specified by the <code>key</code> argument. However, it is normalized
089: * into one of the following values: <br>
090: * <p>
091: * "Dash", "=", "`", "[", "]", "\\", ";", "'", ",", ".", "/", "PageUp", "PageDown", "End", "Home", "ArrowLeft", "ArrowRight",
092: * "ArrowDown", "ArrowUp", "Space", "Enter", "Esc", "Tab", "BackSpace", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9",
093: * "F10", "F11", "F12", "Del", "Ins", "Pause", "ScrollLock", "NumLock", "Num0", "Num1", "Num2", "Num3", "Num4", "Num5", "Num6",
094: * "Num7", "Num8", "Num9", "Num*", "Num+", "NumDash", "Num/", "Num."
095: * </p>
096: * @param ctrl if true, the returned string will contain "Ctrl-" per the rules above.
097: * @param alt if true, the returned string will contain "Alt-" per the rules above.
098: * @param shift if true, the returned string will contain "Shift-" per the rules above.
099: * @param key returned as part of the string, only in a normalized form per the rules above.
100: * @return a key press combo string representing the elements specified per the rules above.
101: */
102: public static String encodeKeyPressCombo(boolean ctrl, boolean alt,
103: boolean shift, String key) {
104: StringBuilder sb = new StringBuilder();
105: if (ctrl)
106: sb.append("Ctrl-");
107: if (alt)
108: sb.append("Alt-");
109: if (shift)
110: sb.append("Shift-");
111: sb.append(getKeyName(key));
112: return sb.toString();
113: }
114:
115: /**
116: * Parses the specified <code>keyPressCombo</code> and return's it in a normalized form. This method will accept a string that
117: * is of any case and that has it's key modifier(s) in any order. The sole restriction is that the elements of the key press
118: * combination must be separated by a dash '-'. The purpose of this method is to provide a way of generating a properly formed
119: * key press combination strings (i.e. normalized). The normalized string form returned by this method is defined by the
120: * <code>encodeKeyPressCombo</code> method above.
121: * @param keyPressCombo a key press combo in any dash separated format.
122: * @return a normalized form of keyPressCombo, per the defintion in the encodeKeyPressCombo method.
123: * @see #encodeKeyPressCombo(boolean, boolean, boolean, String)
124: */
125: public static String normalizeKeyPressCombo(String keyPressCombo) {
126: if (keyPressCombo == null || keyPressCombo.length() == 0)
127: throw new IllegalArgumentException(
128: "keyPressCombo == null || keyPressCombo.length() == 0");
129: boolean ctrl = false;
130: boolean alt = false;
131: boolean shift = false;
132: String key = "";
133: String[] parts = keyPressCombo.toUpperCase().split("-");
134: if (parts.length > 4)
135: throw new IllegalArgumentException("Invalid key combo:"
136: + keyPressCombo);
137:
138: for (String part : parts) {
139: if (part.equals("CTRL")) {
140: ctrl = true;
141: } else if (part.equals("ALT")) {
142: alt = true;
143: } else if (part.equals("SHIFT")) {
144: shift = true;
145: } else {
146: key = getKeyName(part);
147: break;
148: }
149: }
150:
151: return encodeKeyPressCombo(ctrl, alt, shift, key);
152: }
153:
154: private String stringValue;
155: private boolean ctrl;
156: private boolean alt;
157: private boolean shift;
158: private String key;
159: private String keyPressCombo;
160:
161: public KeyPressEvent(String keyPressCombo, Component source) {
162: super (source);
163: this .keyPressCombo = keyPressCombo = normalizeKeyPressCombo(keyPressCombo);
164: ctrl = keyPressCombo.indexOf("Ctrl-") >= 0;
165: alt = keyPressCombo.indexOf("Alt-") >= 0;
166: shift = keyPressCombo.indexOf("Shift-") >= 0;
167: key = keyPressCombo
168: .substring(keyPressCombo.lastIndexOf('-') + 1);
169: }
170:
171: public Component getSourceComponent() {
172: return (Component) getSource();
173: }
174:
175: public boolean isCtrl() {
176: return ctrl;
177: }
178:
179: public boolean isAlt() {
180: return alt;
181: }
182:
183: public boolean isShift() {
184: return shift;
185: }
186:
187: public String getKey() {
188: return key;
189: }
190:
191: public String getKeyPressCombo() {
192: return keyPressCombo;
193: }
194:
195: public boolean equals(Object o) {
196: return o instanceof KeyPressEvent
197: && toString().equals(o.toString());
198: }
199:
200: public int hashCode() {
201: return toString().hashCode();
202: }
203:
204: public String toString() {
205: if (stringValue == null)
206: stringValue = "KeyPressEvent{keyPressCombo:"
207: + keyPressCombo + ",sourceComponent:"
208: + source.getClass().getName() + "@"
209: + System.identityHashCode(source) + "}";
210: return stringValue;
211: }
212: }
|