0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s): Alexandre Iline.
0025: *
0026: * The Original Software is the Jemmy library.
0027: * The Initial Developer of the Original Software is Alexandre Iline.
0028: * All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: *
0041: *
0042: *
0043: * $Id: JSpinnerOperator.java,v 1.3 2007/10/05 11:35:17 jskrivanek Exp $ $Revision: 1.3 $ $Date: 2007/10/05 11:35:17 $
0044: *
0045: */
0046:
0047: package org.netbeans.jemmy.operators;
0048:
0049: import java.awt.Component;
0050: import java.awt.Container;
0051:
0052: import java.text.ParseException;
0053:
0054: import java.util.Date;
0055: import java.util.Hashtable;
0056: import java.util.List;
0057:
0058: import javax.swing.JComponent;
0059: import javax.swing.JSpinner;
0060: import javax.swing.SpinnerDateModel;
0061: import javax.swing.SpinnerListModel;
0062: import javax.swing.SpinnerModel;
0063: import javax.swing.SpinnerNumberModel;
0064: import javax.swing.SwingConstants;
0065:
0066: import javax.swing.event.ChangeListener;
0067:
0068: import javax.swing.plaf.SpinnerUI;
0069:
0070: import org.netbeans.jemmy.Action;
0071: import org.netbeans.jemmy.JemmyException;
0072: import org.netbeans.jemmy.ComponentChooser;
0073: import org.netbeans.jemmy.ComponentSearcher;
0074: import org.netbeans.jemmy.Outputable;
0075: import org.netbeans.jemmy.TestOut;
0076: import org.netbeans.jemmy.Timeoutable;
0077: import org.netbeans.jemmy.Timeouts;
0078:
0079: import org.netbeans.jemmy.drivers.DriverManager;
0080: import org.netbeans.jemmy.drivers.ScrollDriver;
0081:
0082: import org.netbeans.jemmy.drivers.scrolling.ScrollAdjuster;
0083:
0084: /**
0085: * Provides methods to work with <code>javax.swing.JSpinner</code> component <br>
0086: *
0087: * @see NumberSpinnerOperator
0088: * @see ListSpinnerOperator
0089: * @see DateSpinnerOperator
0090: *
0091: * @author Alexandre Iline (alexandre.iline@sun.com)
0092: */
0093:
0094: public class JSpinnerOperator extends JComponentOperator implements
0095: Timeoutable, Outputable {
0096:
0097: /**
0098: * Identifier for a "value" property.
0099: * @see #getDump
0100: */
0101: public static final String VALUE_DPROP = "Value";
0102:
0103: private final static long WHOLE_SCROLL_TIMEOUT = 60000;
0104:
0105: private Timeouts timeouts;
0106: private TestOut output;
0107:
0108: private ScrollDriver driver;
0109:
0110: private JButtonOperator increaseOperator = null;
0111: private JButtonOperator decreaseOperator = null;
0112:
0113: /**
0114: * Constructor.
0115: * @param b JSpinner component.
0116: */
0117: public JSpinnerOperator(JSpinner b) {
0118: super (b);
0119: driver = DriverManager.getScrollDriver(getClass());
0120: }
0121:
0122: /**
0123: * Constructs a JSpinnerOperator object.
0124: * @param cont a container
0125: * @param chooser a component chooser specifying searching criteria.
0126: * @param index an index between appropriate ones.
0127: * @throws TimeoutExpiredException
0128: */
0129: public JSpinnerOperator(ContainerOperator cont,
0130: ComponentChooser chooser, int index) {
0131: this ((JSpinner) cont.waitSubComponent(new JSpinnerFinder(
0132: chooser), index));
0133: copyEnvironment(cont);
0134: }
0135:
0136: /**
0137: * Constructs a JSpinnerOperator object.
0138: * @param cont a container
0139: * @param chooser a component chooser specifying searching criteria.
0140: * @throws TimeoutExpiredException
0141: */
0142: public JSpinnerOperator(ContainerOperator cont,
0143: ComponentChooser chooser) {
0144: this (cont, chooser, 0);
0145: }
0146:
0147: /**
0148: * Constructs a JSpinnerOperator object.
0149: * @param cont The operator for a container containing the sought for button.
0150: * @param text toString() representation of the current spinner value.
0151: * @param index Ordinal component index. The first component has <code>index</code> 0.
0152: * @throws TimeoutExpiredException
0153: */
0154: public JSpinnerOperator(ContainerOperator cont, String text,
0155: int index) {
0156: this ((JSpinner) waitComponent(cont, new JSpinnerByTextFinder(
0157: text, cont.getComparator()), index));
0158: copyEnvironment(cont);
0159: }
0160:
0161: /**
0162: * Constructs a JSpinnerOperator object.
0163: * @param cont The operator for a container containing the sought for button.
0164: * @param text toString() representation of the current spinner value.
0165: * @throws TimeoutExpiredException
0166: */
0167: public JSpinnerOperator(ContainerOperator cont, String text) {
0168: this (cont, text, 0);
0169: }
0170:
0171: /**
0172: * Constructor.
0173: * Waits component in container first.
0174: * Uses cont's timeout and output for waiting and to init operator.
0175: * @param cont Operator pointing a container to search component in.
0176: * @param index Ordinal component index.
0177: * @throws TimeoutExpiredException
0178: */
0179: public JSpinnerOperator(ContainerOperator cont, int index) {
0180: this (
0181: (JSpinner) waitComponent(cont, new JSpinnerFinder(),
0182: index));
0183: copyEnvironment(cont);
0184: }
0185:
0186: /**
0187: * Constructor.
0188: * Waits component in container first.
0189: * Uses cont's timeout and output for waiting and to init operator.
0190: * @param cont Operator pointing a container to search component in.
0191: * @throws TimeoutExpiredException
0192: */
0193: public JSpinnerOperator(ContainerOperator cont) {
0194: this (cont, 0);
0195: }
0196:
0197: /**
0198: * Searches JSpinner in container.
0199: * @param cont Container to search component in.
0200: * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
0201: * @param index Ordinal component index.
0202: * @return JSpinner instance or null if component was not found.
0203: */
0204: public static JSpinner findJSpinner(Container cont,
0205: ComponentChooser chooser, int index) {
0206: return ((JSpinner) findComponent(cont, new JSpinnerFinder(
0207: chooser), index));
0208: }
0209:
0210: /**
0211: * Searches 0'th JSpinner in container.
0212: * @param cont Container to search component in.
0213: * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
0214: * @return JSpinner instance or null if component was not found.
0215: */
0216: public static JSpinner findJSpinner(Container cont,
0217: ComponentChooser chooser) {
0218: return (findJSpinner(cont, chooser, 0));
0219: }
0220:
0221: /**
0222: * Searches JSpinner in container.
0223: * @param cont Container to search component in.
0224: * @param index Ordinal component index.
0225: * @return JSpinner instance or null if component was not found.
0226: */
0227: public static JSpinner findJSpinner(Container cont, int index) {
0228: return (findJSpinner(cont, ComponentSearcher
0229: .getTrueChooser(Integer.toString(index)
0230: + "'th JSpinner instance"), index));
0231: }
0232:
0233: /**
0234: * Searches 0'th JSpinner in container.
0235: * @param cont Container to search component in.
0236: * @return JSpinner instance or null if component was not found.
0237: */
0238: public static JSpinner findJSpinner(Container cont) {
0239: return (findJSpinner(cont, 0));
0240: }
0241:
0242: /**
0243: * Waits JSpinner in container.
0244: * @param cont Container to search component in.
0245: * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
0246: * @param index Ordinal component index.
0247: * @return JSpinner instance or null if component was not displayed.
0248: * @throws TimeoutExpiredException
0249: */
0250: public static JSpinner waitJSpinner(Container cont,
0251: ComponentChooser chooser, int index) {
0252: return ((JSpinner) waitComponent(cont, new JSpinnerFinder(
0253: chooser), index));
0254: }
0255:
0256: /**
0257: * Waits 0'th JSpinner in container.
0258: * @param cont Container to search component in.
0259: * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
0260: * @return JSpinner instance or null if component was not displayed.
0261: * @throws TimeoutExpiredException
0262: */
0263: public static JSpinner waitJSpinner(Container cont,
0264: ComponentChooser chooser) {
0265: return (waitJSpinner(cont, chooser, 0));
0266: }
0267:
0268: /**
0269: * Waits JSpinner in container.
0270: * @param cont Container to search component in.
0271: * @param index Ordinal component index.
0272: * @return JSpinner instance or null if component was not displayed.
0273: * @throws TimeoutExpiredException
0274: */
0275: public static JSpinner waitJSpinner(Container cont, int index) {
0276: return (waitJSpinner(cont, ComponentSearcher
0277: .getTrueChooser(Integer.toString(index)
0278: + "'th JSpinner instance"), index));
0279: }
0280:
0281: /**
0282: * Waits 0'th JSpinner in container.
0283: * @param cont Container to search component in.
0284: * @return JSpinner instance or null if component was not displayed.
0285: * @throws TimeoutExpiredException
0286: */
0287: public static JSpinner waitJSpinner(Container cont) {
0288: return (waitJSpinner(cont, 0));
0289: }
0290:
0291: /**
0292: * Checks operator's model type.
0293: * @param oper an operator to check model
0294: * @param modelClass a model class.
0295: * @throws SpinnerModelException if an operator's model is not an instance of
0296: * specified class.
0297: */
0298: public static void checkModel(JSpinnerOperator oper,
0299: Class modelClass) {
0300: if (!modelClass.isInstance(oper.getModel())) {
0301: throw (new SpinnerModelException("JSpinner model is not a "
0302: + modelClass.getName(), oper.getSource()));
0303: }
0304: }
0305:
0306: static {
0307: Timeouts.initDefault("JSpinnerOperator.WholeScrollTimeout",
0308: WHOLE_SCROLL_TIMEOUT);
0309: }
0310:
0311: public void setOutput(TestOut out) {
0312: output = out;
0313: super .setOutput(output.createErrorOutput());
0314: }
0315:
0316: public TestOut getOutput() {
0317: return (output);
0318: }
0319:
0320: public void setTimeouts(Timeouts timeouts) {
0321: this .timeouts = timeouts;
0322: super .setTimeouts(timeouts);
0323: }
0324:
0325: public Timeouts getTimeouts() {
0326: return (timeouts);
0327: }
0328:
0329: /**
0330: * Returns an instance of <code>NumberSpinnerOperator</code> operator,
0331: * the operator used for <code>JSpinner</code> having <code>SpinnerNumberModel</code> model.
0332: * @return a <code>NumberSpinnerOperator</code> created for the same <code>JSpinner</code> as this operator.
0333: * @throws SpinnerModelException if an operator's model is not an instance of <code>SpinnerNumberModel</code>
0334: */
0335: public NumberSpinnerOperator getNumberSpinner() {
0336: return (new NumberSpinnerOperator(this ));
0337: }
0338:
0339: /**
0340: * Returns an instance of <code>ListSpinnerOperator</code> operator,
0341: * the operator used for <code>JSpinner</code> having <code>SpinnerListModel</code> model.
0342: * @return a <code>ListSpinnerOperator</code> created for the same <code>JSpinner</code> as this operator.
0343: * @throws SpinnerModelException if an operator's model is not an instance of <code>SpinnerListModel</code>
0344: */
0345: public ListSpinnerOperator getListSpinner() {
0346: return (new ListSpinnerOperator(this ));
0347: }
0348:
0349: /**
0350: * Returns an instance of <code>DateSpinnerOperator</code> operator,
0351: * the operator used for <code>JSpinner</code> having <code>SpinnerDateModel</code> model.
0352: * @return a <code>DateSpinnerOperator</code> created for the same <code>JSpinner</code> as this operator.
0353: * @throws SpinnerModelException if an operator's model is not an instance of <code>SpinnerDateModel</code>
0354: */
0355: public DateSpinnerOperator getDateSpinner() {
0356: return (new DateSpinnerOperator(this ));
0357: }
0358:
0359: /**
0360: * Scrolls to reach a condition specified by <code>ScrollAdjuster</code>
0361: * @param adj scrolling criteria.
0362: */
0363: public void scrollTo(final ScrollAdjuster adj) {
0364: produceTimeRestricted(new Action() {
0365: public Object launch(Object obj) {
0366: driver.scroll(JSpinnerOperator.this , adj);
0367: return (null);
0368: }
0369:
0370: public String getDescription() {
0371: return ("Scrolling");
0372: }
0373: }, getTimeouts().getTimeout(
0374: "JSpinnerOperator.WholeScrollTimeout"));
0375: }
0376:
0377: /**
0378: * Scrolls to maximum value.
0379: * @throws SpinnerModelException if an operator's model does not have a maximum value.
0380: */
0381: public void scrollToMaximum() {
0382: produceTimeRestricted(new Action() {
0383: public Object launch(Object obj) {
0384: driver.scrollToMaximum(JSpinnerOperator.this ,
0385: SwingConstants.VERTICAL);
0386: return (null);
0387: }
0388:
0389: public String getDescription() {
0390: return ("Scrolling");
0391: }
0392: }, getTimeouts().getTimeout(
0393: "JSpinnerOperator.WholeScrollTimeout"));
0394: }
0395:
0396: /**
0397: * Scrolls to minimum value.
0398: * @throws SpinnerModelException if an operator's model does not have a minimum value.
0399: */
0400: public void scrollToMinimum() {
0401: produceTimeRestricted(new Action() {
0402: public Object launch(Object obj) {
0403: driver.scrollToMinimum(JSpinnerOperator.this ,
0404: SwingConstants.VERTICAL);
0405: return (null);
0406: }
0407:
0408: public String getDescription() {
0409: return ("Scrolling");
0410: }
0411: }, getTimeouts().getTimeout(
0412: "JSpinnerOperator.WholeScrollTimeout"));
0413: }
0414:
0415: /**
0416: * Scrolls to exact match of a spinner value to the specified value.
0417: * @param value an value to scroll to.
0418: * @param direction a scrolling direction - one of <code>ScrollAdjuster.*_SCROLL_DIRECTION</code> fields.
0419: */
0420: public void scrollToObject(Object value, int direction) {
0421: scrollTo(new ExactScrollAdjuster(this , value, direction));
0422: }
0423:
0424: /**
0425: * Scrolls to matching of <code>getValue().toString() with the pattern.
0426: * @param pattern a pattern to compare with
0427: * @param comparator a string comparision criteria
0428: * @param direction a scrolling direction - one of <code>ScrollAdjuster.*_SCROLL_DIRECTION</code> fields.
0429: */
0430: public void scrollToString(String pattern,
0431: StringComparator comparator, int direction) {
0432: scrollTo(new ToStringScrollAdjuster(this , pattern, comparator,
0433: direction));
0434: }
0435:
0436: /**
0437: * Scrolls to matching of <code>getValue().toString()</code> with the pattern.
0438: * Uses <code>StringComparator</code> assigned to the operator.
0439: * @param pattern a pattern to compare with
0440: * @param direction a scrolling direction - one of <code>ScrollAdjuster.*_SCROLL_DIRECTION</code> fields.
0441: */
0442: public void scrollToString(String pattern, int direction) {
0443: scrollToString(pattern, getComparator(), direction);
0444: }
0445:
0446: /**
0447: * Returns an operator for a button used for value increasing.
0448: * @return an operator for a first <code>JButton<code> inside this spinner.
0449: */
0450: public JButtonOperator getIncreaseOperator() {
0451: if (increaseOperator == null) {
0452: increaseOperator = (JButtonOperator) createSubOperator(
0453: new JButtonOperator.JButtonFinder(), 0);
0454: increaseOperator.copyEnvironment(this );
0455: increaseOperator.setOutput(getOutput().createErrorOutput());
0456: }
0457: return (increaseOperator);
0458: }
0459:
0460: /**
0461: * Returns an operator for a button used for value decreasing.
0462: * @return an operator for a second <code>JButton<code> inside this spinner.
0463: */
0464: public JButtonOperator getDecreaseOperator() {
0465: if (decreaseOperator == null) {
0466: decreaseOperator = (JButtonOperator) createSubOperator(
0467: new JButtonOperator.JButtonFinder(), 1);
0468: decreaseOperator.copyEnvironment(this );
0469: decreaseOperator.setOutput(getOutput().createErrorOutput());
0470: }
0471: return (decreaseOperator);
0472: }
0473:
0474: /**
0475: * Returns a minimal value. Returns null if model is not
0476: * one of the following:
0477: * <code>javax.swing.SpinnerDateModel</code>,
0478: * <code>javax.swing.SpinnerListModel</code>,
0479: * <code>javax.swing.SpinnerNumberModel</code>.
0480: * Also, returns null if the model does not have a minimal value.
0481: * @return a minimal value.
0482: */
0483: public Object getMinimum() {
0484: SpinnerModel model = getModel();
0485: if (model instanceof SpinnerNumberModel) {
0486: return (((SpinnerNumberModel) model).getMinimum());
0487: } else if (model instanceof SpinnerDateModel) {
0488: return (((SpinnerDateModel) model).getEnd());
0489: } else if (model instanceof SpinnerListModel) {
0490: List list = ((SpinnerListModel) model).getList();
0491: return (list.get(list.size() - 1));
0492: } else {
0493: return (null);
0494: }
0495: }
0496:
0497: /**
0498: * Returns a maximal value. Returns null if model is not
0499: * one of the following:
0500: * <code>javax.swing.SpinnerDateModel</code>,
0501: * <code>javax.swing.SpinnerListModel</code>,
0502: * <code>javax.swing.SpinnerNumberModel</code>.
0503: * Also, returns null if the model does not have a maximal value.
0504: * @return a maximal value.
0505: */
0506: public Object getMaximum() {
0507: SpinnerModel model = getModel();
0508: if (model instanceof SpinnerNumberModel) {
0509: return (((SpinnerNumberModel) model).getMaximum());
0510: } else if (model instanceof SpinnerDateModel) {
0511: return (((SpinnerDateModel) model).getEnd());
0512: } else if (model instanceof SpinnerListModel) {
0513: List list = ((SpinnerListModel) model).getList();
0514: return (list.get(list.size() - 1));
0515: } else {
0516: return (null);
0517: }
0518: }
0519:
0520: public Hashtable getDump() {
0521: Hashtable result = super .getDump();
0522: result.put(VALUE_DPROP, ((JSpinner) getSource()).getValue()
0523: .toString());
0524: return (result);
0525: }
0526:
0527: ////////////////////////////////////////////////////////
0528: //Mapping //
0529:
0530: /**Maps <code>JSpinner.getValue()</code> through queue*/
0531: public Object getValue() {
0532: return ((Object) runMapping(new MapAction("getValue") {
0533: public Object map() {
0534: return (((JSpinner) getSource()).getValue());
0535: }
0536: }));
0537: }
0538:
0539: /**Maps <code>JSpinner.setValue(Object)</code> through queue*/
0540: public void setValue(final Object object) {
0541: runMapping(new MapVoidAction("setValue") {
0542: public void map() {
0543: ((JSpinner) getSource()).setValue(object);
0544: }
0545: });
0546: }
0547:
0548: /**Maps <code>JSpinner.getUI()</code> through queue*/
0549: public SpinnerUI getUI() {
0550: return ((SpinnerUI) runMapping(new MapAction("getUI") {
0551: public Object map() {
0552: return (((JSpinner) getSource()).getUI());
0553: }
0554: }));
0555: }
0556:
0557: /**Maps <code>JSpinner.setUI(SpinnerUI)</code> through queue*/
0558: public void setUI(final SpinnerUI spinnerUI) {
0559: runMapping(new MapVoidAction("setUI") {
0560: public void map() {
0561: ((JSpinner) getSource()).setUI(spinnerUI);
0562: }
0563: });
0564: }
0565:
0566: /**Maps <code>JSpinner.setModel(SpinnerModel)</code> through queue*/
0567: public void setModel(final SpinnerModel spinnerModel) {
0568: runMapping(new MapVoidAction("setModel") {
0569: public void map() {
0570: ((JSpinner) getSource()).setModel(spinnerModel);
0571: }
0572: });
0573: }
0574:
0575: /**Maps <code>JSpinner.getModel()</code> through queue*/
0576: public SpinnerModel getModel() {
0577: return ((SpinnerModel) runMapping(new MapAction("getModel") {
0578: public Object map() {
0579: return (((JSpinner) getSource()).getModel());
0580: }
0581: }));
0582: }
0583:
0584: /**Maps <code>JSpinner.getNextValue()</code> through queue*/
0585: public Object getNextValue() {
0586: return ((Object) runMapping(new MapAction("getNextValue") {
0587: public Object map() {
0588: return (((JSpinner) getSource()).getNextValue());
0589: }
0590: }));
0591: }
0592:
0593: /**Maps <code>JSpinner.addChangeListener(ChangeListener)</code> through queue*/
0594: public void addChangeListener(final ChangeListener changeListener) {
0595: runMapping(new MapVoidAction("addChangeListener") {
0596: public void map() {
0597: ((JSpinner) getSource())
0598: .addChangeListener(changeListener);
0599: }
0600: });
0601: }
0602:
0603: /**Maps <code>JSpinner.removeChangeListener(ChangeListener)</code> through queue*/
0604: public void removeChangeListener(final ChangeListener changeListener) {
0605: runMapping(new MapVoidAction("removeChangeListener") {
0606: public void map() {
0607: ((JSpinner) getSource())
0608: .removeChangeListener(changeListener);
0609: }
0610: });
0611: }
0612:
0613: /**Maps <code>JSpinner.getChangeListeners()</code> through queue*/
0614: public ChangeListener[] getChangeListeners() {
0615: return ((ChangeListener[]) runMapping(new MapAction(
0616: "getChangeListeners") {
0617: public Object map() {
0618: return (((JSpinner) getSource()).getChangeListeners());
0619: }
0620: }));
0621: }
0622:
0623: /**Maps <code>JSpinner.getPreviousValue()</code> through queue*/
0624: public Object getPreviousValue() {
0625: return ((Object) runMapping(new MapAction("getPreviousValue") {
0626: public Object map() {
0627: return (((JSpinner) getSource()).getPreviousValue());
0628: }
0629: }));
0630: }
0631:
0632: /**Maps <code>JSpinner.setEditor(JComponent)</code> through queue*/
0633: public void setEditor(final JComponent jComponent) {
0634: runMapping(new MapVoidAction("setEditor") {
0635: public void map() {
0636: ((JSpinner) getSource()).setEditor(jComponent);
0637: }
0638: });
0639: }
0640:
0641: /**Maps <code>JSpinner.getEditor()</code> through queue*/
0642: public JComponent getEditor() {
0643: return ((JComponent) runMapping(new MapAction("getEditor") {
0644: public Object map() {
0645: return (((JSpinner) getSource()).getEditor());
0646: }
0647: }));
0648: }
0649:
0650: /**Maps <code>JSpinner.commitEdit()</code> through queue*/
0651: public void commitEdit() {
0652: runMapping(new MapVoidAction("commitEdit") {
0653: public void map() throws ParseException {
0654: ((JSpinner) getSource()).commitEdit();
0655: }
0656: });
0657: }
0658:
0659: //End of mapping //
0660: ////////////////////////////////////////////////////////
0661:
0662: /**
0663: * Allows to find component by text.
0664: */
0665: public static class JSpinnerByTextFinder implements
0666: ComponentChooser {
0667: String label;
0668: StringComparator comparator;
0669:
0670: /**
0671: * Constructs JSpinnerByTextFinder.
0672: * @param lb a text pattern
0673: * @param comparator specifies string comparision algorithm.
0674: */
0675: public JSpinnerByTextFinder(String lb,
0676: StringComparator comparator) {
0677: label = lb;
0678: this .comparator = comparator;
0679: }
0680:
0681: /**
0682: * Constructs JSpinnerByTextFinder.
0683: * @param lb a text pattern
0684: */
0685: public JSpinnerByTextFinder(String lb) {
0686: this (lb, Operator.getDefaultStringComparator());
0687: }
0688:
0689: public boolean checkComponent(Component comp) {
0690: if (comp instanceof JSpinner) {
0691: if (((JSpinner) comp).getValue() != null) {
0692: return (comparator.equals(((JSpinner) comp)
0693: .getValue().toString(), label));
0694: }
0695: }
0696: return (false);
0697: }
0698:
0699: public String getDescription() {
0700: return ("JSpinner with text \"" + label + "\"");
0701: }
0702: }
0703:
0704: /**
0705: * Checks component type.
0706: */
0707: public static class JSpinnerFinder extends Finder {
0708: /**
0709: * Constructs JSpinnerFinder.
0710: * @param sf other searching criteria.
0711: */
0712: public JSpinnerFinder(ComponentChooser sf) {
0713: super (JSpinner.class, sf);
0714: }
0715:
0716: /**
0717: * Constructs JSpinnerFinder.
0718: */
0719: public JSpinnerFinder() {
0720: super (JSpinner.class);
0721: }
0722: }
0723:
0724: /**
0725: * A <code>ScrollAdjuster</code> to be used for <code>JSpinner</code>
0726: * component having <code>SpinnerNumberModel</code> model.
0727: * @see NumberSpinnerOperator
0728: */
0729: public static class NumberScrollAdjuster implements ScrollAdjuster {
0730: SpinnerNumberModel model;
0731: double value;
0732:
0733: /**
0734: * Constructs a <code>NumberScrollAdjuster</code> object.
0735: * @param oper an operator to work with.
0736: * @param value a value to scroll to.
0737: */
0738: public NumberScrollAdjuster(JSpinnerOperator oper, double value) {
0739: this .value = value;
0740: checkModel(oper, SpinnerNumberModel.class);
0741: model = (SpinnerNumberModel) oper.getModel();
0742: }
0743:
0744: /**
0745: * Constructs a <code>NumberScrollAdjuster</code> object.
0746: * @param oper an operator to work with.
0747: * @param value a value to scroll to.
0748: */
0749: public NumberScrollAdjuster(JSpinnerOperator oper, Number value) {
0750: this (oper, value.doubleValue());
0751: }
0752:
0753: public int getScrollDirection() {
0754: if (value > model.getNumber().doubleValue()) {
0755: return (ScrollAdjuster.INCREASE_SCROLL_DIRECTION);
0756: } else if (value < model.getNumber().doubleValue()) {
0757: return (ScrollAdjuster.DECREASE_SCROLL_DIRECTION);
0758: } else {
0759: return (ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION);
0760: }
0761: }
0762:
0763: public int getScrollOrientation() {
0764: return (SwingConstants.VERTICAL);
0765: }
0766:
0767: public String getDescription() {
0768: return ("Spin to " + value + " value");
0769: }
0770: }
0771:
0772: /**
0773: * A <code>ScrollAdjuster</code> to be used for <code>JSpinner</code>
0774: * component having <code>SpinnerListModel</code> model.
0775: * @see ListSpinnerOperator
0776: */
0777: public static class ListScrollAdjuster implements ScrollAdjuster {
0778: SpinnerListModel model;
0779: int itemIndex;
0780: List elements;
0781:
0782: private ListScrollAdjuster(JSpinnerOperator oper) {
0783: checkModel(oper, SpinnerListModel.class);
0784: model = (SpinnerListModel) oper.getModel();
0785: elements = model.getList();
0786: }
0787:
0788: /**
0789: * Constructs a <code>ListScrollAdjuster</code> object.
0790: * @param oper an operator to work with.
0791: * @param value a value to scroll to.
0792: */
0793: public ListScrollAdjuster(JSpinnerOperator oper, Object value) {
0794: this (oper);
0795: this .itemIndex = elements.indexOf(value);
0796: }
0797:
0798: /**
0799: * Constructs a <code>ListScrollAdjuster</code> object.
0800: * @param oper an operator to work with.
0801: * @param itemIndex an item index to scroll to.
0802: */
0803: public ListScrollAdjuster(JSpinnerOperator oper, int itemIndex) {
0804: this (oper);
0805: this .itemIndex = itemIndex;
0806: }
0807:
0808: public int getScrollDirection() {
0809: int curIndex = elements.indexOf(model.getValue());
0810: if (itemIndex > curIndex) {
0811: return (ScrollAdjuster.INCREASE_SCROLL_DIRECTION);
0812: } else if (itemIndex < curIndex) {
0813: return (ScrollAdjuster.DECREASE_SCROLL_DIRECTION);
0814: } else {
0815: return (ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION);
0816: }
0817: }
0818:
0819: public int getScrollOrientation() {
0820: return (SwingConstants.VERTICAL);
0821: }
0822:
0823: public String getDescription() {
0824: return ("Spin to " + Integer.toString(itemIndex) + "'th item");
0825: }
0826: }
0827:
0828: /**
0829: * A <code>ScrollAdjuster</code> to be used for <code>JSpinner</code>
0830: * component having <code>SpinnerDateModel</code> model.
0831: * @see DateSpinnerOperator
0832: */
0833: public static class DateScrollAdjuster implements ScrollAdjuster {
0834: Date date;
0835: SpinnerDateModel model;
0836:
0837: /**
0838: * Constructs a <code>DateScrollAdjuster</code> object.
0839: * @param oper an operator to work with.
0840: * @param date a date to scroll to.
0841: */
0842: public DateScrollAdjuster(JSpinnerOperator oper, Date date) {
0843: this .date = date;
0844: checkModel(oper, SpinnerDateModel.class);
0845: model = (SpinnerDateModel) oper.getModel();
0846: }
0847:
0848: public int getScrollDirection() {
0849: if (date.after(model.getDate())) {
0850: return (ScrollAdjuster.INCREASE_SCROLL_DIRECTION);
0851: } else if (date.before(model.getDate())) {
0852: return (ScrollAdjuster.DECREASE_SCROLL_DIRECTION);
0853: } else {
0854: return (ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION);
0855: }
0856: }
0857:
0858: public int getScrollOrientation() {
0859: return (SwingConstants.VERTICAL);
0860: }
0861:
0862: public String getDescription() {
0863: return ("Spin to " + date.toString() + " date");
0864: }
0865: }
0866:
0867: /**
0868: * Abstract class for a scrolling of a spinner having unknown model type.
0869: * A subclass needs to override <code>equals(Object)</code> value
0870: * to specify a criteria of successful scrolling.
0871: */
0872: public abstract static class ObjectScrollAdjuster implements
0873: ScrollAdjuster {
0874: SpinnerModel model;
0875: int direction;
0876:
0877: /**
0878: * Constructs a <code>ObjectScrollAdjuster</code> object.
0879: * @param oper an operator to work with.
0880: * @param direction a scrolling direction - one of <code>ScrollAdjuster.*_SCROLL_DIRECTION</code> fields.
0881: */
0882: public ObjectScrollAdjuster(JSpinnerOperator oper, int direction) {
0883: this .direction = direction;
0884: model = oper.getModel();
0885: }
0886:
0887: public int getScrollDirection() {
0888: if (equals(model.getValue())) {
0889: return (ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION);
0890: } else if (direction == ScrollAdjuster.INCREASE_SCROLL_DIRECTION
0891: && model.getNextValue() != null
0892: || direction == ScrollAdjuster.DECREASE_SCROLL_DIRECTION
0893: && model.getPreviousValue() != null) {
0894: return (direction);
0895: } else {
0896: return (ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION);
0897: }
0898: }
0899:
0900: public abstract boolean equals(Object curvalue);
0901:
0902: public int getScrollOrientation() {
0903: return (SwingConstants.VERTICAL);
0904: }
0905: }
0906:
0907: /**
0908: * Class for a scrolling of a spinner having unknown model type.
0909: * Checks spinner value for exact equality with a specified value.
0910: */
0911: public static class ExactScrollAdjuster extends
0912: ObjectScrollAdjuster {
0913: Object obj;
0914:
0915: /**
0916: * Constructs a <code>ExactScrollAdjuster</code> object.
0917: * @param oper an operator to work with.
0918: * @param direction a scrolling direction - one of <code>ScrollAdjuster.*_SCROLL_DIRECTION</code> fields.
0919: */
0920: public ExactScrollAdjuster(JSpinnerOperator oper, Object obj,
0921: int direction) {
0922: super (oper, direction);
0923: this .obj = obj;
0924: }
0925:
0926: public boolean equals(Object curvalue) {
0927: return (curvalue.equals(obj));
0928: }
0929:
0930: public String getDescription() {
0931: return ("Spin to " + obj.toString() + " value");
0932: }
0933:
0934: public int getScrollOrientation() {
0935: return (SwingConstants.VERTICAL);
0936: }
0937: }
0938:
0939: /**
0940: * Class for a scrolling of a spinner having unknown model type.
0941: * Checks spinner value's toString() reprsentation to match a string pattern.
0942: */
0943: public static class ToStringScrollAdjuster extends
0944: ObjectScrollAdjuster {
0945: String pattern;
0946: StringComparator comparator;
0947:
0948: /**
0949: * Constructs a <code>ToStringScrollAdjuster</code> object.
0950: * @param oper an operator to work with.
0951: * @param pattern a pattern to compare with
0952: * @param comparator specifies string comparision algorithm.
0953: * @param direction a scrolling direction - one of <code>ScrollAdjuster.*_SCROLL_DIRECTION</code> fields.
0954: */
0955: public ToStringScrollAdjuster(JSpinnerOperator oper,
0956: String pattern, StringComparator comparator,
0957: int direction) {
0958: super (oper, direction);
0959: this .pattern = pattern;
0960: this .comparator = comparator;
0961: }
0962:
0963: /**
0964: * Constructs a <code>ToStringScrollAdjuster</code> object.
0965: * Uses <code>StringComparator</code> assigned to the operator.
0966: * @param oper an operator to work with.
0967: * @param pattern a pattern to compare with
0968: * @param comparator specifies string comparision algorithm.
0969: * @param direction a scrolling direction - one of <code>ScrollAdjuster.*_SCROLL_DIRECTION</code> fields.
0970: */
0971: public ToStringScrollAdjuster(JSpinnerOperator oper,
0972: String pattern, int direction) {
0973: this (oper, pattern, oper.getComparator(), direction);
0974: }
0975:
0976: public boolean equals(Object curvalue) {
0977: return (comparator.equals(curvalue.toString(), pattern));
0978: }
0979:
0980: public String getDescription() {
0981: return ("Spin to \"" + pattern + "\" value");
0982: }
0983:
0984: public int getScrollOrientation() {
0985: return (SwingConstants.VERTICAL);
0986: }
0987: }
0988:
0989: /**
0990: * Provides some specific functionality for <code>JSpinner</code>
0991: * components having <code>SpinnerNumberModel</code> model.
0992: * Constructor of this object is private - it cannot be received only from
0993: * another JSpinnerOperator instance.
0994: * @see #getNumberSpinner
0995: */
0996: public class NumberSpinnerOperator extends JSpinnerOperator {
0997: private NumberSpinnerOperator(JSpinnerOperator spinner) {
0998: super ((JSpinner) spinner.getSource());
0999: copyEnvironment(spinner);
1000: checkModel(this , SpinnerNumberModel.class);
1001: }
1002:
1003: /**
1004: * Costs spinner's model to <code>SpinnerNumberModel<code>.
1005: * @return a spinner model.
1006: */
1007: public SpinnerNumberModel getNumberModel() {
1008: return ((SpinnerNumberModel) getModel());
1009: }
1010:
1011: /**
1012: * Scrolls to a double value.
1013: * @param value a value to scroll to.
1014: */
1015: public void scrollToValue(double value) {
1016: scrollTo(new NumberScrollAdjuster(this , value));
1017: }
1018:
1019: /**
1020: * Scrolls to a number value.
1021: * @param value a value to scroll to.
1022: */
1023: public void scrollToValue(Number value) {
1024: scrollTo(new NumberScrollAdjuster(this , value));
1025: }
1026: }
1027:
1028: /**
1029: * Provides some specific functionality for <code>JSpinner</code>
1030: * components having <code>SpinnerListModel</code> model.
1031: * Constructor of this object is private - it cannot be received only from
1032: * another JSpinnerOperator instance.
1033: * @see #getListSpinner
1034: */
1035: public class ListSpinnerOperator extends JSpinnerOperator {
1036: private ListSpinnerOperator(JSpinnerOperator spinner) {
1037: super ((JSpinner) spinner.getSource());
1038: copyEnvironment(spinner);
1039: checkModel(this , SpinnerListModel.class);
1040: }
1041:
1042: /**
1043: * Costs spinner's model to <code>SpinnerListModel<code>.
1044: * @return a spinner model.
1045: */
1046: public SpinnerListModel getListModel() {
1047: return ((SpinnerListModel) getModel());
1048: }
1049:
1050: /**
1051: * Looks for an index of an item having <code>toString()</code> matching a specified pattern.
1052: * @param pattern a string pattern
1053: * @param comparator a string comparision criteria.
1054: */
1055: public int findItem(String pattern, StringComparator comparator) {
1056: List list = getListModel().getList();
1057: for (int i = 0; i < list.size(); i++) {
1058: if (comparator.equals(list.get(i).toString(), pattern)) {
1059: return (i);
1060: }
1061: }
1062: return (-1);
1063: }
1064:
1065: /**
1066: * Looks for an index of an item having <code>toString()</code> matching a specified pattern.
1067: * Uses a <code>StringComparator</code> assigned to the operator.
1068: * @param pattern a string pattern
1069: */
1070: public int findItem(String pattern) {
1071: return (findItem(pattern, getComparator()));
1072: }
1073:
1074: /**
1075: * Scrolls to an item having specified instance.
1076: * @param index an index to scroll to.
1077: */
1078: public void scrollToIndex(int index) {
1079: scrollTo(new ListScrollAdjuster(this , index));
1080: }
1081:
1082: /**
1083: * Scrolls to <code>getValue().toString()</code> match a specified pattern.
1084: * @param pattern a string pattern
1085: * @param comparator a string comparision criteria.
1086: */
1087: public void scrollToString(String pattern,
1088: StringComparator comparator) {
1089: int index = findItem(pattern, comparator);
1090: if (index != -1) {
1091: scrollToIndex(index);
1092: } else {
1093: throw (new JemmyException("No \"" + pattern
1094: + "\" item in JSpinner", getSource()));
1095: }
1096: }
1097:
1098: /**
1099: * Scrolls to <code>getValue().toString()</code> match a specified pattern.
1100: * Uses a <code>StringComparator</code> assigned to the operator.
1101: * @param pattern a string pattern
1102: */
1103: public void scrollToString(String pattern) {
1104: scrollToString(pattern, getComparator());
1105: }
1106: }
1107:
1108: /**
1109: * Provides some specific functionality for <code>JSpinner</code>
1110: * components having <code>SpinnerDateModel</code> model.
1111: * Constructor of this object is private - it cannot be received only from
1112: * another JSpinnerOperator instance.
1113: * @see #getDateSpinner
1114: */
1115: public class DateSpinnerOperator extends JSpinnerOperator {
1116: private DateSpinnerOperator(JSpinnerOperator spinner) {
1117: super ((JSpinner) spinner.getSource());
1118: copyEnvironment(spinner);
1119: checkModel(this , SpinnerDateModel.class);
1120: }
1121:
1122: /**
1123: * Costs spinner's model to <code>SpinnerDateModel<code>.
1124: * @return a spinner model.
1125: */
1126: public SpinnerDateModel getDateModel() {
1127: return ((SpinnerDateModel) getModel());
1128: }
1129:
1130: /**
1131: * Scrolls to a date.
1132: * @param date a date to scroll to.
1133: */
1134: public void scrollToDate(Date date) {
1135: scrollTo(new DateScrollAdjuster(this , date));
1136: }
1137: }
1138:
1139: /**
1140: * Exception is thown whenever spinner model is threated wrong.
1141: */
1142: public static class SpinnerModelException extends JemmyException {
1143: /**
1144: * Constructs a <code>SpinnerModelException</code> object.
1145: * @param message error message.
1146: * @param comp a spinner which model cased the exception.
1147: */
1148: public SpinnerModelException(String message, Component comp) {
1149: super(message, comp);
1150: }
1151: }
1152: }
|