001: /*
002: * Jacareto Copyright (c) 2002-2005
003: * Applied Computer Science Research Group, Darmstadt University of
004: * Technology, Institute of Mathematics & Computer Science,
005: * Ludwigsburg University of Education, and Computer Based
006: * Learning Research Group, Aachen University. All rights reserved.
007: *
008: * Jacareto is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * Jacareto is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public
019: * License along with Jacareto; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: *
022: */
023:
024: package jacareto.struct;
025:
026: import jacareto.parse.RecordTokenizer;
027: import jacareto.parse.RecordTokenizerState;
028: import jacareto.record.KeyEventRecordable;
029: import jacareto.system.Environment;
030:
031: import java.awt.event.KeyEvent;
032:
033: import java.util.Vector;
034:
035: /**
036: * This structure element stands for shift and typed keys.
037: *
038: * @author <a href="mailto:cspannagel@web.de">Christian Spannagel</a>
039: * @version 1.0
040: */
041: public class ShiftAndKeys extends StructureElement implements
042: KeyStringOwner {
043: /**
044: * Creates a new "shift and keys" structure element.
045: *
046: * @param env the environment
047: * @param children the child structure elements
048: */
049: public ShiftAndKeys(Environment env, StructureElement[] children) {
050: super (env, children);
051: }
052:
053: /**
054: * Parses a record which is tokenized by the given record tokenizer.
055: *
056: * @param env DOCUMENT ME!
057: * @param recordTokenizer the record tokenizer
058: *
059: * @return a structure element, or <code>null</code> if this class cannot parse the record at
060: * the current position
061: */
062: public static StructureElement parse(Environment env,
063: RecordTokenizer recordTokenizer) {
064: StructureElement result = null;
065: RecordTokenizerState rtState = recordTokenizer.saveState();
066: Vector addedChildren = new Vector(5, 5);
067:
068: try {
069: // Read shift pressed first
070: KeyEventRecordable shiftPressed = (KeyEventRecordable) recordTokenizer
071: .next();
072:
073: if (!((shiftPressed.getKeyCode() == KeyEvent.VK_SHIFT) && (shiftPressed
074: .getID() == KeyEvent.KEY_PRESSED))) {
075: throw new Exception();
076: }
077:
078: addedChildren.add(shiftPressed);
079:
080: // Read the other chars which are not modifiers
081: boolean found = true;
082:
083: do {
084: RecordTokenizerState stateBeforeTyped = recordTokenizer
085: .saveState();
086: KeyTyped keyTyped = (KeyTyped) KeyTyped.parse(env,
087: recordTokenizer);
088:
089: if (keyTyped == null) {
090: break;
091: }
092:
093: if (Character.isLetterOrDigit(keyTyped.getKeyChar())) {
094: addedChildren.add(keyTyped);
095: } else {
096: recordTokenizer.restoreState(stateBeforeTyped);
097: found = false;
098: }
099: } while (found);
100:
101: if (addedChildren.size() == 1) {
102: throw new Exception();
103: }
104:
105: // shift released
106: KeyEventRecordable shiftReleased = (KeyEventRecordable) recordTokenizer
107: .next();
108:
109: if (!((shiftReleased.getKeyCode() == KeyEvent.VK_SHIFT) && (shiftReleased
110: .getID() == KeyEvent.KEY_RELEASED))) {
111: throw new Exception();
112: }
113:
114: addedChildren.add(shiftReleased);
115:
116: result = new ShiftAndKeys(env, vectorToArray(addedChildren));
117: } catch (Throwable t) {
118: recordTokenizer.restoreState(rtState);
119: }
120:
121: // shift pressed, key pressed, shift released, key released
122: if (result == null) {
123: try {
124: KeyEventRecordable shiftPressed = (KeyEventRecordable) recordTokenizer
125: .next();
126: KeyEventRecordable keyPressed = (KeyEventRecordable) recordTokenizer
127: .next();
128: KeyEventRecordable shiftReleased = (KeyEventRecordable) recordTokenizer
129: .next();
130: KeyEventRecordable keyReleased = (KeyEventRecordable) recordTokenizer
131: .next();
132:
133: boolean cond = (shiftPressed.getKeyCode() == KeyEvent.VK_SHIFT)
134: && (shiftPressed.getID() == KeyEvent.KEY_PRESSED);
135: cond = cond
136: && (shiftReleased.getKeyCode() == KeyEvent.VK_SHIFT)
137: && (shiftReleased.getID() == KeyEvent.KEY_RELEASED);
138:
139: if (cond) {
140: StructureElement[] children = new StructureElement[4];
141: children[0] = shiftPressed;
142: children[1] = keyPressed;
143: children[2] = shiftReleased;
144: children[3] = keyReleased;
145: result = new ShiftAndKeys(env, children);
146: } else {
147: throw new Exception();
148: }
149: } catch (Exception e) {
150: recordTokenizer.restoreState(rtState);
151: }
152: }
153:
154: return result;
155: }
156:
157: /**
158: * Returns the name of the element.
159: *
160: * @return the name
161: */
162: public String getElementName() {
163: return language.getString("Structures.ShiftAndKeys.Name");
164: }
165:
166: /**
167: * Returns a description of the element.
168: *
169: * @return the description
170: */
171: public String getElementDescription() {
172: return language
173: .getString("Structures.ShiftAndKeys.Description");
174: }
175:
176: /**
177: * Returns a String which describes the content of the element shortly.
178: *
179: * @return a string with a short description of the element
180: */
181: public String toShortString() {
182: String result = getElementName() + " ("
183: + getInterpretedKeyString() + ")";
184:
185: return result;
186: }
187:
188: /**
189: * Returns a key string.
190: *
191: * @return the key sequence as string
192: */
193: public String getInterpretedKeyString() {
194: String result = "";
195:
196: for (int i = 1; i < (getChildrenCount() - 1); i++) {
197: if (getChild(i) instanceof KeyTyped) {
198: KeyTyped keyTyped = (KeyTyped) getChild(i);
199: result += ("" + keyTyped.getInterpretedKeyString());
200: } else {
201: KeyEventRecordable keyEvent = (KeyEventRecordable) getChild(i);
202:
203: if (keyEvent.getID() == KeyEvent.KEY_PRESSED) {
204: result += ("" + keyEvent.getInterpretedKeyString());
205: }
206: }
207: }
208:
209: return result;
210: }
211:
212: /**
213: * Returns a key string.
214: *
215: * @return the key sequence as string
216: */
217: public String getKeyString() {
218: return getInterpretedKeyString();
219: }
220:
221: /**
222: * Clones the element.
223: *
224: * @return DOCUMENT ME!
225: */
226: public Object clone() {
227: StructureElement[] clonedChildren = getClonedChildren();
228:
229: return new ShiftAndKeys(env, clonedChildren);
230: }
231: }
|