001: package abbot.editor.recorder;
002:
003: import java.awt.*;
004: import java.awt.event.*;
005:
006: import javax.swing.*;
007:
008: import abbot.Log;
009: import abbot.script.*;
010: import abbot.script.Action;
011: import abbot.tester.*;
012: import abbot.util.AWT;
013:
014: /**
015: * Record basic semantic events you might find on an JComboBox. <p>
016: * <ul>
017: * <li>Select an item by value (toString representation)
018: * <li>Enter a value (if editable) (not done)
019: * </ul>
020: */
021: public class JComboBoxRecorder extends JComponentRecorder {
022:
023: private JComboBoxTester tester = new JComboBoxTester();
024: private JComboBox combo = null;
025: private JList list = null;
026: private int index = -1;
027: private ActionListener listener = null;
028:
029: public JComboBoxRecorder(Resolver resolver) {
030: super (resolver);
031: }
032:
033: /** Make sure we only operate on a JComboBox. */
034: public boolean accept(AWTEvent event) {
035: if (isClick(event) && getComboBox(event) == null) {
036: return false;
037: }
038: return super .accept(event);
039: }
040:
041: protected void init(int recordingType) {
042: super .init(recordingType);
043: combo = null;
044: list = null;
045: index = -1;
046: listener = null;
047: }
048:
049: /** Return the JComboBox for the given event, or null if none. */
050: private JComboBox getComboBox(AWTEvent event) {
051: Component comp = (Component) event.getSource();
052: // Depends somewhat on LAF; sometimes the combo box is itself the
053: // button, sometimes a panel containing the button.
054: if (comp instanceof javax.swing.JButton)
055: comp = comp.getParent();
056: if (comp instanceof JComboBox)
057: return (JComboBox) comp;
058: return null;
059: }
060:
061: protected boolean canMultipleClick() {
062: return false;
063: }
064:
065: /** Parse clicks to cancel the recording if we get a click that's not in
066: the JList (or ESC). */
067: protected boolean parseClick(AWTEvent event) {
068:
069: if (isFinished()) {
070: return false;
071: }
072:
073: // FIXME add key-based activation/termination?
074: boolean consumed = true;
075: if (combo == null) {
076: combo = getComboBox(event);
077: listener = new ActionListener() {
078: public void actionPerformed(ActionEvent ev) {
079: index = combo.getSelectedIndex();
080: if (!combo.isPopupVisible()) {
081: combo.removeActionListener(listener);
082: setFinished(true);
083: }
084: }
085: };
086: combo.addActionListener(listener);
087: setStatus("Waiting for selection");
088: } else if (event.getID() == KeyEvent.KEY_RELEASED
089: && (((KeyEvent) event).getKeyCode() == KeyEvent.VK_SPACE || ((KeyEvent) event)
090: .getKeyCode() == KeyEvent.VK_ENTER)) {
091: index = combo.getSelectedIndex();
092: setFinished(true);
093: }
094: // Cancel via click somewhere else
095: else if (event.getID() == MouseEvent.MOUSE_PRESSED
096: && !AWT.isOnPopup((Component) event.getSource())
097: && combo != getComboBox(event)) {
098: setFinished(true);
099: consumed = false;
100: }
101: // Cancel via ESC key
102: else if (event.getID() == KeyEvent.KEY_RELEASED
103: && ((KeyEvent) event).getKeyCode() == KeyEvent.VK_ESCAPE) {
104: setStatus("Selection canceled");
105: setFinished(true);
106: } else {
107: Log.debug("Event ignored");
108: }
109: if (list == null && combo.isPopupVisible())
110: list = tester.findComboList(combo);
111:
112: if (isFinished()) {
113: combo.removeActionListener(listener);
114: listener = null;
115: }
116:
117: return consumed;
118: }
119:
120: protected Step createStep() {
121: Step step = null;
122: if (getRecordingType() == SE_CLICK) {
123: step = createSelection(combo, index);
124: } else {
125: step = super .createStep();
126: }
127: return step;
128: }
129:
130: protected Step createSelection(JComboBox combo, int index) {
131: Step step = null;
132: if (combo != null && index != -1) {
133: ComponentReference cr = getResolver().addComponent(combo);
134: String value = tester.getValueAsString(combo, list, combo
135: .getItemAt(index), index);
136: if (value == null) {
137: step = new Action(getResolver(), null,
138: "actionSelectIndex", new String[] { cr.getID(),
139: String.valueOf(index) },
140: javax.swing.JComboBox.class);
141: } else {
142: step = new Action(getResolver(), null,
143: "actionSelectItem", new String[] { cr.getID(),
144: value }, javax.swing.JComboBox.class);
145: }
146: }
147: return step;
148: }
149:
150: }
|