1/*
2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.netbeans.jemmy.operators;
24
25import java.awt.Component;
26import java.awt.Container;
27import java.awt.event.AdjustmentListener;
28import java.util.Hashtable;
29
30import javax.swing.BoundedRangeModel;
31import javax.swing.JButton;
32import javax.swing.JScrollBar;
33import javax.swing.plaf.ScrollBarUI;
34
35import org.netbeans.jemmy.Action;
36import org.netbeans.jemmy.ComponentChooser;
37import org.netbeans.jemmy.ComponentSearcher;
38import org.netbeans.jemmy.Outputable;
39import org.netbeans.jemmy.TestOut;
40import org.netbeans.jemmy.TimeoutExpiredException;
41import org.netbeans.jemmy.Timeoutable;
42import org.netbeans.jemmy.Timeouts;
43import org.netbeans.jemmy.Waitable;
44import org.netbeans.jemmy.drivers.DriverManager;
45import org.netbeans.jemmy.drivers.ScrollDriver;
46import org.netbeans.jemmy.drivers.scrolling.ScrollAdjuster;
47import org.netbeans.jemmy.util.EmptyVisualizer;
48
49/**
50 *
51 * Operator is supposed to be used to operate with an instance of
52 * javax.swing.JScrollBar class. <BR><BR>
53 *
54 *
55 * <BR><BR>Timeouts used: <BR>
56 * JScrollBarOperator.OneScrollClickTimeout - time for one scroll click <BR>
57 * JScrollBarOperator.WholeScrollTimeout - time for the whole scrolling <BR>
58 * JScrollBarOperator.BeforeDropTimeout - to sleep before drop
59 * JScrollBarOperator.DragAndDropScrollingDelta - to sleep before drag steps
60 * ComponentOperator.WaitComponentTimeout - time to wait component displayed
61 * <BR>.
62 *
63 * @see org.netbeans.jemmy.Timeouts
64 *
65 * @author Alexandre Iline (alexandre.iline@oracle.com)
66 */
67public class JScrollBarOperator extends JComponentOperator
68        implements Timeoutable, Outputable {
69
70    /**
71     * Identifier for a "minimum" property.
72     *
73     * @see #getDump
74     */
75    public static final String MINIMUM_DPROP = "Minimum";
76
77    /**
78     * Identifier for a "maximum" property.
79     *
80     * @see #getDump
81     */
82    public static final String MAXIMUM_DPROP = "Maximum";
83
84    /**
85     * Identifier for a "value" property.
86     *
87     * @see #getDump
88     */
89    public static final String VALUE_DPROP = "Value";
90
91    /**
92     * Identifier for a "orientation" property.
93     *
94     * @see #getDump
95     */
96    public static final String ORIENTATION_DPROP = "Orientation";
97
98    /**
99     * Identifier for a "HORIZONTAL" value of "orientation" property.
100     *
101     * @see #getDump
102     */
103    public static final String HORIZONTAL_ORIENTATION_DPROP_VALUE = "HORIZONTAL";
104
105    /**
106     * Identifier for a "VERTICAL" value of "orientation" property.
107     *
108     * @see #getDump
109     */
110    public static final String VERTICAL_ORIENTATION_DPROP_VALUE = "VERTICAL";
111
112    private final static long ONE_SCROLL_CLICK_TIMEOUT = 0;
113    private final static long WHOLE_SCROLL_TIMEOUT = 60000;
114    private final static long BEFORE_DROP_TIMEOUT = 0;
115    private final static long DRAG_AND_DROP_SCROLLING_DELTA = 0;
116
117    private Timeouts timeouts;
118    private TestOut output;
119    private JButtonOperator minButtOperator;
120    private JButtonOperator maxButtOperator;
121
122    private ScrollDriver driver;
123
124    /**
125     * Constructor.
126     *
127     * @param b JScrollBar component.
128     */
129    public JScrollBarOperator(JScrollBar b) {
130        super(b);
131        driver = DriverManager.getScrollDriver(getClass());
132    }
133
134    /**
135     * Constructs a JScrollBarOperator object.
136     *
137     * @param cont a container
138     * @param chooser a component chooser specifying searching criteria.
139     * @param index an index between appropriate ones.
140     */
141    public JScrollBarOperator(ContainerOperator<?> cont, ComponentChooser chooser, int index) {
142        this((JScrollBar) cont.
143                waitSubComponent(new JScrollBarFinder(chooser),
144                        index));
145        copyEnvironment(cont);
146    }
147
148    /**
149     * Constructs a JScrollBarOperator object.
150     *
151     * @param cont a container
152     * @param chooser a component chooser specifying searching criteria.
153     */
154    public JScrollBarOperator(ContainerOperator<?> cont, ComponentChooser chooser) {
155        this(cont, chooser, 0);
156    }
157
158    /**
159     * Constructor. Waits component in container first. Uses cont's timeout and
160     * output for waiting and to init operator.
161     *
162     * @param cont Operator pointing a container to search component in.
163     * @param index Ordinal component index.
164     * @throws TimeoutExpiredException
165     */
166    public JScrollBarOperator(ContainerOperator<?> cont, int index) {
167        this((JScrollBar) waitComponent(cont,
168                new JScrollBarFinder(),
169                index));
170        copyEnvironment(cont);
171    }
172
173    /**
174     * Constructor. Waits component in container first. Uses cont's timeout and
175     * output for waiting and to init operator.
176     *
177     * @param cont Operator pointing a container to search component in.
178     * @throws TimeoutExpiredException
179     */
180    public JScrollBarOperator(ContainerOperator<?> cont) {
181        this(cont, 0);
182    }
183
184    /**
185     * Searches JScrollBar in container.
186     *
187     * @param cont Container to search component in.
188     * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
189     * @param index Ordinal component index.
190     * @return JScrollBar instance or null if component was not found.
191     */
192    public static JScrollBar findJScrollBar(Container cont, ComponentChooser chooser, int index) {
193        return (JScrollBar) findComponent(cont, new JScrollBarFinder(chooser), index);
194    }
195
196    /**
197     * Searches 0'th JScrollBar in container.
198     *
199     * @param cont Container to search component in.
200     * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
201     * @return JScrollBar instance or null if component was not found.
202     */
203    public static JScrollBar findJScrollBar(Container cont, ComponentChooser chooser) {
204        return findJScrollBar(cont, chooser, 0);
205    }
206
207    /**
208     * Searches JScrollBar in container.
209     *
210     * @param cont Container to search component in.
211     * @param index Ordinal component index.
212     * @return JScrollBar instance or null if component was not found.
213     */
214    public static JScrollBar findJScrollBar(Container cont, int index) {
215        return findJScrollBar(cont, ComponentSearcher.getTrueChooser(Integer.toString(index) + "'th JScrollBar instance"), index);
216    }
217
218    /**
219     * Searches 0'th JScrollBar in container.
220     *
221     * @param cont Container to search component in.
222     * @return JScrollBar instance or null if component was not found.
223     */
224    public static JScrollBar findJScrollBar(Container cont) {
225        return findJScrollBar(cont, 0);
226    }
227
228    /**
229     * Waits JScrollBar in container.
230     *
231     * @param cont Container to search component in.
232     * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
233     * @param index Ordinal component index.
234     * @return JScrollBar instance or null if component was not displayed.
235     * @throws TimeoutExpiredException
236     */
237    public static JScrollBar waitJScrollBar(Container cont, ComponentChooser chooser, int index) {
238        return (JScrollBar) waitComponent(cont, new JScrollBarFinder(chooser), index);
239    }
240
241    /**
242     * Waits 0'th JScrollBar in container.
243     *
244     * @param cont Container to search component in.
245     * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
246     * @return JScrollBar instance or null if component was not displayed.
247     * @throws TimeoutExpiredException
248     */
249    public static JScrollBar waitJScrollBar(Container cont, ComponentChooser chooser) {
250        return waitJScrollBar(cont, chooser, 0);
251    }
252
253    /**
254     * Waits JScrollBar in container.
255     *
256     * @param cont Container to search component in.
257     * @param index Ordinal component index.
258     * @return JScrollBar instance or null if component was not displayed.
259     * @throws TimeoutExpiredException
260     */
261    public static JScrollBar waitJScrollBar(Container cont, int index) {
262        return waitJScrollBar(cont, ComponentSearcher.getTrueChooser(Integer.toString(index) + "'th JScrollBar instance"), index);
263    }
264
265    /**
266     * Waits 0'th JScrollBar in container.
267     *
268     * @param cont Container to search component in.
269     * @return JScrollBar instance or null if component was not displayed.
270     * @throws TimeoutExpiredException
271     */
272    public static JScrollBar waitJScrollBar(Container cont) {
273        return waitJScrollBar(cont, 0);
274    }
275
276    static {
277        Timeouts.initDefault("JScrollBarOperator.OneScrollClickTimeout", ONE_SCROLL_CLICK_TIMEOUT);
278        Timeouts.initDefault("JScrollBarOperator.WholeScrollTimeout", WHOLE_SCROLL_TIMEOUT);
279        Timeouts.initDefault("JScrollBarOperator.BeforeDropTimeout", BEFORE_DROP_TIMEOUT);
280        Timeouts.initDefault("JScrollBarOperator.DragAndDropScrollingDelta", DRAG_AND_DROP_SCROLLING_DELTA);
281    }
282
283    @Override
284    public void setOutput(TestOut out) {
285        output = out;
286        super.setOutput(output.createErrorOutput());
287    }
288
289    @Override
290    public TestOut getOutput() {
291        return output;
292    }
293
294    @Override
295    public void setTimeouts(Timeouts timeouts) {
296        this.timeouts = timeouts;
297        super.setTimeouts(timeouts);
298    }
299
300    @Override
301    public Timeouts getTimeouts() {
302        return timeouts;
303    }
304
305    @Override
306    public void copyEnvironment(Operator anotherOperator) {
307        super.copyEnvironment(anotherOperator);
308        driver
309                = (ScrollDriver) DriverManager.
310                getDriver(DriverManager.SCROLL_DRIVER_ID,
311                        getClass(),
312                        anotherOperator.getProperties());
313    }
314
315    /**
316     * Does simple scroll click.
317     *
318     * @param increase a scrolling direction.
319     * @throws TimeoutExpiredException
320     * @deprecated All scrolling is done through a ScrollDriver registered to
321     * this operator type.
322     */
323    @Deprecated
324    public void scroll(boolean increase) {
325        scrollToValue(getValue() + (increase ? 1 : -1));
326    }
327
328    /**
329     * Scrolls scrollbar to the position defined by w parameter. Uses
330     * ScrollDriver registered to this operator type.
331     *
332     * @param w Scrolling is stopped when w.actionProduced(waiterParam) != null
333     * @param waiterParam a waiting parameter.
334     * @param increase a scrolling direction.
335     * @see #scrollTo(JScrollBarOperator.ScrollChecker)
336     * @throws TimeoutExpiredException
337     */
338    public <P> void scrollTo(Waitable<?, P> w, P waiterParam, boolean increase) {
339        scrollTo(new WaitableChecker<>(w, waiterParam, increase, this));
340    }
341
342    /**
343     * Scrolls scrollbar to the position defined by a ScrollChecker
344     * implementation.
345     *
346     * @param checker ScrollChecker implementation defining scrolling direction,
347     * and so on.
348     * @see ScrollChecker
349     * @throws TimeoutExpiredException
350     */
351    public void scrollTo(ScrollChecker checker) {
352        scrollTo(new CheckerAdjustable(checker, this));
353    }
354
355    /**
356     * Scrolls scrollbar to the position defined by a ScrollAdjuster
357     * implementation.
358     *
359     * @param adj defines scrolling direction, and so on.
360     * @throws TimeoutExpiredException
361     */
362    public void scrollTo(final ScrollAdjuster adj) {
363        initOperators();
364        produceTimeRestricted(new Action<Void, Void>() {
365            @Override
366            public Void launch(Void obj) {
367                driver.scroll(JScrollBarOperator.this, adj);
368                return null;
369            }
370
371            @Override
372            public String getDescription() {
373                return "Scrolling";
374            }
375
376            @Override
377            public String toString() {
378                return "JScrollBarOperator.scrollTo.Action{description = " + getDescription() + '}';
379            }
380        }, "JScrollBarOperator.WholeScrollTimeout");
381    }
382
383    /**
384     * Scrolls scroll bar to necessary value.
385     *
386     * @param value Scroll bar value to scroll to.
387     * @throws TimeoutExpiredException
388     */
389    public void scrollToValue(int value) {
390        output.printTrace("Scroll JScrollBar to " + Integer.toString(value)
391                + " value\n" + toStringSource());
392        output.printGolden("Scroll JScrollBar to " + Integer.toString(value) + " value");
393        scrollTo(new ValueScrollAdjuster(value));
394    }
395
396    /**
397     * Scrolls scroll bar to necessary proportional value.
398     *
399     * @param proportionalValue Proportional scroll to. Must be >= 0 and <= 1.
400     * @throws TimeoutExpiredException
401     */
402    public void scrollToValue(double proportionalValue) {
403        output.printTrace("Scroll JScrollBar to " + Double.toString(proportionalValue)
404                + " proportional value\n" + toStringSource());
405        output.printGolden("Scroll JScrollBar to " + Double.toString(proportionalValue) + " proportional value");
406        scrollTo(new ValueScrollAdjuster((int) (getMinimum()
407                + (getMaximum()
408                - getVisibleAmount()
409                - getMinimum()) * proportionalValue)));
410    }
411
412    /**
413     * Scrolls to minimum value.
414     *
415     * @throws TimeoutExpiredException
416     */
417    public void scrollToMinimum() {
418        output.printTrace("Scroll JScrollBar to minimum value\n"
419                + toStringSource());
420        output.printGolden("Scroll JScrollBar to minimum value");
421        initOperators();
422        produceTimeRestricted(new Action<Void, Void>() {
423            @Override
424            public Void launch(Void obj) {
425                driver.scrollToMinimum(JScrollBarOperator.this, getOrientation());
426                return null;
427            }
428
429            @Override
430            public String getDescription() {
431                return "Scrolling";
432            }
433
434            @Override
435            public String toString() {
436                return "JScrollBarOperator.scrollToMinimum.Action{description = " + getDescription() + '}';
437            }
438        }, "JScrollBarOperator.WholeScrollTimeout");
439    }
440
441    /**
442     * Scrolls to maximum value.
443     *
444     * @throws TimeoutExpiredException
445     */
446    public void scrollToMaximum() {
447        output.printTrace("Scroll JScrollBar to maximum value\n"
448                + toStringSource());
449        output.printGolden("Scroll JScrollBar to maximum value");
450        initOperators();
451        produceTimeRestricted(new Action<Void, Void>() {
452            @Override
453            public Void launch(Void obj) {
454                driver.scrollToMaximum(JScrollBarOperator.this, getOrientation());
455                return null;
456            }
457
458            @Override
459            public String getDescription() {
460                return "Scrolling";
461            }
462
463            @Override
464            public String toString() {
465                return "JScrollBarOperator.scrollToMaximum.Action{description = " + getDescription() + '}';
466            }
467        }, "JScrollBarOperator.WholeScrollTimeout");
468    }
469
470    /**
471     * Returns a button responsible for value decreasing.
472     *
473     * @return an operator for the decrease button.
474     */
475    public JButtonOperator getDecreaseButton() {
476        initOperators();
477        return minButtOperator;
478    }
479
480    /**
481     * Returns a button responsible for value increasing.
482     *
483     * @return an operator for the increase button.
484     */
485    public JButtonOperator getIncreaseButton() {
486        initOperators();
487        return maxButtOperator;
488    }
489
490    @Override
491    public Hashtable<String, Object> getDump() {
492        Hashtable<String, Object> result = super.getDump();
493        result.put(MINIMUM_DPROP, Integer.toString(((JScrollBar) getSource()).getMinimum()));
494        result.put(MAXIMUM_DPROP, Integer.toString(((JScrollBar) getSource()).getMaximum()));
495        result.put(ORIENTATION_DPROP, (((JScrollBar) getSource()).getOrientation() == JScrollBar.HORIZONTAL)
496                ? HORIZONTAL_ORIENTATION_DPROP_VALUE
497                : VERTICAL_ORIENTATION_DPROP_VALUE);
498        result.put(VALUE_DPROP, Integer.toString(((JScrollBar) getSource()).getValue()));
499        return result;
500    }
501
502    ////////////////////////////////////////////////////////
503    //Mapping                                             //
504    /**
505     * Maps {@code JScrollBar.addAdjustmentListener(AdjustmentListener)}
506     * through queue
507     */
508    public void addAdjustmentListener(final AdjustmentListener adjustmentListener) {
509        runMapping(new MapVoidAction("addAdjustmentListener") {
510            @Override
511            public void map() {
512                ((JScrollBar) getSource()).addAdjustmentListener(adjustmentListener);
513            }
514        });
515    }
516
517    /**
518     * Maps {@code JScrollBar.getBlockIncrement()} through queue
519     */
520    public int getBlockIncrement() {
521        return (runMapping(new MapIntegerAction("getBlockIncrement") {
522            @Override
523            public int map() {
524                return ((JScrollBar) getSource()).getBlockIncrement();
525            }
526        }));
527    }
528
529    /**
530     * Maps {@code JScrollBar.getBlockIncrement(int)} through queue
531     */
532    public int getBlockIncrement(final int i) {
533        return (runMapping(new MapIntegerAction("getBlockIncrement") {
534            @Override
535            public int map() {
536                return ((JScrollBar) getSource()).getBlockIncrement(i);
537            }
538        }));
539    }
540
541    /**
542     * Maps {@code JScrollBar.getMaximum()} through queue
543     */
544    public int getMaximum() {
545        return (runMapping(new MapIntegerAction("getMaximum") {
546            @Override
547            public int map() {
548                return ((JScrollBar) getSource()).getMaximum();
549            }
550        }));
551    }
552
553    /**
554     * Maps {@code JScrollBar.getMinimum()} through queue
555     */
556    public int getMinimum() {
557        return (runMapping(new MapIntegerAction("getMinimum") {
558            @Override
559            public int map() {
560                return ((JScrollBar) getSource()).getMinimum();
561            }
562        }));
563    }
564
565    /**
566     * Maps {@code JScrollBar.getModel()} through queue
567     */
568    public BoundedRangeModel getModel() {
569        return (runMapping(new MapAction<BoundedRangeModel>("getModel") {
570            @Override
571            public BoundedRangeModel map() {
572                return ((JScrollBar) getSource()).getModel();
573            }
574        }));
575    }
576
577    /**
578     * Maps {@code JScrollBar.getOrientation()} through queue
579     */
580    public int getOrientation() {
581        return (runMapping(new MapIntegerAction("getOrientation") {
582            @Override
583            public int map() {
584                return ((JScrollBar) getSource()).getOrientation();
585            }
586        }));
587    }
588
589    /**
590     * Maps {@code JScrollBar.getUI()} through queue
591     */
592    public ScrollBarUI getUI() {
593        return (runMapping(new MapAction<ScrollBarUI>("getUI") {
594            @Override
595            public ScrollBarUI map() {
596                return ((JScrollBar) getSource()).getUI();
597            }
598        }));
599    }
600
601    /**
602     * Maps {@code JScrollBar.getUnitIncrement()} through queue
603     */
604    public int getUnitIncrement() {
605        return (runMapping(new MapIntegerAction("getUnitIncrement") {
606            @Override
607            public int map() {
608                return ((JScrollBar) getSource()).getUnitIncrement();
609            }
610        }));
611    }
612
613    /**
614     * Maps {@code JScrollBar.getUnitIncrement(int)} through queue
615     */
616    public int getUnitIncrement(final int i) {
617        return (runMapping(new MapIntegerAction("getUnitIncrement") {
618            @Override
619            public int map() {
620                return ((JScrollBar) getSource()).getUnitIncrement(i);
621            }
622        }));
623    }
624
625    /**
626     * Maps {@code JScrollBar.getValue()} through queue
627     */
628    public int getValue() {
629        return (runMapping(new MapIntegerAction("getValue") {
630            @Override
631            public int map() {
632                return ((JScrollBar) getSource()).getValue();
633            }
634        }));
635    }
636
637    /**
638     * Maps {@code JScrollBar.getValueIsAdjusting()} through queue
639     */
640    public boolean getValueIsAdjusting() {
641        return (runMapping(new MapBooleanAction("getValueIsAdjusting") {
642            @Override
643            public boolean map() {
644                return ((JScrollBar) getSource()).getValueIsAdjusting();
645            }
646        }));
647    }
648
649    /**
650     * Maps {@code JScrollBar.getVisibleAmount()} through queue
651     */
652    public int getVisibleAmount() {
653        return (runMapping(new MapIntegerAction("getVisibleAmount") {
654            @Override
655            public int map() {
656                return ((JScrollBar) getSource()).getVisibleAmount();
657            }
658        }));
659    }
660
661    /**
662     * Maps {@code JScrollBar.removeAdjustmentListener(AdjustmentListener)}
663     * through queue
664     */
665    public void removeAdjustmentListener(final AdjustmentListener adjustmentListener) {
666        runMapping(new MapVoidAction("removeAdjustmentListener") {
667            @Override
668            public void map() {
669                ((JScrollBar) getSource()).removeAdjustmentListener(adjustmentListener);
670            }
671        });
672    }
673
674    /**
675     * Maps {@code JScrollBar.setBlockIncrement(int)} through queue
676     */
677    public void setBlockIncrement(final int i) {
678        runMapping(new MapVoidAction("setBlockIncrement") {
679            @Override
680            public void map() {
681                ((JScrollBar) getSource()).setBlockIncrement(i);
682            }
683        });
684    }
685
686    /**
687     * Maps {@code JScrollBar.setMaximum(int)} through queue
688     */
689    public void setMaximum(final int i) {
690        runMapping(new MapVoidAction("setMaximum") {
691            @Override
692            public void map() {
693                ((JScrollBar) getSource()).setMaximum(i);
694            }
695        });
696    }
697
698    /**
699     * Maps {@code JScrollBar.setMinimum(int)} through queue
700     */
701    public void setMinimum(final int i) {
702        runMapping(new MapVoidAction("setMinimum") {
703            @Override
704            public void map() {
705                ((JScrollBar) getSource()).setMinimum(i);
706            }
707        });
708    }
709
710    /**
711     * Maps {@code JScrollBar.setModel(BoundedRangeModel)} through queue
712     */
713    public void setModel(final BoundedRangeModel boundedRangeModel) {
714        runMapping(new MapVoidAction("setModel") {
715            @Override
716            public void map() {
717                ((JScrollBar) getSource()).setModel(boundedRangeModel);
718            }
719        });
720    }
721
722    /**
723     * Maps {@code JScrollBar.setOrientation(int)} through queue
724     */
725    public void setOrientation(final int i) {
726        runMapping(new MapVoidAction("setOrientation") {
727            @Override
728            public void map() {
729                ((JScrollBar) getSource()).setOrientation(i);
730            }
731        });
732    }
733
734    /**
735     * Maps {@code JScrollBar.setUnitIncrement(int)} through queue
736     */
737    public void setUnitIncrement(final int i) {
738        runMapping(new MapVoidAction("setUnitIncrement") {
739            @Override
740            public void map() {
741                ((JScrollBar) getSource()).setUnitIncrement(i);
742            }
743        });
744    }
745
746    /**
747     * Maps {@code JScrollBar.setValue(int)} through queue
748     */
749    public void setValue(final int i) {
750        runMapping(new MapVoidAction("setValue") {
751            @Override
752            public void map() {
753                ((JScrollBar) getSource()).setValue(i);
754            }
755        });
756    }
757
758    /**
759     * Maps {@code JScrollBar.setValueIsAdjusting(boolean)} through queue
760     */
761    public void setValueIsAdjusting(final boolean b) {
762        runMapping(new MapVoidAction("setValueIsAdjusting") {
763            @Override
764            public void map() {
765                ((JScrollBar) getSource()).setValueIsAdjusting(b);
766            }
767        });
768    }
769
770    /**
771     * Maps {@code JScrollBar.setValues(int, int, int, int)} through queue
772     */
773    public void setValues(final int i, final int i1, final int i2, final int i3) {
774        runMapping(new MapVoidAction("setValues") {
775            @Override
776            public void map() {
777                ((JScrollBar) getSource()).setValues(i, i1, i2, i3);
778            }
779        });
780    }
781
782    /**
783     * Maps {@code JScrollBar.setVisibleAmount(int)} through queue
784     */
785    public void setVisibleAmount(final int i) {
786        runMapping(new MapVoidAction("setVisibleAmount") {
787            @Override
788            public void map() {
789                ((JScrollBar) getSource()).setVisibleAmount(i);
790            }
791        });
792    }
793
794    //End of mapping                                      //
795    ////////////////////////////////////////////////////////
796    private void initOperators() {
797        if (minButtOperator != null
798                && maxButtOperator != null) {
799            return;
800        }
801        ComponentChooser chooser = new ComponentChooser() {
802            @Override
803            public boolean checkComponent(Component comp) {
804                return comp instanceof JButton;
805            }
806
807            @Override
808            public String getDescription() {
809                return "";
810            }
811
812            @Override
813            public String toString() {
814                return "JScrollBarOperator.initOperators.ComponentChooser{description = " + getDescription() + '}';
815            }
816        };
817        ComponentSearcher searcher = new ComponentSearcher((Container) getSource());
818        searcher.setOutput(output.createErrorOutput());
819        JButton butt0 = (JButton) searcher.findComponent(chooser, 0);
820        JButton butt1 = (JButton) searcher.findComponent(chooser, 1);
821
822        if (butt0 == null || butt1 == null) {
823            minButtOperator = null;
824            maxButtOperator = null;
825            return;
826        }
827
828        JButton minButt, maxButt;
829
830        if (((JScrollBar) getSource()).getOrientation() == JScrollBar.HORIZONTAL) {
831            if (butt0.getX() < butt1.getX()) {
832                minButt = butt0;
833                maxButt = butt1;
834            } else {
835                minButt = butt1;
836                maxButt = butt0;
837            }
838        } else if (butt0.getY() < butt1.getY()) {
839            minButt = butt0;
840            maxButt = butt1;
841        } else {
842            minButt = butt1;
843            maxButt = butt0;
844        }
845        minButtOperator = new JButtonOperator(minButt);
846        maxButtOperator = new JButtonOperator(maxButt);
847
848        minButtOperator.copyEnvironment(this);
849        maxButtOperator.copyEnvironment(this);
850
851        minButtOperator.setOutput(output.createErrorOutput());
852        maxButtOperator.setOutput(output.createErrorOutput());
853
854        Timeouts times = timeouts.cloneThis();
855        times.setTimeout("AbstractButtonOperator.PushButtonTimeout",
856                times.getTimeout("JScrollBarOperator.OneScrollClickTimeout"));
857
858        minButtOperator.setTimeouts(times);
859        maxButtOperator.setTimeouts(times);
860
861        minButtOperator.setVisualizer(new EmptyVisualizer());
862        maxButtOperator.setVisualizer(new EmptyVisualizer());
863    }
864
865    /**
866     * Interface can be used to define some kind of complicated scrolling rules.
867     */
868    public interface ScrollChecker {
869
870        /**
871         * Defines a scrolling direction.
872         *
873         * @param oper an operator
874         * @see
875         * org.netbeans.jemmy.drivers.scrolling.ScrollAdjuster#INCREASE_SCROLL_DIRECTION
876         * @see
877         * org.netbeans.jemmy.drivers.scrolling.ScrollAdjuster#DECREASE_SCROLL_DIRECTION
878         * @see
879         * org.netbeans.jemmy.drivers.scrolling.ScrollAdjuster#DO_NOT_TOUCH_SCROLL_DIRECTION
880         * @return one of the following values:<BR>
881         * ScrollAdjuster.INCREASE_SCROLL_DIRECTION<BR>
882         * ScrollAdjuster.DECREASE_SCROLL_DIRECTION<BR>
883         * ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION<BR>
884         */
885        public int getScrollDirection(JScrollBarOperator oper);
886
887        /**
888         * Scrolling rules decription.
889         *
890         * @return a description
891         */
892        public String getDescription();
893    }
894
895    private class ValueScrollAdjuster implements ScrollAdjuster {
896
897        int value;
898
899        public ValueScrollAdjuster(int value) {
900            this.value = value;
901        }
902
903        @Override
904        public int getScrollDirection() {
905            if (getValue() == value) {
906                return ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION;
907            } else {
908                return ((getValue() < value)
909                        ? ScrollAdjuster.INCREASE_SCROLL_DIRECTION
910                        : ScrollAdjuster.DECREASE_SCROLL_DIRECTION);
911            }
912        }
913
914        @Override
915        public int getScrollOrientation() {
916            return getOrientation();
917        }
918
919        @Override
920        public String getDescription() {
921            return "Scroll to " + Integer.toString(value) + " value";
922        }
923
924        @Override
925        public String toString() {
926            return "ValueScrollAdjuster{" + "value=" + value + '}';
927        }
928    }
929
930    private class WaitableChecker<P> implements ScrollAdjuster {
931
932        Waitable<?, P> w;
933        P waitParam;
934        boolean increase;
935        boolean reached = false;
936
937        public WaitableChecker(Waitable<?, P> w, P waitParam, boolean increase, JScrollBarOperator oper) {
938            this.w = w;
939            this.waitParam = waitParam;
940            this.increase = increase;
941        }
942
943        @Override
944        public int getScrollDirection() {
945            if (!reached && w.actionProduced(waitParam) != null) {
946                reached = true;
947            }
948            if (reached) {
949                return ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION;
950            } else {
951                return (increase
952                        ? ScrollAdjuster.INCREASE_SCROLL_DIRECTION
953                        : ScrollAdjuster.DECREASE_SCROLL_DIRECTION);
954            }
955        }
956
957        @Override
958        public int getScrollOrientation() {
959            return getOrientation();
960        }
961
962        @Override
963        public String getDescription() {
964            return w.getDescription();
965        }
966
967        @Override
968        public String toString() {
969            return "WaitableChecker{" + "w=" + w + ", waitParam=" + waitParam + ", increase=" + increase + ", reached=" + reached + '}';
970        }
971    }
972
973    private class CheckerAdjustable implements ScrollAdjuster {
974
975        ScrollChecker checker;
976        JScrollBarOperator oper;
977
978        public CheckerAdjustable(ScrollChecker checker, JScrollBarOperator oper) {
979            this.checker = checker;
980            this.oper = oper;
981        }
982
983        @Override
984        public int getScrollDirection() {
985            return checker.getScrollDirection(oper);
986        }
987
988        @Override
989        public int getScrollOrientation() {
990            return getOrientation();
991        }
992
993        @Override
994        public String getDescription() {
995            return checker.getDescription();
996        }
997
998        @Override
999        public String toString() {
1000            return "CheckerAdjustable{" + "checker=" + checker + ", oper=" + oper + '}';
1001        }
1002    }
1003
1004    /**
1005     * Checks component type.
1006     */
1007    public static class JScrollBarFinder extends Finder {
1008
1009        /**
1010         * Constructs JScrollBarFinder.
1011         *
1012         * @param sf other searching criteria.
1013         */
1014        public JScrollBarFinder(ComponentChooser sf) {
1015            super(JScrollBar.class, sf);
1016        }
1017
1018        /**
1019         * Constructs JScrollBarFinder.
1020         */
1021        public JScrollBarFinder() {
1022            super(JScrollBar.class);
1023        }
1024    }
1025}
1026