diff --git a/jdk/.hgignore b/jdk/.hgignore
index 1ed4344d03f..9710bc5d891 100644
--- a/jdk/.hgignore
+++ b/jdk/.hgignore
@@ -7,3 +7,5 @@
^make/netbeans/.*/dist/
^.hgtip
.DS_Store
+.*/JTreport/.*
+.*/JTwork/.*
diff --git a/jdk/make/netbeans/client_sanity/README b/jdk/make/netbeans/client_sanity/README
new file mode 100644
index 00000000000..76d57db49c3
--- /dev/null
+++ b/jdk/make/netbeans/client_sanity/README
@@ -0,0 +1,15 @@
+This NetBeans project corresponds to client sanity test suite in jdk/test/sanity/client.
+
+It simplifies working on the suite in NetBeans.
+
+It also includes the following custom tasks:
+
+prepare-bundle creates dist/sanity.zip containing standalone bundle of the suite
+
+run-jemmy-browser runs Jemmy browser for the ButtonDemo (hardcoded in build.xml file)
+ The tool allows to explore the UI hierarchy.
+
+There is no task to run tests using JTReg. Please refer to corresponding README file
+in the client sanity test suite folder on how to run the tests.
+
+Contact alexander.kouznetsov@oracle.com in case of issues.
\ No newline at end of file
diff --git a/jdk/make/netbeans/client_sanity/build.xml b/jdk/make/netbeans/client_sanity/build.xml
new file mode 100644
index 00000000000..734fe10b036
--- /dev/null
+++ b/jdk/make/netbeans/client_sanity/build.xml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+ Builds, tests, and runs the project SanityTests.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jdk/make/netbeans/client_sanity/manifest.mf b/jdk/make/netbeans/client_sanity/manifest.mf
new file mode 100644
index 00000000000..1574df4a2de
--- /dev/null
+++ b/jdk/make/netbeans/client_sanity/manifest.mf
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+X-COMMENT: Main-Class will be added automatically by build
+
diff --git a/jdk/make/netbeans/client_sanity/nbproject/build-impl.xml b/jdk/make/netbeans/client_sanity/nbproject/build-impl.xml
new file mode 100644
index 00000000000..00073338957
--- /dev/null
+++ b/jdk/make/netbeans/client_sanity/nbproject/build-impl.xml
@@ -0,0 +1,1429 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set src.src3.dir
+ Must set src.src4.dir
+ Must set src.src2.dir
+ Must set src.src.dir
+ Must set build.dir
+ Must set dist.dir
+ Must set build.classes.dir
+ Must set dist.javadoc.dir
+ Must set build.test.classes.dir
+ Must set build.test.results.dir
+ Must set build.classes.excludes
+ Must set dist.jar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No tests executed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set JVM to use for profiling in profiler.info.jvm
+ Must set profiler agent JVM arguments in profiler.info.jvmargs.agent
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ To run this application from the command line without Ant, try:
+
+ java -jar "${dist.jar.resolved}"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set debug.class
+
+
+
+
+ Must select one file in the IDE or set debug.class
+
+
+
+
+ Must set fix.includes
+
+
+
+
+
+
+
+
+
+ This target only works when run from inside the NetBeans IDE.
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set profile.class
+ This target only works when run from inside the NetBeans IDE.
+
+
+
+
+
+
+
+
+ This target only works when run from inside the NetBeans IDE.
+
+
+
+
+
+
+
+
+
+
+
+
+ This target only works when run from inside the NetBeans IDE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+
+
+ Must select some files in the IDE or set test.includes
+
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+
+ Must select one file in the IDE or set applet.url
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Some tests failed; see details above.
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set test.includes
+
+
+
+ Some tests failed; see details above.
+
+
+
+ Must select some files in the IDE or set test.class
+ Must select some method in the IDE or set test.method
+
+
+
+ Some tests failed; see details above.
+
+
+
+
+ Must select one file in the IDE or set test.class
+
+
+
+ Must select one file in the IDE or set test.class
+ Must select some method in the IDE or set test.method
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set applet.url
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set applet.url
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jdk/make/netbeans/client_sanity/nbproject/genfiles.properties b/jdk/make/netbeans/client_sanity/nbproject/genfiles.properties
new file mode 100644
index 00000000000..fc956fd5f2e
--- /dev/null
+++ b/jdk/make/netbeans/client_sanity/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=0f9d9977
+build.xml.script.CRC32=f902e8b8
+build.xml.stylesheet.CRC32=8064a381@1.75.2.48
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=55414227
+nbproject/build-impl.xml.script.CRC32=c12f9d04
+nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48
diff --git a/jdk/make/netbeans/client_sanity/nbproject/project.properties b/jdk/make/netbeans/client_sanity/nbproject/project.properties
new file mode 100644
index 00000000000..a43ee024fd8
--- /dev/null
+++ b/jdk/make/netbeans/client_sanity/nbproject/project.properties
@@ -0,0 +1,79 @@
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=false
+annotation.processing.processors.list=
+annotation.processing.run.all.processors=true
+annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+application.title=SanityTests
+application.vendor=akouznet
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+# Uncomment to specify the preferred debugger connection transport:
+#debug.transport=dt_socket
+debug.classpath=\
+ ${run.classpath}
+debug.test.classpath=\
+ ${run.test.classpath}
+# Files in build.classes.dir which should be excluded from distribution jar
+dist.archive.excludes=
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/SanityTests.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+endorsed.classpath=
+excludes=*.cfg
+includes=**
+jar.compress=false
+javac.classpath=\
+ ${libs.testng.classpath}
+# Space-separated list of extra javac options
+javac.compilerargs=-Xmaxwarns 9999 -Xlint:all -Xlint:-serial
+javac.deprecation=false
+javac.external.vm=false
+javac.processorpath=\
+ ${javac.classpath}
+javac.source=1.8
+javac.target=1.8
+javac.test.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}
+javac.test.processorpath=\
+ ${javac.test.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+main.class=
+manifest.file=manifest.mf
+meta.inf.dir=${src.dir}/META-INF
+mkdist.disabled=false
+platform.active=default_platform
+run.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project.
+# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
+# To set system properties for unit tests define test-sys-prop.name=value:
+run.jvmargs=-ea
+run.test.classpath=\
+ ${javac.test.classpath}:\
+ ${build.test.classes.dir}
+source.encoding=UTF-8
+src.src.dir=..\\..\\..\\test\\sanity\\client\\SwingSet\\src
+src.src2.dir=..\\..\\..\\test\\sanity\\client\\lib\\SwingSet3\\src
+src.src3.dir=..\\..\\..\\test\\sanity\\client\\lib\\jemmy\\src
+src.src4.dir=..\\..\\..\\test\\sanity\\client\\lib\\Jemmy2Ext\\src
diff --git a/jdk/make/netbeans/client_sanity/nbproject/project.xml b/jdk/make/netbeans/client_sanity/nbproject/project.xml
new file mode 100644
index 00000000000..fccac4ecf31
--- /dev/null
+++ b/jdk/make/netbeans/client_sanity/nbproject/project.xml
@@ -0,0 +1,17 @@
+
+
+ org.netbeans.modules.java.j2seproject
+
+
+ SanityTests
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jdk/test/TEST.groups b/jdk/test/TEST.groups
index 898ace52108..53deee5c732 100644
--- a/jdk/test/TEST.groups
+++ b/jdk/test/TEST.groups
@@ -60,7 +60,8 @@ tier3 = \
:jdk_rmi \
:jdk_beans \
:jdk_imageio \
- :jdk_sound
+ :jdk_sound \
+ :jdk_client_sanity
###############################################################################
#
@@ -351,6 +352,10 @@ jdk_desktop = \
:jdk_sound \
:jdk_imageio
+# SwingSet3 tests.
+jdk_client_sanity = \
+ sanity/client/SwingSet
+
###############################################################################
#
# Serviceability sanity groups
diff --git a/jdk/test/sanity/client/README b/jdk/test/sanity/client/README
new file mode 100644
index 00000000000..09f8e16326a
--- /dev/null
+++ b/jdk/test/sanity/client/README
@@ -0,0 +1,45 @@
+This suite contains automated client sanity tests which can be run using JTReg.
+
+Contact alexander.kouznetsov@oracle.com in case of issues.
+
+-------------------------------------------------------------------------------
+How to run:
+
+1) Download/Install the JDK to be tested in the system.
+ (For example C:/java/jdk1.9.0 in windows or
+ /export/jdk/jdk1.9.0 in linux/mac/solaris)
+2) Download/Install JTReg harness, minimum required version is 4.1 b13.
+3) Open terminal(cmd in windows, *not* cygwin) and go to the this directory.
+4) To run
+ - see the notes below on how to prepare for the test run
+ - set JT_HOME to , for example
+ set JT_HOME=C:\Java\client\jtreg (Windows)
+ - run the command
+ 'sh -ea -k:\!screenshots -jdk: SwingSet'
+
+ For example: 'sh C:/jtreg/bin/jtreg -ea -k:\!screenshots -jdk:C:/java/jdk1.9.0 SwingSet' (Windows)
+ 'sh /export/jtreg/bin/jtreg -ea -k:\!screenshots -jdk:/export/jdk/jdk1.9.0 SwingSet' (Linux/Solaris)
+ 'sh /export/jtreg/bin/jtreg -ea -k:\!screenshots -jdk:/export/jdk/jdk1.9.0/Contents/Home SwingSet' (Mac)
+
+Try to minimize all the other windows for no interference and test stability.
+Do not touch keyboard or mouse, open any window, nor lock the screen while the tests are running.
+The tests will be executed, and the results will be displayed in the terminal.
+
+A report will be generated under
+ a) JTReg: "JTReport/index.html".
+The failure logs could be found under:
+ a) JTReg: "JTWork//.jtr"
+
+The following additional options might be useful:
+-retain:all to keep work files for passed tests
+-k:\!screenshots removal of this option will run tests that require full environment with Robot and screenshots
+-g to run JavaTest GUI
+
+-------------------------------------------------------------------------------
+
+The tests in the suite are based on SwingSet3 demo application. They use Jemmy to
+operate on controls of the demo and verify that it is behaving as expected. Both
+Jemmy and SwingSet3 sources are available as copies in lib folder.
+
+Original Jemmy repository is https://jemmy.java.net
+Original SwingSet3 repository is https://java.net/projects/swingset3
\ No newline at end of file
diff --git a/jdk/test/sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java b/jdk/test/sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java
new file mode 100644
index 00000000000..b6959ac150a
--- /dev/null
+++ b/jdk/test/sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.image.BufferedImage;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.image.StrictImageComparator;
+import org.netbeans.jemmy.operators.JButtonOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import static org.jemmy2ext.JemmyExt.*;
+import org.testng.annotations.Test;
+import static com.sun.swingset3.demos.button.ButtonDemo.*;
+
+/*
+ * @test
+ * @key headful screenshots
+ * @summary Verifies buttons on SwingSet3 ButtonDemo page by clicking each
+ * button, taking its screenshots and checking that pressed button
+ * image is different from initial button image.
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/SwingSet3/src
+ * @build org.jemmy2ext.JemmyExt
+ * @build com.sun.swingset3.demos.button.ButtonDemo
+ * @run testng ButtonDemoScreenshotTest
+ */
+public class ButtonDemoScreenshotTest {
+
+ private static final int BUTTON_COUNT = 6; // TODO: Decide about "open browser" buttons (value was 8 originally)
+
+ @Test
+ public void test() throws Exception {
+ captureDebugInfoOnFail(() -> {
+ Robot rob = new Robot();
+
+ new ClassReference(com.sun.swingset3.demos.button.ButtonDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
+ waitImageIsStill(rob, mainFrame);
+
+ // Check all the buttons
+ for (int i = 0; i < BUTTON_COUNT; i++) {
+ checkButton(mainFrame, i, rob);
+ }
+ });
+ }
+
+ public void checkButton(JFrameOperator jfo, int i, Robot rob) {
+ JButtonOperator button = new JButtonOperator(jfo, i);
+
+ Point loc = button.getLocationOnScreen();
+ rob.mouseMove(loc.x, loc.y);
+
+ BufferedImage initialButtonImage = capture(rob, button);
+ assertNotBlack(initialButtonImage);
+ save(initialButtonImage, "button" + i + "_0initial.png");
+ rob.mousePress(InputEvent.BUTTON1_MASK);
+ try {
+ waitPressed(button);
+ BufferedImage pressedButtonImage = capture(rob, button);
+ assertNotBlack(pressedButtonImage);
+ save(pressedButtonImage, "button" + i + "_1pressed.png");
+
+ StrictImageComparator sComparator = new StrictImageComparator();
+ assertNotEquals("Button " + i + " Test", sComparator, initialButtonImage, pressedButtonImage);
+ } finally {
+ rob.mouseRelease(InputEvent.BUTTON1_MASK);
+ }
+ }
+
+}
diff --git a/jdk/test/sanity/client/SwingSet/src/ButtonDemoTest.java b/jdk/test/sanity/client/SwingSet/src/ButtonDemoTest.java
new file mode 100644
index 00000000000..3d0d8f1afea
--- /dev/null
+++ b/jdk/test/sanity/client/SwingSet/src/ButtonDemoTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.swingset3.demos.JHyperlink;
+import com.sun.swingset3.demos.button.ButtonDemo;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import javax.swing.ButtonModel;
+import javax.swing.JButton;
+import javax.swing.event.ChangeEvent;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.Test;
+import org.jemmy2ext.JemmyExt.ByToolTipChooser;
+import static org.jemmy2ext.JemmyExt.EXACT_STRING_COMPARATOR;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.operators.JButtonOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import static com.sun.swingset3.demos.button.ButtonDemo.*;
+import org.jemmy2ext.JemmyExt;
+import org.jemmy2ext.JemmyExt.MultiThreadedTryCatch;
+import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+
+/*
+ * @test
+ * @key headful
+ * @summary Verifies buttons on SwingSet3 ButtonDemo page by clicking each button
+ * and checking model change events. It also verifies tooltips and text
+ * on buttons before and after click.
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/SwingSet3/src
+ * @build org.jemmy2ext.JemmyExt
+ * @build com.sun.swingset3.demos.button.ButtonDemo
+ * @run testng ButtonDemoTest
+ */
+public class ButtonDemoTest {
+
+ private static final String[] BUTTON_TEXT_AFTER = {
+ DO_IT_AGAIN,};
+
+ private static final String[] BUTTON_TEXT_BEFORE = {
+ DO_IT,
+ "",
+ FIND,
+ GO,
+ CONNECT,
+ "",
+ GET_MORE_INFO,
+ null
+ };
+
+ private static final String[] BUTTON_TOOLTIP = {
+ SIMPLE_BUTTON,
+ IMAGE_BUTTON,
+ BUTTON_WITH_TEXT_AND_IMAGE,
+ BUTTON_WITH_BACKGROUND_COLOR,
+ BUTTON_WITH_NO_BORDER,
+ BUTTON_WITH_ROLLOVER_IMAGE,
+ JAVA_SE_URL,
+ JAVA_BLOGS_URL
+ };
+
+ private static final String[] GOLDEN = {
+ "isArmed = false, isEnabled = true, isPressed = false, isSelected = false",
+ "isArmed = true, isEnabled = true, isPressed = false, isSelected = false",
+ "isArmed = true, isEnabled = true, isPressed = true, isSelected = false",
+ "isArmed = true, isEnabled = true, isPressed = false, isSelected = false",
+ "isArmed = false, isEnabled = true, isPressed = false, isSelected = false"
+ };
+
+ @Test
+ public void test() throws Exception {
+
+ captureDebugInfoOnFail(() -> {
+
+ new ClassReference(ButtonDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
+ mainFrame.setComparator(EXACT_STRING_COMPARATOR);
+
+ // Check all the buttons
+ for (int i = 0; i < BUTTON_TOOLTIP.length; i++) {
+ String tooltip = BUTTON_TOOLTIP[i];
+
+ JButtonOperator button = new JButtonOperator(mainFrame, new ByToolTipChooser(tooltip));
+
+ assertEquals(BUTTON_TEXT_BEFORE[i], button.getText());
+
+ // Two buttons are hyperlinks, we don't want to click them
+ if (!button.getSource().getClass().equals(JHyperlink.class)) {
+ checkButton(button);
+ }
+
+ if (BUTTON_TEXT_AFTER.length > i) {
+ assertEquals(BUTTON_TEXT_AFTER[i], button.getText());
+ } else {
+ assertEquals(BUTTON_TEXT_BEFORE[i], button.getText());
+ }
+ }
+
+ });
+ }
+
+ private void checkButton(JButtonOperator button) throws Exception {
+ MultiThreadedTryCatch tryCatch = new JemmyExt.MultiThreadedTryCatch();
+ try {
+ BlockingQueue modelStateChanges = new ArrayBlockingQueue<>(GOLDEN.length);
+ button.getQueueTool().invokeAndWait(() -> {
+ try {
+ JButton jButton = (JButton) button.getSource();
+ ButtonModel model = jButton.getModel();
+ String line = toString(model);
+ System.out.println("Inital: " + line);
+ modelStateChanges.add(line);
+ model.addChangeListener((ChangeEvent e) -> {
+ try {
+ String line2 = toString(model);
+ System.out.println("ChangeEvent: " + line2);
+
+ // We are only interested in the first GOLDEN.length events
+ if (modelStateChanges.remainingCapacity() > 0) {
+ modelStateChanges.add(line2);
+ }
+ } catch (RuntimeException | Error t) {
+ tryCatch.register(t);
+ }
+ });
+ } catch (Error error) {
+ // All exceptions are already handled by Jemmy but Errors are not
+ tryCatch.register(error);
+ throw error;
+ }
+ });
+
+ assertEquals("Initial state check", GOLDEN[0], modelStateChanges.take());
+
+ button.clickMouse();
+
+ for (int state = 1; state < GOLDEN.length; state++) {
+ assertEquals(GOLDEN[state], modelStateChanges.take());
+ }
+ } catch (RuntimeException | Error | InterruptedException t) {
+ tryCatch.registerRoot(t);
+ } finally {
+ tryCatch.throwRegistered();
+ }
+ }
+
+ private static String toString(ButtonModel model) {
+ return "isArmed = " + model.isArmed()
+ + ", isEnabled = " + model.isEnabled()
+ + ", isPressed = " + model.isPressed()
+ + ", isSelected = " + model.isSelected();
+ }
+
+}
diff --git a/jdk/test/sanity/client/SwingSet/src/ComboBoxDemoTest.java b/jdk/test/sanity/client/SwingSet/src/ComboBoxDemoTest.java
new file mode 100644
index 00000000000..303bbd681f1
--- /dev/null
+++ b/jdk/test/sanity/client/SwingSet/src/ComboBoxDemoTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.swingset3.demos.combobox.ComboBoxDemo;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.Test;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.operators.JComboBoxOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import static com.sun.swingset3.demos.combobox.ComboBoxDemo.*;
+import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+
+/*
+ * @test
+ * @key headful
+ * @summary Verifies ComboBoxes on SwingSet2 ComboBoxDemo page by selecting
+ * each value of each ComboBox.
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/SwingSet3/src
+ * @build org.jemmy2ext.JemmyExt
+ * @build com.sun.swingset3.demos.combobox.ComboBoxDemo
+ * @run testng ComboBoxDemoTest
+ */
+public class ComboBoxDemoTest {
+
+ private static enum ComboBoxInfo {
+ PRESETS("Presets:"),
+ HAIR("Hair:"),
+ EYES_N_NOSE("Eyes & Nose:"),
+ MOUTH("Mouth:");
+
+ private final String comboBoxName;
+
+ private ComboBoxInfo(String comboBoxName) {
+ this.comboBoxName = comboBoxName;
+ }
+
+ }
+
+ @Test
+ public void test() throws Exception {
+ captureDebugInfoOnFail(() -> {
+ new ClassReference(ComboBoxDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+ for (ComboBoxInfo comboBoxInfo : ComboBoxInfo.values()) {
+ comboBoxChecker(frame, comboBoxInfo);
+ }
+ });
+ }
+
+ private void comboBoxChecker(JFrameOperator jfo, ComboBoxInfo comboBoxInfo) {
+ JComboBoxOperator jcbo = new JComboBoxOperator(jfo, comboBoxInfo.ordinal());
+ for (int i = 0; i < jcbo.getItemCount(); i++) {
+ jcbo.selectItem(i);
+ assertEquals(comboBoxInfo.comboBoxName + " ComboBox SelectedIndex is correct", i, jcbo.getSelectedIndex());
+ }
+ }
+
+}
diff --git a/jdk/test/sanity/client/SwingSet/src/ListDemoTest.java b/jdk/test/sanity/client/SwingSet/src/ListDemoTest.java
new file mode 100644
index 00000000000..c24399e526b
--- /dev/null
+++ b/jdk/test/sanity/client/SwingSet/src/ListDemoTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.swingset3.demos.list.ListDemo;
+import static com.sun.swingset3.demos.list.ListDemo.DEMO_TITLE;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.Test;
+import static org.jemmy2ext.JemmyExt.getLabeledContainerOperator;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.operators.JCheckBoxOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JListOperator;
+import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+
+/*
+ * @test
+ * @key headful
+ * @summary Verifies SwingSet3 ListDemo page by checking and unchecking all
+ * the checkboxes on the page and verifying the number of items in the
+ * list.
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/SwingSet3/src
+ * @build org.jemmy2ext.JemmyExt
+ * @build com.sun.swingset3.demos.list.ListDemo
+ * @run testng ListDemoTest
+ */
+public class ListDemoTest {
+
+ private static final int CHECKBOX_COUNT = 50;
+
+ @Test
+ public void test() throws Exception {
+ captureDebugInfoOnFail(() -> {
+ new ClassReference(ListDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+ JListOperator listOp = new JListOperator(frame);
+
+ // Check *NO* Prefix and Suffixes Marked
+ for (int i = 0; i < CHECKBOX_COUNT; i++) {
+ JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+ checkBox.changeSelection(false);
+ }
+ System.out.println("######## Number of Items = " + listOp.getModel().getSize());
+ assertEquals("Select None number of items is correct", 0, listOp.getModel().getSize());
+
+ // Check *ALL* Prefix and Suffixes Marked
+ for (int i = 0; i < CHECKBOX_COUNT; i++) {
+ JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+ checkBox.changeSelection(true);
+ }
+ System.out.println("######## Number of Items = " + listOp.getModel().getSize());
+ assertEquals("Select All number of items is correct", CHECKBOX_COUNT / 2 * CHECKBOX_COUNT / 2, listOp.getModel().getSize());
+
+ // Check *ALL* Prefix and *NO* Suffixes Marked
+ for (int i = 0; i < CHECKBOX_COUNT; i++) {
+ JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+ if (i < CHECKBOX_COUNT / 2) {
+ checkBox.changeSelection(true);
+ } else {
+ checkBox.changeSelection(false);
+ }
+ }
+ System.out.println("######## Number of Items = " + listOp.getModel().getSize());
+ assertEquals("Select All Prefixes and NO Suffixes number of items is correct", 0, listOp.getModel().getSize());
+
+ // Check *NO* Prefix and *ALL* Suffixes Marked
+ for (int i = 0; i < CHECKBOX_COUNT; i++) {
+ JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+ if (i < CHECKBOX_COUNT / 2) {
+ checkBox.changeSelection(false);
+ } else {
+ checkBox.changeSelection(true);
+ }
+ }
+ System.out.println("######## Number of Items = " + listOp.getModel().getSize());
+ assertEquals("Select NO Prefixes and All Suffixes number of items is correct", 0, listOp.getModel().getSize());
+ });
+ }
+
+ private JCheckBoxOperator getJCheckBoxOperator(JFrameOperator frame, int index) {
+
+ // We map first half of indexes to the Prefixes panel and the second half
+ // to the Suffixes panel
+ String labelText;
+ int subindex;
+ if (index < CHECKBOX_COUNT / 2) {
+ labelText = "Prefixes";
+ subindex = index;
+ } else {
+ labelText = "Suffixes";
+ subindex = index - CHECKBOX_COUNT / 2;
+ }
+
+ return new JCheckBoxOperator(getLabeledContainerOperator(frame, labelText), subindex);
+ }
+
+}
diff --git a/jdk/test/sanity/client/SwingSet/src/OptionPaneDemoTest.java b/jdk/test/sanity/client/SwingSet/src/OptionPaneDemoTest.java
new file mode 100644
index 00000000000..2cecfe72637
--- /dev/null
+++ b/jdk/test/sanity/client/SwingSet/src/OptionPaneDemoTest.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.swingset3.demos.optionpane.OptionPaneDemo;
+import static com.sun.swingset3.demos.optionpane.OptionPaneDemo.*;
+import javax.swing.UIManager;
+import static org.jemmy2ext.JemmyExt.*;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.Test;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.operators.JButtonOperator;
+import org.netbeans.jemmy.operators.JComboBoxOperator;
+import org.netbeans.jemmy.operators.JDialogOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JLabelOperator;
+import org.netbeans.jemmy.operators.JTextFieldOperator;
+
+
+/*
+ * @test
+ * @key headful
+ * @summary Verifies SwingSet3 OptionPaneDemo page by opening all the dialogs
+ * and choosing different options in them.
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/SwingSet3/src
+ * @build org.jemmy2ext.JemmyExt
+ * @build com.sun.swingset3.demos.optionpane.OptionPaneDemo
+ * @run testng OptionPaneDemoTest
+ */
+public class OptionPaneDemoTest {
+
+ public static final String SOME_TEXT_TO_TYPE = "I am some text";
+ public static final String MESSAGE = UIManager.getString("OptionPane.messageDialogTitle");
+ public static final String OK = "OK";
+ public static final String CANCEL = "Cancel";
+ public static final String INPUT = UIManager.getString("OptionPane.inputDialogTitle");
+ public static final String TEXT_TO_TYPE = "Hooray! I'm a textField";
+ public static final String NO = "No";
+ public static final String YES = "Yes";
+ public static final String SELECT_AN__OPTION = UIManager.getString("OptionPane.titleText");
+
+ @Test
+ public void test() throws Exception {
+ captureDebugInfoOnFail(() -> {
+ new ClassReference(OptionPaneDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+
+ showInputDialog(frame);
+ showWarningDialog(frame);
+ showMessageDialog(frame);
+ showComponentDialog(frame);
+ showConfirmationDialog(frame);
+ });
+ }
+
+ public void showInputDialog(JFrameOperator jfo) throws Exception {
+ // Cancel with text case
+ {
+ new JButtonOperator(jfo, INPUT_BUTTON).pushNoBlock();
+
+ JDialogOperator jdo = new JDialogOperator(INPUT);
+ JTextFieldOperator jto = new JTextFieldOperator(jdo);
+ jto.setText(SOME_TEXT_TO_TYPE);
+
+ assertTrue("Show Input Dialog cancel w/ Text", jdo.isShowing());
+
+ new JButtonOperator(jdo, CANCEL).push();
+
+ assertFalse("Show Input Dialog cancel w/ Text", jdo.isShowing());
+ }
+
+ // Cancel with *NO* text case
+ {
+ new JButtonOperator(jfo, INPUT_BUTTON).pushNoBlock();
+
+ JDialogOperator jdo = new JDialogOperator(INPUT);
+
+ assertTrue("Show Input Dialog cancel w/o Text", jdo.isShowing());
+
+ new JButtonOperator(jdo, CANCEL).push();
+
+ assertFalse("Show Input Dialog cancel w/o Text", jdo.isShowing());
+ }
+
+ // Text field has *NO* input
+ {
+ new JButtonOperator(jfo, INPUT_BUTTON).pushNoBlock();
+
+ JDialogOperator jdo = new JDialogOperator(INPUT);
+
+ assertTrue("Show Input Dialog w/o Input", jdo.isShowing());
+
+ new JButtonOperator(jdo, OK).push();
+
+ assertFalse("Show Input Dialog w/o Input", jdo.isShowing());
+ }
+
+ // Text field has input
+ {
+ final String enteredText = "Rambo";
+
+ new JButtonOperator(jfo, INPUT_BUTTON).pushNoBlock();
+
+ JDialogOperator jdo = new JDialogOperator(INPUT);
+ JTextFieldOperator jto = new JTextFieldOperator(jdo);
+ jto.setText(enteredText);
+ new JButtonOperator(jdo, OK).pushNoBlock();
+
+ JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
+
+ assertTrue("Show Input Dialog w/ Input", jdo1.isShowing());
+
+ final String labelText = enteredText + INPUT_RESPONSE;
+ JLabelOperator jLabelOperator = new JLabelOperator(jdo1, labelText);
+ assertEquals("Text from the field made it into the dialog", labelText, jLabelOperator.getText());
+
+ new JButtonOperator(jdo1, OK).push();
+
+ assertFalse("Show Input Dialog w/ Input", jdo1.isShowing());
+ }
+ }
+
+ public void showWarningDialog(JFrameOperator jfo) throws Exception {
+ new JButtonOperator(jfo, WARNING_BUTTON).pushNoBlock();
+
+ JDialogOperator jdo = new JDialogOperator(WARNING_TITLE);
+
+ assertTrue("Show Warning Dialog", jdo.isShowing());
+
+ new JButtonOperator(jdo, OK).push();
+
+ assertFalse("Show Warning Dialog", jdo.isShowing());
+ }
+
+ public void showMessageDialog(JFrameOperator jfo) throws Exception {
+ new JButtonOperator(jfo, MESSAGE_BUTTON).pushNoBlock();
+
+ JDialogOperator jdo = new JDialogOperator(MESSAGE);
+
+ assertTrue("Show Message Dialog", jdo.isShowing());
+
+ new JButtonOperator(jdo, OK).push();
+
+ assertFalse("Show Message Dialog", jdo.isShowing());
+ }
+
+ public void showComponentDialog(JFrameOperator jfo) throws Exception {
+ // Case: Cancel
+ {
+ new JButtonOperator(jfo, COMPONENT_BUTTON).pushNoBlock();
+
+ JDialogOperator jdo = new JDialogOperator(COMPONENT_TITLE);
+
+ assertTrue("Show Component Dialog Cancel Option", jdo.isShowing());
+
+ new JButtonOperator(jdo, COMPONENT_OP5).push();
+
+ assertFalse("Show Component Dialog Cancel Option", jdo.isShowing());
+ }
+
+ // Case: Yes option selected
+ {
+ new JButtonOperator(jfo, COMPONENT_BUTTON).pushNoBlock();
+
+ JDialogOperator jdo = new JDialogOperator(COMPONENT_TITLE);
+ new JButtonOperator(jdo, COMPONENT_OP1).pushNoBlock();
+
+ JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
+
+ assertTrue("Component Dialog Example Yes Option", jdo1.isShowing());
+
+ final String labelText = COMPONENT_R1;
+ JLabelOperator jLabelOperator = new JLabelOperator(jdo1, labelText);
+ assertEquals("Dialog contains appropriate text", labelText, jLabelOperator.getText());
+
+ new JButtonOperator(jdo1, OK).push();
+
+ assertFalse("Component Dialog Example Yes Option", jdo1.isShowing());
+ }
+
+ // Case: No option selected
+ {
+ new JButtonOperator(jfo, COMPONENT_BUTTON).pushNoBlock();
+
+ JDialogOperator jdo = new JDialogOperator(COMPONENT_TITLE);
+ new JButtonOperator(jdo, COMPONENT_OP2).pushNoBlock();
+
+ JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
+
+ assertTrue("Component Dialog Example No Option", jdo1.isShowing());
+
+ final String labelText = COMPONENT_R2;
+ JLabelOperator jLabelOperator = new JLabelOperator(jdo1, labelText);
+ assertEquals("Dialog contains appropriate text", labelText, jLabelOperator.getText());
+
+ new JButtonOperator(jdo1, OK).push();
+
+ assertFalse("Component Dialog Example No Option", jdo1.isShowing());
+ }
+
+ // Case: Maybe option selected
+ {
+ new JButtonOperator(jfo, COMPONENT_BUTTON).pushNoBlock();
+
+ JDialogOperator jdo = new JDialogOperator(COMPONENT_TITLE);
+ new JButtonOperator(jdo, COMPONENT_OP3).pushNoBlock();
+
+ JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
+
+ assertTrue("Component Dialog Maybe Yes Option", jdo1.isShowing());
+
+ final String labelText = COMPONENT_R3;
+ JLabelOperator jLabelOperator = new JLabelOperator(jdo1, labelText);
+ assertEquals("Dialog contains appropriate text", labelText, jLabelOperator.getText());
+
+ new JButtonOperator(jdo1, OK).push();
+
+ assertFalse("Component Dialog Maybe Yes Option", jdo1.isShowing());
+ }
+
+ // Case: Probably option selected
+ {
+ new JButtonOperator(jfo, COMPONENT_BUTTON).pushNoBlock();
+
+ JDialogOperator jdo = new JDialogOperator(COMPONENT_TITLE);
+ new JButtonOperator(jdo, COMPONENT_OP4).pushNoBlock();
+
+ JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
+
+ assertTrue("Component Dialog Example Probably Option", jdo1.isShowing());
+
+ final String labelText = COMPONENT_R4;
+ JLabelOperator jLabelOperator = new JLabelOperator(jdo1, labelText);
+ assertEquals("Dialog contains appropriate text", labelText, jLabelOperator.getText());
+
+ new JButtonOperator(jdo1, OK).push();
+
+ assertFalse("Component Dialog Example Probably Option", jdo1.isShowing());
+ }
+
+ // Case TextField and ComboBox functional
+ {
+ new JButtonOperator(jfo, COMPONENT_BUTTON).push();
+
+ JDialogOperator jdo = new JDialogOperator(COMPONENT_TITLE);
+
+ JTextFieldOperator jto = new JTextFieldOperator(jdo);
+ jto.clearText();
+ jto.typeText(TEXT_TO_TYPE);
+
+ JComboBoxOperator jcbo = new JComboBoxOperator(jdo);
+ jcbo.selectItem(2);
+
+ assertEquals("Show Component Dialog TextField", TEXT_TO_TYPE, jto.getText());
+ assertEquals("Show Component Dialog ComboBox", 2, jcbo.getSelectedIndex());
+
+ new JButtonOperator(jdo, "cancel").push();
+ }
+ }
+
+ public void showConfirmationDialog(JFrameOperator jfo) throws Exception {
+ // Case: Yes option selected
+ {
+ new JButtonOperator(jfo, CONFIRM_BUTTON).pushNoBlock();
+
+ JDialogOperator jdo = new JDialogOperator(SELECT_AN__OPTION);
+ new JButtonOperator(jdo, YES).pushNoBlock();
+
+ JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
+
+ assertTrue("Show Confirmation Dialog Yes Option", jdo1.isShowing());
+
+ final String labelText = CONFIRM_YES;
+ JLabelOperator jLabelOperator = new JLabelOperator(jdo1, labelText);
+ assertEquals("Dialog contains appropriate text", labelText, jLabelOperator.getText());
+
+ new JButtonOperator(jdo1, OK).push();
+
+ assertFalse("Show Confirmation Dialog Yes Option", jdo1.isShowing());
+ }
+
+ // Case: No option selected
+ {
+ new JButtonOperator(jfo, CONFIRM_BUTTON).pushNoBlock();
+
+ JDialogOperator jdo = new JDialogOperator(SELECT_AN__OPTION);
+ new JButtonOperator(jdo, NO).pushNoBlock();
+
+ JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
+
+ assertTrue("Show Confirmation Dialog No Option", jdo1.isShowing());
+
+ final String labelText = CONFIRM_NO;
+ JLabelOperator jLabelOperator = new JLabelOperator(jdo1, labelText);
+ assertEquals("Dialog contains appropriate text", labelText, jLabelOperator.getText());
+
+ new JButtonOperator(jdo1, OK).push();
+
+ assertFalse("Show Confirmation Dialog No Option", jdo1.isShowing());
+ }
+
+ // Case: Cancel option selected
+ {
+ new JButtonOperator(jfo, CONFIRM_BUTTON).pushNoBlock();
+
+ JDialogOperator jdo = new JDialogOperator(SELECT_AN__OPTION);
+
+ assertTrue("Show Confirmation Dialog Cancel Option", jdo.isShowing());
+
+ new JButtonOperator(jdo, CANCEL).push();
+
+ assertFalse("Show Confirmation Dialog Cancel Option", jdo.isShowing());
+ }
+ }
+
+}
diff --git a/jdk/test/sanity/client/SwingSet/src/ProgressBarDemoTest.java b/jdk/test/sanity/client/SwingSet/src/ProgressBarDemoTest.java
new file mode 100644
index 00000000000..411d05cd1b7
--- /dev/null
+++ b/jdk/test/sanity/client/SwingSet/src/ProgressBarDemoTest.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.swingset3.demos.progressbar.ProgressBarDemo;
+import static com.sun.swingset3.demos.progressbar.ProgressBarDemo.*;
+import java.awt.Component;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.Test;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.operators.JButtonOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JProgressBarOperator;
+import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+
+/*
+ * @test
+ * @key headful
+ * @summary Verifies SwingSet3 ProgressBarDemo page by pressing start and stop
+ * buttons and checking the progress bar and the buttons state.
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/SwingSet3/src
+ * @build org.jemmy2ext.JemmyExt
+ * @build com.sun.swingset3.demos.progressbar.ProgressBarDemo
+ * @run testng ProgressBarDemoTest
+ */
+public class ProgressBarDemoTest {
+
+ @Test
+ public void test() throws Exception {
+ captureDebugInfoOnFail(() -> {
+ new ClassReference(ProgressBarDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+
+ JButtonOperator startButton = new JButtonOperator(frame, START_BUTTON);
+ JButtonOperator stopButton = new JButtonOperator(frame, STOP_BUTTON);
+ JProgressBarOperator jpbo = new JProgressBarOperator(frame);
+
+ // Check that progress completes and corect enable/disable of start/stop buttons
+ checkCompleteProgress(frame, startButton, stopButton, jpbo);
+
+ // Check progess bar progression and start/stop button disabled/enabled states
+ checkStartStop(frame, startButton, stopButton, jpbo);
+ });
+ }
+
+ // Check that progress completes and corect enable/disable of start/stop buttons
+ public void checkStartStop(JFrameOperator frame, JButtonOperator startButton, JButtonOperator stopButton, JProgressBarOperator progressBar) throws Exception {
+ int initialProgress = progressBar.getValue();
+ System.out.println("initialProgress = " + initialProgress);
+ int maximum = progressBar.getMaximum();
+
+ startButton.pushNoBlock();
+
+ progressBar.waitState(new ComponentChooser() {
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ int value = progressBar.getValue();
+ System.out.println("checkComponent1 value = " + value);
+ return value < maximum;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Progress < maximum (" + maximum + ")";
+ }
+ });
+
+ stopButton.waitComponentEnabled();
+
+ progressBar.waitState(new ComponentChooser() {
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ int value = progressBar.getValue();
+ System.out.println("checkComponent2 value = " + value);
+ return value > 0;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Progress > 0";
+ }
+ });
+
+ int progress = progressBar.getValue();
+ System.out.println("progress = " + progress);
+
+ //Check that progress par has progressed and Start Button Disabled
+ assertTrue("Progress Bar Progressing (progress > 0, actual value: " + progress + ")", progress > 0);
+ assertFalse("Start Button Disabled", startButton.isEnabled());
+ assertTrue("Stop Button Enabled", stopButton.isEnabled());
+
+ //Wait a liitle bit longer then Press stop get progress
+ progressBar.waitState(new ComponentChooser() {
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ return progressBar.getValue() > progress;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Progress > " + progress;
+ }
+ });
+
+ stopButton.pushNoBlock();
+
+ startButton.waitComponentEnabled();
+
+ int interimProgress = progressBar.getValue();
+
+ // Check that progress par has Stopped and Start Button Disabled
+ assertTrue("Progress Bar Stopped "
+ + "(interimProgress, actual value: " + interimProgress + " "
+ + "> progress, actual value: " + progress + ")",
+ interimProgress > progress);
+ assertTrue("Start Button Enabled", startButton.isEnabled());
+ assertFalse("Stop Button Disabled", stopButton.isEnabled());
+ }
+
+ // Check progess bar progression and start/stop button disabled/enabled states
+ public void checkCompleteProgress(JFrameOperator frame, JButtonOperator startButton, JButtonOperator stopButton, JProgressBarOperator progressBar) throws Exception {
+ startButton.pushNoBlock();
+
+ progressBar.waitValue(progressBar.getMaximum());
+
+ startButton.waitComponentEnabled();
+
+ assertEquals("Complete Progress", progressBar.getMaximum(), progressBar.getValue());
+ assertTrue("Start Button Enabled", startButton.isEnabled());
+ assertFalse("Stop Button Disabled", stopButton.isEnabled());
+ }
+
+}
diff --git a/jdk/test/sanity/client/SwingSet/src/ScrollPaneDemoTest.java b/jdk/test/sanity/client/SwingSet/src/ScrollPaneDemoTest.java
new file mode 100644
index 00000000000..bd88904f875
--- /dev/null
+++ b/jdk/test/sanity/client/SwingSet/src/ScrollPaneDemoTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.swingset3.demos.scrollpane.ScrollPaneDemo;
+import static com.sun.swingset3.demos.scrollpane.ScrollPaneDemo.DEMO_TITLE;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.Test;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JScrollPaneOperator;
+import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+
+/*
+ * @test
+ * @key headful
+ * @summary Verifies SwingSet3 ScrollPaneDemo by scrolling to bottom, to top,
+ * to left and to right and checking scroll bar values.
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/SwingSet3/src
+ * @build org.jemmy2ext.JemmyExt
+ * @build com.sun.swingset3.demos.scrollpane.ScrollPaneDemo
+ * @run testng ScrollPaneDemoTest
+ */
+public class ScrollPaneDemoTest {
+
+ @Test
+ public void test() throws Exception {
+ captureDebugInfoOnFail(() -> {
+ new ClassReference(ScrollPaneDemo.class.getName()).startApplication();
+
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+ JScrollPaneOperator jspo = new JScrollPaneOperator(frame);
+
+ // Set initial scrollbar positions
+ int initialVerticalValue = jspo.getVerticalScrollBar().getValue();
+ int initialHorizontalValue = jspo.getHorizontalScrollBar().getValue();
+
+ System.out.println("Initial Vertical Value = " + jspo.getVerticalScrollBar().getValue());
+ System.out.println("Initial HoriZontal Value = " + jspo.getHorizontalScrollBar().getValue());
+
+ // Check scroll to Bottom
+ {
+ jspo.scrollToBottom();
+ int currentValue = jspo.getVerticalScrollBar().getValue();
+ System.out.println("Final Value = " + currentValue);
+ assertTrue("Scroll to Bottom of Pane "
+ + "(initialVerticalValue, actual value: " + initialVerticalValue + " "
+ + "< currentValue, actual value = " + currentValue + ")",
+ initialVerticalValue < currentValue);
+ }
+
+ // Check scroll to Top
+ {
+ jspo.scrollToTop();
+ int currentValue = jspo.getVerticalScrollBar().getValue();
+ System.out.println("Top Scroll Final Value = " + currentValue);
+ assertTrue("Scroll to Top of Pane "
+ + "(initialVerticalValue, actual value: " + initialVerticalValue + " "
+ + "> currentValue, actual value = " + currentValue + ")",
+ initialVerticalValue > currentValue);
+ }
+
+ // Check scroll to Left
+ {
+ jspo.scrollToLeft();
+ int currentValue = jspo.getHorizontalScrollBar().getValue();
+ System.out.println("Scroll to Left Final Value = " + currentValue);
+ assertTrue("Scroll to Left of Pane "
+ + "(initialHorizontalValue, actual value: " + initialHorizontalValue + " "
+ + "> currentValue, actual value = " + currentValue + ")",
+ initialHorizontalValue > currentValue);
+ }
+
+ // Check scroll to Right
+ {
+ jspo.scrollToRight();
+ int currentValue = jspo.getHorizontalScrollBar().getValue();
+ System.out.println("Scroll to Right Final Value = " + currentValue);
+ assertTrue("Scroll to Right of Pane "
+ + "(initialHorizontalValue, actual value: " + initialHorizontalValue + " "
+ + "< currentValue, actual value = " + currentValue + ")",
+ initialHorizontalValue < currentValue);
+ }
+ });
+ }
+
+}
diff --git a/jdk/test/sanity/client/SwingSet/src/SpinnerDemoTest.java b/jdk/test/sanity/client/SwingSet/src/SpinnerDemoTest.java
new file mode 100644
index 00000000000..89585adb6ad
--- /dev/null
+++ b/jdk/test/sanity/client/SwingSet/src/SpinnerDemoTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.swingset3.demos.spinner.SpinnerDemo;
+import static com.sun.swingset3.demos.spinner.SpinnerDemo.DEMO_TITLE;
+import java.text.DecimalFormat;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.Test;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JSpinnerOperator;
+import org.netbeans.jemmy.operators.JTextFieldOperator;
+import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+
+/*
+ * @test
+ * @key headful
+ * @summary Verifies SwingSet3 SpinnerDemo by adjusting each spinner value via
+ * the spinner button and checking text field value.
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/SwingSet3/src
+ * @build org.jemmy2ext.JemmyExt
+ * @build com.sun.swingset3.demos.spinner.SpinnerDemo
+ * @run testng SpinnerDemoTest
+ */
+public class SpinnerDemoTest {
+
+ private static final int SPINNERS_COUNT = 9;
+ private static final DecimalFormat decimalFormat = new DecimalFormat();
+
+ @Test
+ public void test() throws Exception {
+ captureDebugInfoOnFail(() -> {
+ new ClassReference(SpinnerDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+
+ // Check changing different spinners
+ for (int i = 0; i < SPINNERS_COUNT; i++) {
+ changeValues(frame, i);
+ }
+ });
+ }
+
+ private void changeValues(JFrameOperator jfo, int spinnerIndex) throws Exception {
+ JSpinnerOperator spinner = new JSpinnerOperator(jfo, spinnerIndex);
+ JTextFieldOperator jtfo = new JTextFieldOperator(spinner);
+ float originalFieldValue = decimalFormat.parse(jtfo.getText()).floatValue();
+ float finalFieldValue;
+
+ // increment by one the value via spinner
+ spinner.getIncreaseOperator().push();
+ finalFieldValue = decimalFormat.parse(jtfo.getText()).floatValue();
+
+ // check that the value was increased
+ assertTrue("Increment Spinner " + spinner
+ + " (originalFieldValue, actual value: " + originalFieldValue + " "
+ + "< finalFieldValue, actual value = " + finalFieldValue + ")",
+ originalFieldValue < finalFieldValue);
+
+ // decrease value via spinner
+ spinner.getDecreaseOperator().push();
+ finalFieldValue = decimalFormat.parse(jtfo.getText()).floatValue();
+
+ // check that the value was decrimented
+ assertTrue("Decrement Spinner " + spinner
+ + " (originalFieldValue, actual value: " + originalFieldValue + " "
+ + ">= finalFieldValue, actual value = " + finalFieldValue + ")",
+ originalFieldValue >= finalFieldValue);
+ }
+
+}
diff --git a/jdk/test/sanity/client/SwingSet/src/SplitPaneDemoTest.java b/jdk/test/sanity/client/SwingSet/src/SplitPaneDemoTest.java
new file mode 100644
index 00000000000..2a242cc3f16
--- /dev/null
+++ b/jdk/test/sanity/client/SwingSet/src/SplitPaneDemoTest.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.swingset3.demos.splitpane.SplitPaneDemo;
+import static com.sun.swingset3.demos.splitpane.SplitPaneDemo.*;
+import java.awt.event.KeyEvent;
+import javax.swing.JSplitPane;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.Test;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.operators.JButtonOperator;
+import org.netbeans.jemmy.operators.JCheckBoxOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JRadioButtonOperator;
+import org.netbeans.jemmy.operators.JSplitPaneOperator;
+import org.netbeans.jemmy.operators.JTextFieldOperator;
+import static org.jemmy2ext.JemmyExt.*;
+
+/*
+ * @test
+ * @key headful
+ * @summary Verifies SwingSet3 SplitPaneDemo by performing OneClick expansion,
+ * changing size of the divier, moving the divider to different positions
+ * and changing the divider orientation.
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/SwingSet3/src
+ * @build org.jemmy2ext.JemmyExt
+ * @build com.sun.swingset3.demos.splitpane.SplitPaneDemo
+ * @run testng SplitPaneDemoTest
+ */
+public class SplitPaneDemoTest {
+
+ @Test
+ public void test() throws Exception {
+ captureDebugInfoOnFail(() -> {
+ new ClassReference(SplitPaneDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+
+ JSplitPaneOperator splitPane = new JSplitPaneOperator(frame);
+
+ // Toggle OneTouch Expandable
+ checkOneTouch(frame, splitPane, true);
+ checkOneTouch(frame, splitPane, false);
+
+ // Check changing divider size to minimum and maximum values
+ changeDividerSize(frame, splitPane, 50);
+ changeDividerSize(frame, splitPane, 6);
+
+ // Check moving the divider
+ checkDividerMoves(frame, splitPane, false);
+ checkDividerMoves(frame, splitPane, true);
+
+ // Check different minumum Day/Night sizes
+ changeMinimumSizes(frame, splitPane, 100);
+ changeMinimumSizes(frame, splitPane, 0);
+ });
+ }
+
+ // Check for different day and night minimum size
+ public void changeMinimumSizes(JFrameOperator frame, JSplitPaneOperator splitPane, int amount) throws Exception {
+ for (String label : new String[]{FIRST_COMPONENT_MIN_SIZE, SECOND_COMPONENT_MIN_SIZE}) {
+ JTextFieldOperator size = new JTextFieldOperator(getLabeledContainerOperator(frame, label));
+ size.enterText(Integer.toString(amount));
+ size.pressKey(KeyEvent.VK_ENTER);
+ }
+ checkDividerMoves(frame, splitPane, false);
+ checkDividerMoves(frame, splitPane, true);
+ }
+
+ // Check moving of divider
+ public void checkDividerMoves(JFrameOperator frame, JSplitPaneOperator splitPane, boolean isVertical) throws Exception {
+ if (isVertical) {
+ new JRadioButtonOperator(frame, VERTICAL_SPLIT).doClick();
+ } else {
+ new JRadioButtonOperator(frame, HORIZONTAL_SPLIT).doClick();
+ }
+
+ splitPane.moveDivider(0.0);
+ assertEquals("Move Minimum, dividerLocation is at minimumDividerLocation",
+ splitPane.getMinimumDividerLocation(), splitPane.getDividerLocation());
+
+ // use getMaximumDividerLocation() to move divider to here because using proportion 1.0 does not work
+ splitPane.moveDivider(1.0);
+
+ assertEquals("Move Maximum, dividerLocation is at maximumDividerLocation",
+ splitPane.getMaximumDividerLocation(), splitPane.getDividerLocation());
+
+ splitPane.moveDivider(0.5);
+ assertEquals("Move Middle, dividerLocation is at the artithmetic average of minimum and maximum DividerLocations",
+ (splitPane.getMaximumDividerLocation() + splitPane.getMinimumDividerLocation()) / 2, splitPane.getDividerLocation());
+ }
+
+ // Check changing the size of the divider
+ public void changeDividerSize(JFrameOperator frame, JSplitPaneOperator splitPane, int amount) throws Exception {
+ JTextFieldOperator size = new JTextFieldOperator(getLabeledContainerOperator(frame, DIVIDER_SIZE));
+ size.clearText();
+ size.typeText(Integer.toString(amount));
+ size.pressKey(KeyEvent.VK_ENTER);
+
+ assertEquals("Change Divider Size", amount, splitPane.getDividerSize());
+ }
+
+ public void checkOneTouch(JFrameOperator frame, JSplitPaneOperator splitPane, boolean oneTouch) throws Exception {
+ JCheckBoxOperator checkBox = new JCheckBoxOperator(frame, ONE_TOUCH_EXPANDABLE);
+ JButtonOperator buttonLeft = new JButtonOperator(splitPane.getDivider(), 0);
+ JButtonOperator buttonRight = new JButtonOperator(splitPane.getDivider(), 1);
+ int initDividerLocation = splitPane.getDividerLocation();
+
+ if (oneTouch) {
+ if (!checkBox.isSelected()) {
+ // uncheck
+ checkBox.doClick();
+ }
+
+ int left = getUIValue(splitPane, (JSplitPane sp) -> sp.getInsets().left);
+ System.out.println("left = " + left);
+ int right = getUIValue(splitPane, (JSplitPane sp) -> sp.getInsets().right);
+ System.out.println("right = " + right);
+
+ // expand full left
+ buttonLeft.push();
+ assertEquals("Expandable Left", left, splitPane.getDividerLocation());
+
+ // expand back from full left
+ buttonRight.push();
+ assertEquals("Expandable Back to Original from Left",
+ initDividerLocation, splitPane.getDividerLocation());
+
+ // expand all the way right
+ buttonRight.push();
+ assertEquals("Expandable Right",
+ splitPane.getWidth() - splitPane.getDividerSize() - right,
+ splitPane.getDividerLocation());
+
+ // Click to move back from right expansion
+ buttonLeft.push();
+ assertEquals("Expandable Back to Original from Right",
+ initDividerLocation, splitPane.getDividerLocation());
+ }
+
+ // Test for case where one touch expandable is disabled
+ if (!oneTouch) {
+ if (checkBox.isSelected()) {
+ // uncheck
+ checkBox.doClick();
+ }
+ assertFalse("One Touch Expandable Off", splitPane.isOneTouchExpandable());
+ }
+ }
+
+}
diff --git a/jdk/test/sanity/client/SwingSet/src/TabbedPaneDemoTest.java b/jdk/test/sanity/client/SwingSet/src/TabbedPaneDemoTest.java
new file mode 100644
index 00000000000..d3d8d28245f
--- /dev/null
+++ b/jdk/test/sanity/client/SwingSet/src/TabbedPaneDemoTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.swingset3.demos.tabbedpane.TabbedPaneDemo;
+import static com.sun.swingset3.demos.tabbedpane.TabbedPaneDemo.*;
+import static org.jemmy2ext.JemmyExt.getLabeledContainerOperator;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.Test;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.operators.ContainerOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JRadioButtonOperator;
+import org.netbeans.jemmy.operators.JTabbedPaneOperator;
+import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+
+/*
+ * @test
+ * @key headful
+ * @summary Verifies SwingSet3 TabbedPaneDemo by iterating through tab placement
+ * positions, opening each tab and verifying the the tab gets selected.
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/SwingSet3/src
+ * @build org.jemmy2ext.JemmyExt
+ * @build com.sun.swingset3.demos.tabbedpane.TabbedPaneDemo
+ * @run testng TabbedPaneDemoTest
+ */
+public class TabbedPaneDemoTest {
+
+ @Test
+ public void test() throws Exception {
+ captureDebugInfoOnFail(() -> {
+ new ClassReference(TabbedPaneDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
+
+ for (String tp : new String[]{TOP, LEFT, BOTTOM, RIGHT}) {
+ testTabs(mainFrame, tp);
+ }
+ });
+ }
+
+ public void testTabs(JFrameOperator mainFrame, String tabPlacement) throws Exception {
+ ContainerOperator> rbCont = getLabeledContainerOperator(mainFrame, TAB_PLACEMENT);
+ new JRadioButtonOperator(rbCont, tabPlacement).doClick();
+
+ final String[] tabTitles = new String[]{CAMILLE, MIRANDA, EWAN, BOUNCE};
+ for (int i = 0; i < tabTitles.length; i++) {
+ String pageTitle = tabTitles[i];
+ JTabbedPaneOperator tabOperator = new JTabbedPaneOperator(mainFrame);
+ tabOperator.selectPage(pageTitle);
+
+ assertEquals("Selected tab is selected", i, tabOperator.getSelectedIndex());
+ }
+ }
+
+}
diff --git a/jdk/test/sanity/client/SwingSet/src/TextFieldDemoTest.java b/jdk/test/sanity/client/SwingSet/src/TextFieldDemoTest.java
new file mode 100644
index 00000000000..4d38ce38a38
--- /dev/null
+++ b/jdk/test/sanity/client/SwingSet/src/TextFieldDemoTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.swingset3.demos.textfield.JHistoryTextField;
+import com.sun.swingset3.demos.textfield.TextFieldDemo;
+import static com.sun.swingset3.demos.textfield.TextFieldDemo.*;
+import java.awt.Color;
+import java.awt.event.KeyEvent;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import javax.swing.JFormattedTextField;
+import static org.jemmy2ext.JemmyExt.*;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.Test;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.operators.ContainerOperator;
+import org.netbeans.jemmy.operators.JButtonOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JLabelOperator;
+import org.netbeans.jemmy.operators.JPasswordFieldOperator;
+import org.netbeans.jemmy.operators.JTextFieldOperator;
+
+/*
+ * @test
+ * @key headful
+ * @summary Verifies SwingSet3 TextFieldDemo by entering text in each field and
+ * checking that app reacts accordingly.
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/SwingSet3/src
+ * @build org.jemmy2ext.JemmyExt
+ * @build com.sun.swingset3.demos.textfield.TextFieldDemo
+ * @run testng TextFieldDemoTest
+ */
+public class TextFieldDemoTest {
+
+ @Test
+ public void test() throws Exception {
+ captureDebugInfoOnFail(() -> {
+ new ClassReference(TextFieldDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+
+ historyTextField(frame);
+ dateTextField(frame);
+ passwordField(frame);
+ });
+ }
+
+ private void historyTextField(JFrameOperator jfo) throws Exception {
+ JTextFieldOperator jtfo = new JTextFieldOperator(jfo, new ByClassChooser(JHistoryTextField.class));
+ jtfo.typeText("cat");
+
+ jtfo.pressKey(KeyEvent.VK_DOWN);
+ jtfo.pressKey(KeyEvent.VK_DOWN);
+ jtfo.pressKey(KeyEvent.VK_ENTER);
+
+ final String expectedValue = "category";
+ jtfo.waitText(expectedValue);
+ assertEquals("Select History Item", expectedValue, jtfo.getText());
+ }
+
+ public void dateTextField(JFrameOperator jfo) throws Exception {
+ JTextFieldOperator jtfo = new JTextFieldOperator(jfo,
+ new ByClassChooser(JFormattedTextField.class));
+ ContainerOperator> containerOperator = new ContainerOperator<>(jtfo.getParent());
+ JButtonOperator jbo = new JButtonOperator(containerOperator, GO);
+ JLabelOperator dowLabel = new JLabelOperator(containerOperator);
+ Calendar calendar = Calendar.getInstance(Locale.ENGLISH);
+
+ // Check default date Day of the Week
+ jbo.push();
+ assertEquals("Default DOW",
+ calendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.ENGLISH),
+ dowLabel.getText());
+
+ // Check Custom Day of the Week
+ calendar.set(2012, 9, 11); // Represents "Oct 11, 2012"
+ Date date = calendar.getTime();
+ String dateString = jtfo.getQueueTool().invokeAndWait(
+ new QueueTool.QueueAction("Formatting the value using JFormattedTextField formatter") {
+
+ @Override
+ public String launch() throws Exception {
+ return ((JFormattedTextField) jtfo.getSource()).getFormatter().valueToString(date);
+ }
+ });
+ System.out.println("dateString = " + dateString);
+ jtfo.enterText(dateString);
+
+ jbo.push();
+ assertEquals("Custom DOW", "Thursday", dowLabel.getText());
+ }
+
+ public void passwordField(JFrameOperator jfo) throws Exception {
+ JPasswordFieldOperator password1 = new JPasswordFieldOperator(jfo, 0);
+ JPasswordFieldOperator password2 = new JPasswordFieldOperator(jfo, 1);
+
+ password1.typeText("password");
+ password2.typeText("password");
+
+ // Check Matching Passwords
+ assertEquals("Matching Passwords", Color.green, password1.getBackground());
+ assertEquals("Matching Passwords", Color.green, password2.getBackground());
+
+ // Check non-matching passwords
+ password2.typeText("passwereertegrs");
+ assertEquals("Non-Matching Passwords", Color.white, password1.getBackground());
+ assertEquals("Non-Matching Passwords", Color.white, password2.getBackground());
+ }
+
+}
diff --git a/jdk/test/sanity/client/SwingSet/src/ToggleButtonDemoTest.java b/jdk/test/sanity/client/SwingSet/src/ToggleButtonDemoTest.java
new file mode 100644
index 00000000000..c240540739e
--- /dev/null
+++ b/jdk/test/sanity/client/SwingSet/src/ToggleButtonDemoTest.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.swingset3.DemoProperties;
+import com.sun.swingset3.demos.togglebutton.DirectionPanel;
+import com.sun.swingset3.demos.togglebutton.LayoutControlPanel;
+import com.sun.swingset3.demos.togglebutton.ToggleButtonDemo;
+import static com.sun.swingset3.demos.togglebutton.ToggleButtonDemo.*;
+import java.util.function.BiFunction;
+import org.jemmy2ext.JemmyExt.ByClassChooser;
+import static org.jemmy2ext.JemmyExt.EXACT_STRING_COMPARATOR;
+import static org.jemmy2ext.JemmyExt.getBorderTitledJPanelOperator;
+import static org.jemmy2ext.JemmyExt.getLabeledContainerOperator;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.Test;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.operators.ContainerOperator;
+import org.netbeans.jemmy.operators.JCheckBoxOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JRadioButtonOperator;
+import org.netbeans.jemmy.operators.JTabbedPaneOperator;
+import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+
+/*
+ * @test
+ * @key headful
+ * @summary Verifies SwingSet3 ToggleButtonDemo by toggling each radio button,
+ * each checkbox and each location of the direction dial toggle.
+ * It verifies initial selected values for all the elements and checks
+ * that those change upon clicking. When toggling radio buttons it
+ * verifies that other radio buttons in the same group are not longer
+ * selected.
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/SwingSet3/src
+ * @build org.jemmy2ext.JemmyExt
+ * @build com.sun.swingset3.demos.togglebutton.ToggleButtonDemo
+ * @run testng ToggleButtonDemoTest
+ */
+public class ToggleButtonDemoTest {
+
+ @Test
+ public void test() throws Exception {
+ captureDebugInfoOnFail(() -> {
+ new ClassReference(ToggleButtonDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator mainFrame = new JFrameOperator(ToggleButtonDemo.class.getAnnotation(DemoProperties.class).value());
+ JTabbedPaneOperator tabPane = new JTabbedPaneOperator(mainFrame);
+
+ // Radio Button Toggles
+ testRadioButtons(getBorderTitledJPanelOperator(mainFrame, TEXT_RADIO_BUTTONS), 3, null);
+ testRadioButtons(getBorderTitledJPanelOperator(mainFrame, IMAGE_RADIO_BUTTONS), 3, null);
+ testRadioButtons(getLabeledContainerOperator(mainFrame, PAD_AMOUNT), 3, (t, i) -> DEFAULT.equals(t));
+
+ // switch to the Check Boxes Tab
+ tabPane.selectPage(CHECK_BOXES);
+
+ // Check Box Toggles
+ ContainerOperator> textCheckBoxesJPanel = getBorderTitledJPanelOperator(mainFrame, TEXT_CHECKBOXES);
+ testCheckBox(textCheckBoxesJPanel, CHECK1, false);
+ testCheckBox(textCheckBoxesJPanel, CHECK2, false);
+ testCheckBox(textCheckBoxesJPanel, CHECK3, false);
+
+ ContainerOperator> imageCheckBoxesJPanel = getBorderTitledJPanelOperator(mainFrame, IMAGE_CHECKBOXES);
+ testCheckBox(imageCheckBoxesJPanel, CHECK1, false);
+ testCheckBox(imageCheckBoxesJPanel, CHECK2, false);
+ testCheckBox(imageCheckBoxesJPanel, CHECK3, false);
+
+ ContainerOperator> displayOptionsContainer = getLabeledContainerOperator(mainFrame, DISPLAY_OPTIONS);
+ testCheckBox(displayOptionsContainer, PAINT_BORDER, false);
+ testCheckBox(displayOptionsContainer, PAINT_FOCUS, true);
+ testCheckBox(displayOptionsContainer, ENABLED, true);
+ testCheckBox(displayOptionsContainer, CONTENT_FILLED, true);
+
+ // Direction Button Toggles
+ testToggleButtons(mainFrame);
+ });
+ }
+
+ /**
+ * The interface is invoked for each radio button providing its name and
+ * index and it should return whether the radio button has to be selected.
+ */
+ private static interface SelectedRadioButton extends BiFunction {
+ }
+
+ /**
+ * Tests a group of radio buttons
+ *
+ * @param parent container containing the buttons
+ * @param radioButtonCount number of radio buttons
+ * @param selectedRadioButton initial selected radio button
+ */
+ private void testRadioButtons(ContainerOperator> parent, int radioButtonCount, SelectedRadioButton selectedRadioButton) {
+ JRadioButtonOperator[] jrbo = new JRadioButtonOperator[radioButtonCount];
+ for (int i = 0; i < radioButtonCount; i++) {
+ jrbo[i] = new JRadioButtonOperator(parent, i);
+ if (selectedRadioButton != null && selectedRadioButton.apply(jrbo[i].getText(), i)) {
+ assertTrue("Radio Button " + i + " is initially selected", jrbo[i].isSelected());
+ } else {
+ assertFalse("Radio Button " + i + " is initially not selected", jrbo[i].isSelected());
+ }
+ }
+
+ for (int i = 0; i < radioButtonCount; i++) {
+ jrbo[i].doClick();
+ assertTrue("Radio Button " + i + " is selected", jrbo[i].isSelected());
+
+ for (int j = 0; j < radioButtonCount; j++) {
+ if (i != j) {
+ assertFalse("Radio Button " + j + " is not selected", jrbo[j].isSelected());
+ }
+ }
+ }
+ }
+
+ /**
+ * Will change the state of the CheckBox then change back to initial state.
+ *
+ * @param parent
+ * @param text
+ * @param expectedValue
+ * @throws Exception
+ */
+ private void testCheckBox(ContainerOperator> parent, String text, boolean expectedValue) {
+
+ parent.setComparator(EXACT_STRING_COMPARATOR);
+ JCheckBoxOperator jcbo = new JCheckBoxOperator(parent, text);
+ assertEquals("Initial selection state of the checkbox '" + text + "'", expectedValue, jcbo.isSelected());
+
+ // click check box (toggle the state)
+ jcbo.doClick();
+ assertEquals("Selection state of the checkbox '" + text + "' after click", !expectedValue, jcbo.isSelected());
+ if (jcbo.isSelected()) {
+ // toggle back to not-selected state
+ jcbo.doClick();
+ assertFalse("Check Box '" + text + "' is not selected", jcbo.isSelected());
+ } else {
+ // toggle back to selected state
+ jcbo.doClick();
+
+ assertTrue("Check Box '" + text + "' is selected", jcbo.isSelected());
+ }
+ }
+
+
+ /*
+ * testDirectionRadioButtons(JFrameOperator) will toggle each position of
+ * the direction radio button panels
+ */
+ private void testToggleButtons(JFrameOperator jfo) {
+ ComponentChooser directionPanelChooser = new ByClassChooser(DirectionPanel.class);
+
+ String text_Position = LayoutControlPanel.TEXT_POSITION;
+ ContainerOperator> textPositionContainer = getLabeledContainerOperator(jfo, text_Position);
+ ContainerOperator> directionPanelOperator = new ContainerOperator<>(textPositionContainer, directionPanelChooser);
+ testRadioButtons(directionPanelOperator, 9, (t, i) -> i == 5);
+
+ // Unfortunately, both directionPanels are in the same parent container
+ // so we have to use indexes here.
+ // There is no guarantee that if the UI changes, the code would be still
+ // valid in terms of which directionPanel is checked first. However, it
+ // does guarantee that two different directionPanels are checked.
+ String content_Alignment = LayoutControlPanel.CONTENT_ALIGNMENT;
+ ContainerOperator> contentAlignmentContainer = getLabeledContainerOperator(jfo, content_Alignment);
+ ContainerOperator> directionPanelOperator2 = new ContainerOperator<>(contentAlignmentContainer, directionPanelChooser,
+ contentAlignmentContainer.getSource() == textPositionContainer.getSource() ? 1 : 0);
+ testRadioButtons(directionPanelOperator2, 9, (t, i) -> i == 4);
+
+ }
+
+}
diff --git a/jdk/test/sanity/client/SwingSet/src/TreeDemoTest.java b/jdk/test/sanity/client/SwingSet/src/TreeDemoTest.java
new file mode 100644
index 00000000000..b558d6fb96c
--- /dev/null
+++ b/jdk/test/sanity/client/SwingSet/src/TreeDemoTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.swingset3.demos.tree.TreeDemo;
+import static com.sun.swingset3.demos.tree.TreeDemo.DEMO_TITLE;
+import javax.swing.tree.TreePath;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.Test;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JTreeOperator;
+import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+
+/*
+ * @test
+ * @key headful
+ * @summary Verifies SwingSet3 TreeDemo by expanding all collapsed nodes in the
+ * tree and then collapsing all the expanded nodes in the tree. It
+ * verifies the number of nodes expanded, number of nodes collapsed and
+ * number of rows in the tree in the begininng, after expanding and
+ * after collapsing the nodes. It also checks that the tree grows
+ * vertically (as ScrollPane allows it).
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/SwingSet3/src
+ * @build org.jemmy2ext.JemmyExt
+ * @build com.sun.swingset3.demos.tree.TreeDemo
+ * @run testng TreeDemoTest
+ */
+public class TreeDemoTest {
+
+ @Test
+ public void test() throws Exception {
+ captureDebugInfoOnFail(() -> {
+ new ClassReference(TreeDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+
+ JTreeOperator tree = new JTreeOperator(frame);
+
+ assertEquals("Initial number of rows in the tree", 4, tree.getRowCount());
+
+ int initialTreeHeight = tree.getHeight();
+
+ // expand all nodes
+ int expandsCount = 0;
+ for (int i = 0; i < tree.getRowCount(); i++) {
+ TreePath tp = tree.getPathForRow(i);
+ if (tree.getChildCount(tp) > 0 && !tree.isExpanded(tp)) {
+ tree.expandRow(i);
+ expandsCount++;
+ }
+ }
+
+ assertEquals("Number of rows expanded", 75, expandsCount);
+ assertEquals("Number of rows in the tree after expanding all of them",
+ 616, tree.getRowCount());
+
+ int expandedTreeHeight = tree.getHeight();
+ assertTrue("Expanded tree height has increased, current "
+ + expandedTreeHeight + " > initial " + initialTreeHeight,
+ expandedTreeHeight > initialTreeHeight);
+
+ // collapse all nodes
+ int collapsesCount = 0;
+ for (int i = tree.getRowCount() - 1; i >= 0; i--) {
+ TreePath tp = tree.getPathForRow(i);
+ if (tree.getChildCount(tp) > 0 && tree.isExpanded(tp)) {
+ tree.collapseRow(i);
+ collapsesCount++;
+ }
+ }
+
+ assertEquals("Number of rows collapsed", 76, collapsesCount);
+ assertEquals("Number of rows in the tree after collapsing all of them",
+ 1, tree.getRowCount());
+
+ int collapsedTreeHeight = tree.getHeight();
+ assertTrue("Collpased tree height is not longer than initial, "
+ + "current " + collapsedTreeHeight + " <= initial "
+ + initialTreeHeight,
+ collapsedTreeHeight <= initialTreeHeight);
+
+ });
+ }
+
+}
diff --git a/jdk/test/sanity/client/SwingSet/src/WindowDemoTest.java b/jdk/test/sanity/client/SwingSet/src/WindowDemoTest.java
new file mode 100644
index 00000000000..ef0fb850360
--- /dev/null
+++ b/jdk/test/sanity/client/SwingSet/src/WindowDemoTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.swingset3.demos.window.WindowDemo;
+import static com.sun.swingset3.demos.window.WindowDemo.*;
+import static org.jemmy2ext.JemmyExt.*;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.Test;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.operators.JButtonOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JLabelOperator;
+import org.netbeans.jemmy.operators.WindowOperator;
+
+/*
+ * @test
+ * @key headful
+ * @summary Verifies SwingSet3 WindowDemo by checking that separate JWindow is
+ * shown, it contains predefined label and no new windows are opened
+ * when the "Show JWindow..." button is clicked.
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/SwingSet3/src
+ * @build org.jemmy2ext.JemmyExt
+ * @build com.sun.swingset3.demos.window.WindowDemo
+ * @run testng WindowDemoTest
+ */
+public class WindowDemoTest {
+
+ @Test
+ public void test() throws Exception {
+ captureDebugInfoOnFail(() -> {
+ new ClassReference(WindowDemo.class.getCanonicalName()).startApplication();
+
+ JFrameOperator frame = new JFrameOperator();
+
+ assertEquals("Only one JWindow is shown", 1, getJWindowCount());
+
+ WindowOperator window = new WindowOperator(getJWindow());
+
+ assertTrue("JFrame is showing", frame.isShowing());
+ assertFalse("JFrame is not iconified", isIconified(frame));
+ assertTrue("JWindow is showing", window.isShowing());
+
+ final String labelText = I_HAVE_NO_SYSTEM_BORDER;
+ JLabelOperator jLabelOperator = new JLabelOperator(window, labelText);
+ assertEquals("JWindow contains the label with corresponding text", labelText, jLabelOperator.getText());
+
+ new JButtonOperator(frame, SHOW_J_WINDOW).push();
+
+ assertEquals("Only one JWindow is shown", 1, getJWindowCount());
+ });
+ }
+
+}
diff --git a/jdk/test/sanity/client/TEST.ROOT.template b/jdk/test/sanity/client/TEST.ROOT.template
new file mode 100644
index 00000000000..6881809d9f8
--- /dev/null
+++ b/jdk/test/sanity/client/TEST.ROOT.template
@@ -0,0 +1,24 @@
+# This file identifies the root of the test-suite hierarchy.
+# It also contains test-suite configuration information.
+
+# The list of keywords supported in the entire test suite. The
+# "intermittent" keyword marks tests known to fail intermittently.
+# The "randomness" keyword marks tests using randomness with test
+# cases differing from run to run. (A test using a fixed random seed
+# would not count as "randomness" by this definition.) Extra care
+# should be taken to handle test failures of intermittent or
+# randomness tests.
+#
+# A "headful" test requires a graphical environment to meaningfully
+# run. Tests that are not headful are "headless."
+
+keys=screenshots
+
+# Tests that must run in othervm mode
+othervm.dirs=sanity/client/SwingSet
+
+# Tests that cannot run concurrently
+exclusiveAccess.dirs=sanity/client/SwingSet
+
+# Tests using jtreg 4.1 b13 features
+requiredVersion=4.1 b13
diff --git a/jdk/test/sanity/client/TEST.properties b/jdk/test/sanity/client/TEST.properties
new file mode 100644
index 00000000000..343e80e76f2
--- /dev/null
+++ b/jdk/test/sanity/client/TEST.properties
@@ -0,0 +1,14 @@
+# This file contains test-suite configuration information related to this portion
+# of the test suite.
+#
+# A "screenshots" test requires a 100% headful graphical environment
+# as they rely on Robot to take screenshots and move mouse.
+
+# The list of keywords supported in this part of the test suite
+keys=screenshots
+
+# Tests that cannot run concurrently
+exclusiveAccess.dirs=SwingSet
+
+# Tests require jtreg 4.1 b13 features
+#requiredVersion=4.1 b13
diff --git a/jdk/test/sanity/client/lib/Jemmy2Ext/src/org/jemmy2ext/JemmyExt.java b/jdk/test/sanity/client/lib/Jemmy2Ext/src/org/jemmy2ext/JemmyExt.java
new file mode 100644
index 00000000000..fe0431b684e
--- /dev/null
+++ b/jdk/test/sanity/client/lib/Jemmy2Ext/src/org/jemmy2ext/JemmyExt.java
@@ -0,0 +1,614 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.jemmy2ext;
+
+import java.awt.Component;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.Window;
+import java.awt.image.BufferedImage;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Function;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.IntStream;
+import javax.imageio.ImageIO;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JWindow;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.TitledBorder;
+import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.DefaultCharBindingMap;
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.TimeoutExpiredException;
+import org.netbeans.jemmy.Waitable;
+import org.netbeans.jemmy.Waiter;
+import org.netbeans.jemmy.drivers.scrolling.JSpinnerDriver;
+import org.netbeans.jemmy.image.StrictImageComparator;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.ContainerOperator;
+import org.netbeans.jemmy.operators.FrameOperator;
+import org.netbeans.jemmy.operators.JButtonOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JLabelOperator;
+import org.netbeans.jemmy.operators.Operator;
+import org.netbeans.jemmy.util.Dumper;
+import org.netbeans.jemmy.util.PNGEncoder;
+import static org.testng.AssertJUnit.*;
+
+/**
+ * This class solves two tasks: 1. It adds functionality that is missing in
+ * Jemmy 2. It references all the Jemmy API that is needed by tests so that they
+ * can just @build JemmyExt class and do not worry about Jemmy
+ *
+ * @author akouznet
+ */
+public class JemmyExt {
+
+ /**
+ * Statically referencing all the classes that are needed by tests so that
+ * they're compiled by jtreg
+ */
+ static final Class>[] DEPENDENCIES = {
+ JSpinnerDriver.class,
+ DefaultCharBindingMap.class
+ };
+
+ public static void assertNotBlack(BufferedImage image) {
+ int w = image.getWidth();
+ int h = image.getHeight();
+ try {
+ assertFalse("All pixels are not black", IntStream.range(0, w).parallel().allMatch(x
+ -> IntStream.range(0, h).allMatch(y -> (image.getRGB(x, y) & 0xffffff) == 0)
+ ));
+ } catch (Throwable t) {
+ save(image, "allPixelsAreBlack.png");
+ throw t;
+ }
+ }
+
+ public static void waitArmed(JButtonOperator button) {
+ button.waitState(new ComponentChooser() {
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ return isArmed(button);
+ }
+
+ @Override
+ public String getDescription() {
+ return "Button is armed";
+ }
+ });
+ }
+
+ public static boolean isArmed(JButtonOperator button) {
+ return button.getQueueTool().invokeSmoothly(new QueueTool.QueueAction("getModel().isArmed()") {
+
+ @Override
+ public Boolean launch() throws Exception {
+ return ((JButton) button.getSource()).getModel().isArmed();
+ }
+ });
+ }
+
+ public static void waitPressed(JButtonOperator button) {
+ button.waitState(new ComponentChooser() {
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ return isPressed(button);
+ }
+
+ @Override
+ public String getDescription() {
+ return "Button is pressed";
+ }
+ });
+ }
+
+ public static boolean isPressed(JButtonOperator button) {
+ return button.getQueueTool().invokeSmoothly(new QueueTool.QueueAction("getModel().isPressed()") {
+
+ @Override
+ public Boolean launch() throws Exception {
+ return ((JButton) button.getSource()).getModel().isPressed();
+ }
+ });
+ }
+
+ public static void assertEquals(String string, StrictImageComparator comparator, BufferedImage expected, BufferedImage actual) {
+ try {
+ assertTrue(string, comparator.compare(expected, actual));
+ } catch (Error err) {
+ save(expected, "expected.png");
+ save(actual, "actual.png");
+ throw err;
+ }
+ }
+
+ public static void assertNotEquals(String string, StrictImageComparator comparator, BufferedImage notExpected, BufferedImage actual) {
+ try {
+ assertFalse(string, comparator.compare(notExpected, actual));
+ } catch (Error err) {
+ save(notExpected, "notExpected.png");
+ save(actual, "actual.png");
+ throw err;
+ }
+ }
+
+ public static void save(BufferedImage image, String filename) {
+ String filepath = filename;
+ try {
+ filepath = new File(filename).getCanonicalPath();
+ System.out.println("Saving screenshot to " + filepath);
+ BufferedOutputStream file = new BufferedOutputStream(new FileOutputStream(filepath));
+ new PNGEncoder(file, PNGEncoder.COLOR_MODE).encode(image);
+ } catch (IOException ioe) {
+ throw new RuntimeException("Failed to save image to " + filepath, ioe);
+ }
+ }
+
+ public static void waitImageIsStill(Robot rob, ComponentOperator operator) {
+ operator.waitState(new ComponentChooser() {
+
+ private BufferedImage previousImage = null;
+ private int index = 0;
+ private final StrictImageComparator sComparator = new StrictImageComparator();
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ BufferedImage currentImage = capture(rob, operator);
+ save(currentImage, "waitImageIsStill" + index + ".png");
+ index++;
+ boolean compareResult = previousImage == null ? false : sComparator.compare(currentImage, previousImage);
+ previousImage = currentImage;
+ return compareResult;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Image of " + operator + " is still";
+ }
+ });
+ }
+
+ private static class ThrowableHolder {
+
+ volatile Throwable t;
+ }
+
+ public static void waitFor(String description, RunnableWithException r) throws Exception {
+ Waiter waiter = new Waiter<>(new Waitable() {
+
+ @Override
+ public Boolean actionProduced(ThrowableHolder obj) {
+ try {
+ r.run();
+ return true;
+ } catch (Throwable t) {
+ obj.t = t;
+ return null;
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+ });
+ ThrowableHolder th = new ThrowableHolder();
+ try {
+ waiter.waitAction(th);
+ } catch (TimeoutExpiredException tee) {
+ Throwable t = th.t;
+ if (t != null) {
+ t.addSuppressed(tee);
+ if (t instanceof Exception) {
+ throw (Exception) t;
+ } else if (t instanceof Error) {
+ throw (Error) t;
+ } else if (t instanceof RuntimeException) {
+ throw (RuntimeException) t;
+ } else {
+ throw new IllegalStateException("Unexpected exception type", t);
+ }
+ }
+ }
+ }
+
+ public static BufferedImage capture(Robot rob, ComponentOperator operator) {
+ Rectangle boundary = new Rectangle(operator.getLocationOnScreen(),
+ operator.getSize());
+ return rob.createScreenCapture(boundary);
+ }
+
+ /**
+ * Wraps the test code so that in case of any failure as much information as
+ * possible is captured
+ *
+ * @param r test code Runnable
+ * @throws Exception whatever exception the test may throw
+ */
+ public static void captureDebugInfoOnFail(RunnableWithException r) throws Exception {
+ // TODO: Remove this once https://bugs.openjdk.java.net/browse/JDK-8151671 is fixed
+ try {
+ r.run();
+ System.out.println("TEST PASSED");
+ } catch (Throwable t) {
+ captureAll();
+ throw t;
+ }
+ }
+
+ /**
+ * This is a helper class which allows to catch throwables thrown in other
+ * threads and throw them in the main test thread
+ */
+ public static class MultiThreadedTryCatch {
+
+ private final List throwables
+ = Collections.synchronizedList(new ArrayList<>());
+
+ /**
+ * Throws registered throwables. If the list of the registered
+ * throwables is not empty, it re-throws the first throwable in the list
+ * adding all others into its suppressed list. Can be used in any
+ * thread.
+ *
+ * @throws Exception
+ */
+ public void throwRegistered() throws Exception {
+ Throwable root = null;
+ synchronized (throwables) {
+ if (!throwables.isEmpty()) {
+ root = throwables.remove(0);
+ while (!throwables.isEmpty()) {
+ root.addSuppressed(throwables.remove(0));
+ }
+ }
+ }
+ if (root != null) {
+ if (root instanceof Error) {
+ throw (Error) root;
+ } else if (root instanceof Exception) {
+ throw (Exception) root;
+ } else {
+ throw new AssertionError("Unexpected exception type: " + root.getClass() + " (" + root + ")");
+ }
+ }
+ }
+
+ /**
+ * Registers a throwable and adds it to the list of throwables. Can be
+ * used in any thread.
+ *
+ * @param t
+ */
+ public void register(Throwable t) {
+ t.printStackTrace();
+ throwables.add(t);
+ }
+
+ /**
+ * Registers a throwable and adds it as the first item of the list of
+ * catched throwables.
+ *
+ * @param t
+ */
+ public void registerRoot(Throwable t) {
+ t.printStackTrace();
+ throwables.add(0, t);
+ }
+ }
+
+ /**
+ * Trying to capture as much information as possible. Currently it includes
+ * full dump and a screenshot of the whole screen.
+ */
+ public static void captureAll() {
+ PNGEncoder.captureScreen("failure.png", PNGEncoder.COLOR_MODE);
+ try {
+ Dumper.dumpAll("dumpAll.xml");
+ } catch (FileNotFoundException ex) {
+ Logger.getLogger(JemmyExt.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ captureWindows();
+ }
+
+ /**
+ * Captures each showing window image using Window.paint() method.
+ */
+ private static void captureWindows() {
+ try {
+ EventQueue.invokeAndWait(() -> {
+ Window[] windows = Window.getWindows();
+ int index = 0;
+ for (Window w : windows) {
+ if (!w.isShowing()) {
+ continue;
+ }
+ BufferedImage img = new BufferedImage(w.getWidth(), w.getHeight(), BufferedImage.TYPE_INT_ARGB);
+ Graphics g = img.getGraphics();
+ w.paint(g);
+ g.dispose();
+
+ try {
+ ImageIO.write(img, "png", new File("window" + index++ + ".png"));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ } catch (InterruptedException | InvocationTargetException ex) {
+ Logger.getLogger(JemmyExt.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ public static interface RunnableWithException {
+
+ public void run() throws Exception;
+ }
+
+ public static void waitIsFocused(JFrameOperator jfo) {
+ jfo.waitState(new ComponentChooser() {
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ return jfo.isFocused();
+ }
+
+ @Override
+ public String getDescription() {
+ return "JFrame is focused";
+ }
+ });
+ }
+
+ public static int getJWindowCount() {
+ return new QueueTool().invokeAndWait(new QueueTool.QueueAction(null) {
+
+ @Override
+ public Integer launch() throws Exception {
+ Window[] windows = Window.getWindows();
+ int windowCount = 0;
+ for (Window w : windows) {
+ if (w.getClass().equals(JWindow.class)) {
+ windowCount++;
+ }
+ }
+ return windowCount;
+ }
+ });
+ }
+
+ public static JWindow getJWindow() {
+ return getJWindow(0);
+ }
+
+ public static JWindow getJWindow(int index) {
+ return new QueueTool().invokeAndWait(new QueueTool.QueueAction(null) {
+
+ @Override
+ public JWindow launch() throws Exception {
+ Window[] windows = Window.getWindows();
+ int windowIndex = 0;
+ for (Window w : windows) {
+ if (w.getClass().equals(JWindow.class)) {
+ if (windowIndex == index) {
+ return (JWindow) w;
+ }
+ windowIndex++;
+ }
+ }
+ return null;
+ }
+ });
+ }
+
+ public static boolean isIconified(FrameOperator frameOperator) {
+ return frameOperator.getQueueTool().invokeAndWait(new QueueTool.QueueAction("Frame is iconified") {
+
+ @Override
+ public Boolean launch() throws Exception {
+ return (((Frame) frameOperator.getSource()).getState() & Frame.ICONIFIED) != 0;
+ }
+ });
+ }
+
+ public static final Operator.DefaultStringComparator EXACT_STRING_COMPARATOR
+ = new Operator.DefaultStringComparator(true, true);
+
+ /**
+ * Finds a label with the exact labelText and returns the operator for its
+ * parent container.
+ *
+ * @param container
+ * @param labelText
+ * @return
+ */
+ public static ContainerOperator> getLabeledContainerOperator(ContainerOperator> container, String labelText) {
+
+ container.setComparator(EXACT_STRING_COMPARATOR);
+
+ JLabelOperator jLabelOperator = new JLabelOperator(container, labelText);
+
+ assert labelText.equals(jLabelOperator.getText());
+
+ return new ContainerOperator<>(jLabelOperator.getParent());
+ }
+
+ /**
+ * Finds a JPanel with exact title text.
+ *
+ * @param container
+ * @param titleText
+ * @return
+ */
+ public static ContainerOperator> getBorderTitledJPanelOperator(ContainerOperator> container, String titleText) {
+ return new ContainerOperator<>(container, new JPanelByBorderTitleFinder(titleText, EXACT_STRING_COMPARATOR));
+ }
+
+ public static final QueueTool QUEUE_TOOL = new QueueTool();
+
+ /**
+ * Allows to find JPanel by the title text in its border.
+ */
+ public static class JPanelByBorderTitleFinder implements ComponentChooser {
+
+ String titleText;
+ Operator.StringComparator comparator;
+
+ /**
+ * @param titleText title text pattern
+ * @param comparator specifies string comparison algorithm.
+ */
+ public JPanelByBorderTitleFinder(String titleText, Operator.StringComparator comparator) {
+ this.titleText = titleText;
+ this.comparator = comparator;
+ }
+
+ /**
+ * @param titleText title text pattern
+ */
+ public JPanelByBorderTitleFinder(String titleText) {
+ this(titleText, Operator.getDefaultStringComparator());
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ assert EventQueue.isDispatchThread();
+ if (comp instanceof JPanel) {
+ return checkBorder(((JPanel) comp).getBorder());
+ }
+ return false;
+ }
+
+ public boolean checkBorder(Border border) {
+ if (border instanceof TitledBorder) {
+ String title = ((TitledBorder) border).getTitle();
+ return comparator.equals(title, titleText);
+ } else if (border instanceof CompoundBorder) {
+ CompoundBorder compoundBorder = (CompoundBorder) border;
+ return checkBorder(compoundBorder.getInsideBorder()) || checkBorder(compoundBorder.getOutsideBorder());
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return ("JPanel with border title text \"" + titleText + "\" with comparator " + comparator);
+ }
+ }
+
+ public static class ByClassSimpleNameChooser implements ComponentChooser {
+
+ private final String className;
+
+ public ByClassSimpleNameChooser(String className) {
+ this.className = className;
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ return comp.getClass().getSimpleName().equals(className);
+ }
+
+ @Override
+ public String getDescription() {
+ return "Component with the simple class name of " + className;
+ }
+
+ }
+
+ public static class ByClassChooser implements ComponentChooser {
+
+ private final Class> clazz;
+
+ public ByClassChooser(Class> clazz) {
+ this.clazz = clazz;
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ return comp.getClass().equals(clazz);
+ }
+
+ @Override
+ public String getDescription() {
+ return "Component with the class of " + clazz;
+ }
+
+ }
+
+ public static class ByToolTipChooser implements ComponentChooser {
+
+ private final String tooltip;
+
+ public ByToolTipChooser(String tooltip) {
+ if (tooltip == null) {
+ throw new NullPointerException("Tooltip cannot be null");
+ }
+ this.tooltip = tooltip;
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ return (comp instanceof JComponent)
+ ? tooltip.equals(((JComponent) comp).getToolTipText())
+ : false;
+ }
+
+ @Override
+ public String getDescription() {
+ return "JComponent with the tooltip '" + tooltip + "'";
+ }
+
+ }
+
+ @SuppressWarnings(value = "unchecked")
+ public static R getUIValue(O operator, Function getter) {
+ return operator.getQueueTool().invokeSmoothly(new QueueTool.QueueAction("getting UI value through the queue using " + getter) {
+
+ @Override
+ public R launch() throws Exception {
+ return getter.apply((S) operator.getSource());
+ }
+ });
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/README b/jdk/test/sanity/client/lib/SwingSet3/README
new file mode 100644
index 00000000000..1952a70cd26
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/README
@@ -0,0 +1,4 @@
+This content of this src folder was originally taken from SwingSet3 demo project: https://java.net/projects/swingset3/.
+Then it was modified to increase testability and remove extra content and extra dependencies.
+
+Do NOT modify files in it.
\ No newline at end of file
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/DemoProperties.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/DemoProperties.java
new file mode 100644
index 00000000000..19781096f74
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/DemoProperties.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Annotation type for specifying meta-data about Demo
+ *
+ * @author aim
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DemoProperties {
+
+ String value(); // Name
+
+ String category();
+
+ String description();
+
+ String iconFile() default "";
+
+ String[] sourceFiles() default "";
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/DemoUtilities.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/DemoUtilities.java
new file mode 100644
index 00000000000..8049ec9ba3b
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/DemoUtilities.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos;
+
+import java.awt.*;
+import java.net.URI;
+import java.io.IOException;
+import javax.swing.*;
+
+/**
+ * @author Pavel Porvatov
+ */
+public class DemoUtilities {
+
+ private DemoUtilities() {
+ // Hide constructor
+ }
+
+ public static void setToplevelLocation(Window toplevel, Component component,
+ int relativePosition) {
+
+ Rectangle compBounds = component.getBounds();
+
+ // Convert component location to screen coordinates
+ Point p = new Point();
+ SwingUtilities.convertPointToScreen(p, component);
+
+ int x;
+ int y;
+
+ // Set frame location to be centered on panel
+ switch (relativePosition) {
+ case SwingConstants.NORTH: {
+ x = (p.x + (compBounds.width / 2)) - (toplevel.getWidth() / 2);
+ y = p.y - toplevel.getHeight();
+ break;
+ }
+ case SwingConstants.EAST: {
+ x = p.x + compBounds.width;
+ y = (p.y + (compBounds.height / 2)) - (toplevel.getHeight() / 2);
+ break;
+ }
+ case SwingConstants.SOUTH: {
+ x = (p.x + (compBounds.width / 2)) - (toplevel.getWidth() / 2);
+ y = p.y + compBounds.height;
+ break;
+ }
+ case SwingConstants.WEST: {
+ x = p.x - toplevel.getWidth();
+ y = (p.y + (compBounds.height / 2)) - (toplevel.getHeight() / 2);
+ break;
+ }
+ case SwingConstants.NORTH_EAST: {
+ x = p.x + compBounds.width;
+ y = p.y - toplevel.getHeight();
+ break;
+ }
+ case SwingConstants.NORTH_WEST: {
+ x = p.x - toplevel.getWidth();
+ y = p.y - toplevel.getHeight();
+ break;
+ }
+ case SwingConstants.SOUTH_EAST: {
+ x = p.x + compBounds.width;
+ y = p.y + compBounds.height;
+ break;
+ }
+ case SwingConstants.SOUTH_WEST: {
+ x = p.x - toplevel.getWidth();
+ y = p.y + compBounds.height;
+ break;
+ }
+ default:
+ case SwingConstants.CENTER: {
+ x = (p.x + (compBounds.width / 2)) - (toplevel.getWidth() / 2);
+ y = (p.y + (compBounds.height / 2)) - (toplevel.getHeight() / 2);
+ }
+ }
+ toplevel.setLocation(x, y);
+ }
+
+ public static boolean browse(URI uri) throws IOException {
+ // Try using the Desktop api first
+ try {
+ Desktop desktop = Desktop.getDesktop();
+ desktop.browse(uri);
+
+ return true;
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ }
+
+ return false;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/JGridPanel.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/JGridPanel.java
new file mode 100644
index 00000000000..a0f5bf577b7
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/JGridPanel.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos;
+
+import java.awt.*;
+import javax.swing.*;
+
+/**
+ * JGridPanel
+ *
+ * @author Pavel Porvatov
+ */
+public class JGridPanel extends JPanel {
+
+ public static final int DEFAULT_GAP = 5;
+
+ public enum Layout {
+ FIRST,
+ CENTER,
+ LAST,
+ FILL
+ }
+
+ private enum ComponentType {
+ NO_RESIZABLE,
+ HORIZONTAL_FILL,
+ FULL
+ }
+
+ private final int cols;
+
+ private int bigCol = -1;
+
+ private int bigRow = -1;
+
+ private int vGap = -1;
+
+ private int hGap = -1;
+
+ public JGridPanel(int cols) {
+ this(cols, -1, -1);
+ }
+
+ public JGridPanel(int cols, int bigCol) {
+ this(cols, bigCol, -1);
+ }
+
+ public JGridPanel(int cols, int bigCol, int bigRow) {
+ super(new GridBagLayout());
+
+ assert cols > 0;
+ assert bigCol >= -1 && bigCol < cols;
+ assert bigRow >= -1;
+
+ this.cols = cols;
+ this.bigCol = bigCol;
+ this.bigRow = bigRow;
+ }
+
+ public void setVGap(int vGap) {
+ this.vGap = vGap;
+ }
+
+ public void setHGap(int hGap) {
+ this.hGap = hGap;
+ }
+
+ public JGridPanel cell() {
+ return cell(null, getHLayout(null), getVLayout(null), null);
+ }
+
+ public JGridPanel cell(Component component) {
+ return cell(component, getHLayout(component), getVLayout(component), null);
+ }
+
+ public JGridPanel cell(Component component, Layout hLayout) {
+ return cell(component, hLayout, getVLayout(component), null);
+ }
+
+ public JGridPanel cell(Component component, Layout hLayout, Layout vLayout) {
+ return cell(component, hLayout, vLayout, null);
+ }
+
+ public JGridPanel cell(Component component, Insets insets) {
+ assert insets != null;
+
+ return cell(component, getHLayout(component), getVLayout(component), insets);
+ }
+
+ private JGridPanel cell(Component component, Layout hLayout, Layout vLayout, Insets insets) {
+ int componentCount = getComponentCount();
+ int x = componentCount % cols;
+ int y = componentCount / cols;
+
+ int weightx = x == bigCol || (bigCol < 0 && hLayout == Layout.FILL) ? 1 : 0;
+ int weighty = y == bigRow || (bigRow < 0 && vLayout == Layout.FILL) ? 1 : 0;
+
+ if (insets == null) {
+ int topGap = y == 0 ? 0 : vGap;
+ int leftGap = x == 0 ? 0 : hGap;
+
+ insets = new Insets(topGap < 0 ? DEFAULT_GAP : topGap,
+ leftGap < 0 ? DEFAULT_GAP : leftGap, 0, 0);
+ }
+
+ add(component == null ? createSeparator() : component,
+ new GridBagConstraints(x, y,
+ 1, 1,
+ weightx, weighty,
+ getAnchor(hLayout, vLayout), getFill(hLayout, vLayout),
+ insets, 0, 0));
+
+ return this;
+ }
+
+ public void setComponent(Component component, int col, int row) {
+ assert col >= 0 && col < cols;
+ assert row >= 0;
+
+ GridBagLayout layout = (GridBagLayout) getLayout();
+
+ for (int i = 0; i < getComponentCount(); i++) {
+ Component oldComponent = getComponent(i);
+
+ GridBagConstraints constraints = layout.getConstraints(oldComponent);
+
+ if (constraints.gridx == col && constraints.gridy == row) {
+ remove(i);
+
+ add(component == null ? createSeparator() : component, constraints);
+
+ validate();
+ repaint();
+
+ return;
+ }
+ }
+
+ // Cell not found
+ assert false;
+ }
+
+ private static JComponent createSeparator() {
+ return new JLabel();
+ }
+
+ private static int getFill(Layout hLayout, Layout vLayout) {
+ if (hLayout == Layout.FILL) {
+ return vLayout == Layout.FILL ? GridBagConstraints.BOTH : GridBagConstraints.HORIZONTAL;
+ }
+
+ return vLayout == Layout.FILL ? GridBagConstraints.VERTICAL : GridBagConstraints.NONE;
+ }
+
+ private static ComponentType getComponentType(Component component) {
+ if (component == null
+ || component instanceof JLabel
+ || component instanceof JRadioButton
+ || component instanceof JCheckBox
+ || component instanceof JButton) {
+ return ComponentType.NO_RESIZABLE;
+ }
+
+ if (component instanceof JComboBox
+ || component instanceof JTextField) {
+ return ComponentType.HORIZONTAL_FILL;
+ }
+
+ return ComponentType.FULL;
+ }
+
+ private static Layout getHLayout(Component component) {
+ if (getComponentType(component) == ComponentType.NO_RESIZABLE) {
+ return Layout.FIRST;
+ } else {
+ return Layout.FILL;
+ }
+ }
+
+ private static Layout getVLayout(Component component) {
+ if (getComponentType(component) == ComponentType.FULL) {
+ return Layout.FILL;
+ } else {
+ return Layout.CENTER;
+ }
+ }
+
+ private static final int[][] ANCHORS = new int[][]{
+ {GridBagConstraints.NORTHWEST, GridBagConstraints.NORTH, GridBagConstraints.NORTHEAST},
+ {GridBagConstraints.WEST, GridBagConstraints.CENTER, GridBagConstraints.EAST},
+ {GridBagConstraints.SOUTHWEST, GridBagConstraints.SOUTH, GridBagConstraints.SOUTHEAST}
+ };
+
+ private static int getAnchorIndex(Layout layout) {
+ if (layout == Layout.CENTER) {
+ return 1;
+ } else if (layout == Layout.LAST) {
+ return 2;
+ } else {
+ return 0;
+ }
+ }
+
+ private static int getAnchor(Layout hLayout, Layout vLayout) {
+ return ANCHORS[getAnchorIndex(vLayout)][getAnchorIndex(hLayout)];
+ }
+
+ public void setBorderEqual(int border) {
+ setBorder(BorderFactory.createEmptyBorder(border, border, border, border));
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/JHyperlink.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/JHyperlink.java
new file mode 100644
index 00000000000..1deb250c5fe
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/JHyperlink.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos;
+
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.net.URI;
+import java.net.URISyntaxException;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ButtonModel;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+/**
+ *
+ * @author aim
+ */
+//Create HTML hyperlink
+//Create HTML image hyperlink
+public class JHyperlink extends JButton {
+
+ private static final BrowseAction defaultBrowseAction = new BrowseAction();
+
+ private URI targetURI;
+ private boolean visited;
+
+ private final transient Rectangle viewRect = new Rectangle();
+ private final transient Rectangle iconRect = new Rectangle();
+ private final transient Rectangle textRect = new Rectangle();
+
+ //remind(aim): lookup colors instead of hardcoding them
+ private Color normalForeground;
+ private Color activeForeground;
+ private Color visitedForeground;
+ private boolean drawUnderline = true;
+
+ static {
+ UIManager.put("Hyperlink.foreground", Color.blue);
+ UIManager.put("Hyperlink.activeForeground", Color.red);
+ UIManager.put("Hyperlink.visitedForeground", new Color(85, 145, 90));
+ }
+
+ /**
+ * Creates a new instance of JHyperlink
+ */
+ public JHyperlink() {
+ super();
+ normalForeground = UIManager.getColor("Hyperlink.foreground");
+ activeForeground = UIManager.getColor("Hyperlink.activeForeground");
+ visitedForeground = UIManager.getColor("Hyperlink.visitedForeground");
+ setBorderPainted(false);
+ setContentAreaFilled(false);
+ setForeground(normalForeground);
+ setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ setMargin(new Insets(0, 0, 0, 0));
+ setAction(defaultBrowseAction);
+ }
+
+ /**
+ * Creates a new instance of JHyperlink
+ */
+ public JHyperlink(String text) {
+ this();
+ setText(text); // override the inheritence of the action's name
+ }
+
+ public JHyperlink(String text, String targetURI) throws URISyntaxException {
+ this(text, new URI(targetURI));
+ }
+
+ public JHyperlink(String text, URI target) {
+ this(text);
+ setTarget(target);
+ }
+
+ public JHyperlink(String text, Action action) {
+ this(text);
+ setAction(action); // replaces default browse action
+ setText(text); // override the inheritence of the action's name
+ }
+
+ public JHyperlink(String text, Icon icon) {
+ this(text);
+ setIcon(icon);
+ }
+
+ public JHyperlink(Icon icon, String targetURI) throws URISyntaxException {
+ this(null, icon, targetURI);
+ }
+
+ public JHyperlink(String text, Icon icon, String targetURI) throws URISyntaxException {
+ this(text, new URI(targetURI));
+ setIcon(icon);
+ }
+
+ public JHyperlink(String text, Icon icon, URI target) {
+ this(text);
+ setIcon(icon);
+ setTarget(target);
+ }
+
+ public void setTarget(URI target) {
+ this.targetURI = target;
+ setToolTipText(target.toASCIIString());
+ }
+
+ public URI getTarget() {
+ return targetURI;
+ }
+
+ public void setVisited(boolean visited) {
+ this.visited = visited;
+ }
+
+ public boolean isVisited() {
+ return visited;
+ }
+
+ @Override
+ public void setForeground(Color foreground) {
+ normalForeground = foreground;
+ super.setForeground(foreground);
+ }
+
+ public void setVisitedForeground(Color visited) {
+ visitedForeground = visited;
+ }
+
+ public void setDrawUnderline(boolean drawUnderline) {
+ this.drawUnderline = drawUnderline;
+ }
+
+ public boolean getDrawUnderline() {
+ return drawUnderline;
+ }
+
+ @Override
+ protected void paintComponent(Graphics g) {
+ // Set the foreground on the fly to ensure the text is painted
+ // with the proper color in super.paintComponent
+ ButtonModel model = getModel();
+ if (model.isArmed()) {
+ super.setForeground(activeForeground);
+ } else if (visited) {
+ super.setForeground(visitedForeground);
+ } else {
+ super.setForeground(normalForeground);
+ }
+ super.paintComponent(g);
+
+ if (drawUnderline) {
+ Insets insets = getInsets();
+ viewRect.x = insets.left;
+ viewRect.y = insets.top;
+ viewRect.width = getWidth() - insets.left - insets.right;
+ viewRect.height = getHeight() - insets.top - insets.bottom;
+ int baseline = getBaseline(viewRect.width, viewRect.height);
+
+ iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
+ textRect.x = textRect.y = textRect.width = textRect.height = 0;
+ SwingUtilities.layoutCompoundLabel(g.getFontMetrics(), getText(),
+ getIcon(), getVerticalAlignment(), getHorizontalAlignment(),
+ getVerticalTextPosition(), getHorizontalTextPosition(),
+ viewRect, iconRect, textRect, getIconTextGap());
+
+ // getBaseline not returning correct results, so workaround for now
+ if (UIManager.getLookAndFeel().getName().equals("Nimbus")) {
+ baseline += 7;
+ } else {
+ baseline += 3;
+ }
+
+ g.setColor(getForeground());
+ g.drawLine(textRect.x,
+ baseline,
+ textRect.x + textRect.width,
+ baseline);
+ }
+
+ }
+
+ // This action is stateless and hence can be shared across hyperlinks
+ private static class BrowseAction extends AbstractAction {
+
+ public BrowseAction() {
+ super();
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JHyperlink hyperlink = (JHyperlink) e.getSource();
+
+ URI targetURI = hyperlink.getTarget();
+ if (targetURI != null) {
+ try {
+ DemoUtilities.browse(targetURI);
+ hyperlink.setVisited(true);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ System.err.println(ex);
+ }
+
+ }
+ }
+
+ }
+//
+//
+
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/ResourceManager.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/ResourceManager.java
new file mode 100644
index 00000000000..af44f84a6ad
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/ResourceManager.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos;
+
+import java.net.URL;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.*;
+
+/**
+ * @author Pavel Porvatov
+ */
+public class ResourceManager {
+
+ private static final Logger logger = Logger.getLogger(ResourceManager.class.getName());
+
+ private final Class> demoClass;
+
+ // Resource bundle for internationalized and accessible text
+ private ResourceBundle bundle = null;
+
+ public ResourceManager(Class> demoClass) {
+ this.demoClass = demoClass;
+
+ String bundleName = demoClass.getPackage().getName() + ".resources." + demoClass.getSimpleName();
+
+ try {
+ bundle = ResourceBundle.getBundle(bundleName);
+ } catch (MissingResourceException e) {
+ logger.log(Level.SEVERE, "Couldn't load bundle: " + bundleName);
+ }
+ }
+
+ public String getString(String key) {
+ return bundle != null ? bundle.getString(key) : key;
+ }
+
+ public char getMnemonic(String key) {
+ return (getString(key)).charAt(0);
+ }
+
+ public ImageIcon createImageIcon(String filename, String description) {
+ String path = "resources/images/" + filename;
+
+ URL imageURL = demoClass.getResource(path);
+
+ if (imageURL == null) {
+ logger.log(Level.SEVERE, "unable to access image file: " + path);
+
+ return null;
+ } else {
+ return new ImageIcon(imageURL, description);
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/ButtonDemo.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/ButtonDemo.java
new file mode 100644
index 00000000000..728e0543b68
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/ButtonDemo.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.button;
+
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.net.URISyntaxException;
+import javax.swing.BorderFactory;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+import com.sun.swingset3.DemoProperties;
+import com.sun.swingset3.demos.JHyperlink;
+
+/**
+ *
+ * @author aim
+ */
+@DemoProperties(
+ value = "JButton Demo",
+ category = "Controls",
+ description = "Demonstrates the many uses of JButton, Swing's push button component.",
+ sourceFiles = {
+ "com/sun/swingset3/demos/button/ButtonDemo.java",
+ "com/sun/swingset3/demos/JHyperlink.java",
+ "com/sun/swingset3/demos/button/resources/ButtonDemo.html",
+ "com/sun/swingset3/demos/button/resources/images/blogs.png",
+ "com/sun/swingset3/demos/button/resources/images/ButtonDemo.gif",
+ "com/sun/swingset3/demos/button/resources/images/document-print.png",
+ "com/sun/swingset3/demos/button/resources/images/earth_day.gif",
+ "com/sun/swingset3/demos/button/resources/images/earth_night.gif",
+ "com/sun/swingset3/demos/button/resources/images/edit-find.png",
+ "com/sun/swingset3/demos/button/resources/images/redbutton.png",
+ "com/sun/swingset3/demos/button/resources/images/redbutton_dark.png",
+ "com/sun/swingset3/demos/button/resources/images/redbutton_glow.png"
+ }
+)
+public final class ButtonDemo extends JPanel {
+
+ public static final String DEMO_TITLE = ButtonDemo.class.getAnnotation(DemoProperties.class).value();
+ public static final String DO_IT_AGAIN = "Do it again";
+ public static final String DO_IT = "Do it";
+ public static final String BUTTON_WITH_TEXT_AND_IMAGE = "button with text and image";
+ public static final String BUTTON_WITH_BACKGROUND_COLOR = "button with background color";
+ public static final String GO = "Go";
+ public static final String FIND = "Find";
+ public static final String IMAGE_BUTTON = "image button";
+ public static final String SIMPLE_BUTTON = "simple button";
+ public static final String GET_MORE_INFO = "Get More Info";
+ public static final String JAVA_BLOGS_URL = "https://blogs.oracle.com/java/";
+ public static final String JAVA_SE_URL = "http://www.oracle.com/technetwork/java/javase/overview/index.html";
+ public static final String BUTTON_WITH_ROLLOVER_IMAGE = "button with rollover image";
+ public static final String BUTTON_WITH_NO_BORDER = "button with no border";
+ public static final String CONNECT = "Connect";
+
+ public ButtonDemo() {
+ setToolTipText("Demonstrates JButton, Swing's push button component.");
+ initComponents();
+ setOpaque(false);
+ }
+
+ protected void initComponents() {
+ setLayout(new GridLayout(0, 1));
+
+ add(createSimpleButtonPanel());
+ add(createCreativeButtonPanel());
+ }
+
+ protected JPanel createSimpleButtonPanel() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 8));
+ panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(),
+ "Simple Buttons"));
+
+ //Create simple button
+ final JButton simpleButton = new JButton(DO_IT);
+ simpleButton.setToolTipText(SIMPLE_BUTTON);
+ //
+ //Add action listener using anonymous inner class
+ // This style is useful when the action code is tied to a
+ // single button instance and it's useful for simplicity
+ // sake to keep the action code located near the button.
+ // More global application actions should be implemented
+ // using Action classes instead.
+ simpleButton.addActionListener((ActionEvent event) -> {
+ simpleButton.setText(DO_IT_AGAIN);
+ // Need to force toplevel to relayout to accommodate new button size
+ SwingUtilities.getWindowAncestor(simpleButton).validate();
+ });
+ //
+ simpleButton.putClientProperty("snippetKey", "Create simple button");
+ panel.add(simpleButton);
+
+ //Create image button
+ // Image is from the Java Look and Feel Graphics Repository
+ JButton button = new JButton(new ImageIcon(getClass().
+ getResource("resources/images/document-print.png")));
+ button.setToolTipText(IMAGE_BUTTON);
+ //
+ button.putClientProperty("snippetKey", "Create image button");
+ panel.add(button);
+
+ //Create button with text and image
+ // Image is from the Java Look and Feel Graphics Repository
+ button = new JButton(FIND,
+ new ImageIcon(getClass().
+ getResource("resources/images/edit-find.png")));
+ button.setToolTipText(BUTTON_WITH_TEXT_AND_IMAGE);
+ button.setHorizontalTextPosition(JButton.LEADING);
+ button.setIconTextGap(6);
+ //
+ button.putClientProperty("snippetKey", "Create button with text and image");
+ panel.add(button);
+
+ //Create button with background color
+ button = new JButton(GO);
+ button.setBackground(Color.green);
+ button.setContentAreaFilled(true);
+ button.setOpaque(false);
+ button.setToolTipText(BUTTON_WITH_BACKGROUND_COLOR);
+ //
+ button.putClientProperty("snippetKey", "Create button with background color");
+ panel.add(button);
+
+ return panel;
+ }
+
+ protected JPanel createCreativeButtonPanel() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new FlowLayout(FlowLayout.CENTER, 16, 8));
+ panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(),
+ "More Interesting Buttons"));
+
+ //Create button with no border
+ JButton button = new JButton();
+ button.setText(CONNECT);
+ button.setIcon(new ImageIcon(getClass().getResource("resources/images/earth_day.gif")));
+ button.setPressedIcon(new ImageIcon(getClass().getResource("resources/images/earth_night.gif")));
+ button.setBorderPainted(false);
+ button.setContentAreaFilled(false);
+ button.setVerticalTextPosition(JButton.BOTTOM);
+ button.setHorizontalTextPosition(JButton.CENTER);
+ button.setIconTextGap(0);
+ button.setToolTipText(BUTTON_WITH_NO_BORDER);
+ //
+ button.putClientProperty("snippetKey", "Create button with no border");
+ panel.add(button);
+
+ //Create image button with rollover image
+ button = new JButton();
+ button.setBorderPainted(false);
+ button.setContentAreaFilled(false);
+ button.setIcon(new ImageIcon(getClass().getResource("resources/images/redbutton.png")));
+ button.setRolloverEnabled(true);
+ button.setRolloverIcon(new ImageIcon(getClass().getResource("resources/images/redbutton_glow.png")));
+ button.setPressedIcon(new ImageIcon(getClass().getResource("resources/images/redbutton_dark.png")));
+ button.setToolTipText(BUTTON_WITH_ROLLOVER_IMAGE);
+ //
+ button.putClientProperty("snippetKey", "Create image button with rollover image");
+ panel.add(button);
+
+ //Create HTML hyperlink
+ JHyperlink hyperlink;
+ try {
+ hyperlink = new JHyperlink(GET_MORE_INFO, JAVA_SE_URL);
+ } catch (URISyntaxException use) {
+ use.printStackTrace();
+ hyperlink = new JHyperlink(GET_MORE_INFO);
+ }
+ //
+ hyperlink.putClientProperty("snippetKey", "Create HTML hyperlink");
+ panel.add(hyperlink);
+
+ //Create HTML image hyperlink
+ try {
+ hyperlink = new JHyperlink(
+ new ImageIcon(getClass().getResource("resources/images/blogs.png")), JAVA_BLOGS_URL);
+ } catch (URISyntaxException use) {
+ use.printStackTrace();
+ }
+ //
+ button.putClientProperty("snippetKey", "Create HTML image hyperlink");
+ panel.add(hyperlink);
+
+ return panel;
+ }
+
+ public static void main(String args[]) {
+ final ButtonDemo buttonDemo = new ButtonDemo();
+
+ javax.swing.SwingUtilities.invokeLater(() -> {
+ JFrame frame = new JFrame(DEMO_TITLE);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.add(buttonDemo);
+ frame.pack();
+ frame.setVisible(true);
+ });
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/ButtonDemo.html b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/ButtonDemo.html
new file mode 100644
index 00000000000..866856b9e6a
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/ButtonDemo.html
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
Today's modern GUIs often use buttons which don't look like the traditional "push" button. Swing's button component, javax.swing.JButton,
+ can be used to create both ordinary and more creative button visuals. In the end, they all perform an action when clicked.
+
+
+ To highlight the source code used to create a particular button, popup the context menu over that button.
+
+
+
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/ButtonDemo.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/ButtonDemo.gif
new file mode 100644
index 00000000000..9f400fe4ac0
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/ButtonDemo.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/blogs.png b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/blogs.png
new file mode 100644
index 00000000000..cde6b947c2c
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/blogs.png differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/document-print.png b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/document-print.png
new file mode 100644
index 00000000000..99abfb51b08
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/document-print.png differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/earth_day.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/earth_day.gif
new file mode 100644
index 00000000000..01d61f74eb7
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/earth_day.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/earth_night.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/earth_night.gif
new file mode 100644
index 00000000000..649a3892f70
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/earth_night.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/edit-find.png b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/edit-find.png
new file mode 100644
index 00000000000..44376a6775a
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/edit-find.png differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/redbutton.png b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/redbutton.png
new file mode 100644
index 00000000000..b07c818766d
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/redbutton.png differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/redbutton_dark.png b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/redbutton_dark.png
new file mode 100644
index 00000000000..64539c9e461
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/redbutton_dark.png differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/redbutton_glow.png b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/redbutton_glow.png
new file mode 100644
index 00000000000..b2e99220d1c
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/resources/images/redbutton_glow.png differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/ComboBoxDemo.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/ComboBoxDemo.java
new file mode 100644
index 00000000000..5fc080f95bb
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/ComboBoxDemo.java
@@ -0,0 +1,445 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.combobox;
+
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.HashMap;
+import java.util.Map;
+import javax.accessibility.AccessibleRelation;
+import javax.swing.*;
+import javax.swing.border.BevelBorder;
+
+import com.sun.swingset3.demos.ResourceManager;
+import com.sun.swingset3.DemoProperties;
+
+/**
+ * JComboBox Demo
+ *
+ * @author Jeff Dinkins
+ * @version 1.13 11/17/05
+ */
+@DemoProperties(
+ value = "JComboBox Demo",
+ category = "Controls",
+ description = "Demonstrates JComboBox, a control which allows the user to make a selection from a popup list",
+ sourceFiles = {
+ "com/sun/swingset3/demos/combobox/ComboBoxDemo.java",
+ "com/sun/swingset3/demos/ResourceManager.java",
+ "com/sun/swingset3/demos/combobox/resources/ComboBoxDemo.properties",
+ "com/sun/swingset3/demos/combobox/resources/images/brenteyes.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/brenthair.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/brentmouth.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/ComboBoxDemo.gif",
+ "com/sun/swingset3/demos/combobox/resources/images/georgeseyes.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/georgeshair.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/georgesmouth.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/hanseyes.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/hanshair.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/hansmouth.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/howardeyes.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/howardhair.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/howardmouth.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/jameseyes.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/jameshair.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/jamesmouth.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/jeffeyes.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/jeffhair.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/jeffmouth.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/joneyes.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/jonhair.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/jonmouth.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/laraeyes.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/larahair.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/laramouth.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/larryeyes.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/larryhair.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/larrymouth.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/lisaeyes.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/lisahair.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/lisamouth.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/michaeleyes.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/michaelhair.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/michaelmouth.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/philipeyes.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/philiphair.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/philipmouth.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/scotteyes.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/scotthair.jpg",
+ "com/sun/swingset3/demos/combobox/resources/images/scottmouth.jpg"
+ }
+)
+public class ComboBoxDemo extends JPanel implements ActionListener {
+
+ private static final Dimension VGAP15 = new Dimension(1, 15);
+ private static final Dimension HGAP20 = new Dimension(20, 1);
+ private static final Dimension VGAP20 = new Dimension(1, 20);
+ private static final Dimension HGAP30 = new Dimension(30, 1);
+ private static final Dimension VGAP30 = new Dimension(1, 30);
+
+ private final ResourceManager resourceManager = new ResourceManager(this.getClass());
+ public static final String DEMO_TITLE = ComboBoxDemo.class.getAnnotation(DemoProperties.class).value();
+
+ private Face face;
+ private JLabel faceLabel;
+
+ private JComboBox hairCB;
+ private JComboBox eyesCB;
+ private JComboBox mouthCB;
+
+ private JComboBox presetCB;
+
+ private final Map parts = new HashMap<>();
+
+ /**
+ * main method allows us to run as a standalone demo.
+ *
+ * @param args
+ */
+ public static void main(String[] args) {
+ JFrame frame = new JFrame(DEMO_TITLE);
+
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.getContentPane().add(new ComboBoxDemo());
+ frame.setPreferredSize(new Dimension(800, 600));
+ frame.pack();
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+ }
+
+ /**
+ * ComboBoxDemo Constructor
+ */
+ public ComboBoxDemo() {
+ createComboBoxDemo();
+ }
+
+ private void createComboBoxDemo() {
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+
+ JPanel innerPanel = new JPanel();
+ innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.X_AXIS));
+
+ add(Box.createRigidArea(VGAP20));
+ add(innerPanel);
+ add(Box.createRigidArea(VGAP20));
+
+ innerPanel.add(Box.createRigidArea(HGAP20));
+
+ // Create a panel to hold buttons
+ JPanel comboBoxPanel = new JPanel() {
+ @Override
+ public Dimension getMaximumSize() {
+ return new Dimension(getPreferredSize().width, super.getMaximumSize().height);
+ }
+ };
+ comboBoxPanel.setLayout(new BoxLayout(comboBoxPanel, BoxLayout.Y_AXIS));
+
+ comboBoxPanel.add(Box.createRigidArea(VGAP15));
+
+ JLabel l = (JLabel) comboBoxPanel.add(new JLabel(resourceManager.getString("ComboBoxDemo.presets")));
+ l.setAlignmentX(JLabel.LEFT_ALIGNMENT);
+ comboBoxPanel.add(presetCB = createPresetComboBox());
+ presetCB.setAlignmentX(JComboBox.LEFT_ALIGNMENT);
+ l.setLabelFor(presetCB);
+ comboBoxPanel.add(Box.createRigidArea(VGAP30));
+
+ l = (JLabel) comboBoxPanel.add(new JLabel(resourceManager.getString("ComboBoxDemo.hair_description")));
+ l.setAlignmentX(JLabel.LEFT_ALIGNMENT);
+ comboBoxPanel.add(hairCB = createHairComboBox());
+ hairCB.setAlignmentX(JComboBox.LEFT_ALIGNMENT);
+ l.setLabelFor(hairCB);
+ comboBoxPanel.add(Box.createRigidArea(VGAP15));
+
+ l = (JLabel) comboBoxPanel.add(new JLabel(resourceManager.getString("ComboBoxDemo.eyes_description")));
+ l.setAlignmentX(JLabel.LEFT_ALIGNMENT);
+ comboBoxPanel.add(eyesCB = createEyesComboBox());
+ eyesCB.setAlignmentX(JComboBox.LEFT_ALIGNMENT);
+ l.setLabelFor(eyesCB);
+ comboBoxPanel.add(Box.createRigidArea(VGAP15));
+
+ l = (JLabel) comboBoxPanel.add(new JLabel(resourceManager.getString("ComboBoxDemo.mouth_description")));
+ l.setAlignmentX(JLabel.LEFT_ALIGNMENT);
+ comboBoxPanel.add(mouthCB = createMouthComboBox());
+
+ mouthCB.setAlignmentX(JComboBox.LEFT_ALIGNMENT);
+ l.setLabelFor(mouthCB);
+ comboBoxPanel.add(Box.createRigidArea(VGAP15));
+
+ // Fill up the remaining space
+ comboBoxPanel.add(new JPanel(new BorderLayout()));
+
+ // Create and place the Face.
+ face = new Face();
+ JPanel facePanel = new JPanel();
+ facePanel.setLayout(new BorderLayout());
+ facePanel.setBorder(new BevelBorder(BevelBorder.LOWERED));
+
+ faceLabel = new JLabel(face);
+ facePanel.add(faceLabel, BorderLayout.CENTER);
+ // Indicate that the face panel is controlled by the hair, eyes and
+ // mouth combo boxes.
+ Object[] controlledByObjects = new Object[3];
+ controlledByObjects[0] = hairCB;
+ controlledByObjects[1] = eyesCB;
+ controlledByObjects[2] = mouthCB;
+ AccessibleRelation controlledByRelation
+ = new AccessibleRelation(AccessibleRelation.CONTROLLED_BY_PROPERTY,
+ controlledByObjects);
+ facePanel.getAccessibleContext().getAccessibleRelationSet().add(controlledByRelation);
+
+ // Indicate that the hair, eyes and mouth combo boxes are controllers
+ // for the face panel.
+ AccessibleRelation controllerForRelation
+ = new AccessibleRelation(AccessibleRelation.CONTROLLER_FOR_PROPERTY,
+ facePanel);
+ hairCB.getAccessibleContext().getAccessibleRelationSet().add(controllerForRelation);
+ eyesCB.getAccessibleContext().getAccessibleRelationSet().add(controllerForRelation);
+ mouthCB.getAccessibleContext().getAccessibleRelationSet().add(controllerForRelation);
+
+ // add buttons and image panels to inner panel
+ innerPanel.add(comboBoxPanel);
+ innerPanel.add(Box.createRigidArea(HGAP30));
+ innerPanel.add(facePanel);
+ innerPanel.add(Box.createRigidArea(HGAP20));
+
+ // load up the face parts
+ addFace("brent", resourceManager.getString("ComboBoxDemo.brent"));
+ addFace("georges", resourceManager.getString("ComboBoxDemo.georges"));
+ addFace("hans", resourceManager.getString("ComboBoxDemo.hans"));
+ addFace("howard", resourceManager.getString("ComboBoxDemo.howard"));
+ addFace("james", resourceManager.getString("ComboBoxDemo.james"));
+ addFace("jeff", resourceManager.getString("ComboBoxDemo.jeff"));
+ addFace("jon", resourceManager.getString("ComboBoxDemo.jon"));
+ addFace("lara", resourceManager.getString("ComboBoxDemo.lara"));
+ addFace("larry", resourceManager.getString("ComboBoxDemo.larry"));
+ addFace("lisa", resourceManager.getString("ComboBoxDemo.lisa"));
+ addFace("michael", resourceManager.getString("ComboBoxDemo.michael"));
+ addFace("philip", resourceManager.getString("ComboBoxDemo.philip"));
+ addFace("scott", resourceManager.getString("ComboBoxDemo.scott"));
+
+ // set the default face
+ presetCB.setSelectedIndex(0);
+ }
+
+ private void addFace(String name, String i18n_name) {
+ ImageIcon i;
+ String i18n_hair = resourceManager.getString("ComboBoxDemo.hair");
+ String i18n_eyes = resourceManager.getString("ComboBoxDemo.eyes");
+ String i18n_mouth = resourceManager.getString("ComboBoxDemo.mouth");
+
+ parts.put(i18n_name, name); // i18n name lookup
+ parts.put(name, i18n_name); // reverse name lookup
+
+ i = resourceManager.createImageIcon(name + "hair.jpg", i18n_name + i18n_hair);
+ parts.put(name + "hair", i);
+
+ i = resourceManager.createImageIcon(name + "eyes.jpg", i18n_name + i18n_eyes);
+ parts.put(name + "eyes", i);
+
+ i = resourceManager.createImageIcon(name + "mouth.jpg", i18n_name + i18n_mouth);
+ parts.put(name + "mouth", i);
+ }
+
+ private JComboBox createHairComboBox() {
+ JComboBox cb = new JComboBox<>();
+ fillComboBox(cb);
+ cb.addActionListener(this);
+ return cb;
+ }
+
+ private JComboBox createEyesComboBox() {
+ JComboBox cb = new JComboBox<>();
+ fillComboBox(cb);
+ cb.addActionListener(this);
+ return cb;
+ }
+
+ private JComboBox createMouthComboBox() {
+ JComboBox cb = new JComboBox<>();
+ fillComboBox(cb);
+ cb.addActionListener(this);
+ return cb;
+ }
+
+ private JComboBox createPresetComboBox() {
+ JComboBox cb = new JComboBox<>();
+ cb.addItem(resourceManager.getString("ComboBoxDemo.preset1"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.preset2"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.preset3"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.preset4"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.preset5"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.preset6"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.preset7"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.preset8"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.preset9"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.preset10"));
+ cb.addActionListener(this);
+ return cb;
+ }
+
+ private void fillComboBox(JComboBox cb) {
+ cb.addItem(resourceManager.getString("ComboBoxDemo.brent"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.georges"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.hans"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.howard"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.james"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.jeff"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.jon"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.lara"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.larry"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.lisa"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.michael"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.philip"));
+ cb.addItem(resourceManager.getString("ComboBoxDemo.scott"));
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == hairCB) {
+ String name = (String) parts.get(hairCB.getSelectedItem());
+ face.setHair((ImageIcon) parts.get(name + "hair"));
+ faceLabel.repaint();
+ } else if (e.getSource() == eyesCB) {
+ String name = (String) parts.get(eyesCB.getSelectedItem());
+ face.setEyes((ImageIcon) parts.get(name + "eyes"));
+ faceLabel.repaint();
+ } else if (e.getSource() == mouthCB) {
+ String name = (String) parts.get(mouthCB.getSelectedItem());
+ face.setMouth((ImageIcon) parts.get(name + "mouth"));
+ faceLabel.repaint();
+ } else if (e.getSource() == presetCB) {
+ String hair = null;
+ String eyes = null;
+ String mouth = null;
+ switch (presetCB.getSelectedIndex()) {
+ case 0:
+ hair = (String) parts.get("philip");
+ eyes = (String) parts.get("howard");
+ mouth = (String) parts.get("jeff");
+ break;
+ case 1:
+ hair = (String) parts.get("jeff");
+ eyes = (String) parts.get("larry");
+ mouth = (String) parts.get("philip");
+ break;
+ case 2:
+ hair = (String) parts.get("howard");
+ eyes = (String) parts.get("scott");
+ mouth = (String) parts.get("hans");
+ break;
+ case 3:
+ hair = (String) parts.get("philip");
+ eyes = (String) parts.get("jeff");
+ mouth = (String) parts.get("hans");
+ break;
+ case 4:
+ hair = (String) parts.get("brent");
+ eyes = (String) parts.get("jon");
+ mouth = (String) parts.get("scott");
+ break;
+ case 5:
+ hair = (String) parts.get("lara");
+ eyes = (String) parts.get("larry");
+ mouth = (String) parts.get("lisa");
+ break;
+ case 6:
+ hair = (String) parts.get("james");
+ eyes = (String) parts.get("philip");
+ mouth = (String) parts.get("michael");
+ break;
+ case 7:
+ hair = (String) parts.get("philip");
+ eyes = (String) parts.get("lisa");
+ mouth = (String) parts.get("brent");
+ break;
+ case 8:
+ hair = (String) parts.get("james");
+ eyes = (String) parts.get("philip");
+ mouth = (String) parts.get("jon");
+ break;
+ case 9:
+ hair = (String) parts.get("lara");
+ eyes = (String) parts.get("jon");
+ mouth = (String) parts.get("scott");
+ break;
+ }
+ if (hair != null) {
+ hairCB.setSelectedItem(hair);
+ eyesCB.setSelectedItem(eyes);
+ mouthCB.setSelectedItem(mouth);
+ faceLabel.repaint();
+ }
+ }
+ }
+
+ private static class Face implements Icon {
+
+ private ImageIcon hair;
+ private ImageIcon eyes;
+ private ImageIcon mouth;
+
+ void setHair(ImageIcon i) {
+ hair = i;
+ }
+
+ void setEyes(ImageIcon i) {
+ eyes = i;
+ }
+
+ void setMouth(ImageIcon i) {
+ mouth = i;
+ }
+
+ @Override
+ public void paintIcon(Component c, Graphics g, int x, int y) {
+ int height = y;
+ x = c.getWidth() / 2 - getIconWidth() / 2;
+
+ if (hair != null) {
+ hair.paintIcon(c, g, x, height);
+ height += hair.getIconHeight();
+ }
+
+ if (eyes != null) {
+ eyes.paintIcon(c, g, x, height);
+ height += eyes.getIconHeight();
+ }
+
+ if (mouth != null) {
+ mouth.paintIcon(c, g, x, height);
+ }
+ }
+
+ @Override
+ public int getIconWidth() {
+ return 344;
+ }
+
+ @Override
+ public int getIconHeight() {
+ return 455;
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/ComboBoxDemo.properties b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/ComboBoxDemo.properties
new file mode 100644
index 00000000000..51ee144e0c8
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/ComboBoxDemo.properties
@@ -0,0 +1,42 @@
+### ComboBox Demo ###
+
+ComboBoxDemo.accessible_description=This demo shows an example of using the JComboBox component.
+ComboBoxDemo.tooltip=JComboBox demo
+ComboBoxDemo.name=ComboBox Demo
+
+ComboBoxDemo.hair=hair
+ComboBoxDemo.eyes=eyes
+ComboBoxDemo.mouth=mouth
+ComboBoxDemo.presets=Presets:
+
+ComboBoxDemo.preset1=Philip, Howard, Jeff
+ComboBoxDemo.preset2=Jeff, Larry, Philip
+ComboBoxDemo.preset3=Howard, Scott, Hans
+ComboBoxDemo.preset4=Philip, Jeff, Hans
+ComboBoxDemo.preset5=Brent, Jon, Scott
+ComboBoxDemo.preset6=Lara, Larry, Lisa
+ComboBoxDemo.preset7=James, Philip, Michael
+ComboBoxDemo.preset8=Philip, Lisa, Brent
+ComboBoxDemo.preset9=James, Philip, Jon
+ComboBoxDemo.preset10=Lara, Jon, Scott
+
+
+ComboBoxDemo.hair_description=Hair:
+ComboBoxDemo.eyes_description=Eyes & Nose:
+ComboBoxDemo.mouth_description=Mouth:
+
+ComboBoxDemo.amy=Amy
+ComboBoxDemo.brent=Brent
+ComboBoxDemo.georges=Georges
+ComboBoxDemo.hans=Hans
+ComboBoxDemo.howard=Howard
+ComboBoxDemo.james=James
+ComboBoxDemo.jeff=Jeff
+ComboBoxDemo.jon=Jon
+ComboBoxDemo.lara=Lara
+ComboBoxDemo.larry=Larry
+ComboBoxDemo.lisa=Lisa
+ComboBoxDemo.michael=Michael
+ComboBoxDemo.philip=Philip
+ComboBoxDemo.scott=Scott
+
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/ComboBoxDemo.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/ComboBoxDemo.gif
new file mode 100644
index 00000000000..f8e971f19ce
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/ComboBoxDemo.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/brenteyes.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/brenteyes.jpg
new file mode 100644
index 00000000000..6f7d0f4fee2
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/brenteyes.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/brenthair.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/brenthair.jpg
new file mode 100644
index 00000000000..cfde575e7ce
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/brenthair.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/brentmouth.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/brentmouth.jpg
new file mode 100644
index 00000000000..6b3c5259b37
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/brentmouth.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/georgeseyes.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/georgeseyes.jpg
new file mode 100644
index 00000000000..224cef61da1
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/georgeseyes.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/georgeshair.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/georgeshair.jpg
new file mode 100644
index 00000000000..7071dde0adb
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/georgeshair.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/georgesmouth.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/georgesmouth.jpg
new file mode 100644
index 00000000000..b917e515d48
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/georgesmouth.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/hanseyes.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/hanseyes.jpg
new file mode 100644
index 00000000000..e7001add02b
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/hanseyes.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/hanshair.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/hanshair.jpg
new file mode 100644
index 00000000000..bf46bb63ed0
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/hanshair.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/hansmouth.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/hansmouth.jpg
new file mode 100644
index 00000000000..09eb9e014d4
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/hansmouth.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/howardeyes.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/howardeyes.jpg
new file mode 100644
index 00000000000..b5f1ba50bb1
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/howardeyes.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/howardhair.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/howardhair.jpg
new file mode 100644
index 00000000000..b0cdb19a8d9
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/howardhair.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/howardmouth.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/howardmouth.jpg
new file mode 100644
index 00000000000..ebc85f021d2
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/howardmouth.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jameseyes.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jameseyes.jpg
new file mode 100644
index 00000000000..a53f9224760
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jameseyes.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jameshair.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jameshair.jpg
new file mode 100644
index 00000000000..52d2ca53ba9
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jameshair.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jamesmouth.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jamesmouth.jpg
new file mode 100644
index 00000000000..7b0e35c1872
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jamesmouth.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jeffeyes.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jeffeyes.jpg
new file mode 100644
index 00000000000..0608e070772
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jeffeyes.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jeffhair.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jeffhair.jpg
new file mode 100644
index 00000000000..b67834a5c01
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jeffhair.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jeffmouth.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jeffmouth.jpg
new file mode 100644
index 00000000000..8a313496d45
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jeffmouth.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/joneyes.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/joneyes.jpg
new file mode 100644
index 00000000000..f7440841e6f
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/joneyes.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jonhair.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jonhair.jpg
new file mode 100644
index 00000000000..59a182451e2
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jonhair.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jonmouth.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jonmouth.jpg
new file mode 100644
index 00000000000..9f39f0b1e4d
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/jonmouth.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/laraeyes.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/laraeyes.jpg
new file mode 100644
index 00000000000..24c8778e5f9
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/laraeyes.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/larahair.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/larahair.jpg
new file mode 100644
index 00000000000..8c23d01953d
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/larahair.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/laramouth.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/laramouth.jpg
new file mode 100644
index 00000000000..b00407c9213
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/laramouth.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/larryeyes.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/larryeyes.jpg
new file mode 100644
index 00000000000..a2b771ec709
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/larryeyes.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/larryhair.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/larryhair.jpg
new file mode 100644
index 00000000000..5366c15d599
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/larryhair.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/larrymouth.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/larrymouth.jpg
new file mode 100644
index 00000000000..d0642d274ba
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/larrymouth.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/lisaeyes.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/lisaeyes.jpg
new file mode 100644
index 00000000000..4a9cc86a1b8
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/lisaeyes.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/lisahair.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/lisahair.jpg
new file mode 100644
index 00000000000..3eb7d4f3084
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/lisahair.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/lisamouth.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/lisamouth.jpg
new file mode 100644
index 00000000000..ac565029910
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/lisamouth.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/michaeleyes.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/michaeleyes.jpg
new file mode 100644
index 00000000000..ae8487facdf
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/michaeleyes.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/michaelhair.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/michaelhair.jpg
new file mode 100644
index 00000000000..271d20c2c56
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/michaelhair.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/michaelmouth.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/michaelmouth.jpg
new file mode 100644
index 00000000000..02119ed0202
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/michaelmouth.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/philipeyes.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/philipeyes.jpg
new file mode 100644
index 00000000000..1d308070cd2
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/philipeyes.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/philiphair.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/philiphair.jpg
new file mode 100644
index 00000000000..18988dfc5cc
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/philiphair.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/philipmouth.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/philipmouth.jpg
new file mode 100644
index 00000000000..dcf4b96bc74
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/philipmouth.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/scotteyes.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/scotteyes.jpg
new file mode 100644
index 00000000000..fa7ead76cb2
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/scotteyes.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/scotthair.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/scotthair.jpg
new file mode 100644
index 00000000000..ef237cb248b
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/scotthair.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/scottmouth.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/scottmouth.jpg
new file mode 100644
index 00000000000..9eea453afaf
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/resources/images/scottmouth.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/ListDemo.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/ListDemo.java
new file mode 100644
index 00000000000..b8dce72ba9e
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/ListDemo.java
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.list;
+
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.util.Vector;
+import javax.swing.*;
+
+import com.sun.swingset3.DemoProperties;
+import com.sun.swingset3.demos.ResourceManager;
+
+/**
+ * List Demo. This demo shows that it is not always necessary to have an array
+ * of objects as big as the size of the list stored.
+ *
+ * Indeed, in this example, there is no array kept for the list data, rather it
+ * is generated on the fly as only those elements are needed.
+ *
+ * @version 1.17 11/17/05
+ * @author Jeff Dinkins
+ */
+@DemoProperties(
+ value = "JList Demo",
+ category = "Data",
+ description = "Demonstrates JList, a component which supports display/editing of a data list",
+ sourceFiles = {
+ "com/sun/swingset3/demos/list/ListDemo.java",
+ "com/sun/swingset3/demos/list/Permuter.java",
+ "com/sun/swingset3/demos/ResourceManager.java",
+ "com/sun/swingset3/demos/list/resources/ListDemo.properties",
+ "com/sun/swingset3/demos/list/resources/images/blue.gif",
+ "com/sun/swingset3/demos/list/resources/images/cyan.gif",
+ "com/sun/swingset3/demos/list/resources/images/gray.gif",
+ "com/sun/swingset3/demos/list/resources/images/green.gif",
+ "com/sun/swingset3/demos/list/resources/images/ListDemo.gif",
+ "com/sun/swingset3/demos/list/resources/images/magenta.gif",
+ "com/sun/swingset3/demos/list/resources/images/red.gif",
+ "com/sun/swingset3/demos/list/resources/images/yellow.gif"
+ }
+)
+public final class ListDemo extends JPanel {
+
+ private static final Dimension HGAP10 = new Dimension(10, 1);
+ private static final Dimension VGAP10 = new Dimension(1, 10);
+ private static final Dimension HGAP15 = new Dimension(15, 1);
+ private static final Dimension HGAP30 = new Dimension(30, 1);
+
+ private final ResourceManager resourceManager = new ResourceManager(this.getClass());
+ public static final String DEMO_TITLE = ListDemo.class.getAnnotation(DemoProperties.class).value();
+
+ private final JList list;
+
+ private JPanel prefixList;
+ private JPanel suffixList;
+
+ private Action prefixAction;
+ private Action suffixAction;
+
+ private final GeneratedListModel listModel;
+
+ /**
+ * main method allows us to run as a standalone demo.
+ *
+ * @param args
+ */
+ public static void main(String[] args) {
+ JFrame frame = new JFrame(DEMO_TITLE);
+
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.getContentPane().add(new ListDemo());
+ frame.setPreferredSize(new Dimension(800, 600));
+ frame.pack();
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+ }
+
+ /**
+ * ListDemo Constructor
+ */
+ public ListDemo() {
+ setLayout(new BorderLayout());
+
+ loadImages();
+
+ JLabel description = new JLabel(resourceManager.getString("ListDemo.description"));
+ add(description, BorderLayout.NORTH);
+
+ JPanel centerPanel = new JPanel();
+ centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.X_AXIS));
+ centerPanel.add(Box.createRigidArea(HGAP10));
+ add(centerPanel, BorderLayout.CENTER);
+
+ JPanel listPanel = new JPanel();
+ listPanel.setLayout(new BoxLayout(listPanel, BoxLayout.Y_AXIS));
+ listPanel.add(Box.createRigidArea(VGAP10));
+
+ centerPanel.add(listPanel);
+ centerPanel.add(Box.createRigidArea(HGAP30));
+
+ // Create the list
+ list = new JList<>();
+ list.setCellRenderer(new CompanyLogoListCellRenderer());
+ listModel = new GeneratedListModel();
+ list.setModel(listModel);
+
+ // Set the preferred row count. This affects the preferredSize
+ // of the JList when it's in a scrollpane.
+ list.setVisibleRowCount(22);
+
+ // Add list to a scrollpane
+ JScrollPane scrollPane = new JScrollPane(list);
+ listPanel.add(scrollPane);
+ listPanel.add(Box.createRigidArea(VGAP10));
+
+ // Add the control panel (holds the prefix/suffix list and prefix/suffix checkboxes)
+ centerPanel.add(createControlPanel());
+
+ // create prefixes and suffixes
+ addPrefix("Tera", true);
+ addPrefix("Micro", false);
+ addPrefix("Southern", false);
+ addPrefix("Net", true);
+ addPrefix("YoYo", true);
+ addPrefix("Northern", false);
+ addPrefix("Tele", false);
+ addPrefix("Eastern", false);
+ addPrefix("Neo", false);
+ addPrefix("Digi", false);
+ addPrefix("National", false);
+ addPrefix("Compu", true);
+ addPrefix("Meta", true);
+ addPrefix("Info", false);
+ addPrefix("Western", false);
+ addPrefix("Data", false);
+ addPrefix("Atlantic", false);
+ addPrefix("Advanced", false);
+ addPrefix("Euro", false);
+ addPrefix("Pacific", false);
+ addPrefix("Mobile", false);
+ addPrefix("In", false);
+ addPrefix("Computa", false);
+ addPrefix("Digital", false);
+ addPrefix("Analog", false);
+
+ addSuffix("Tech", true);
+ addSuffix("Soft", true);
+ addSuffix("Telecom", true);
+ addSuffix("Solutions", false);
+ addSuffix("Works", true);
+ addSuffix("Dyne", false);
+ addSuffix("Services", false);
+ addSuffix("Vers", false);
+ addSuffix("Devices", false);
+ addSuffix("Software", false);
+ addSuffix("Serv", false);
+ addSuffix("Systems", true);
+ addSuffix("Dynamics", true);
+ addSuffix("Net", false);
+ addSuffix("Sys", false);
+ addSuffix("Computing", false);
+ addSuffix("Scape", false);
+ addSuffix("Com", false);
+ addSuffix("Ware", false);
+ addSuffix("Widgets", false);
+ addSuffix("Media", false);
+ addSuffix("Computer", false);
+ addSuffix("Hardware", false);
+ addSuffix("Gizmos", false);
+ addSuffix("Concepts", false);
+ }
+
+ private JPanel createControlPanel() {
+ JPanel controlPanel = new JPanel() {
+ private final Insets insets = new Insets(0, 4, 10, 10);
+
+ @Override
+ public Insets getInsets() {
+ return insets;
+ }
+ };
+ controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.X_AXIS));
+
+ JPanel prefixPanel = new JPanel();
+ prefixPanel.setLayout(new BoxLayout(prefixPanel, BoxLayout.Y_AXIS));
+ prefixPanel.add(new JLabel(resourceManager.getString("ListDemo.prefixes")));
+
+ JPanel suffixPanel = new JPanel();
+ suffixPanel.setLayout(new BoxLayout(suffixPanel, BoxLayout.Y_AXIS));
+ suffixPanel.add(new JLabel(resourceManager.getString("ListDemo.suffixes")));
+
+ prefixList = new JPanel() {
+ private final Insets insets = new Insets(0, 4, 0, 0);
+
+ @Override
+ public Insets getInsets() {
+ return insets;
+ }
+ };
+ prefixList.setLayout(new BoxLayout(prefixList, BoxLayout.Y_AXIS));
+ JScrollPane scrollPane = new JScrollPane(prefixList);
+ scrollPane.getVerticalScrollBar().setUnitIncrement(10);
+ prefixPanel.add(scrollPane);
+ prefixPanel.add(Box.createRigidArea(HGAP10));
+
+ suffixList = new JPanel() {
+ private final Insets insets = new Insets(0, 4, 0, 0);
+
+ @Override
+ public Insets getInsets() {
+ return insets;
+ }
+ };
+ suffixList.setLayout(new BoxLayout(suffixList, BoxLayout.Y_AXIS));
+ scrollPane = new JScrollPane(suffixList);
+ scrollPane.getVerticalScrollBar().setUnitIncrement(10);
+ suffixPanel.add(scrollPane);
+ suffixPanel.add(Box.createRigidArea(HGAP10));
+
+ controlPanel.add(prefixPanel);
+ controlPanel.add(Box.createRigidArea(HGAP15));
+ controlPanel.add(suffixPanel);
+ return controlPanel;
+ }
+
+ private final FocusListener listFocusListener = new FocusAdapter() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ JComponent c = (JComponent) e.getComponent();
+ c.scrollRectToVisible(new Rectangle(0, 0, c.getWidth(), c.getHeight()));
+ }
+ };
+
+ private void addPrefix(String prefix, boolean selected) {
+ if (prefixAction == null) {
+ prefixAction = new UpdatePrefixListAction(listModel);
+ }
+ final JCheckBox cb = (JCheckBox) prefixList.add(new JCheckBox(prefix));
+ cb.setSelected(selected);
+ cb.addActionListener(prefixAction);
+ if (selected) {
+ listModel.addPrefix(prefix);
+ }
+ cb.addFocusListener(listFocusListener);
+ }
+
+ private void addSuffix(String suffix, boolean selected) {
+ if (suffixAction == null) {
+ suffixAction = new UpdateSuffixListAction(listModel);
+ }
+ final JCheckBox cb = (JCheckBox) suffixList.add(new JCheckBox(suffix));
+ cb.setSelected(selected);
+ cb.addActionListener(suffixAction);
+ if (selected) {
+ listModel.addSuffix(suffix);
+ }
+ cb.addFocusListener(listFocusListener);
+ }
+
+ private static class UpdatePrefixListAction extends AbstractAction {
+
+ private final GeneratedListModel listModel;
+
+ protected UpdatePrefixListAction(GeneratedListModel listModel) {
+ this.listModel = listModel;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JCheckBox cb = (JCheckBox) e.getSource();
+ if (cb.isSelected()) {
+ listModel.addPrefix(cb.getText());
+ } else {
+ listModel.removePrefix(cb.getText());
+ }
+ }
+ }
+
+ private static class UpdateSuffixListAction extends AbstractAction {
+
+ private final GeneratedListModel listModel;
+
+ protected UpdateSuffixListAction(GeneratedListModel listModel) {
+ this.listModel = listModel;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JCheckBox cb = (JCheckBox) e.getSource();
+ if (cb.isSelected()) {
+ listModel.addSuffix(cb.getText());
+ } else {
+ listModel.removeSuffix(cb.getText());
+ }
+ }
+ }
+
+ private static class GeneratedListModel extends AbstractListModel {
+
+ private Permuter permuter;
+
+ private final Vector prefix = new Vector<>();
+ private final Vector suffix = new Vector<>();
+
+ private void update() {
+ permuter = new Permuter(getSize());
+ fireContentsChanged(this, 0, getSize());
+ }
+
+ public void addPrefix(String s) {
+ if (!prefix.contains(s)) {
+ prefix.addElement(s);
+ update();
+ }
+ }
+
+ public void removePrefix(String s) {
+ prefix.removeElement(s);
+ update();
+ }
+
+ public void addSuffix(String s) {
+ if (!suffix.contains(s)) {
+ suffix.addElement(s);
+ update();
+ }
+ }
+
+ public void removeSuffix(String s) {
+ suffix.removeElement(s);
+ update();
+ }
+
+ @Override
+ public int getSize() {
+ return prefix.size() * suffix.size();
+ }
+
+ @Override
+ public String getElementAt(int index) {
+ if (permuter == null) {
+ update();
+ }
+ // morph the index to another int -- this has the benefit of
+ // causing the list to look random.
+ int j = permuter.map(index);
+ int ps = prefix.size();
+ int ss = suffix.size();
+ return prefix.elementAt(j % ps) + suffix.elementAt((j / ps) % ss);
+ }
+ }
+
+ private final ImageIcon[] images = new ImageIcon[7];
+
+ void loadImages() {
+ images[0] = resourceManager.createImageIcon("red.gif", resourceManager.getString("ListDemo.red"));
+ images[1] = resourceManager.createImageIcon("blue.gif", resourceManager.getString("ListDemo.blue"));
+ images[2] = resourceManager.createImageIcon("yellow.gif", resourceManager.getString("ListDemo.yellow"));
+ images[3] = resourceManager.createImageIcon("green.gif", resourceManager.getString("ListDemo.green"));
+ images[4] = resourceManager.createImageIcon("gray.gif", resourceManager.getString("ListDemo.gray"));
+ images[5] = resourceManager.createImageIcon("cyan.gif", resourceManager.getString("ListDemo.cyan"));
+ images[6] = resourceManager.createImageIcon("magenta.gif", resourceManager.getString("ListDemo.magenta"));
+ }
+
+ private class CompanyLogoListCellRenderer extends DefaultListCellRenderer {
+
+ @Override
+ public Component getListCellRendererComponent(
+ JList> list,
+ Object value,
+ int index,
+ boolean isSelected,
+ boolean cellHasFocus) {
+ Component retValue = super.getListCellRendererComponent(
+ list, value, index, isSelected, cellHasFocus
+ );
+ setIcon(images[index % 7]);
+ return retValue;
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/Permuter.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/Permuter.java
new file mode 100644
index 00000000000..7b3dc726723
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/Permuter.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.list;
+
+/**
+ * An object that implements a cheesy pseudorandom permutation of the integers
+ * from zero to some user-specified value. (The permutation is a linear
+ * function.)
+ *
+ * @version 1.9 11/17/05
+ * @author Josh Bloch
+ */
+class Permuter {
+
+ /**
+ * The size of the permutation.
+ */
+ private int modulus;
+
+ /**
+ * Nonnegative integer less than n that is relatively prime to m.
+ */
+ private int multiplier;
+
+ /**
+ * Pseudorandom nonnegative integer less than n.
+ */
+ private static final int ADDEND = 22;
+
+ public Permuter(int n) {
+ if (n < 0) {
+ throw new IllegalArgumentException();
+ }
+ modulus = n;
+ if (n == 1) {
+ return;
+ }
+
+ // Initialize the multiplier and offset
+ multiplier = (int) Math.sqrt(n);
+ while (gcd(multiplier, n) != 1) {
+ if (++multiplier == n) {
+ multiplier = 1;
+ }
+ }
+ }
+
+ /**
+ * Returns the integer to which this permuter maps the specified integer.
+ * The specified integer must be between 0 and n-1, and the returned integer
+ * will be as well.
+ */
+ public int map(int i) {
+ return (multiplier * i + ADDEND) % modulus;
+ }
+
+ /**
+ * Calculate GCD of a and b, which are assumed to be non-negative.
+ */
+ private static int gcd(int a, int b) {
+ while (b != 0) {
+ int tmp = a % b;
+ a = b;
+ b = tmp;
+ }
+ return a;
+ }
+
+ /**
+ * Simple test. Takes modulus on command line and prints out permutation.
+ */
+ public static void main(String[] args) {
+ int modulus = Integer.parseInt(args[0]);
+ Permuter p = new Permuter(modulus);
+ for (int i = 0; i < modulus; i++) {
+ System.out.print(p.map(i) + " ");
+ }
+ System.out.println();
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/ListDemo.properties b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/ListDemo.properties
new file mode 100644
index 00000000000..197cb7f69e9
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/ListDemo.properties
@@ -0,0 +1,18 @@
+### List Demo ###
+
+ListDemo.accessible_description=JList Demo
+ListDemo.name=List Demo
+ListDemo.tooltip=JList demo
+ListDemo.prefixes=Prefixes
+ListDemo.suffixes=Suffixes
+ListDemo.count_label=Number of generated list entries:
+ListDemo.all=All
+ListDemo.none=None
+ListDemo.red=Red Company Logo Image
+ListDemo.yellow=Red Company Logo Image
+ListDemo.blue=Blue Company Logo Image
+ListDemo.gray=Gray Company Logo Image
+ListDemo.green=Green Company Logo Image
+ListDemo.magenta=Magenta Company Logo Image
+ListDemo.cyan=Cyan Company Logo Image
+ListDemo.description=
This demo shows how to present lists of data in two different ways. On the left is a JList component whose list items consist of the permutations of the checked prefixes and suffixes. The prefix and suffix checkbox columns on the right are created by using a JPanel with a Y Axis BoxLayout inside a JScrollPane.
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/ListDemo.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/ListDemo.gif
new file mode 100644
index 00000000000..d50e74f75ee
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/ListDemo.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/blue.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/blue.gif
new file mode 100644
index 00000000000..0cbfc10f3c5
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/blue.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/cyan.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/cyan.gif
new file mode 100644
index 00000000000..1a15194edaa
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/cyan.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/gray.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/gray.gif
new file mode 100644
index 00000000000..7e168315415
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/gray.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/green.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/green.gif
new file mode 100644
index 00000000000..5613d8dbe1c
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/green.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/magenta.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/magenta.gif
new file mode 100644
index 00000000000..e3741ab69ee
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/magenta.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/red.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/red.gif
new file mode 100644
index 00000000000..c197ffce1bc
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/red.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/yellow.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/yellow.gif
new file mode 100644
index 00000000000..9baeebfe585
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/resources/images/yellow.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/OptionPaneDemo.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/OptionPaneDemo.java
new file mode 100644
index 00000000000..0e8c1e46a13
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/OptionPaneDemo.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.optionpane;
+
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.net.URL;
+import javax.swing.*;
+
+import com.sun.swingset3.demos.ResourceManager;
+import com.sun.swingset3.DemoProperties;
+
+/**
+ * JOptionPaneDemo
+ *
+ * @author Jeff Dinkins
+ * @version 1.11 11/17/05
+ */
+@DemoProperties(
+ value = "JOptionPane Demo",
+ category = "Choosers",
+ description = "Demonstrates JOptionPane, a component which displays standard message dialogs (question, warning, error, etc).",
+ sourceFiles = {
+ "com/sun/swingset3/demos/optionpane/OptionPaneDemo.java",
+ "com/sun/swingset3/demos/ResourceManager.java",
+ "com/sun/swingset3/demos/optionpane/resources/OptionPaneDemo.properties",
+ "com/sun/swingset3/demos/optionpane/resources/images/bottle.gif",
+ "com/sun/swingset3/demos/optionpane/resources/images/OptionPaneDemo.gif"
+ }
+)
+public class OptionPaneDemo extends JPanel {
+
+ private static final Dimension VGAP15 = new Dimension(1, 15);
+ private static final Dimension VGAP30 = new Dimension(1, 30);
+
+ private static final ResourceManager resourceManager = new ResourceManager(OptionPaneDemo.class);
+ public static final String WARNING_TITLE = resourceManager.getString("OptionPaneDemo.warningtitle");
+ public static final String WARNING_TEXT = resourceManager.getString("OptionPaneDemo.warningtext");
+ public static final String WARNING_BUTTON = resourceManager.getString("OptionPaneDemo.warningbutton");
+ public static final String CONFIRM_NO = resourceManager.getString("OptionPaneDemo.confirmno");
+ public static final String CONFIRM_YES = resourceManager.getString("OptionPaneDemo.confirmyes");
+ public static final String CONFIRM_QUESTION = resourceManager.getString("OptionPaneDemo.confirmquestion");
+ public static final String CONFIRM_BUTTON = resourceManager.getString("OptionPaneDemo.confirmbutton");
+ public static final String MESSAGE_TEXT = resourceManager.getString("OptionPaneDemo.messagetext");
+ public static final String MESSAGE_BUTTON = resourceManager.getString("OptionPaneDemo.messagebutton");
+ public static final String INPUT_QUESTION = resourceManager.getString("OptionPaneDemo.inputquestion");
+ public static final String INPUT_RESPONSE = ": " + resourceManager.getString("OptionPaneDemo.inputresponse");
+ public static final String INPUT_BUTTON = resourceManager.getString("OptionPaneDemo.inputbutton");
+ public static final String COMPONENT_R4 = resourceManager.getString("OptionPaneDemo.component_r4");
+ public static final String COMPONENT_R3 = resourceManager.getString("OptionPaneDemo.component_r3");
+ public static final String COMPONENT_R2 = resourceManager.getString("OptionPaneDemo.component_r2");
+ public static final String COMPONENT_R1 = resourceManager.getString("OptionPaneDemo.component_r1");
+ public static final String COMPONENT_TITLE = resourceManager.getString("OptionPaneDemo.componenttitle");
+ public static final String COMPONENT_OP5 = resourceManager.getString("OptionPaneDemo.component_op5");
+ public static final String COMPONENT_OP4 = resourceManager.getString("OptionPaneDemo.component_op4");
+ public static final String COMPONENT_OP3 = resourceManager.getString("OptionPaneDemo.component_op3");
+ public static final String COMPONENT_OP2 = resourceManager.getString("OptionPaneDemo.component_op2");
+ public static final String COMPONENT_OP1 = resourceManager.getString("OptionPaneDemo.component_op1");
+ public static final String COMPONENT_MESSAGE_2 = resourceManager.getString("OptionPaneDemo.componentmessage2");
+ public static final String COMPONENT_CB3 = resourceManager.getString("OptionPaneDemo.component_cb3");
+ public static final String COMPONENT_CB2 = resourceManager.getString("OptionPaneDemo.component_cb2");
+ public static final String COMPONENT_CB1 = resourceManager.getString("OptionPaneDemo.component_cb1");
+ public static final String COMPONENT_BUTTON = resourceManager.getString("OptionPaneDemo.componentbutton");
+ public static final String COMPONENT_TEXT_FIELD = resourceManager.getString("OptionPaneDemo.componenttextfield");
+ public static final String COMPONENT_MESSAGE = resourceManager.getString("OptionPaneDemo.componentmessage");
+ public static final String DEMO_TITLE = OptionPaneDemo.class.getAnnotation(DemoProperties.class).value();
+
+ /**
+ * main method allows us to run as a standalone demo.
+ *
+ * @param args
+ */
+ public static void main(String[] args) {
+ JFrame frame = new JFrame(DEMO_TITLE);
+
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.getContentPane().add(new OptionPaneDemo());
+ frame.setPreferredSize(new Dimension(800, 600));
+ frame.pack();
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+ }
+
+ /**
+ * OptionPaneDemo Constructor
+ */
+ public OptionPaneDemo() {
+ setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
+
+ JPanel bp = new JPanel() {
+ @Override
+ public Dimension getMaximumSize() {
+ return new Dimension(getPreferredSize().width, super.getMaximumSize().height);
+ }
+ };
+ bp.setLayout(new BoxLayout(bp, BoxLayout.Y_AXIS));
+
+ bp.add(Box.createRigidArea(VGAP30));
+ bp.add(Box.createRigidArea(VGAP30));
+
+ bp.add(createInputDialogButton());
+ bp.add(Box.createRigidArea(VGAP15));
+ bp.add(createWarningDialogButton());
+ bp.add(Box.createRigidArea(VGAP15));
+ bp.add(createMessageDialogButton());
+ bp.add(Box.createRigidArea(VGAP15));
+ bp.add(createComponentDialogButton());
+ bp.add(Box.createRigidArea(VGAP15));
+ bp.add(createConfirmDialogButton());
+ bp.add(Box.createVerticalGlue());
+
+ add(Box.createHorizontalGlue());
+ add(bp);
+ add(Box.createHorizontalGlue());
+ }
+
+ private JButton createWarningDialogButton() {
+ Action a = new AbstractAction(WARNING_BUTTON) {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JOptionPane.showMessageDialog(OptionPaneDemo.this,
+ WARNING_TEXT,
+ WARNING_TITLE,
+ JOptionPane.WARNING_MESSAGE
+ );
+ }
+ };
+ return createButton(a);
+ }
+
+ private JButton createMessageDialogButton() {
+ Action a = new AbstractAction(MESSAGE_BUTTON) {
+ final URL img = getClass().getResource("resources/images/bottle.gif");
+ final String imagesrc = "";
+ final String message = MESSAGE_TEXT;
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JOptionPane.showMessageDialog(
+ OptionPaneDemo.this,
+ "" + imagesrc + "
" + message + "
"
+ );
+ }
+ };
+ return createButton(a);
+ }
+
+ private JButton createConfirmDialogButton() {
+ Action a = new AbstractAction(CONFIRM_BUTTON) {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ int result = JOptionPane.showConfirmDialog(OptionPaneDemo.this, CONFIRM_QUESTION);
+ if (result == JOptionPane.YES_OPTION) {
+ JOptionPane.showMessageDialog(OptionPaneDemo.this, CONFIRM_YES);
+ } else if (result == JOptionPane.NO_OPTION) {
+ JOptionPane.showMessageDialog(OptionPaneDemo.this, CONFIRM_NO);
+ }
+ }
+ };
+ return createButton(a);
+ }
+
+ private JButton createInputDialogButton() {
+ Action a = new AbstractAction(INPUT_BUTTON) {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ String result = JOptionPane.showInputDialog(OptionPaneDemo.this, INPUT_QUESTION);
+ if ((result != null) && (result.length() > 0)) {
+ JOptionPane.showMessageDialog(OptionPaneDemo.this,
+ result + INPUT_RESPONSE);
+ }
+ }
+ };
+ return createButton(a);
+ }
+
+ private JButton createComponentDialogButton() {
+ Action a = new AbstractAction(COMPONENT_BUTTON) {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ // In a ComponentDialog, you can show as many message components and
+ // as many options as you want:
+
+ // Messages
+ Object[] message = new Object[4];
+ message[0] = COMPONENT_MESSAGE;
+ message[1] = new JTextField(COMPONENT_TEXT_FIELD);
+
+ JComboBox cb = new JComboBox<>();
+ cb.addItem(COMPONENT_CB1);
+ cb.addItem(COMPONENT_CB2);
+ cb.addItem(COMPONENT_CB3);
+ message[2] = cb;
+
+ message[3] = COMPONENT_MESSAGE_2;
+
+ // Options
+ String[] options = {
+ COMPONENT_OP1, COMPONENT_OP2, COMPONENT_OP3, COMPONENT_OP4, COMPONENT_OP5};
+ int result = JOptionPane.showOptionDialog(
+ OptionPaneDemo.this, // the parent that the dialog blocks
+ message, // the dialog message array
+ COMPONENT_TITLE, // the title of the dialog window
+ JOptionPane.DEFAULT_OPTION, // option type
+ JOptionPane.INFORMATION_MESSAGE, // message type
+ null, // optional icon, use null to use the default icon
+ options, // options string array, will be made into buttons
+ options[3] // option that should be made into a default button
+ );
+ switch (result) {
+ case 0: // yes
+ JOptionPane.showMessageDialog(OptionPaneDemo.this, COMPONENT_R1);
+ break;
+ case 1: // no
+ JOptionPane.showMessageDialog(OptionPaneDemo.this, COMPONENT_R2);
+ break;
+ case 2: // maybe
+ JOptionPane.showMessageDialog(OptionPaneDemo.this, COMPONENT_R3);
+ break;
+ case 3: // probably
+ JOptionPane.showMessageDialog(OptionPaneDemo.this, COMPONENT_R4);
+ break;
+ default:
+ break;
+ }
+
+ }
+ };
+ return createButton(a);
+ }
+
+ private JButton createButton(Action a) {
+ JButton b = new JButton() {
+ @Override
+ public Dimension getMaximumSize() {
+ int width = Short.MAX_VALUE;
+ int height = super.getMaximumSize().height;
+ return new Dimension(width, height);
+ }
+ };
+ // setting the following client property informs the button to show
+ // the action text as it's name. The default is to not show the
+ // action text.
+ b.putClientProperty("displayActionText", Boolean.TRUE);
+ b.setAction(a);
+ // b.setAlignmentX(JButton.CENTER_ALIGNMENT);
+ return b;
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/resources/OptionPaneDemo.properties b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/resources/OptionPaneDemo.properties
new file mode 100644
index 00000000000..e4cf7077992
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/resources/OptionPaneDemo.properties
@@ -0,0 +1,42 @@
+### OptionPane Demo ###
+
+OptionPaneDemo.accessible_description=The OptionPane Demo shows examples of using JOptionPane to generate different common option dialog boxes
+OptionPaneDemo.tooltip=JOptionPane Demo
+OptionPaneDemo.name=Option Pane Demo
+
+OptionPaneDemo.warningbutton=Show Warning Dialog
+OptionPaneDemo.componentbutton=Show Component Dialog
+OptionPaneDemo.inputbutton=Show Input Dialog
+OptionPaneDemo.confirmbutton=Show Confirmation Dialog
+OptionPaneDemo.messagebutton=Show Message Dialog
+
+OptionPaneDemo.warningtitle=Warning Dialog Example
+OptionPaneDemo.warningtext=
This is a test of the Emergency Broadcast System. This is only a test. The webmaster of your local intranet, in voluntary cooperation with the Federal and State authorities, have developed this system to keep you informed in the event of an emergency. If this had been an actual emergency, the signal you just heard would have been followed by official information, news or instructions. This concludes this test of the Emergency Broadcast System.
Developer Note: This dialog demo used HTML for text formatting.
+
+OptionPaneDemo.messagetext=Message in a Bottle (yeah)
+
+OptionPaneDemo.confirmquestion=Is the sun shining outside today?
+OptionPaneDemo.confirmyes=Well what are you doing playing on the computer? Get outside! Take a trip to the beach! Get a little sun!
+OptionPaneDemo.confirmno=Well good thing you're inside protected from the elements!
+
+OptionPaneDemo.inputquestion=What is your favorite movie?
+OptionPaneDemo.inputresponse=That was a pretty good movie!
+
+OptionPaneDemo.componenttitle=Component Dialog Example
+OptionPaneDemo.componentmessage=JOptionPane can contain as many components as you want, such as a text field:
+OptionPaneDemo.componenttextfield=or a combobox:
+OptionPaneDemo.component_cb1=item 1
+OptionPaneDemo.component_cb2=item 2
+OptionPaneDemo.component_cb3=item 3
+OptionPaneDemo.componentmessage2=JOptionPane can also show as many options as you want:
+OptionPaneDemo.component_op1=Yes
+OptionPaneDemo.component_op2=No
+OptionPaneDemo.component_op3=Maybe
+OptionPaneDemo.component_op4=Probably
+OptionPaneDemo.component_op5=Cancel
+
+OptionPaneDemo.component_r1=Upbeat and positive! I like that! Good choice.
+OptionPaneDemo.component_r2=Definitely not, I wouldn't do it either.
+OptionPaneDemo.component_r3= Mmmm.. yes, the situation is unclear at this time. Check back when you know for sure.
+OptionPaneDemo.component_r4=You know you want to. I think you should have gone for broke and pressed "Yes".
+
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/resources/images/OptionPaneDemo.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/resources/images/OptionPaneDemo.gif
new file mode 100644
index 00000000000..114e1ab7bd3
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/resources/images/OptionPaneDemo.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/resources/images/bottle.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/resources/images/bottle.gif
new file mode 100644
index 00000000000..e706c0c2fb9
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/resources/images/bottle.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/progressbar/ProgressBarDemo.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/progressbar/ProgressBarDemo.java
new file mode 100644
index 00000000000..e49b47926ea
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/progressbar/ProgressBarDemo.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.progressbar;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import javax.swing.*;
+import javax.swing.border.BevelBorder;
+import javax.swing.border.SoftBevelBorder;
+
+import com.sun.swingset3.DemoProperties;
+import com.sun.swingset3.demos.ResourceManager;
+
+/**
+ * JProgressBar Demo
+ *
+ * @version 1.12 11/17/05
+ * @author Jeff Dinkins # @author Peter Korn (accessibility support)
+ */
+@DemoProperties(
+ value = "ProgressBar Demo",
+ category = "Controls",
+ description = "Demonstrates the JProgressBar, a control which displays progress to the user",
+ sourceFiles = {
+ "com/sun/swingset3/demos/progressbar/ProgressBarDemo.java",
+ "com/sun/swingset3/demos/ResourceManager.java",
+ "com/sun/swingset3/demos/progressbar/resources/ProgressBarDemo.properties",
+ "com/sun/swingset3/demos/progressbar/resources/images/ProgressBarDemo.gif"
+ }
+)
+public class ProgressBarDemo extends JPanel {
+
+ private static final ResourceManager resourceManager = new ResourceManager(ProgressBarDemo.class);
+ public static final String STOP_BUTTON = resourceManager.getString("ProgressBarDemo.stop_button");
+ public static final String START_BUTTON = resourceManager.getString("ProgressBarDemo.start_button");
+ public static final String DEMO_TITLE = ProgressBarDemo.class.getAnnotation(DemoProperties.class).value();
+
+ /**
+ * main method allows us to run as a standalone demo.
+ *
+ * @param args
+ */
+ public static void main(String[] args) {
+ JFrame frame = new JFrame(DEMO_TITLE);
+
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.getContentPane().add(new ProgressBarDemo());
+ frame.setPreferredSize(new Dimension(800, 600));
+ frame.pack();
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+ }
+
+ /**
+ * ProgressBarDemo Constructor
+ */
+ public ProgressBarDemo() {
+ createProgressPanel();
+ }
+
+ private final javax.swing.Timer timer = new javax.swing.Timer(18, createTextLoadAction());
+ private Action loadAction;
+ private Action stopAction;
+ private JProgressBar progressBar;
+ private JTextArea progressTextArea;
+
+ private void createProgressPanel() {
+ setLayout(new BorderLayout());
+
+ JPanel textWrapper = new JPanel(new BorderLayout());
+ textWrapper.setBorder(new SoftBevelBorder(BevelBorder.LOWERED));
+ textWrapper.setAlignmentX(LEFT_ALIGNMENT);
+ progressTextArea = new MyTextArea();
+
+ progressTextArea.getAccessibleContext().setAccessibleName(
+ resourceManager.getString("ProgressBarDemo.accessible_text_area_name"));
+ progressTextArea.getAccessibleContext().setAccessibleDescription(
+ resourceManager.getString("ProgressBarDemo.accessible_text_area_description"));
+ textWrapper.add(new JScrollPane(progressTextArea), BorderLayout.CENTER);
+
+ add(textWrapper, BorderLayout.CENTER);
+
+ JPanel progressPanel = new JPanel();
+ add(progressPanel, BorderLayout.SOUTH);
+
+ progressBar = new JProgressBar(JProgressBar.HORIZONTAL, 0, text.length()) {
+ @Override
+ public Dimension getPreferredSize() {
+ return new Dimension(300, super.getPreferredSize().height);
+ }
+ };
+ progressBar.getAccessibleContext().setAccessibleName(
+ resourceManager.getString("ProgressBarDemo.accessible_text_loading_progress"));
+
+ progressPanel.add(progressBar);
+ progressPanel.add(createLoadButton());
+ progressPanel.add(createStopButton());
+ }
+
+ private JButton createLoadButton() {
+ loadAction = new AbstractAction(START_BUTTON) {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ loadAction.setEnabled(false);
+ stopAction.setEnabled(true);
+ if (progressBar.getValue() == progressBar.getMaximum()) {
+ progressBar.setValue(0);
+ textLocation = 0;
+ progressTextArea.setText("");
+ }
+ timer.start();
+ }
+ };
+ return createButton(loadAction);
+ }
+
+ private JButton createStopButton() {
+ stopAction = new AbstractAction(STOP_BUTTON) {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ timer.stop();
+ loadAction.setEnabled(true);
+ stopAction.setEnabled(false);
+ }
+ };
+ return createButton(stopAction);
+ }
+
+ private static JButton createButton(Action a) {
+ JButton b = new JButton();
+ // setting the following client property informs the button to show
+ // the action text as it's name. The default is to not show the
+ // action text.
+ b.putClientProperty("displayActionText", Boolean.TRUE);
+ b.setAction(a);
+ return b;
+ }
+
+ private int textLocation = 0;
+
+ private final String text = resourceManager.getString("ProgressBarDemo.text");
+
+ private Action createTextLoadAction() {
+ return new AbstractAction("text load action") {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (progressBar.getValue() < progressBar.getMaximum()) {
+ progressBar.setValue(progressBar.getValue() + 1);
+ progressTextArea.append(text.substring(textLocation, textLocation + 1));
+ textLocation++;
+ } else {
+ timer.stop();
+ loadAction.setEnabled(true);
+ stopAction.setEnabled(false);
+ }
+ }
+ };
+ }
+
+ private static class MyTextArea extends JTextArea {
+
+ private MyTextArea() {
+ super(null, 0, 0);
+ setEditable(false);
+ setText("");
+ }
+
+ @Override
+ public float getAlignmentX() {
+ return LEFT_ALIGNMENT;
+ }
+
+ @Override
+ public float getAlignmentY() {
+ return TOP_ALIGNMENT;
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/progressbar/resources/ProgressBarDemo.properties b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/progressbar/resources/ProgressBarDemo.properties
new file mode 100644
index 00000000000..7660e0b141e
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/progressbar/resources/ProgressBarDemo.properties
@@ -0,0 +1,35 @@
+### ProgressBar Demo ###
+
+ProgressBarDemo.accessible_description=This demo shows an example of using the JProgressBar component.
+ProgressBarDemo.tooltip=JProgressBar demo
+ProgressBarDemo.name=ProgressBar Demo
+ProgressBarDemo.start_button=Start Loading Text
+ProgressBarDemo.stop_button=Stop Loading Text
+ProgressBarDemo.accessible_text_loading_progress=Text loading progress
+ProgressBarDemo.accessible_text_area_name=Text progressively being loaded in
+
+ProgressBarDemo.accessible_text_area_description=This JTextArea is being filled with text from a buffer progressively a character at a time while the progress bar a the bottom of the window shows the loading progress
+
+ProgressBarDemo.text=\
+The saying goes: if an infinite number of monkeys typed on an infinite number of typewriters, eventually \n\
+all the great works of mankind would emerge. Now, with today's high speed computers, we can finally test \n\
+this theory... \n\n\
+\tLzskd jfy 92y;ho4 th;qlh sd 6yty;q2 hnlj 8sdf. Djfy 92y;ho4, th;qxhz d7yty; \n\
+\tQ0hnlj 23&^ (# ljask djf y92y; fy92y; Sd6y ty;q2h nl jk la gfa harvin garvel\n\
+\tlasdfsd a83sl la8z ks8l 92y;ho4 th;qlh sd 6yty;q2 hnlj 8sdf. Djfy 92y;ho4,\n\
+\tth;qxhz d7yty; Q0hnlj 23&^ nknod mrs88 jsd79lfm#%$JLaoz6df lso7dj f2 jfls\n\
+\t67d9ol1@2fou99s 1lkj2 @l.k1 2; a89o7aljf 1l3i7ou8 d8l3 lqwerty0092 #1!\n\
+\tja9o do8lkjj139rojsd9**!l6*hd # ljasd78 l2awkjad78 3ol7asljf 3 ldif & l.js\n\
+\tLl ls ewan la8uj 23lll7u 8l 3h hhxx8 8d lsd fixx 891lkjno99sl d8l@@@!!8#8\n\
+\tdfoil jarooda mklaoorj nowai the smisthliylka jkdlfjiw ladajadra lthhheeejfjl\n\
+\tdkddooolda bub mirznod of the koojgaf!! But 2 be or not to be... that is the\n\
+\tquestion. Then when shall we three meet again In thunder, lightning, or in\n\
+\train? When the hurlyburly's done, When the battle's lost and won. That will\n\
+\tbe ere the set of sun. Where the place? Upon the heath. There to meet with\n\
+\tMacbeth. But hath forth not to want..... a banana, or to be.... a banana.\n\
+\tBanana, I knew him banana. Banana banana. Banana banana banana banana.\n\
+\n\
+\n\
+\n\
+\n\
+Well... hmm.... it seemed like a good idea...
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/progressbar/resources/images/ProgressBarDemo.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/progressbar/resources/images/ProgressBarDemo.gif
new file mode 100644
index 00000000000..1aa706d257c
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/progressbar/resources/images/ProgressBarDemo.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/ScrollPaneDemo.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/ScrollPaneDemo.java
new file mode 100644
index 00000000000..5a492ea53fd
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/ScrollPaneDemo.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.scrollpane;
+
+import java.awt.*;
+import javax.swing.*;
+
+import com.sun.swingset3.DemoProperties;
+import com.sun.swingset3.demos.ResourceManager;
+
+/**
+ * Scroll Pane Demo
+ *
+ * @version 1.9 11/17/05
+ * @author Jeff Dinkins
+ */
+@DemoProperties(
+ value = "JScrollPane Demo",
+ category = "Containers",
+ description = "Demonstrates JScrollPane, a container for scrolling contents within a view port",
+ sourceFiles = {
+ "com/sun/swingset3/demos/scrollpane/ScrollPaneDemo.java",
+ "com/sun/swingset3/demos/ResourceManager.java",
+ "com/sun/swingset3/demos/scrollpane/resources/ScrollPaneDemo.properties",
+ "com/sun/swingset3/demos/scrollpane/resources/images/colheader.jpg",
+ "com/sun/swingset3/demos/scrollpane/resources/images/COPYRIGHT",
+ "com/sun/swingset3/demos/scrollpane/resources/images/crayons.jpg",
+ "com/sun/swingset3/demos/scrollpane/resources/images/lowerleft.jpg",
+ "com/sun/swingset3/demos/scrollpane/resources/images/rowheader.jpg",
+ "com/sun/swingset3/demos/scrollpane/resources/images/ScrollPaneDemo.gif",
+ "com/sun/swingset3/demos/scrollpane/resources/images/upperleft.jpg",
+ "com/sun/swingset3/demos/scrollpane/resources/images/upperright.jpg"}
+)
+public class ScrollPaneDemo extends JPanel {
+
+ private final ResourceManager resourceManager = new ResourceManager(this.getClass());
+ public static final String DEMO_TITLE = ScrollPaneDemo.class.getAnnotation(DemoProperties.class).value();
+
+ /**
+ * main method allows us to run as a standalone demo.
+ *
+ * @param args
+ */
+ public static void main(String[] args) {
+ JFrame frame = new JFrame(DEMO_TITLE);
+
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.getContentPane().add(new ScrollPaneDemo());
+ frame.setPreferredSize(new Dimension(800, 600));
+ frame.pack();
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+ }
+
+ /**
+ * ScrollPaneDemo Constructor
+ */
+ public ScrollPaneDemo() {
+ setLayout(new BorderLayout());
+
+ ImageIcon crayons = resourceManager.createImageIcon("crayons.jpg",
+ resourceManager.getString("ScrollPaneDemo.crayons"));
+ add(new ImageScroller(crayons), BorderLayout.CENTER);
+ }
+
+ /**
+ * ScrollPane class that demonstrates how to set the various column and row
+ * headers and corners.
+ */
+ private class ImageScroller extends JScrollPane {
+
+ public ImageScroller(Icon icon) {
+ super();
+
+ // Panel to hold the icon image
+ JPanel p = new JPanel(new BorderLayout());
+ p.add(new JLabel(icon), BorderLayout.CENTER);
+ getViewport().add(p);
+
+ // Create and add a column header to the scrollpane
+ JLabel colHeader = new JLabel(
+ resourceManager.createImageIcon("colheader.jpg", resourceManager.getString("ScrollPaneDemo.colheader")));
+ setColumnHeaderView(colHeader);
+
+ // Create and add a row header to the scrollpane
+ JLabel rowHeaderLabel = new JLabel(
+ resourceManager.createImageIcon("rowheader.jpg", resourceManager.getString("ScrollPaneDemo.rowheader")));
+ setRowHeaderView(rowHeaderLabel);
+
+ // Create and add the upper left corner
+ JLabel cornerUL = new JLabel(
+ resourceManager.createImageIcon("upperleft.jpg", resourceManager.getString("ScrollPaneDemo.upperleft")));
+ setCorner(UPPER_LEFT_CORNER, cornerUL);
+
+ // Create and add the upper right corner
+ JLabel cornerUR = new JLabel(
+ resourceManager.createImageIcon("upperright.jpg", resourceManager.getString("ScrollPaneDemo.upperright")));
+ setCorner(UPPER_RIGHT_CORNER, cornerUR);
+
+ // Create and add the lower left corner
+ JLabel cornerLL = new JLabel(
+ resourceManager.createImageIcon("lowerleft.jpg", resourceManager.getString("ScrollPaneDemo.lowerleft")));
+ setCorner(LOWER_LEFT_CORNER, cornerLL);
+
+ JScrollBar vsb = getVerticalScrollBar();
+ JScrollBar hsb = getHorizontalScrollBar();
+
+ vsb.setValue(icon.getIconHeight());
+ hsb.setValue(icon.getIconWidth() / 10);
+ }
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/ScrollPaneDemo.properties b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/ScrollPaneDemo.properties
new file mode 100644
index 00000000000..4d33fb50162
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/ScrollPaneDemo.properties
@@ -0,0 +1,11 @@
+### ScrollPane Demo ###
+
+ScrollPaneDemo.accessible_description=JScrollPane Demo
+ScrollPaneDemo.name=Scroll Pane Demo
+ScrollPaneDemo.tooltip=JScrollPane demo
+ScrollPaneDemo.crayons=Lots of Crayons
+ScrollPaneDemo.colheader=Column Header
+ScrollPaneDemo.rowheader=Row Header
+ScrollPaneDemo.upperleft=Upper Left Corner
+ScrollPaneDemo.upperright=Upper Right Column Header Corner
+ScrollPaneDemo.lowerleft=Lower Left Row Header Corner
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/COPYRIGHT b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/COPYRIGHT
new file mode 100644
index 00000000000..a7bdd30d377
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/COPYRIGHT
@@ -0,0 +1,2 @@
+
+ All images in this directory are copyright 1995 by Jeff Dinkins.
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/ScrollPaneDemo.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/ScrollPaneDemo.gif
new file mode 100644
index 00000000000..95fcc12da47
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/ScrollPaneDemo.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/colheader.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/colheader.jpg
new file mode 100644
index 00000000000..774deed99a9
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/colheader.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/crayons.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/crayons.jpg
new file mode 100644
index 00000000000..922171db310
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/crayons.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/lowerleft.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/lowerleft.jpg
new file mode 100644
index 00000000000..b9e60474b99
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/lowerleft.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/rowheader.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/rowheader.jpg
new file mode 100644
index 00000000000..c791147c9f2
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/rowheader.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/upperleft.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/upperleft.jpg
new file mode 100644
index 00000000000..69e2a00c6f9
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/upperleft.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/upperright.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/upperright.jpg
new file mode 100644
index 00000000000..a40a1284923
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/resources/images/upperright.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/JMandelbrot.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/JMandelbrot.java
new file mode 100644
index 00000000000..c777ec80da9
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/JMandelbrot.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.spinner;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.geom.Point2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.util.List;
+
+import com.sun.swingset3.demos.ResourceManager;
+
+/**
+ * @author Mikhail Lapshin
+ */
+public class JMandelbrot extends JComponent {
+
+ private static final double EPSILON = 1E-16;
+ private static final int MIN_WIDTH = 50;
+ private static final int MIN_HEIGHT = 50;
+ private static final double ZOOM_RATE = 3;
+ private static final int NUM_OF_THREADS = 4;
+
+ private Point2D center;
+ public static final String CENTER_PROPERTY_NAME = "center";
+
+ private int maxIteration = 300;
+ public static final String MAX_ITERATION_PROPERTY_NAME = "maxIteration";
+
+ private Palette palette;
+ public static final String PALETTE_PROPERTY_NAME = "palette";
+
+ private BufferedImage buffer;
+ private final MandelbrotCalculator[] calculators
+ = new MandelbrotCalculator[NUM_OF_THREADS];
+
+ private double xLowLimit = -2;
+ private double xHighLimit = 2;
+ private double yLowLimit = -2;
+ private double yHighLimit = 2;
+ private double xScale = 100;
+ private double yScale = 100;
+ private int oldComponentWidth = (int) (xScale * (xHighLimit - xLowLimit));
+ private int oldComponentHeight = (int) (yScale * (yHighLimit - yLowLimit));
+
+ public JMandelbrot(int width, int height, Palette palette,
+ ResourceManager resourceManager) {
+ setPreferredSize(new Dimension(width, height));
+ setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
+ calcConstants(width, height);
+ setPalette(palette);
+ setToolTipText(resourceManager.getString("SpinnerDemo.toolTip"));
+ installListeners();
+ }
+
+ private void calcConstants() {
+ calcConstants(getWidth(), getHeight());
+ }
+
+ private void calcConstants(int width, int height) {
+ if ((width >= MIN_WIDTH) && (height >= MIN_HEIGHT)) {
+ double oldIntervalWidth = xHighLimit - xLowLimit;
+ double oldIntervalHeight = yHighLimit - yLowLimit;
+ double newIntervalWidth
+ = width * oldIntervalWidth / oldComponentWidth;
+ double newIntervalHeight
+ = height * oldIntervalHeight / oldComponentHeight;
+ double xDiff = newIntervalWidth - oldIntervalWidth;
+ double yDiff = newIntervalHeight - oldIntervalHeight;
+ xLowLimit -= xDiff / 2;
+ xHighLimit += xDiff / 2;
+ yLowLimit -= yDiff / 2;
+ yHighLimit += yDiff / 2;
+ buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ oldComponentWidth = width;
+ oldComponentHeight = height;
+ setCenter(calcCenter());
+ }
+ }
+
+ private void installListeners() {
+ addMouseListener(new MouseAdapter() {
+ @Override
+ public void mousePressed(MouseEvent e) {
+ int xCoord = e.getX();
+ int yCoord = e.getY();
+ double intervalWidth = xHighLimit - xLowLimit;
+ double intervalHeight = yHighLimit - yLowLimit;
+ double x = intervalWidth * xCoord / getWidth() + xLowLimit;
+ double y = intervalHeight * yCoord / getHeight() + yLowLimit;
+
+ double newIntervalWidth;
+ double newIntervalHeight;
+ if (e.getButton() == MouseEvent.BUTTON1) {
+ boolean limitReached = false;
+ newIntervalWidth = intervalWidth / ZOOM_RATE;
+ if ((newIntervalWidth / getWidth()) < EPSILON) {
+ newIntervalWidth = intervalWidth;
+ limitReached = true;
+ }
+ newIntervalHeight = intervalHeight / ZOOM_RATE;
+ if ((newIntervalHeight / getHeight()) < EPSILON) {
+ newIntervalHeight = intervalHeight;
+ limitReached = true;
+ }
+ if (!limitReached) {
+ xLowLimit = x - (x - xLowLimit) / ZOOM_RATE;
+ yLowLimit = y - (y - yLowLimit) / ZOOM_RATE;
+ }
+ } else {
+ newIntervalWidth = intervalWidth * ZOOM_RATE;
+ newIntervalHeight = intervalHeight * ZOOM_RATE;
+ xLowLimit = x - (x - xLowLimit) * ZOOM_RATE;
+ yLowLimit = y - (y - yLowLimit) * ZOOM_RATE;
+ }
+
+ xHighLimit = xLowLimit + newIntervalWidth;
+ yHighLimit = yLowLimit + newIntervalHeight;
+
+ setCenter(calcCenter());
+
+ xScale = getWidth() / newIntervalWidth;
+ yScale = getHeight() / newIntervalHeight;
+
+ calculatePicture();
+ }
+ });
+
+ addComponentListener(new ComponentListener() {
+ @Override
+ public void componentResized(ComponentEvent e) {
+ calcConstants();
+ calculatePicture();
+ repaint();
+ }
+
+ @Override
+ public void componentMoved(ComponentEvent e) {
+ }
+
+ @Override
+ public void componentShown(ComponentEvent e) {
+ }
+
+ @Override
+ public void componentHidden(ComponentEvent e) {
+ }
+ });
+ }
+
+ //Use SwingWorker to asynchronously calculate parts of the picture
+ public void calculatePicture() {
+ int yStep = getHeight() / NUM_OF_THREADS;
+ int yStart = 0;
+ for (int i = 0; i < calculators.length; i++) {
+ if ((calculators[i] != null) && !calculators[i].isDone()) {
+ calculators[i].cancel(true);
+ }
+ int yEnd = i == calculators.length - 1 ? getHeight() : yStart + yStep;
+ calculators[i] = new MandelbrotCalculator(yStart, yEnd);
+ calculators[i].execute();
+ yStart = yEnd;
+ }
+ }
+ //
+
+ private Point2D calcCenter() {
+ return new Point2D.Double(xLowLimit + (xHighLimit - xLowLimit) / 2,
+ yLowLimit + (yHighLimit - yLowLimit) / 2);
+ }
+
+ @Override
+ protected void paintComponent(Graphics g) {
+ super.paintComponent(g);
+ g.drawImage(buffer, 0, 0, null);
+ }
+
+ //Use SwingWorker to asynchronously calculate parts of the picture
+ private class MandelbrotCalculator extends SwingWorker
+
+ // Getters and Setters
+ public int getMaxIteration() {
+ return maxIteration;
+ }
+
+ public void setMaxIteration(int maxIteration) {
+ int oldValue = this.maxIteration;
+ this.maxIteration = maxIteration;
+ firePropertyChange(MAX_ITERATION_PROPERTY_NAME, oldValue, maxIteration);
+ palette.setSize(maxIteration);
+ }
+
+ public double getXHighLimit() {
+ return xHighLimit;
+ }
+
+ public double getXLowLimit() {
+ return xLowLimit;
+ }
+
+ public double getYLowLimit() {
+ return yLowLimit;
+ }
+
+ public double getYHighLimit() {
+ return yHighLimit;
+ }
+
+ public Point2D getCenter() {
+ return center;
+ }
+
+ public void setCenter(Point2D coords) {
+ Point2D oldValue = this.center;
+ this.center = coords;
+
+ double width = xHighLimit - xLowLimit;
+ double height = yHighLimit - yLowLimit;
+
+ xLowLimit = coords.getX() - width / 2;
+ xHighLimit = xLowLimit + width;
+ yLowLimit = coords.getY() - height / 2;
+ yHighLimit = yLowLimit + height;
+
+ firePropertyChange(CENTER_PROPERTY_NAME, oldValue, coords);
+ }
+
+ public Palette getPalette() {
+ return palette;
+ }
+
+ public void setPalette(Palette palette) {
+ Palette oldValue = this.palette;
+ palette.setSize(maxIteration);
+ this.palette = palette;
+ firePropertyChange(PALETTE_PROPERTY_NAME, oldValue, palette);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/JPaletteShower.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/JPaletteShower.java
new file mode 100644
index 00000000000..fc305da03b0
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/JPaletteShower.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.spinner;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author Mikhail Lapshin
+ */
+public class JPaletteShower extends JComponent {
+
+ private Palette palette;
+
+ public JPaletteShower(Palette palette, int width, int height) {
+ setPreferredSize(new Dimension(width, height));
+ setMinimumSize(new Dimension(width, height));
+ this.palette = palette;
+ }
+
+ @Override
+ protected void paintComponent(Graphics g) {
+ super.paintComponent(g);
+ int w = getSize().width;
+ int h = getSize().height;
+ int maxIndex = palette.getSize() - 1;
+ double rate = (double) maxIndex / w;
+ for (int x = 0; x < w; x++) {
+ g.setColor(palette.getColor((int) (x * rate)));
+ g.fillRect(x, 0, 1, h);
+ }
+ }
+
+ public Palette getPalette() {
+ return palette;
+ }
+
+ public void setPalette(Palette palette) {
+ this.palette = palette;
+ repaint();
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/JSpinnerPanel.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/JSpinnerPanel.java
new file mode 100644
index 00000000000..b3cfb0d3d95
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/JSpinnerPanel.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.spinner;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * Arranges labels and spinners into two vertical columns. Labels at the left,
+ * spinners at the right.
+ *
+ * @author Mikhail Lapshin
+ */
+//Helpful component for layout of labeled spinners
+public class JSpinnerPanel extends JPanel {
+
+ private final JPanel labelPanel;
+ private final JPanel spinnerPanel;
+
+ public JSpinnerPanel() {
+ setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
+
+ labelPanel = new JPanel();
+ labelPanel.setLayout(new GridLayout(0, 1));
+
+ spinnerPanel = new JPanel();
+ spinnerPanel.setLayout(new GridLayout(0, 1));
+
+ add(labelPanel);
+ add(Box.createHorizontalStrut(5));
+ add(spinnerPanel);
+ }
+
+ public void addSpinner(String labelText, JSpinner spinner) {
+ JLabel label = new JLabel(labelText);
+ label.setHorizontalAlignment(SwingConstants.TRAILING);
+ labelPanel.add(label);
+
+ JPanel flowPanel = new JPanel();
+ flowPanel.setLayout(new FlowLayout(FlowLayout.LEADING, 5, 1));
+ flowPanel.add(spinner);
+ spinnerPanel.add(flowPanel);
+ }
+}
+//
+
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/MandelbrotControl.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/MandelbrotControl.java
new file mode 100644
index 00000000000..9773febbc1c
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/MandelbrotControl.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.spinner;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.geom.Point2D;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.ChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeEvent;
+
+import com.sun.swingset3.demos.ResourceManager;
+
+/**
+ * @author Mikhail Lapshin
+ */
+public class MandelbrotControl extends JPanel {
+
+ private final JMandelbrot mandelbrot;
+ private JSpinner iterSpinner;
+ private CoordSpinner xSpinner;
+ private CoordSpinner ySpinner;
+ private static final double COORD_SPINNER_STEP = 0.1d; // part of width or height
+ private final ResourceManager resourceManager;
+
+ public MandelbrotControl(JMandelbrot mandelbrot,
+ ResourceManager resourceManager) {
+ this.mandelbrot = mandelbrot;
+ this.resourceManager = resourceManager;
+ createUI();
+ installListeners();
+ }
+
+ private void createUI() {
+ setLayout(new FlowLayout(FlowLayout.LEADING, 5, 0));
+ setBorder(BorderFactory.createTitledBorder(
+ resourceManager.getString("SpinnerDemo.fractalControls")));
+ JSpinnerPanel spinnerPanel = new JSpinnerPanel();
+
+ //Create spinner
+ iterSpinner = new JSpinner(new SpinnerNumberModel(
+ mandelbrot.getMaxIteration(), 10, 100000, 50));
+ //
+ //Add change listener using anonymus inner class
+ iterSpinner.addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ mandelbrot.setMaxIteration((Integer) iterSpinner.getValue());
+ mandelbrot.calculatePicture();
+ }
+ });
+ //
+ spinnerPanel.addSpinner(
+ resourceManager.getString("SpinnerDemo.iterations"), iterSpinner);
+
+ //Create spinner
+ final double xValue = mandelbrot.getCenter().getX();
+ double width = mandelbrot.getXHighLimit() - mandelbrot.getXLowLimit();
+ xSpinner = new CoordSpinner(xValue, width * COORD_SPINNER_STEP);
+ //
+ //Add change listener using anonymus inner class
+ xSpinner.addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ Double newX = (Double) xSpinner.getValue();
+ mandelbrot.setCenter(new Point2D.Double(
+ newX, mandelbrot.getCenter().getY()));
+ mandelbrot.calculatePicture();
+ }
+ });
+ //
+ spinnerPanel.addSpinner(
+ resourceManager.getString("SpinnerDemo.x"), xSpinner);
+
+ //Create spinner
+ final double yValue = mandelbrot.getCenter().getY();
+ double height = mandelbrot.getYHighLimit() - mandelbrot.getYLowLimit();
+ ySpinner = new CoordSpinner(yValue, height * COORD_SPINNER_STEP);
+ //
+ //Add change listener using anonymus inner class
+ ySpinner.addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ Double newY = (Double) ySpinner.getValue();
+ mandelbrot.setCenter(new Point2D.Double(
+ mandelbrot.getCenter().getX(), newY));
+ mandelbrot.calculatePicture();
+ }
+ });
+ //
+ spinnerPanel.addSpinner(
+ resourceManager.getString("SpinnerDemo.y"), ySpinner);
+
+ add(spinnerPanel);
+ }
+
+ private void installListeners() {
+ mandelbrot.addPropertyChangeListener(
+ JMandelbrot.CENTER_PROPERTY_NAME,
+ new PropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ double width = mandelbrot.getXHighLimit()
+ - mandelbrot.getXLowLimit();
+ double newX = mandelbrot.getCenter().getX();
+ xSpinner.updateModel(newX, width * COORD_SPINNER_STEP);
+ double height = mandelbrot.getYHighLimit()
+ - mandelbrot.getYLowLimit();
+ double newY = mandelbrot.getCenter().getY();
+ ySpinner.updateModel(newY, height * COORD_SPINNER_STEP);
+ }
+ }
+ );
+ }
+
+ //Customized spinner class
+ // It uses special format for NumberEditor and has constant preferred width
+ private static class CoordSpinner extends JSpinner {
+
+ @Override
+ protected JComponent createEditor(SpinnerModel model) {
+ return new NumberEditor(this, "#.####################");
+ }
+
+ public CoordSpinner(double value, double stepSize) {
+ super(new SpinnerNumberModel(value, -100, 100, stepSize));
+ }
+
+ //A useful shortcut method
+ public void updateModel(double value, double stepSize) {
+ SpinnerNumberModel model = (SpinnerNumberModel) getModel();
+ model.setValue(value);
+ model.setStepSize(stepSize);
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ Dimension prefSize = super.getPreferredSize();
+ prefSize.setSize(180, prefSize.getHeight());
+ return prefSize;
+ }
+ }
+ //
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/Palette.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/Palette.java
new file mode 100644
index 00000000000..6e7ac6950fa
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/Palette.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.spinner;
+
+/**
+ * @author Mikhail Lapshin
+ */
+import java.awt.*;
+
+public class Palette {
+
+ private final int minColor;
+ private final int colorRange;
+ private Color[] colors;
+ private int[] rgbColors;
+ private final int rSteps;
+ private final int gSteps;
+ private final int bSteps;
+ private int totalRange;
+ private int rRange;
+ private int gRange;
+ private int bRange;
+ private final double rStart;
+ private final double gStart;
+ private final double bStart;
+
+ public Palette(int totalRange, int minColor, int maxColor, double rStart,
+ double gStart, double bStart, int rSteps, int gSteps, int bSteps) {
+ this.minColor = minColor;
+ this.colorRange = maxColor - minColor;
+ this.rStart = rStart;
+ this.gStart = gStart;
+ this.bStart = bStart;
+ this.rSteps = rSteps;
+ this.gSteps = gSteps;
+ this.bSteps = bSteps;
+ setSize(totalRange);
+ }
+
+ public void setSize(int newSize) {
+ totalRange = newSize;
+ rRange = totalRange / rSteps;
+ gRange = totalRange / gSteps;
+ bRange = totalRange / bSteps;
+ fillColorTable();
+ }
+
+ private void fillColorTable() {
+ colors = new Color[totalRange];
+ rgbColors = new int[totalRange];
+ for (int i = 0; i < totalRange; i++) {
+ double cosR = Math.cos(i * 2 * Math.PI / rRange + rStart);
+ double cosG = Math.cos(i * 2 * Math.PI / gRange + gStart);
+ double cosB = Math.cos(i * 2 * Math.PI / bRange + bStart);
+ Color color = new Color(
+ (int) ((cosR * colorRange) + colorRange) / 2 + minColor,
+ (int) ((cosG * colorRange) + colorRange) / 2 + minColor,
+ (int) ((cosB * colorRange) + colorRange) / 2 + minColor);
+ colors[i] = color;
+ rgbColors[i] = color.getRGB();
+ }
+ }
+
+ public Color getColor(int index) {
+ return colors[index];
+ }
+
+ public int getRgbColor(int index) {
+ return rgbColors[index];
+ }
+
+ public int getSize() {
+ return totalRange;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/PaletteChooser.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/PaletteChooser.java
new file mode 100644
index 00000000000..0a839dbd672
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/PaletteChooser.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.spinner;
+
+import javax.swing.*;
+import java.awt.*;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.ChangeEvent;
+
+import com.sun.swingset3.demos.ResourceManager;
+
+/**
+ * @author Mikhail Lapshin
+ */
+public class PaletteChooser extends JPanel {
+
+ private static final int MIN_COLOR = 50;
+ private static final int MAX_COLOR = 255;
+ private static final int R_STEPS = 5;
+ private static final int G_STEPS = 5;
+ private static final int B_STEPS = 5;
+ private static final int R_ANGLE = 270;
+ private static final int G_ANGLE = 90;
+ private static final int B_ANGLE = 0;
+
+ public static final String PALETTE_PROPERTY_NAME = "palette";
+
+ private final ResourceManager resourceManager;
+ private Palette palette;
+ private final JPaletteShower shower;
+ private final ChangeListener changeListener;
+
+ private JSpinner rsSpinner;
+ private JSpinner gsSpinner;
+ private JSpinner bsSpinner;
+ private JSpinner raSpinner;
+ private JSpinner gaSpinner;
+ private JSpinner baSpinner;
+
+ public PaletteChooser(ResourceManager resourceManager) {
+ this.resourceManager = resourceManager;
+ palette = new Palette(MAX_COLOR - MIN_COLOR, MIN_COLOR, MAX_COLOR,
+ Math.toRadians(R_ANGLE), Math.toRadians(G_ANGLE),
+ Math.toRadians(B_ANGLE), R_STEPS, G_STEPS, B_STEPS);
+ shower = new JPaletteShower(palette, 250, 25);
+
+ //Use single change listener for several spinners
+ changeListener = new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ setPalette(createPalette());
+ shower.setPalette(palette);
+ repaint();
+ }
+ };
+ //
+
+ setBorder(BorderFactory.createTitledBorder(
+ resourceManager.getString("SpinnerDemo.colorPalette")));
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ add(shower);
+ add(createControlPanel());
+ }
+
+ private double toRadians(JSpinner spinner) {
+ return Math.toRadians(getIntValue(spinner));
+ }
+
+ private Palette createPalette() {
+ return new Palette(getWidth(), MIN_COLOR, MAX_COLOR,
+ toRadians(raSpinner), toRadians(gaSpinner),
+ toRadians(baSpinner), getIntValue(rsSpinner),
+ getIntValue(gsSpinner), getIntValue(bsSpinner));
+ }
+
+ private static int getIntValue(JSpinner spinner) {
+ return (Integer) spinner.getValue();
+ }
+
+ private JPanel createControlPanel() {
+ JPanel controlPanel = new JPanel();
+ controlPanel.setLayout(new GridLayout(1, 2));
+ controlPanel.add(createStepPanel());
+ controlPanel.add(createStartAnglePanel());
+ return controlPanel;
+ }
+
+ private JPanel createStartAnglePanel() {
+ JSpinnerPanel startAnglePanel = new JSpinnerPanel();
+ startAnglePanel.setBorder(BorderFactory.createTitledBorder(
+ resourceManager.getString("SpinnerDemo.startAngles")));
+
+ raSpinner = createAngleSpinner(R_ANGLE, "SpinnerDemo.r", startAnglePanel);
+ gaSpinner = createAngleSpinner(G_ANGLE, "SpinnerDemo.g", startAnglePanel);
+ baSpinner = createAngleSpinner(B_ANGLE, "SpinnerDemo.b", startAnglePanel);
+
+ return startAnglePanel;
+ }
+
+ private JPanel createStepPanel() {
+ JSpinnerPanel stepPanel = new JSpinnerPanel();
+ stepPanel.setBorder(BorderFactory.createTitledBorder(
+ resourceManager.getString("SpinnerDemo.steps")));
+
+ rsSpinner = createStepSpinner(R_STEPS, "SpinnerDemo.r", stepPanel);
+ gsSpinner = createStepSpinner(G_STEPS, "SpinnerDemo.g", stepPanel);
+ bsSpinner = createStepSpinner(B_STEPS, "SpinnerDemo.b", stepPanel);
+
+ return stepPanel;
+ }
+
+ private JSpinner createAngleSpinner(int startAngle, String resourceName,
+ JSpinnerPanel parent) {
+ SpinnerModel model = new SpinnerNumberModel(startAngle, 0, 360, 10);
+ return createSpinner(model, resourceName, parent);
+ }
+
+ private JSpinner createStepSpinner(int startSteps, String resourceName,
+ JSpinnerPanel parent) {
+ SpinnerModel model = new SpinnerNumberModel(startSteps, 1, 1000, 1);
+ return createSpinner(model, resourceName, parent);
+ }
+
+ private JSpinner createSpinner(SpinnerModel model, String resourceName,
+ JSpinnerPanel parent) {
+
+ //Create spinner
+ JSpinner spinner = new JSpinner(model);
+ //
+ //Use single change listener for several spinners
+ spinner.addChangeListener(changeListener);
+ //
+ parent.addSpinner(resourceManager.getString(resourceName), spinner);
+ return spinner;
+ }
+
+ public Palette getPalette() {
+ return palette;
+ }
+
+ private void setPalette(Palette palette) {
+ Palette oldValue = this.palette;
+ this.palette = palette;
+ firePropertyChange(PALETTE_PROPERTY_NAME, oldValue, palette);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/SpinnerDemo.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/SpinnerDemo.java
new file mode 100644
index 00000000000..0694a843341
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/SpinnerDemo.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.spinner;
+
+import javax.swing.*;
+import java.awt.*;
+import java.beans.PropertyChangeEvent;
+
+import com.sun.swingset3.DemoProperties;
+import com.sun.swingset3.demos.ResourceManager;
+
+/**
+ * Demonstrates JSpinner and SwingWorker
+ *
+ * @author Mikhail Lapshin
+ */
+@DemoProperties(
+ value = "Spinner Demo",
+ category = "Controls",
+ description = "Demonstrates JSpinner and SwingWorker",
+ sourceFiles = {
+ "com/sun/swingset3/demos/spinner/SpinnerDemo.java",
+ "com/sun/swingset3/demos/spinner/JMandelbrot.java",
+ "com/sun/swingset3/demos/spinner/JPaletteShower.java",
+ "com/sun/swingset3/demos/spinner/JSpinnerPanel.java",
+ "com/sun/swingset3/demos/spinner/MandelbrotControl.java",
+ "com/sun/swingset3/demos/spinner/Palette.java",
+ "com/sun/swingset3/demos/spinner/PaletteChooser.java",
+ "com/sun/swingset3/demos/ResourceManager.java",
+ "com/sun/swingset3/demos/spinner/resources/SpinnerDemo.properties",
+ "com/sun/swingset3/demos/spinner/resources/images/SpinnerDemo.gif"
+ }
+)
+public class SpinnerDemo extends JPanel {
+
+ private final ResourceManager resourceManager = new ResourceManager(getClass());
+ public static final String DEMO_TITLE = SpinnerDemo.class.getAnnotation(DemoProperties.class).value();
+
+ public static void main(String[] args) {
+ JFrame frame = new JFrame(DEMO_TITLE);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.getContentPane().add(new SpinnerDemo());
+ frame.setPreferredSize(new Dimension(800, 600));
+ frame.pack();
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+ }
+
+ public SpinnerDemo() {
+ setLayout(new BorderLayout());
+
+ // Create main components
+ PaletteChooser chooser
+ = new PaletteChooser(resourceManager);
+ final JMandelbrot mandelbrot
+ = new JMandelbrot(400, 400, chooser.getPalette(), resourceManager);
+ MandelbrotControl mandelbrotControl
+ = new MandelbrotControl(mandelbrot, resourceManager);
+
+ // Connect palette chooser and mandelbrot component
+ chooser.addPropertyChangeListener(PaletteChooser.PALETTE_PROPERTY_NAME,
+ (PropertyChangeEvent evt) -> {
+ mandelbrot.setPalette((Palette) evt.getNewValue());
+ mandelbrot.calculatePicture();
+ });
+
+ // Layout components
+ add(mandelbrot);
+
+ JPanel controlPanel = new JPanel();
+ controlPanel.setLayout(new BorderLayout());
+ controlPanel.add(chooser, BorderLayout.NORTH);
+
+ JPanel mandelbrotControlPanel = new JPanel();
+ mandelbrotControlPanel.setLayout(new BorderLayout());
+ mandelbrotControlPanel.add(mandelbrotControl, BorderLayout.NORTH);
+ controlPanel.add(mandelbrotControlPanel, BorderLayout.CENTER);
+
+ add(controlPanel, BorderLayout.EAST);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/resources/SpinnerDemo.properties b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/resources/SpinnerDemo.properties
new file mode 100644
index 00000000000..c5372efe5fb
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/resources/SpinnerDemo.properties
@@ -0,0 +1,15 @@
+### Spinner Demo ###
+
+SpinnerDemo.toolTip=Use left and right mouse buttons to zoom in and zoom out
+SpinnerDemo.colorPalette=Color palette
+SpinnerDemo.steps=Steps 1..1000
+SpinnerDemo.startAngles=Start angle 0..360
+SpinnerDemo.iterations=Iterations
+SpinnerDemo.fractalControls=Fractal controls
+SpinnerDemo.zoomRate=Zoom rate
+SpinnerDemo.threads=Threads
+SpinnerDemo.x=X
+SpinnerDemo.y=Y
+SpinnerDemo.r=R
+SpinnerDemo.g=G
+SpinnerDemo.b=B
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/resources/images/SpinnerDemo.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/resources/images/SpinnerDemo.gif
new file mode 100644
index 00000000000..87d560def43
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/resources/images/SpinnerDemo.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/SplitPaneDemo.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/SplitPaneDemo.java
new file mode 100644
index 00000000000..0bc0cd78f0f
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/SplitPaneDemo.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.splitpane;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import com.sun.swingset3.DemoProperties;
+import com.sun.swingset3.demos.ResourceManager;
+
+/**
+ * Split Pane demo
+ *
+ * @version 1.12 11/17/05
+ * @author Scott Violet
+ * @author Jeff Dinkins
+ */
+@DemoProperties(
+ value = "JSplitPane Demo",
+ category = "Containers",
+ description = "Demonstrates JSplitPane, a container which lays out two components in an adjustable split view (horizontal or vertical)",
+ sourceFiles = {
+ "com/sun/swingset3/demos/splitpane/SplitPaneDemo.java",
+ "com/sun/swingset3/demos/ResourceManager.java",
+ "com/sun/swingset3/demos/splitpane/resources/SplitPaneDemo.properties",
+ "com/sun/swingset3/demos/splitpane/resources/images/day.jpg",
+ "com/sun/swingset3/demos/splitpane/resources/images/night.jpg",
+ "com/sun/swingset3/demos/splitpane/resources/images/SplitPaneDemo.gif"
+ }
+)
+public class SplitPaneDemo extends JPanel {
+
+ private static final ResourceManager resourceManager = new ResourceManager(SplitPaneDemo.class);
+ public static final String VERTICAL_SPLIT = resourceManager.getString("SplitPaneDemo.vert_split");
+ public static final String HORIZONTAL_SPLIT = resourceManager.getString("SplitPaneDemo.horz_split");
+ public static final String ONE_TOUCH_EXPANDABLE = resourceManager.getString("SplitPaneDemo.one_touch_expandable");
+ public static final String SECOND_COMPONENT_MIN_SIZE = resourceManager.getString("SplitPaneDemo.second_component_min_size");
+ public static final String FIRST_COMPONENT_MIN_SIZE = resourceManager.getString("SplitPaneDemo.first_component_min_size");
+ public static final String DIVIDER_SIZE = resourceManager.getString("SplitPaneDemo.divider_size");
+ public static final String DEMO_TITLE = SplitPaneDemo.class.getAnnotation(DemoProperties.class).value();
+
+ private static final Insets insets = new Insets(4, 8, 4, 8);
+
+ private final JSplitPane splitPane;
+ private final JLabel day;
+ private final JLabel night;
+
+ private JPanel controlPanel;
+ private GridBagLayout gridbag;
+ private GridBagConstraints c;
+
+ /**
+ * main method allows us to run as a standalone demo.
+ *
+ * @param args
+ */
+ public static void main(String[] args) {
+ JFrame frame = new JFrame(DEMO_TITLE);
+
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.getContentPane().add(new SplitPaneDemo());
+ frame.setPreferredSize(new Dimension(800, 600));
+ frame.pack();
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+ }
+
+ /**
+ * SplitPaneDemo Constructor
+ */
+ public SplitPaneDemo() {
+ setLayout(new BorderLayout());
+
+ //Create horizontal SplitPane with day and night
+ day = new JLabel(resourceManager.createImageIcon("day.jpg",
+ resourceManager.getString("SplitPaneDemo.day")));
+ night = new JLabel(resourceManager.createImageIcon("night.jpg",
+ resourceManager.getString("SplitPaneDemo.night")));
+
+ splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, day, night);
+ //
+
+ //Turn on continuous layout
+ splitPane.setContinuousLayout(true);
+ //
+
+ //Turn on one-touch expansion
+ splitPane.setOneTouchExpandable(true);
+ //
+
+ //Set divider location
+ splitPane.setDividerLocation(200);
+ //
+
+ //Set minimum size for each child
+ day.setMinimumSize(new Dimension(20, 20));
+ night.setMinimumSize(new Dimension(20, 20));
+ //
+
+ add(splitPane, BorderLayout.CENTER);
+ setBackground(Color.black);
+
+ add(createSplitPaneControls(), BorderLayout.SOUTH);
+ }
+
+ /**
+ * Creates controls to alter the JSplitPane.
+ *
+ * @return
+ */
+ protected final JPanel createSplitPaneControls() {
+
+ gridbag = new GridBagLayout();
+ c = new GridBagConstraints();
+ controlPanel = new JPanel(gridbag);
+
+ //Create radio box to edit splitpane orientation
+ Box box = Box.createHorizontalBox();
+ ButtonGroup group = new ButtonGroup();
+
+ OrientationListener orientationListener = new OrientationListener();
+
+ JRadioButton button = new JRadioButton(VERTICAL_SPLIT);
+ button.setActionCommand("vertical");
+ button.addActionListener(orientationListener);
+ group.add(button);
+ box.add(button);
+
+ button = new JRadioButton(HORIZONTAL_SPLIT);
+ button.setActionCommand("horizontal");
+ button.setSelected(true);
+ button.addActionListener(orientationListener);
+ group.add(button);
+ box.add(button);
+ //
+
+ addToGridbag(box, 0, 0, 1, 1,
+ GridBagConstraints.NONE, GridBagConstraints.WEST);
+
+ //Create checkbox to edit continuous layout
+ JCheckBox checkBox = new JCheckBox(resourceManager.getString("SplitPaneDemo.cont_layout"));
+ checkBox.setSelected(true);
+
+ checkBox.addChangeListener((ChangeEvent e) -> {
+ splitPane.setContinuousLayout(
+ ((JCheckBox) e.getSource()).isSelected());
+ });
+ //
+
+ c.gridy++;
+ addToGridbag(checkBox, 0, 1, 1, 1,
+ GridBagConstraints.NONE, GridBagConstraints.WEST);
+
+ //Create checkbox to edit one-touch-expandable
+ checkBox = new JCheckBox(ONE_TOUCH_EXPANDABLE);
+ checkBox.setSelected(true);
+
+ checkBox.addChangeListener((ChangeEvent e) -> {
+ splitPane.setOneTouchExpandable(
+ ((JCheckBox) e.getSource()).isSelected());
+ });
+ //
+
+ addToGridbag(checkBox, 0, 2, 1, 1,
+ GridBagConstraints.NONE, GridBagConstraints.WEST);
+
+ JSeparator separator = new JSeparator(JSeparator.VERTICAL);
+ addToGridbag(separator, 1, 0, 1, 3,
+ GridBagConstraints.VERTICAL, GridBagConstraints.CENTER);
+
+ //Create spinner to edit divider size
+ final JSpinner spinner = new JSpinner(
+ new SpinnerNumberModel(splitPane.getDividerSize(), 5, 50, 2));
+
+ spinner.addChangeListener((ChangeEvent event) -> {
+ SpinnerNumberModel model = (SpinnerNumberModel) spinner.getModel();
+ splitPane.setDividerSize(model.getNumber().intValue());
+ });
+ //
+
+ JLabel label = new JLabel(DIVIDER_SIZE);
+ label.setLabelFor(spinner);
+ addToGridbag(label, 2, 0, 1, 1,
+ GridBagConstraints.NONE, GridBagConstraints.EAST);
+ addToGridbag(spinner, 3, 0, 1, 1,
+ GridBagConstraints.NONE, GridBagConstraints.WEST);
+
+ //Create spinners to edit day & night's minimum sizes
+ JSpinner minSizeSpinner = new JSpinner(
+ new SpinnerNumberModel(day.getMinimumSize().width, 0, 300, 10));
+
+ minSizeSpinner.addChangeListener(new MinimumSizeListener(day));
+ //
+
+ label = new JLabel(FIRST_COMPONENT_MIN_SIZE);
+ label.setLabelFor(minSizeSpinner);
+ addToGridbag(label, 2, 1, 1, 1,
+ GridBagConstraints.NONE, GridBagConstraints.EAST);
+ addToGridbag(minSizeSpinner, 3, 1, 1, 1,
+ GridBagConstraints.NONE, GridBagConstraints.WEST);
+
+ //Create spinners to edit day & night's minimum sizes
+ minSizeSpinner = new JSpinner(
+ new SpinnerNumberModel(night.getMinimumSize().width, 0, 300, 10));
+
+ minSizeSpinner.addChangeListener(new MinimumSizeListener(night));
+ //
+
+ label = new JLabel(SECOND_COMPONENT_MIN_SIZE);
+ label.setLabelFor(minSizeSpinner);
+ addToGridbag(label, 2, 2, 1, 1,
+ GridBagConstraints.NONE, GridBagConstraints.EAST);
+ addToGridbag(minSizeSpinner, 3, 2, 1, 1,
+ GridBagConstraints.NONE, GridBagConstraints.WEST);
+
+ return controlPanel;
+ }
+
+ protected void addToGridbag(JComponent child, int gx, int gy,
+ int gwidth, int gheight, int fill, int anchor) {
+ c.insets = insets;
+ c.gridx = gx;
+ c.gridy = gy;
+ c.gridwidth = gwidth;
+ c.gridheight = gheight;
+ c.fill = fill;
+ c.anchor = anchor;
+ gridbag.addLayoutComponent(child, c);
+ controlPanel.add(child);
+
+ }
+
+ //Create radio box to edit splitpane orientation
+ private class OrientationListener implements ActionListener {
+
+ @Override
+ public void actionPerformed(ActionEvent event) {
+ splitPane.setOrientation(event.getActionCommand().equals("vertical")
+ ? JSplitPane.VERTICAL_SPLIT : JSplitPane.HORIZONTAL_SPLIT);
+ }
+
+ }
+ //
+
+ //Create spinners to edit day & night's minimum sizes
+ public class MinimumSizeListener implements ChangeListener {
+
+ private final JComponent component;
+
+ public MinimumSizeListener(JComponent c) {
+ this.component = c;
+ }
+
+ @Override
+ public void stateChanged(ChangeEvent event) {
+ JSpinner spinner = (JSpinner) event.getSource();
+ SpinnerNumberModel model = (SpinnerNumberModel) spinner.getModel();
+ int min = model.getNumber().intValue();
+ component.setMinimumSize(new Dimension(min, min));
+ }
+ }
+ //
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/resources/SplitPaneDemo.properties b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/resources/SplitPaneDemo.properties
new file mode 100644
index 00000000000..ef61ebdbdfd
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/resources/SplitPaneDemo.properties
@@ -0,0 +1,14 @@
+### SplitPane Demo ###
+
+SplitPaneDemo.accessible_description=JSplitPane Demo
+SplitPaneDemo.name=Split Pane Demo
+SplitPaneDemo.tooltip=JSplitPane demo
+SplitPaneDemo.day=San Francisco by day
+SplitPaneDemo.night=San Francisco by night
+SplitPaneDemo.vert_split=Vertical Split
+SplitPaneDemo.horz_split=Horizontal Split
+SplitPaneDemo.cont_layout=Continuous Layout
+SplitPaneDemo.one_touch_expandable=One-Touch expandable
+SplitPaneDemo.divider_size=Divider Size
+SplitPaneDemo.first_component_min_size=Day's Minimum Size
+SplitPaneDemo.second_component_min_size=Night's Minimum Size
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/resources/images/SplitPaneDemo.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/resources/images/SplitPaneDemo.gif
new file mode 100644
index 00000000000..945aa5b5e77
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/resources/images/SplitPaneDemo.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/resources/images/day.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/resources/images/day.jpg
new file mode 100644
index 00000000000..a838c5ca619
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/resources/images/day.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/resources/images/night.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/resources/images/night.jpg
new file mode 100644
index 00000000000..bc8738732c9
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/resources/images/night.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/TabbedPaneDemo.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/TabbedPaneDemo.java
new file mode 100644
index 00000000000..9809d6babbe
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/TabbedPaneDemo.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.tabbedpane;
+
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Random;
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+
+import com.sun.swingset3.DemoProperties;
+import com.sun.swingset3.demos.ResourceManager;
+
+/**
+ * JTabbedPane Demo
+ *
+ * @version 1.11 11/17/05
+ * @author Jeff Dinkins
+ */
+@DemoProperties(
+ value = "JTabbedPane Demo",
+ category = "Containers",
+ description = "Demonstrates JTabbedPane, a container which allows tabbed navigation of components",
+ sourceFiles = {
+ "com/sun/swingset3/demos/tabbedpane/TabbedPaneDemo.java",
+ "com/sun/swingset3/demos/ResourceManager.java",
+ "com/sun/swingset3/demos/tabbedpane/resources/TabbedPaneDemo.properties",
+ "com/sun/swingset3/demos/tabbedpane/resources/images/blake.gif",
+ "com/sun/swingset3/demos/tabbedpane/resources/images/brooke.gif",
+ "com/sun/swingset3/demos/tabbedpane/resources/images/camille.jpg",
+ "com/sun/swingset3/demos/tabbedpane/resources/images/david.gif",
+ "com/sun/swingset3/demos/tabbedpane/resources/images/ewan.gif",
+ "com/sun/swingset3/demos/tabbedpane/resources/images/ewan.jpg",
+ "com/sun/swingset3/demos/tabbedpane/resources/images/miranda.jpg",
+ "com/sun/swingset3/demos/tabbedpane/resources/images/matthew.gif",
+ "com/sun/swingset3/demos/tabbedpane/resources/images/stephen.gif",
+ "com/sun/swingset3/demos/tabbedpane/resources/images/TabbedPaneDemo.gif"
+ }
+)
+public class TabbedPaneDemo extends JPanel implements ActionListener {
+
+ private static final ResourceManager resourceManager = new ResourceManager(TabbedPaneDemo.class);
+ public static final String BOUNCE = resourceManager.getString("TabbedPaneDemo.bounce");
+ public static final String EWAN = resourceManager.getString("TabbedPaneDemo.ewan");
+ public static final String MIRANDA = resourceManager.getString("TabbedPaneDemo.miranda");
+ public static final String CAMILLE = resourceManager.getString("TabbedPaneDemo.camille");
+ public static final String TAB_PLACEMENT = resourceManager.getString("TabbedPaneDemo.label");
+ public static final String RIGHT = resourceManager.getString("TabbedPaneDemo.right");
+ public static final String BOTTOM = resourceManager.getString("TabbedPaneDemo.bottom");
+ public static final String LEFT = resourceManager.getString("TabbedPaneDemo.left");
+ public static final String TOP = resourceManager.getString("TabbedPaneDemo.top");
+ public static final String DEMO_TITLE = TabbedPaneDemo.class.getAnnotation(DemoProperties.class).value();
+
+ private final HeadSpin spin;
+
+ private final JTabbedPane tabbedpane;
+
+ private final ButtonGroup group;
+
+ private final JRadioButton top;
+ private final JRadioButton bottom;
+ private final JRadioButton left;
+ private final JRadioButton right;
+
+ /**
+ * main method allows us to run as a standalone demo.
+ *
+ * @param args
+ */
+ public static void main(String[] args) {
+ JFrame frame = new JFrame(DEMO_TITLE);
+
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.getContentPane().add(new TabbedPaneDemo());
+ frame.setPreferredSize(new Dimension(800, 600));
+ frame.pack();
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+ }
+
+ /**
+ * TabbedPaneDemo Constructor
+ */
+ public TabbedPaneDemo() {
+ setLayout(new BorderLayout());
+
+ // create tab position controls
+ JPanel tabControls = new JPanel();
+ tabControls.add(new JLabel(TAB_PLACEMENT));
+ top = (JRadioButton) tabControls.add(new JRadioButton(TOP));
+ left = (JRadioButton) tabControls.add(new JRadioButton(LEFT));
+ bottom = (JRadioButton) tabControls.add(new JRadioButton(BOTTOM));
+ right = (JRadioButton) tabControls.add(new JRadioButton(RIGHT));
+ add(tabControls, BorderLayout.NORTH);
+
+ group = new ButtonGroup();
+ group.add(top);
+ group.add(bottom);
+ group.add(left);
+ group.add(right);
+
+ top.setSelected(true);
+
+ top.addActionListener(this);
+ bottom.addActionListener(this);
+ left.addActionListener(this);
+ right.addActionListener(this);
+
+ // create tab
+ tabbedpane = new JTabbedPane();
+ add(tabbedpane, BorderLayout.CENTER);
+
+ String name = CAMILLE;
+ JLabel pix = new JLabel(resourceManager.createImageIcon("camille.jpg", name));
+ tabbedpane.add(name, pix);
+
+ name = MIRANDA;
+ pix = new JLabel(resourceManager.createImageIcon("miranda.jpg", name));
+ pix.setToolTipText(resourceManager.getString("TabbedPaneDemo.miranda.tooltip"));
+ tabbedpane.add(name, pix);
+
+ name = EWAN;
+ pix = new JLabel(resourceManager.createImageIcon("ewan.jpg", name));
+ tabbedpane.add(name, pix);
+
+ name = BOUNCE;
+ spin = new HeadSpin();
+ tabbedpane.add(name, spin);
+
+ tabbedpane.getModel().addChangeListener((ChangeEvent e) -> {
+ SingleSelectionModel model = (SingleSelectionModel) e.getSource();
+ if (model.getSelectedIndex() == tabbedpane.getTabCount() - 1) {
+ spin.go();
+ }
+ });
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == top) {
+ tabbedpane.setTabPlacement(JTabbedPane.TOP);
+ } else if (e.getSource() == left) {
+ tabbedpane.setTabPlacement(JTabbedPane.LEFT);
+ } else if (e.getSource() == bottom) {
+ tabbedpane.setTabPlacement(JTabbedPane.BOTTOM);
+ } else if (e.getSource() == right) {
+ tabbedpane.setTabPlacement(JTabbedPane.RIGHT);
+ }
+ }
+
+ private class HeadSpin extends JComponent implements ActionListener {
+
+ private javax.swing.Timer animator;
+
+ private final ImageIcon[] icon = new ImageIcon[6];
+
+ private final static int numImages = 6;
+
+ private final double[] x = new double[numImages];
+ private final double[] y = new double[numImages];
+
+ private final int[] xh = new int[numImages];
+ private final int[] yh = new int[numImages];
+
+ private final double[] scale = new double[numImages];
+
+ private final Random rand = new Random();
+
+ public HeadSpin() {
+ setBackground(Color.black);
+ icon[0] = resourceManager.createImageIcon("ewan.gif", resourceManager.getString("TabbedPaneDemo.ewan"));
+ icon[1] = resourceManager.createImageIcon("stephen.gif", resourceManager.getString("TabbedPaneDemo.stephen"));
+ icon[2] = resourceManager.createImageIcon("david.gif", resourceManager.getString("TabbedPaneDemo.david"));
+ icon[3] = resourceManager.createImageIcon("matthew.gif", resourceManager.getString("TabbedPaneDemo.matthew"));
+ icon[4] = resourceManager.createImageIcon("blake.gif", resourceManager.getString("TabbedPaneDemo.blake"));
+ icon[5] = resourceManager.createImageIcon("brooke.gif", resourceManager.getString("TabbedPaneDemo.brooke"));
+
+ /*
+ for(int i = 0; i < 6; i++) {
+ x[i] = (double) rand.nextInt(500);
+ y[i] = (double) rand.nextInt(500);
+ }
+ */
+ }
+
+ public void go() {
+ animator = new javax.swing.Timer(22 + 22 + 22, this);
+ animator.start();
+ }
+
+ @Override
+ public void paint(Graphics g) {
+ g.setColor(getBackground());
+ g.fillRect(0, 0, getWidth(), getHeight());
+
+ for (int i = 0; i < numImages; i++) {
+ if (x[i] > 3 * i) {
+ nudge(i);
+ squish(g, icon[i], xh[i], yh[i], scale[i]);
+ } else {
+ x[i] += .05;
+ y[i] += .05;
+ }
+ }
+ }
+
+ public void nudge(int i) {
+ x[i] += (double) rand.nextInt(1000) / 8756;
+ y[i] += (double) rand.nextInt(1000) / 5432;
+ int tmpScale = (int) (Math.abs(Math.sin(x[i])) * 10);
+ scale[i] = (double) tmpScale / 10;
+ int nudgeX = (int) (((double) getWidth() / 2) * .8);
+ int nudgeY = (int) (((double) getHeight() / 2) * .60);
+ xh[i] = (int) (Math.sin(x[i]) * nudgeX) + nudgeX;
+ yh[i] = (int) (Math.sin(y[i]) * nudgeY) + nudgeY;
+ }
+
+ public void squish(Graphics g, ImageIcon icon, int x, int y, double scale) {
+ if (isVisible()) {
+ g.drawImage(icon.getImage(), x, y,
+ (int) (icon.getIconWidth() * scale),
+ (int) (icon.getIconHeight() * scale),
+ this);
+ }
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (isVisible()) {
+ repaint();
+ } else {
+ animator.stop();
+ }
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/TabbedPaneDemo.properties b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/TabbedPaneDemo.properties
new file mode 100644
index 00000000000..f32d96330e0
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/TabbedPaneDemo.properties
@@ -0,0 +1,22 @@
+### TabbedPane Demo ###
+
+TabbedPaneDemo.accessible_description=This demo shows an example of using the JTabbedPane component.
+TabbedPaneDemo.tooltip=JTabbedPane demo
+TabbedPaneDemo.name=TabbedPane Demo
+
+TabbedPaneDemo.bounce=
Bouncing Babies!
+TabbedPaneDemo.stephen=Stephen
+TabbedPaneDemo.david=David
+TabbedPaneDemo.matthew=Matthew
+TabbedPaneDemo.ewan=Ewan
+TabbedPaneDemo.blake=Blake
+TabbedPaneDemo.brooke=Brooke
+TabbedPaneDemo.camille=Camille
+TabbedPaneDemo.miranda=Miranda
+TabbedPaneDemo.miranda.tooltip=Check out the Java code on her onesie!
+
+TabbedPaneDemo.label=Tab Placement:
+TabbedPaneDemo.top=Top
+TabbedPaneDemo.bottom=Bottom
+TabbedPaneDemo.left=Left
+TabbedPaneDemo.right=Right
\ No newline at end of file
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/TabbedPaneDemo.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/TabbedPaneDemo.gif
new file mode 100644
index 00000000000..9be6463cd04
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/TabbedPaneDemo.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/blake.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/blake.gif
new file mode 100644
index 00000000000..679639edf77
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/blake.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/brooke.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/brooke.gif
new file mode 100644
index 00000000000..815ce772553
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/brooke.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/camille.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/camille.jpg
new file mode 100644
index 00000000000..d00eabd779b
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/camille.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/david.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/david.gif
new file mode 100644
index 00000000000..46de559a228
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/david.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/ewan.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/ewan.gif
new file mode 100644
index 00000000000..82c8e58f524
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/ewan.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/ewan.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/ewan.jpg
new file mode 100644
index 00000000000..d19210eea28
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/ewan.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/matthew.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/matthew.gif
new file mode 100644
index 00000000000..812775e2b8a
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/matthew.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/miranda.jpg b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/miranda.jpg
new file mode 100644
index 00000000000..83df2778530
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/miranda.jpg differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/stephen.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/stephen.gif
new file mode 100644
index 00000000000..470c3bcb2e0
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/resources/images/stephen.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/JHistoryTextField.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/JHistoryTextField.java
new file mode 100644
index 00000000000..a6474bdefa2
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/JHistoryTextField.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.textfield;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.util.List;
+import javax.swing.*;
+import javax.swing.border.LineBorder;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+/**
+ * JHistoryTextField
+ *
+ * @author Pavel Porvatov
+ */
+public class JHistoryTextField extends JTextField {
+
+ private static final int MAX_VISIBLE_ROWS = 8;
+
+ private final List history = new ArrayList();
+
+ private final JPopupMenu popup = new JPopupMenu() {
+ @Override
+ public Dimension getPreferredSize() {
+ Dimension dimension = super.getPreferredSize();
+
+ dimension.width = JHistoryTextField.this.getWidth();
+
+ return dimension;
+ }
+ };
+
+ private final JList list = new JList<>(new DefaultListModel<>());
+
+ private String userText;
+
+ private boolean notificationDenied;
+
+ public JHistoryTextField() {
+ JScrollPane scrollPane = new JScrollPane(list,
+ ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
+ ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
+ scrollPane.setHorizontalScrollBar(null);
+ scrollPane.setBorder(null);
+
+ list.setFocusable(false);
+
+ popup.add(scrollPane);
+ popup.setFocusable(false);
+ popup.setBorder(new LineBorder(Color.BLACK, 1));
+
+ getDocument().addDocumentListener(new DocumentListener() {
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ onTextChanged();
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ onTextChanged();
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ onTextChanged();
+ }
+ });
+
+ list.addMouseMotionListener(new MouseAdapter() {
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ int index = list.locationToIndex(e.getPoint());
+
+ if (index >= 0 && list.getSelectedIndex() != index) {
+ list.setSelectedIndex(index);
+ }
+ }
+ });
+
+ list.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ if (SwingUtilities.isLeftMouseButton(e)) {
+ setTextWithoutNotification(list.getSelectedValue());
+
+ popup.setVisible(false);
+ }
+ }
+ });
+
+ addFocusListener(new FocusAdapter() {
+ @Override
+ public void focusLost(FocusEvent e) {
+ popup.setVisible(false);
+ }
+ });
+
+ addKeyListener(new KeyAdapter() {
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if (popup.isShowing()) {
+ switch (e.getKeyCode()) {
+ case KeyEvent.VK_UP: {
+ changeListSelectedIndex(-1);
+
+ break;
+ }
+
+ case KeyEvent.VK_PAGE_UP: {
+ changeListSelectedIndex(-list.getVisibleRowCount());
+
+ break;
+ }
+
+ case KeyEvent.VK_DOWN: {
+ changeListSelectedIndex(1);
+
+ break;
+ }
+
+ case KeyEvent.VK_PAGE_DOWN: {
+ changeListSelectedIndex(list.getVisibleRowCount());
+
+ break;
+ }
+
+ case KeyEvent.VK_ESCAPE: {
+ popup.setVisible(false);
+
+ setTextWithoutNotification(userText);
+
+ break;
+ }
+
+ case KeyEvent.VK_ENTER:
+ case KeyEvent.VK_LEFT:
+ case KeyEvent.VK_RIGHT: {
+ popup.setVisible(false);
+
+ break;
+ }
+ }
+ } else if (e.getKeyCode() == KeyEvent.VK_DOWN
+ || e.getKeyCode() == KeyEvent.VK_UP
+ || e.getKeyCode() == KeyEvent.VK_PAGE_UP
+ || e.getKeyCode() == KeyEvent.VK_PAGE_DOWN) {
+ userText = getText();
+
+ showFilteredHistory();
+ }
+ }
+ });
+ }
+
+ private void changeListSelectedIndex(int delta) {
+ int size = list.getModel().getSize();
+ int index = list.getSelectedIndex();
+
+ int newIndex;
+
+ if (index < 0) {
+ newIndex = delta > 0 ? 0 : size - 1;
+ } else {
+ newIndex = index + delta;
+ }
+
+ if (newIndex >= size || newIndex < 0) {
+ newIndex = newIndex < 0 ? 0 : size - 1;
+
+ if (index == newIndex) {
+ newIndex = -1;
+ }
+ }
+
+ if (newIndex < 0) {
+ list.getSelectionModel().clearSelection();
+ list.ensureIndexIsVisible(0);
+
+ setTextWithoutNotification(userText);
+ } else {
+ list.setSelectedIndex(newIndex);
+ list.ensureIndexIsVisible(newIndex);
+
+ setTextWithoutNotification(list.getSelectedValue());
+ }
+ }
+
+ private void setTextWithoutNotification(String text) {
+ notificationDenied = true;
+
+ try {
+ setText(text);
+ } finally {
+ notificationDenied = false;
+ }
+ }
+
+ private void onTextChanged() {
+ if (!notificationDenied) {
+ userText = getText();
+
+ showFilteredHistory();
+ }
+ }
+
+ private void showFilteredHistory() {
+ list.getSelectionModel().clearSelection();
+
+ DefaultListModel model = (DefaultListModel) list.getModel();
+
+ model.clear();
+
+ for (String s : history) {
+ if (s.contains(userText)) {
+ model.addElement(s);
+ }
+ }
+
+ int size = model.size();
+
+ if (size == 0) {
+ popup.setVisible(false);
+ } else {
+ list.setVisibleRowCount(size < MAX_VISIBLE_ROWS ? size : MAX_VISIBLE_ROWS);
+
+ popup.pack();
+
+ if (!popup.isShowing()) {
+ popup.show(JHistoryTextField.this, 0, getHeight());
+ }
+ }
+ }
+
+ public List getHistory() {
+ return Collections.unmodifiableList(history);
+ }
+
+ public void setHistory(List extends String> history) {
+ this.history.clear();
+ this.history.addAll(history);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/TextFieldDemo.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/TextFieldDemo.java
new file mode 100644
index 00000000000..be7c9a7e7d0
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/TextFieldDemo.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.textfield;
+
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+import com.sun.swingset3.demos.JGridPanel;
+import com.sun.swingset3.demos.ResourceManager;
+import com.sun.swingset3.DemoProperties;
+
+/**
+ * JTextField Demo
+ *
+ * @author Pavel Porvatov
+ */
+@DemoProperties(
+ value = "TextField Demo",
+ category = "Text",
+ description = "Demonstrates the JTextField, a control which allows to input text",
+ sourceFiles = {
+ "com/sun/swingset3/demos/textfield/TextFieldDemo.java",
+ "com/sun/swingset3/demos/textfield/JHistoryTextField.java",
+ "com/sun/swingset3/demos/JGridPanel.java",
+ "com/sun/swingset3/demos/ResourceManager.java",
+ "com/sun/swingset3/demos/textfield/resources/TextFieldDemo.properties",
+ "com/sun/swingset3/demos/textfield/resources/images/TextFieldDemo.gif"
+ }
+)
+public class TextFieldDemo extends JPanel {
+
+ private static final ResourceManager resourceManager = new ResourceManager(TextFieldDemo.class);
+ public static final String DEMO_TITLE = TextFieldDemo.class.getAnnotation(DemoProperties.class).value();
+
+ private final JLabel lbHistoryTextField = new JLabel(resourceManager.getString("TextFieldDemo.historytextfield.text"));
+
+ private final JHistoryTextField tfHistory = new JHistoryTextField();
+
+ private final JLabel lbDow = new JLabel(resourceManager.getString("TextFieldDemo.dow.text"));
+
+ private final JFormattedTextField tfDow = new JFormattedTextField();
+
+ private final JButton btnGo = new JButton(GO);
+ public static final String GO = resourceManager.getString("TextFieldDemo.go.text");
+
+ private final JLabel lbDowResult = new JLabel();
+
+ private final JLabel lbPassword = new JLabel(resourceManager.getString("TextFieldDemo.password.text"));
+
+ private final JPasswordField tfPassword1 = new JPasswordField(20);
+
+ private final JPasswordField tfPassword2 = new JPasswordField(20);
+
+ private final DocumentListener passwordListener = new DocumentListener() {
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ highlightPasswords();
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ highlightPasswords();
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ highlightPasswords();
+ }
+
+ private void highlightPasswords() {
+ Color color;
+
+ if (tfPassword1.getPassword().length > 0
+ && Arrays.equals(tfPassword1.getPassword(), tfPassword2.getPassword())) {
+ color = Color.GREEN;
+ } else {
+ color = UIManager.getColor("TextField.background");
+ }
+
+ tfPassword1.setBackground(color);
+ tfPassword2.setBackground(color);
+ }
+ };
+
+ /**
+ * main method allows us to run as a standalone demo.
+ *
+ * @param args
+ */
+ public static void main(String[] args) {
+ JFrame frame = new JFrame(DEMO_TITLE);
+
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.getContentPane().add(new TextFieldDemo());
+ frame.setPreferredSize(new Dimension(800, 600));
+ frame.pack();
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+ }
+
+ public TextFieldDemo() {
+ setLayout(new BorderLayout());
+
+ initUI();
+
+ tfDow.setValue(new Date());
+
+ btnGo.addActionListener((ActionEvent e) -> {
+ Calendar calendar = Calendar.getInstance(Locale.ENGLISH);
+
+ calendar.setTime((Date) tfDow.getValue());
+
+ lbDowResult.setText(calendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.ENGLISH));
+ });
+
+ tfPassword1.getDocument().addDocumentListener(passwordListener);
+
+ tfPassword2.getDocument().addDocumentListener(passwordListener);
+ }
+
+ private void initUI() {
+ tfHistory.setHistory(Arrays.asList(resourceManager.getString("TextFieldDemo.history.words").split("\\,")));
+
+ JGridPanel pnDow = new JGridPanel(3, 2);
+
+ pnDow.cell(tfDow).
+ cell(btnGo).
+ cell(lbDowResult);
+
+ JGridPanel pnPassword = new JGridPanel(3, 2);
+
+ pnPassword.cell(tfPassword1).
+ cell(tfPassword2).
+ cell();
+
+ JGridPanel pnContent = new JGridPanel(1, 0, 6);
+
+ pnContent.setBorderEqual(10);
+
+ pnContent.cell(lbHistoryTextField).
+ cell(tfHistory).
+ cell(lbDow, new Insets(20, 0, 0, 0)).
+ cell(pnDow).
+ cell(lbPassword, new Insets(20, 0, 0, 0)).
+ cell(pnPassword).
+ cell();
+
+ add(pnContent);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/resources/TextFieldDemo.properties b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/resources/TextFieldDemo.properties
new file mode 100644
index 00000000000..5bb7b0aba7c
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/resources/TextFieldDemo.properties
@@ -0,0 +1,7 @@
+### TextField Demo ###
+
+TextFieldDemo.historytextfield.text = This is an example of a text field with a history. To try it in action, type "cat".
+TextFieldDemo.history.words = armageddon,cars,cartoon,casanova,casino,castle,castlevania,cat,category,caterpillar,click,dog,magpie,hare,rabbit
+TextFieldDemo.dow.text = Enter a date and find out what day of the week it is.
+TextFieldDemo.go.text = Go
+TextFieldDemo.password.text = The text fields below become highlighted when they get identical values.
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/resources/images/TextFieldDemo.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/resources/images/TextFieldDemo.gif
new file mode 100644
index 00000000000..a4053d7e84a
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/resources/images/TextFieldDemo.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/DirectionPanel.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/DirectionPanel.java
new file mode 100644
index 00000000000..81d96b1019a
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/DirectionPanel.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.togglebutton;
+
+import java.awt.event.ActionListener;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.ButtonGroup;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.border.Border;
+
+/**
+ * @version 1.8 11/17/05
+ * @author Jeff Dinkins
+ * @author Chester Rose
+ * @author Brian Beck
+ */
+public class DirectionPanel extends JPanel {
+
+ private final ButtonGroup group;
+
+ public DirectionPanel(boolean enable, String selection, ActionListener l) {
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ setAlignmentY(TOP_ALIGNMENT);
+ setAlignmentX(LEFT_ALIGNMENT);
+
+ Box firstThree = Box.createHorizontalBox();
+ Box secondThree = Box.createHorizontalBox();
+ Box thirdThree = Box.createHorizontalBox();
+
+ if (!enable) {
+ selection = "None";
+ }
+
+ group = new ButtonGroup();
+ DirectionButton b;
+ b = (DirectionButton) firstThree.add(new DirectionButton(tl_dot, tldn_dot, "NW", "Sets the orientation to the North-West", l, group, selection.equals("NW")));
+ b.setEnabled(enable);
+ b = (DirectionButton) firstThree.add(new DirectionButton(tm_dot, tmdn_dot, "N", "Sets the orientation to the North", l, group, selection.equals("N")));
+ b.setEnabled(enable);
+ b = (DirectionButton) firstThree.add(new DirectionButton(tr_dot, trdn_dot, "NE", "Sets the orientation to the North-East", l, group, selection.equals("NE")));
+ b.setEnabled(enable);
+ b = (DirectionButton) secondThree.add(new DirectionButton(ml_dot, mldn_dot, "W", "Sets the orientation to the West", l, group, selection.equals("W")));
+ b.setEnabled(enable);
+ b = (DirectionButton) secondThree.add(new DirectionButton(c_dot, cdn_dot, "C", "Sets the orientation to the Center", l, group, selection.equals("C")));
+ b.setEnabled(enable);
+ b = (DirectionButton) secondThree.add(new DirectionButton(mr_dot, mrdn_dot, "E", "Sets the orientation to the East", l, group, selection.equals("E")));
+ b.setEnabled(enable);
+ b = (DirectionButton) thirdThree.add(new DirectionButton(bl_dot, bldn_dot, "SW", "Sets the orientation to the South-West", l, group, selection.equals("SW")));
+ b.setEnabled(enable);
+ b = (DirectionButton) thirdThree.add(new DirectionButton(bm_dot, bmdn_dot, "S", "Sets the orientation to the South", l, group, selection.equals("S")));
+ b.setEnabled(enable);
+ b = (DirectionButton) thirdThree.add(new DirectionButton(br_dot, brdn_dot, "SE", "Sets the orientation to the South-East", l, group, selection.equals("SE")));
+ b.setEnabled(enable);
+
+ add(firstThree);
+ add(secondThree);
+ add(thirdThree);
+ }
+
+ // Chester's way cool layout buttons
+ private final ImageIcon bl_dot = loadImageIcon("bl.gif", "bottom left layout button");
+ private final ImageIcon bldn_dot = loadImageIcon("bldn.gif", "selected bottom left layout button");
+ private final ImageIcon bm_dot = loadImageIcon("bm.gif", "bottom middle layout button");
+ private final ImageIcon bmdn_dot = loadImageIcon("bmdn.gif", "selected bottom middle layout button");
+ private final ImageIcon br_dot = loadImageIcon("br.gif", "bottom right layout button");
+ private final ImageIcon brdn_dot = loadImageIcon("brdn.gif", "selected bottom right layout button");
+ private final ImageIcon c_dot = loadImageIcon("c.gif", "center layout button");
+ private final ImageIcon cdn_dot = loadImageIcon("cdn.gif", "selected center layout button");
+ private final ImageIcon ml_dot = loadImageIcon("ml.gif", "middle left layout button");
+ private final ImageIcon mldn_dot = loadImageIcon("mldn.gif", "selected middle left layout button");
+ private final ImageIcon mr_dot = loadImageIcon("mr.gif", "middle right layout button");
+ private final ImageIcon mrdn_dot = loadImageIcon("mrdn.gif", "selected middle right layout button");
+ private final ImageIcon tl_dot = loadImageIcon("tl.gif", "top left layout button");
+ private final ImageIcon tldn_dot = loadImageIcon("tldn.gif", "selected top left layout button");
+ private final ImageIcon tm_dot = loadImageIcon("tm.gif", "top middle layout button");
+ private final ImageIcon tmdn_dot = loadImageIcon("tmdn.gif", "selected top middle layout button");
+ private final ImageIcon tr_dot = loadImageIcon("tr.gif", "top right layout button");
+ private final ImageIcon trdn_dot = loadImageIcon("trdn.gif", "selected top right layout button");
+
+ private ImageIcon loadImageIcon(String filename, String description) {
+ String path = "resources/images/" + filename;
+ return new ImageIcon(getClass().getResource(path), description);
+ }
+
+ private static class DirectionButton extends JRadioButton {
+
+ /**
+ * A layout direction button
+ */
+ public DirectionButton(Icon icon, Icon downIcon, String direction,
+ String description, ActionListener l,
+ ButtonGroup group, boolean selected) {
+ super();
+ this.addActionListener(l);
+ setFocusPainted(false);
+ setHorizontalTextPosition(CENTER);
+ group.add(this);
+ setIcon(icon);
+ setSelectedIcon(downIcon);
+ setActionCommand(direction);
+ getAccessibleContext().setAccessibleName(direction);
+ getAccessibleContext().setAccessibleDescription(description);
+ setSelected(selected);
+ }
+
+ @Override
+ @Deprecated
+ public boolean isFocusTraversable() {
+ return false;
+ }
+
+ @Override
+ public void setBorder(Border b) {
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/LayoutControlPanel.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/LayoutControlPanel.java
new file mode 100644
index 00000000000..c8c79bac29e
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/LayoutControlPanel.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.togglebutton;
+
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.*;
+
+import com.sun.swingset3.demos.ResourceManager;
+
+/*
+ * The LayoutControlPanel contains controls for setting an
+ * AbstractButton's horizontal and vertical text position and
+ * horizontal and vertical alignment.
+ */
+public final class LayoutControlPanel extends JPanel implements SwingConstants {
+
+ private static final Dimension VGAP20 = new Dimension(1, 20);
+ private static final ResourceManager resourceManager = ToggleButtonDemo.resourceManager;
+ public static final String CONTENT_ALIGNMENT = resourceManager.getString("LayoutControlPanel.contentalignment_label");
+ public static final String TEXT_POSITION = resourceManager.getString("LayoutControlPanel.textposition_label");
+ private final boolean absolutePositions;
+ private ToggleButtonDemo demo = null;
+
+ // private ComponentOrientChanger componentOrientChanger = null;
+ LayoutControlPanel(ToggleButtonDemo demo) {
+ this.demo = demo;
+
+ // this.componentOrientationChanger = componentOrientationChanger;
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ setAlignmentX(LEFT_ALIGNMENT);
+ setAlignmentY(TOP_ALIGNMENT);
+
+ JLabel l;
+
+ // If SwingSet has a ComponentOrientationChanger, then include control
+ // for choosing between absolute and relative positioning. This will
+ // only happen when we're running on JDK 1.2 or above.
+ //
+ // if(componentOrientationChanger != null ) {
+ // l = new JLabel("Positioning:");
+ // add(l);
+ //
+ // ButtonGroup group = new ButtonGroup();
+ // PositioningListener positioningListener = new PositioningListener();
+ // JRadioButton absolutePos = new JRadioButton("Absolute");
+ // absolutePos.setMnemonic('a');
+ // absolutePos.setToolTipText("Text/Content positioning is independant of line direction");
+ // group.add(absolutePos);
+ // absolutePos.addItemListener(positioningListener);
+ // add(absolutePos);
+ //
+ // JRadioButton relativePos = new JRadioButton("Relative");
+ // relativePos.setMnemonic('r');
+ // relativePos.setToolTipText("Text/Content positioning depends on line direction.");
+ // group.add(relativePos);
+ // relativePos.addItemListener(positioningListener);
+ // add(relativePos);
+ //
+ // add(Box.createRigidArea(demo.VGAP20));
+ //
+ // absolutePositions = false;
+ // relativePos.setSelected(true);
+ //
+ // componentOrientationChanger.addActionListener( new OrientationChangeListener() );
+ //} else {
+ absolutePositions = true;
+ //}
+
+ DirectionPanel textPosition = new DirectionPanel(true, "E", new TextPositionListener());
+ DirectionPanel labelAlignment = new DirectionPanel(true, "C", new LabelAlignmentListener());
+
+ // Make sure the controls' text position and label alignment match
+ // the initial value of the associated direction panel.
+ for (JComponent control : demo.getCurrentControls()) {
+ setPosition(control, RIGHT, CENTER);
+ setAlignment(control, CENTER, CENTER);
+ }
+
+ l = new JLabel(TEXT_POSITION);
+ add(l);
+ add(textPosition);
+
+ add(Box.createRigidArea(VGAP20));
+
+ l = new JLabel(CONTENT_ALIGNMENT);
+ add(l);
+ add(labelAlignment);
+
+ add(Box.createGlue());
+ }
+
+ // Text Position Listener
+ private class TextPositionListener implements ActionListener {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JRadioButton rb = (JRadioButton) e.getSource();
+ if (!rb.isSelected()) {
+ return;
+ }
+ String cmd = rb.getActionCommand();
+ int hPos, vPos;
+ switch (cmd) {
+ case "NW":
+ hPos = LEFT;
+ vPos = TOP;
+ break;
+ case "N":
+ hPos = CENTER;
+ vPos = TOP;
+ break;
+ case "NE":
+ hPos = RIGHT;
+ vPos = TOP;
+ break;
+ case "W":
+ hPos = LEFT;
+ vPos = CENTER;
+ break;
+ case "C":
+ hPos = CENTER;
+ vPos = CENTER;
+ break;
+ case "E":
+ hPos = RIGHT;
+ vPos = CENTER;
+ break;
+ case "SW":
+ hPos = LEFT;
+ vPos = BOTTOM;
+ break;
+ case "S":
+ hPos = CENTER;
+ vPos = BOTTOM;
+ break;
+ /*if(cmd.equals("SE"))*/
+ default:
+ hPos = RIGHT;
+ vPos = BOTTOM;
+ break;
+ }
+ for (JComponent control : demo.getCurrentControls()) {
+ setPosition(control, hPos, vPos);
+ }
+ demo.invalidate();
+ demo.validate();
+ demo.repaint();
+ }
+ }
+
+ // Label Alignment Listener
+ private class LabelAlignmentListener implements ActionListener {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JRadioButton rb = (JRadioButton) e.getSource();
+ if (!rb.isSelected()) {
+ return;
+ }
+ String cmd = rb.getActionCommand();
+ int hPos, vPos;
+ switch (cmd) {
+ case "NW":
+ hPos = LEFT;
+ vPos = TOP;
+ break;
+ case "N":
+ hPos = CENTER;
+ vPos = TOP;
+ break;
+ case "NE":
+ hPos = RIGHT;
+ vPos = TOP;
+ break;
+ case "W":
+ hPos = LEFT;
+ vPos = CENTER;
+ break;
+ case "C":
+ hPos = CENTER;
+ vPos = CENTER;
+ break;
+ case "E":
+ hPos = RIGHT;
+ vPos = CENTER;
+ break;
+ case "SW":
+ hPos = LEFT;
+ vPos = BOTTOM;
+ break;
+ case "S":
+ hPos = CENTER;
+ vPos = BOTTOM;
+ break;
+ /*if(cmd.equals("SE"))*/
+ default:
+ hPos = RIGHT;
+ vPos = BOTTOM;
+ break;
+ }
+ for (JComponent control : demo.getCurrentControls()) {
+ setAlignment(control, hPos, vPos);
+ control.invalidate();
+ }
+ demo.invalidate();
+ demo.validate();
+ demo.repaint();
+ }
+ }
+
+ // Position
+ void setPosition(Component c, int hPos, int vPos) {
+ boolean ltr = c.getComponentOrientation().isLeftToRight();
+ if (absolutePositions) {
+ if (hPos == LEADING) {
+ hPos = ltr ? LEFT : RIGHT;
+ } else if (hPos == TRAILING) {
+ hPos = ltr ? RIGHT : LEFT;
+ }
+ } else if (hPos == LEFT) {
+ hPos = ltr ? LEADING : TRAILING;
+ } else if (hPos == RIGHT) {
+ hPos = ltr ? TRAILING : LEADING;
+ }
+ if (c instanceof AbstractButton) {
+ AbstractButton x = (AbstractButton) c;
+ x.setHorizontalTextPosition(hPos);
+ x.setVerticalTextPosition(vPos);
+ } else if (c instanceof JLabel) {
+ JLabel x = (JLabel) c;
+ x.setHorizontalTextPosition(hPos);
+ x.setVerticalTextPosition(vPos);
+ }
+ }
+
+ void setAlignment(Component c, int hPos, int vPos) {
+ boolean ltr = c.getComponentOrientation().isLeftToRight();
+ if (absolutePositions) {
+ if (hPos == LEADING) {
+ hPos = ltr ? LEFT : RIGHT;
+ } else if (hPos == TRAILING) {
+ hPos = ltr ? RIGHT : LEFT;
+ }
+ } else if (hPos == LEFT) {
+ hPos = ltr ? LEADING : TRAILING;
+ } else if (hPos == RIGHT) {
+ hPos = ltr ? TRAILING : LEADING;
+ }
+ if (c instanceof AbstractButton) {
+ AbstractButton x = (AbstractButton) c;
+ x.setHorizontalAlignment(hPos);
+ x.setVerticalAlignment(vPos);
+ } else if (c instanceof JLabel) {
+ JLabel x = (JLabel) c;
+ x.setHorizontalAlignment(hPos);
+ x.setVerticalAlignment(vPos);
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/ToggleButtonDemo.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/ToggleButtonDemo.java
new file mode 100644
index 00000000000..5adf5f7a62b
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/ToggleButtonDemo.java
@@ -0,0 +1,563 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.togglebutton;
+
+import java.awt.*;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.util.*;
+import java.util.List;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import com.sun.swingset3.DemoProperties;
+import com.sun.swingset3.demos.ResourceManager;
+
+/**
+ * JButton, JRadioButton, JToggleButton, JCheckBox Demos
+ *
+ * @version 1.15 11/17/05
+ * @author Jeff Dinkins
+ */
+@DemoProperties(
+ value = "ToggleButtons Demo",
+ category = "Controls",
+ description = "Demonstrates JCheckBox & JRadioButton",
+ sourceFiles = {
+ "com/sun/swingset3/demos/togglebutton/ToggleButtonDemo.java",
+ "com/sun/swingset3/demos/togglebutton/DirectionPanel.java",
+ "com/sun/swingset3/demos/togglebutton/LayoutControlPanel.java",
+ "com/sun/swingset3/demos/ResourceManager.java",
+ "com/sun/swingset3/demos/togglebutton/resources/ToggleButtonDemo.properties",
+ "com/sun/swingset3/demos/togglebutton/resources/images/b1.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/b1d.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/b1p.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/b1r.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/b2.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/b2d.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/b2p.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/b2r.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/b3.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/b3d.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/b3p.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/b3r.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/bl.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/bldn.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/bm.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/bmdn.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/br.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/brdn.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/c.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/cb.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/cbr.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/cbrs.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/cbs.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/cdn.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/ml.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/mldn.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/mr.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/mrdn.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/rb.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/rbp.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/rbr.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/rbrs.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/rbs.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/tl.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/tldn.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/tm.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/tmdn.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/ToggleButtonDemo.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/tr.gif",
+ "com/sun/swingset3/demos/togglebutton/resources/images/trdn.gif"
+ }
+)
+public class ToggleButtonDemo extends JPanel implements ChangeListener {
+
+ private static final Dimension HGAP10 = new Dimension(10, 1);
+ private static final Dimension HGAP20 = new Dimension(20, 1);
+ private static final Dimension VGAP20 = new Dimension(1, 20);
+ private static final Dimension VGAP30 = new Dimension(1, 30);
+
+ static final ResourceManager resourceManager = new ResourceManager(ToggleButtonDemo.class);
+ public static final String RADIO3 = resourceManager.getString("ToggleButtonDemo.radio3");
+ public static final String RADIO2 = resourceManager.getString("ToggleButtonDemo.radio2");
+ public static final String RADIO1 = resourceManager.getString("ToggleButtonDemo.radio1");
+ public static final String IMAGE_RADIO_BUTTONS = resourceManager.getString("ToggleButtonDemo.imageradiobuttons");
+ public static final String TEXT_RADIO_BUTTONS = resourceManager.getString("ToggleButtonDemo.textradiobuttons");
+ public static final String CHECK3 = resourceManager.getString("ToggleButtonDemo.check3");
+ public static final String CHECK2 = resourceManager.getString("ToggleButtonDemo.check2");
+ public static final String CHECK1 = resourceManager.getString("ToggleButtonDemo.check1");
+ public static final String CHECK_BOXES = resourceManager.getString("ToggleButtonDemo.checkboxes");
+ public static final String IMAGE_CHECKBOXES = resourceManager.getString("ToggleButtonDemo.imagecheckboxes");
+ public static final String TEXT_CHECKBOXES = resourceManager.getString("ToggleButtonDemo.textcheckboxes");
+ public static final String CONTENT_FILLED = resourceManager.getString("ToggleButtonDemo.contentfilled");
+ public static final String ENABLED = resourceManager.getString("ToggleButtonDemo.enabled");
+ public static final String PAINT_FOCUS = resourceManager.getString("ToggleButtonDemo.paintfocus");
+ public static final String PAINT_BORDER = resourceManager.getString("ToggleButtonDemo.paintborder");
+ public static final String DISPLAY_OPTIONS = resourceManager.getString("ToggleButtonDemo.controlpanel_label");
+ public static final String DEFAULT = resourceManager.getString("ToggleButtonDemo.default");
+ public static final String PAD_AMOUNT = resourceManager.getString("ToggleButtonDemo.padamount_label");
+
+ private final JTabbedPane tab;
+
+ private final JPanel checkboxPanel = new JPanel();
+ private final JPanel radioButtonPanel = new JPanel();
+
+ private final List buttons = new ArrayList<>();
+ private final List checkboxes = new ArrayList<>();
+ private final List radiobuttons = new ArrayList<>();
+ private final List togglebuttons = new ArrayList<>();
+
+ private List extends JComponent> currentControls = buttons;
+
+ private final EmptyBorder border5 = new EmptyBorder(5, 5, 5, 5);
+
+ private ItemListener buttonDisplayListener = null;
+ private ItemListener buttonPadListener = null;
+
+ private final Insets insets0 = new Insets(0, 0, 0, 0);
+ private final Insets insets10 = new Insets(10, 10, 10, 10);
+
+ private final Border loweredBorder = new CompoundBorder(
+ new SoftBevelBorder(SoftBevelBorder.LOWERED), new EmptyBorder(5, 5, 5, 5));
+
+ /**
+ * main method allows us to run as a standalone demo.
+ *
+ * @param args
+ */
+ public static void main(String[] args) {
+ JFrame frame = new JFrame(ToggleButtonDemo.class.getAnnotation(DemoProperties.class).value());
+
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.getContentPane().add(new ToggleButtonDemo());
+ frame.setPreferredSize(new Dimension(800, 600));
+ frame.pack();
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+ }
+
+ /**
+ * ButtonDemo Constructor
+ */
+ public ToggleButtonDemo() {
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+
+ tab = new JTabbedPane();
+ tab.getModel().addChangeListener(this);
+
+ add(tab);
+
+ //addButtons();
+ addRadioButtons();
+ addCheckBoxes();
+ //addToggleButtons();
+ currentControls = checkboxes;
+ }
+
+ private void addRadioButtons() {
+ ButtonGroup group = new ButtonGroup();
+
+ tab.addTab(resourceManager.getString("ToggleButtonDemo.radiobuttons"), radioButtonPanel);
+ radioButtonPanel.setLayout(new BoxLayout(radioButtonPanel, BoxLayout.X_AXIS));
+ radioButtonPanel.setBorder(border5);
+
+ JPanel p1 = createVerticalPanel(true);
+ p1.setAlignmentY(TOP_ALIGNMENT);
+ radioButtonPanel.add(p1);
+
+ // Text Radio Buttons
+ JPanel p2 = createHorizontalPanel(false);
+ p1.add(p2);
+ p2.setBorder(new CompoundBorder(
+ new TitledBorder(
+ null, TEXT_RADIO_BUTTONS,
+ TitledBorder.LEFT, TitledBorder.TOP), border5)
+ );
+
+ JRadioButton radio = (JRadioButton) p2.add(new JRadioButton(RADIO1));
+ group.add(radio);
+ radiobuttons.add(radio);
+ p2.add(Box.createRigidArea(HGAP10));
+
+ radio = (JRadioButton) p2.add(new JRadioButton(RADIO2));
+ group.add(radio);
+ radiobuttons.add(radio);
+ p2.add(Box.createRigidArea(HGAP10));
+
+ radio = (JRadioButton) p2.add(new JRadioButton(RADIO3));
+ group.add(radio);
+ radiobuttons.add(radio);
+
+ // Image Radio Buttons
+ group = new ButtonGroup();
+ p1.add(Box.createRigidArea(VGAP30));
+ JPanel p3 = createHorizontalPanel(false);
+ p1.add(p3);
+ p3.setLayout(new BoxLayout(p3, BoxLayout.X_AXIS));
+ p3.setBorder(new TitledBorder(null, IMAGE_RADIO_BUTTONS,
+ TitledBorder.LEFT, TitledBorder.TOP));
+
+ // image radio button 1
+ String description = resourceManager.getString("ToggleButtonDemo.customradio");
+ String text = RADIO1;
+ radio = new JRadioButton(text, resourceManager.createImageIcon("rb.gif", description));
+ radio.setPressedIcon(resourceManager.createImageIcon("rbp.gif", description));
+ radio.setRolloverIcon(resourceManager.createImageIcon("rbr.gif", description));
+ radio.setRolloverSelectedIcon(resourceManager.createImageIcon("rbrs.gif", description));
+ radio.setSelectedIcon(resourceManager.createImageIcon("rbs.gif", description));
+ radio.setMargin(new Insets(0, 0, 0, 0));
+ group.add(radio);
+ p3.add(radio);
+ radiobuttons.add(radio);
+ p3.add(Box.createRigidArea(HGAP20));
+
+ // image radio button 2
+ text = RADIO2;
+ radio = new JRadioButton(text, resourceManager.createImageIcon("rb.gif", description));
+ radio.setPressedIcon(resourceManager.createImageIcon("rbp.gif", description));
+ radio.setRolloverIcon(resourceManager.createImageIcon("rbr.gif", description));
+ radio.setRolloverSelectedIcon(resourceManager.createImageIcon("rbrs.gif", description));
+ radio.setSelectedIcon(resourceManager.createImageIcon("rbs.gif", description));
+ radio.setMargin(new Insets(0, 0, 0, 0));
+ group.add(radio);
+ p3.add(radio);
+ radiobuttons.add(radio);
+ p3.add(Box.createRigidArea(HGAP20));
+
+ // image radio button 3
+ text = RADIO3;
+ radio = new JRadioButton(text, resourceManager.createImageIcon("rb.gif", description));
+ radio.setPressedIcon(resourceManager.createImageIcon("rbp.gif", description));
+ radio.setRolloverIcon(resourceManager.createImageIcon("rbr.gif", description));
+ radio.setRolloverSelectedIcon(resourceManager.createImageIcon("rbrs.gif", description));
+ radio.setSelectedIcon(resourceManager.createImageIcon("rbs.gif", description));
+ radio.setMargin(new Insets(0, 0, 0, 0));
+ group.add(radio);
+ radiobuttons.add(radio);
+ p3.add(radio);
+
+ // verticaly glue fills out the rest of the box
+ p1.add(Box.createVerticalGlue());
+
+ radioButtonPanel.add(Box.createHorizontalGlue());
+ currentControls = radiobuttons;
+ radioButtonPanel.add(createControls());
+ }
+
+ private void addCheckBoxes() {
+ tab.addTab(CHECK_BOXES, checkboxPanel);
+ checkboxPanel.setLayout(new BoxLayout(checkboxPanel, BoxLayout.X_AXIS));
+ checkboxPanel.setBorder(border5);
+
+ JPanel p1 = createVerticalPanel(true);
+ p1.setAlignmentY(TOP_ALIGNMENT);
+ checkboxPanel.add(p1);
+
+ // Text Radio Buttons
+ JPanel p2 = createHorizontalPanel(false);
+ p1.add(p2);
+ p2.setBorder(new CompoundBorder(
+ new TitledBorder(
+ null, TEXT_CHECKBOXES,
+ TitledBorder.LEFT, TitledBorder.TOP), border5)
+ );
+
+ JCheckBox checkBox1 = new JCheckBox(CHECK1);
+ checkboxes.add(checkBox1);
+ p2.add(checkBox1);
+ p2.add(Box.createRigidArea(HGAP10));
+
+ JCheckBox checkBox2 = new JCheckBox(CHECK2);
+ checkboxes.add(checkBox2);
+ p2.add(checkBox2);
+ p2.add(Box.createRigidArea(HGAP10));
+
+ JCheckBox checkBox3 = new JCheckBox(CHECK3);
+ checkboxes.add(checkBox3);
+ p2.add(checkBox3);
+
+ // Image Radio Buttons
+ p1.add(Box.createRigidArea(VGAP30));
+ JPanel p3 = createHorizontalPanel(false);
+ p1.add(p3);
+ p3.setLayout(new BoxLayout(p3, BoxLayout.X_AXIS));
+ p3.setBorder(new TitledBorder(null, IMAGE_CHECKBOXES,
+ TitledBorder.LEFT, TitledBorder.TOP));
+
+ // image checkbox 1
+ String description = resourceManager.getString("ToggleButtonDemo.customcheck");
+ String text = CHECK1;
+ JCheckBox check = new JCheckBox(text,
+ resourceManager.createImageIcon("cb.gif", description));
+ check.setRolloverIcon(resourceManager.createImageIcon("cbr.gif", description));
+ check.setRolloverSelectedIcon(resourceManager.createImageIcon("cbrs.gif", description));
+ check.setSelectedIcon(resourceManager.createImageIcon("cbs.gif", description));
+ check.setMargin(new Insets(0, 0, 0, 0));
+ p3.add(check);
+ checkboxes.add(check);
+ p3.add(Box.createRigidArea(HGAP20));
+
+ // image checkbox 2
+ text = CHECK2;
+ check = new JCheckBox(text, resourceManager.createImageIcon("cb.gif", description));
+ check.setRolloverIcon(resourceManager.createImageIcon("cbr.gif", description));
+ check.setRolloverSelectedIcon(resourceManager.createImageIcon("cbrs.gif", description));
+ check.setSelectedIcon(resourceManager.createImageIcon("cbs.gif", description));
+ check.setMargin(new Insets(0, 0, 0, 0));
+ p3.add(check);
+ checkboxes.add(check);
+ p3.add(Box.createRigidArea(HGAP20));
+
+ // image checkbox 3
+ text = CHECK3;
+ check = new JCheckBox(text, resourceManager.createImageIcon("cb.gif", description));
+ check.setRolloverIcon(resourceManager.createImageIcon("cbr.gif", description));
+ check.setRolloverSelectedIcon(resourceManager.createImageIcon("cbrs.gif", description));
+ check.setSelectedIcon(resourceManager.createImageIcon("cbs.gif", description));
+ check.setMargin(new Insets(0, 0, 0, 0));
+ p3.add(check);
+ checkboxes.add(check);
+
+ // verticaly glue fills out the rest of the box
+ p1.add(Box.createVerticalGlue());
+
+ checkboxPanel.add(Box.createHorizontalGlue());
+ currentControls = checkboxes;
+ checkboxPanel.add(createControls());
+ }
+
+ private JPanel createControls() {
+ JPanel controls = new JPanel() {
+ @Override
+ public Dimension getMaximumSize() {
+ return new Dimension(300, super.getMaximumSize().height);
+ }
+ };
+ controls.setLayout(new BoxLayout(controls, BoxLayout.Y_AXIS));
+ controls.setAlignmentY(TOP_ALIGNMENT);
+ controls.setAlignmentX(LEFT_ALIGNMENT);
+
+ JPanel buttonControls = createHorizontalPanel(true);
+ buttonControls.setAlignmentY(TOP_ALIGNMENT);
+ buttonControls.setAlignmentX(LEFT_ALIGNMENT);
+
+ JPanel leftColumn = createVerticalPanel(false);
+ leftColumn.setAlignmentX(LEFT_ALIGNMENT);
+ leftColumn.setAlignmentY(TOP_ALIGNMENT);
+
+ JPanel rightColumn = new LayoutControlPanel(this);
+
+ buttonControls.add(leftColumn);
+ buttonControls.add(Box.createRigidArea(HGAP20));
+ buttonControls.add(rightColumn);
+ buttonControls.add(Box.createRigidArea(HGAP20));
+
+ controls.add(buttonControls);
+
+ createListeners();
+
+ // Display Options
+ JLabel l = new JLabel(DISPLAY_OPTIONS);
+ leftColumn.add(l);
+
+ JCheckBox bordered = new JCheckBox(PAINT_BORDER);
+ bordered.setActionCommand("PaintBorder");
+ bordered.setToolTipText(resourceManager.getString("ToggleButtonDemo.paintborder_tooltip"));
+ bordered.setMnemonic(resourceManager.getMnemonic("ToggleButtonDemo.paintborder_mnemonic"));
+ if (currentControls == buttons) {
+ bordered.setSelected(true);
+ }
+ bordered.addItemListener(buttonDisplayListener);
+ leftColumn.add(bordered);
+
+ JCheckBox focused = new JCheckBox(PAINT_FOCUS);
+ focused.setActionCommand("PaintFocus");
+ focused.setToolTipText(resourceManager.getString("ToggleButtonDemo.paintfocus_tooltip"));
+ focused.setMnemonic(resourceManager.getMnemonic("ToggleButtonDemo.paintfocus_mnemonic"));
+ focused.setSelected(true);
+ focused.addItemListener(buttonDisplayListener);
+ leftColumn.add(focused);
+
+ JCheckBox enabled = new JCheckBox(ENABLED);
+ enabled.setActionCommand("Enabled");
+ enabled.setToolTipText(resourceManager.getString("ToggleButtonDemo.enabled_tooltip"));
+ enabled.setSelected(true);
+ enabled.addItemListener(buttonDisplayListener);
+ enabled.setMnemonic(resourceManager.getMnemonic("ToggleButtonDemo.enabled_mnemonic"));
+ leftColumn.add(enabled);
+
+ JCheckBox filled = new JCheckBox(CONTENT_FILLED);
+ filled.setActionCommand("ContentFilled");
+ filled.setToolTipText(resourceManager.getString("ToggleButtonDemo.contentfilled_tooltip"));
+ filled.setSelected(true);
+ filled.addItemListener(buttonDisplayListener);
+ filled.setMnemonic(resourceManager.getMnemonic("ToggleButtonDemo.contentfilled_mnemonic"));
+ leftColumn.add(filled);
+
+ leftColumn.add(Box.createRigidArea(VGAP20));
+
+ l = new JLabel(PAD_AMOUNT);
+ leftColumn.add(l);
+ ButtonGroup group = new ButtonGroup();
+ JRadioButton defaultPad = new JRadioButton(DEFAULT);
+ defaultPad.setToolTipText(resourceManager.getString("ToggleButtonDemo.default_tooltip"));
+ defaultPad.setMnemonic(resourceManager.getMnemonic("ToggleButtonDemo.default_mnemonic"));
+ defaultPad.addItemListener(buttonPadListener);
+ group.add(defaultPad);
+ defaultPad.setSelected(true);
+ leftColumn.add(defaultPad);
+
+ JRadioButton zeroPad = new JRadioButton(resourceManager.getString("ToggleButtonDemo.zero"));
+ zeroPad.setActionCommand("ZeroPad");
+ zeroPad.setToolTipText(resourceManager.getString("ToggleButtonDemo.zero_tooltip"));
+ zeroPad.addItemListener(buttonPadListener);
+ zeroPad.setMnemonic(resourceManager.getMnemonic("ToggleButtonDemo.zero_mnemonic"));
+ group.add(zeroPad);
+ leftColumn.add(zeroPad);
+
+ JRadioButton tenPad = new JRadioButton(resourceManager.getString("ToggleButtonDemo.ten"));
+ tenPad.setActionCommand("TenPad");
+ tenPad.setMnemonic(resourceManager.getMnemonic("ToggleButtonDemo.ten_mnemonic"));
+ tenPad.setToolTipText(resourceManager.getString("ToggleButtonDemo.ten_tooltip"));
+ tenPad.addItemListener(buttonPadListener);
+ group.add(tenPad);
+ leftColumn.add(tenPad);
+
+ leftColumn.add(Box.createRigidArea(VGAP20));
+ return controls;
+ }
+
+ private void createListeners() {
+ buttonDisplayListener = (ItemEvent e) -> {
+ JCheckBox cb = (JCheckBox) e.getSource();
+ String command = cb.getActionCommand();
+ switch (command) {
+ case "Enabled":
+ for (JComponent control : currentControls) {
+ control.setEnabled(cb.isSelected());
+ control.invalidate();
+ }
+ break;
+ case "PaintBorder":
+ if (currentControls.get(0) instanceof AbstractButton) {
+ for (JComponent control : currentControls) {
+ AbstractButton b = (AbstractButton) control;
+ b.setBorderPainted(cb.isSelected());
+ b.invalidate();
+ }
+ }
+ break;
+ case "PaintFocus":
+ if (currentControls.get(0) instanceof AbstractButton) {
+ for (JComponent control : currentControls) {
+ AbstractButton b = (AbstractButton) control;
+ b.setFocusPainted(cb.isSelected());
+ b.invalidate();
+ }
+ }
+ break;
+ case "ContentFilled":
+ if (currentControls.get(0) instanceof AbstractButton) {
+ for (JComponent control : currentControls) {
+ AbstractButton b = (AbstractButton) control;
+ b.setContentAreaFilled(cb.isSelected());
+ b.invalidate();
+ }
+ }
+ break;
+ }
+ invalidate();
+ validate();
+ repaint();
+ };
+
+ buttonPadListener = (ItemEvent e) -> {
+ // *** pad = 0
+ int pad = -1;
+ JRadioButton rb = (JRadioButton) e.getSource();
+ String command = rb.getActionCommand();
+ if ("ZeroPad".equals(command) && rb.isSelected()) {
+ pad = 0;
+ } else if ("TenPad".equals(command) && rb.isSelected()) {
+ pad = 10;
+ }
+
+ for (JComponent control : currentControls) {
+ AbstractButton b = (AbstractButton) control;
+ if (pad == -1) {
+ b.setMargin(null);
+ } else if (pad == 0) {
+ b.setMargin(insets0);
+ } else {
+ b.setMargin(insets10);
+ }
+ }
+ invalidate();
+ validate();
+ repaint();
+ };
+ }
+
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ SingleSelectionModel model = (SingleSelectionModel) e.getSource();
+ if (model.getSelectedIndex() == 0) {
+ currentControls = buttons;
+ } else if (model.getSelectedIndex() == 1) {
+ currentControls = radiobuttons;
+ } else if (model.getSelectedIndex() == 2) {
+ currentControls = checkboxes;
+ } else {
+ currentControls = togglebuttons;
+ }
+ }
+
+ public List extends JComponent> getCurrentControls() {
+ return currentControls;
+ }
+
+ private JPanel createHorizontalPanel(boolean threeD) {
+ JPanel p = new JPanel();
+ p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
+ p.setAlignmentY(TOP_ALIGNMENT);
+ p.setAlignmentX(LEFT_ALIGNMENT);
+ if (threeD) {
+ p.setBorder(loweredBorder);
+ }
+ return p;
+ }
+
+ private JPanel createVerticalPanel(boolean threeD) {
+ JPanel p = new JPanel();
+ p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
+ p.setAlignmentY(TOP_ALIGNMENT);
+ p.setAlignmentX(LEFT_ALIGNMENT);
+ if (threeD) {
+ p.setBorder(loweredBorder);
+ }
+ return p;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/ToggleButtonDemo.properties b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/ToggleButtonDemo.properties
new file mode 100644
index 00000000000..241368aacaa
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/ToggleButtonDemo.properties
@@ -0,0 +1,69 @@
+### Button Demo ###
+
+ToggleButtonDemo.accessible_description=The ButtonDemo shows examples of using JButton, JRadioButton, JToggleButton, and JCheckBox
+ToggleButtonDemo.tooltip=JButton, JRadioButton, JToggleButton, JCheckbox demos
+ToggleButtonDemo.name=Button Demo
+
+ToggleButtonDemo.buttons=Buttons
+ToggleButtonDemo.checkboxes=Check Boxes
+ToggleButtonDemo.radiobuttons=Radio Buttons
+ToggleButtonDemo.togglebuttons=Toggle Buttons
+
+ToggleButtonDemo.textbuttons=Text Buttons
+ToggleButtonDemo.imagebuttons=Image Buttons
+ToggleButtonDemo.textradiobuttons=Text Radio Buttons
+ToggleButtonDemo.imageradiobuttons=Image Radio Buttons
+ToggleButtonDemo.texttogglebuttons=Text Toggle Buttons
+ToggleButtonDemo.imagetogglebuttons=Image Toggle Buttons
+ToggleButtonDemo.textcheckboxes=Text CheckBoxes
+ToggleButtonDemo.imagecheckboxes=Image CheckBoxes
+
+ToggleButtonDemo.button1=One
+ToggleButtonDemo.button2=Two
+ToggleButtonDemo.button3=Three!
+
+ToggleButtonDemo.radio1=Radio One
+ToggleButtonDemo.radio2=Radio Two
+ToggleButtonDemo.radio3=Radio Three
+ToggleButtonDemo.radioX=Three(HTML!)
+
+ToggleButtonDemo.check1=One
+ToggleButtonDemo.check2=Two
+ToggleButtonDemo.check3=Three
+ToggleButtonDemo.checkX=Three(HTML!)
+
+ToggleButtonDemo.customradio=A custom "chrome" radio button.
+ToggleButtonDemo.customcheck=A custom lightbulb checkbox.
+
+ToggleButtonDemo.phone=Phone
+ToggleButtonDemo.write=Write
+ToggleButtonDemo.peace=Peace
+
+ToggleButtonDemo.controlpanel_label=Display Options:
+ToggleButtonDemo.paintborder=Paint Border
+ToggleButtonDemo.paintborder_tooltip=Click here to turn border painting on or off.
+ToggleButtonDemo.paintborder_mnemonic=b
+ToggleButtonDemo.paintfocus=Paint Focus
+ToggleButtonDemo.paintfocus_tooltip=Click here to turn focus painting on or off.
+ToggleButtonDemo.paintfocus_mnemonic=f
+ToggleButtonDemo.enabled=Enabled
+ToggleButtonDemo.enabled_tooltip=Click here to enable or disable the buttons.
+ToggleButtonDemo.enabled_mnemonic=e
+ToggleButtonDemo.contentfilled=Content Filled
+ToggleButtonDemo.contentfilled_tooltip=Click here to control the filling of the content area.
+ToggleButtonDemo.contentfilled_mnemonic=i
+
+ToggleButtonDemo.padamount_label=Pad Amount:
+ToggleButtonDemo.default=Default
+ToggleButtonDemo.default_tooltip=Uses the default padding between the border and label.
+ToggleButtonDemo.default_mnemonic=d
+ToggleButtonDemo.zero=0
+ToggleButtonDemo.zero_mnemonic=0
+ToggleButtonDemo.zero_tooltip=Uses no padding between the border and label.
+ToggleButtonDemo.ten=10
+ToggleButtonDemo.ten_mnemonic=1
+ToggleButtonDemo.ten_tooltip=Uses a 10 pixel pad between the border and label.
+
+LayoutControlPanel.textposition_label=Text Position:
+LayoutControlPanel.contentalignment_label=Content Alignment:
+
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/ToggleButtonDemo.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/ToggleButtonDemo.gif
new file mode 100644
index 00000000000..35099bb894f
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/ToggleButtonDemo.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b1.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b1.gif
new file mode 100644
index 00000000000..24a7dea299f
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b1.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b1d.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b1d.gif
new file mode 100644
index 00000000000..383404e7646
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b1d.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b1p.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b1p.gif
new file mode 100644
index 00000000000..1f3fd66328b
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b1p.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b1r.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b1r.gif
new file mode 100644
index 00000000000..2a669a24988
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b1r.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b2.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b2.gif
new file mode 100644
index 00000000000..af6d626058a
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b2.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b2d.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b2d.gif
new file mode 100644
index 00000000000..b745943ed6c
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b2d.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b2p.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b2p.gif
new file mode 100644
index 00000000000..0f4abf37992
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b2p.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b2r.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b2r.gif
new file mode 100644
index 00000000000..21becb949f4
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b2r.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b3.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b3.gif
new file mode 100644
index 00000000000..67876264d8f
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b3.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b3d.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b3d.gif
new file mode 100644
index 00000000000..4d397a394f4
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b3d.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b3p.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b3p.gif
new file mode 100644
index 00000000000..0db029f56c3
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b3p.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b3r.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b3r.gif
new file mode 100644
index 00000000000..7ddd2f9dc74
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/b3r.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/bl.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/bl.gif
new file mode 100644
index 00000000000..75fd0b9198d
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/bl.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/bldn.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/bldn.gif
new file mode 100644
index 00000000000..546f06fee6b
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/bldn.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/bm.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/bm.gif
new file mode 100644
index 00000000000..80f7352332b
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/bm.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/bmdn.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/bmdn.gif
new file mode 100644
index 00000000000..3d42d0b9e15
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/bmdn.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/br.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/br.gif
new file mode 100644
index 00000000000..b02e4484fd0
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/br.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/brdn.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/brdn.gif
new file mode 100644
index 00000000000..58cf892514b
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/brdn.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/c.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/c.gif
new file mode 100644
index 00000000000..66d0276d98a
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/c.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/cb.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/cb.gif
new file mode 100644
index 00000000000..f3acd971132
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/cb.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/cbr.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/cbr.gif
new file mode 100644
index 00000000000..278dab92f38
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/cbr.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/cbrs.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/cbrs.gif
new file mode 100644
index 00000000000..0cd04d731b4
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/cbrs.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/cbs.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/cbs.gif
new file mode 100644
index 00000000000..dbbd338a207
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/cbs.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/cdn.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/cdn.gif
new file mode 100644
index 00000000000..8a2ca4b696e
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/cdn.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/ml.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/ml.gif
new file mode 100644
index 00000000000..d8ad5804623
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/ml.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/mldn.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/mldn.gif
new file mode 100644
index 00000000000..0902554010b
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/mldn.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/mr.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/mr.gif
new file mode 100644
index 00000000000..c94cc82db54
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/mr.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/mrdn.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/mrdn.gif
new file mode 100644
index 00000000000..3b700779b1e
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/mrdn.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/rb.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/rb.gif
new file mode 100644
index 00000000000..f6ff994ceee
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/rb.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/rbp.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/rbp.gif
new file mode 100644
index 00000000000..e82d607a265
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/rbp.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/rbr.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/rbr.gif
new file mode 100644
index 00000000000..9836e0c450d
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/rbr.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/rbrs.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/rbrs.gif
new file mode 100644
index 00000000000..f48e799f448
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/rbrs.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/rbs.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/rbs.gif
new file mode 100644
index 00000000000..5c11fce0329
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/rbs.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/tl.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/tl.gif
new file mode 100644
index 00000000000..5d7a11c7357
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/tl.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/tldn.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/tldn.gif
new file mode 100644
index 00000000000..5db2fc1a402
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/tldn.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/tm.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/tm.gif
new file mode 100644
index 00000000000..c69edc99e5c
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/tm.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/tmdn.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/tmdn.gif
new file mode 100644
index 00000000000..8f765b99f5f
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/tmdn.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/tr.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/tr.gif
new file mode 100644
index 00000000000..42e601738f4
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/tr.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/trdn.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/trdn.gif
new file mode 100644
index 00000000000..8f3c186f2ad
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/resources/images/trdn.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/TreeDemo.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/TreeDemo.java
new file mode 100644
index 00000000000..1a4c555945e
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/TreeDemo.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.tree;
+
+import java.awt.*;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import javax.swing.*;
+import javax.swing.tree.DefaultMutableTreeNode;
+
+import com.sun.swingset3.DemoProperties;
+import com.sun.swingset3.demos.ResourceManager;
+
+/**
+ * JTree Demo
+ *
+ * @version 1.13 11/17/05
+ * @author Jeff Dinkins
+ */
+@DemoProperties(
+ value = "JTree Demo",
+ category = "Data",
+ description = "Demonstrates JTree, a component which supports display/editing of hierarchical data",
+ sourceFiles = {
+ "com/sun/swingset3/demos/tree/TreeDemo.java",
+ "com/sun/swingset3/demos/ResourceManager.java",
+ "com/sun/swingset3/demos/tree/resources/tree.txt",
+ "com/sun/swingset3/demos/tree/resources/TreeDemo.properties",
+ "com/sun/swingset3/demos/tree/resources/images/TreeDemo.gif"
+ }
+)
+public class TreeDemo extends JPanel {
+
+ private final ResourceManager resourceManager = new ResourceManager(this.getClass());
+ public static final String DEMO_TITLE = TreeDemo.class.getAnnotation(DemoProperties.class).value();
+
+ /**
+ * main method allows us to run as a standalone demo.
+ *
+ * @param args
+ */
+ public static void main(String[] args) {
+ JFrame frame = new JFrame(DEMO_TITLE);
+
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.getContentPane().add(new TreeDemo());
+ frame.setPreferredSize(new Dimension(800, 600));
+ frame.pack();
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+ }
+
+ /**
+ * TreeDemo Constructor
+ */
+ public TreeDemo() {
+ setLayout(new BorderLayout());
+
+ add(new JScrollPane(createTree()), BorderLayout.CENTER);
+ }
+
+ private JTree createTree() {
+ DefaultMutableTreeNode top = new DefaultMutableTreeNode(resourceManager.getString("TreeDemo.music"));
+ DefaultMutableTreeNode catagory = null;
+ DefaultMutableTreeNode artist = null;
+ DefaultMutableTreeNode record = null;
+
+ // open tree data
+ URL url = getClass().getResource("resources/tree.txt");
+
+ try {
+ // convert url to buffered string
+ InputStream is = url.openStream();
+ InputStreamReader isr = new InputStreamReader(is, "UTF-8");
+ BufferedReader reader = new BufferedReader(isr);
+
+ // read one line at a time, put into tree
+ String line = reader.readLine();
+ while (line != null) {
+ // System.out.println("reading in: ->" + line + "<-");
+ char linetype = line.charAt(0);
+ switch (linetype) {
+ case 'C':
+ catagory = new DefaultMutableTreeNode(line.substring(2));
+ top.add(catagory);
+ break;
+ case 'A':
+ if (catagory != null) {
+ catagory.add(artist = new DefaultMutableTreeNode(line.substring(2)));
+ }
+ break;
+ case 'R':
+ if (artist != null) {
+ artist.add(record = new DefaultMutableTreeNode(line.substring(2)));
+ }
+ break;
+ case 'S':
+ if (record != null) {
+ record.add(new DefaultMutableTreeNode(line.substring(2)));
+ }
+ break;
+ default:
+ break;
+ }
+ line = reader.readLine();
+ }
+ } catch (IOException ignored) {
+ }
+
+ JTree tree = new JTree(top) {
+ @Override
+ public Insets getInsets() {
+ return new Insets(5, 5, 5, 5);
+ }
+ };
+
+ tree.setEditable(true);
+
+ return tree;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/resources/TreeDemo.properties b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/resources/TreeDemo.properties
new file mode 100644
index 00000000000..77c6f82fc1e
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/resources/TreeDemo.properties
@@ -0,0 +1,8 @@
+### Tree Demo ###
+
+TreeDemo.accessible_description=This demo shows shows a sample usage of a JTree component.
+TreeDemo.tooltip=JTree demo
+TreeDemo.name=Tree Demo
+TreeDemo.music=Music
+
+
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/resources/images/TreeDemo.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/resources/images/TreeDemo.gif
new file mode 100644
index 00000000000..0f72dca4edf
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/resources/images/TreeDemo.gif differ
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/resources/tree.txt b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/resources/tree.txt
new file mode 100644
index 00000000000..2c92fcab4b7
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/resources/tree.txt
@@ -0,0 +1,628 @@
+################################################################################
+# Note: do not add blank lines, the data parser in TreeDemo.java cannot #
+# handle them. #
+# #
+# Key: #
+# Popular / Classical #
+# ---------------------------- #
+# A = Artist / Composer #
+# R = Record / Style #
+# S = Song Name / Composition #
+# C = Catagory #
+# #
+################################################################################
+C Classical
+A Beethoven
+R concertos
+S No. 1 - C
+S No. 2 - B-Flat Major
+S No. 3 - C Minor
+S No. 4 - G Major
+S No. 5 - E-Flat Major
+R Quartets
+S Six String Quartets
+S Three String Quartets
+S Grosse Fugue for String Quartets
+R Sonatas
+S Sonata in A Minor
+S Sonata in F Major
+R Symphonies
+S No. 1 - C Major
+S No. 2 - D Major
+S No. 3 - E-Flat Major
+S No. 4 - B-Flat Major
+S No. 5 - C Minor
+S No. 6 - F Major
+S No. 7 - A Major
+S No. 8 - F Major
+S No. 9 - D Minor
+A Brahms
+R Concertos
+S Violin Concerto
+S Double Concerto - A Minor
+S Piano Concerto No. 1 - D Minor
+S Piano Concerto No. 2 - B-Flat Major
+R Quartets
+S Piano Quartet No. 1 - G Minor
+S Piano Quartet No. 2 - A Major
+S Piano Quartet No. 3 - C Minor
+S String Quartet No. 3 - B-Flat Minor
+R Sonatas
+S Two Sonatas for Clarinet - F Minor
+S Two Sonatas for Clarinet - E-Flat Major
+R Symphonies
+S No. 1 - C Minor
+S No. 2 - D Minor
+S No. 3 - F Major
+S No. 4 - E Minor
+A Mozart
+R Concertos
+S Piano Concerto No. 12
+S Piano Concerto No. 17
+S Clarinet Concerto
+S Violin Concerto No. 5
+S Violin Concerto No. 4
+C Jazz
+A Albert Ayler
+R My Name is Albert Ayler
+S Bye Bye Blackbird
+S Billie's Bounce
+S Summertime
+S On Green Dolphin Street
+S C.T.
+R Swing Low Sweet Spiritual
+S Goin' Home
+S Old Man River
+S When The Saints Go Marching In
+S Deep River
+S Down By The Riverside
+S Spirits
+S Witches and Devils
+S Holy, Holy
+S Saints
+R Prophesy
+S Spirits
+S Wizard
+S Ghosts
+S Prophecy
+R New Grass
+S Free At Last
+S Everybody's Movin'
+S New Generation
+S Heart Love
+S Sun Watcher
+A Chet Baker
+R Sings and Plays
+S Let's Get Lost
+S This Is Always
+S Long Ago and Far Away
+S I Wish I Knew
+S Daybreak
+S Grey December
+S I Remember You
+R My Funny Valentine
+S My Funny Valentine
+S Someone To Watch Over Me
+S Moonlight Becomes You
+S I'm Glad There is You
+S This is Always
+S Time After Time
+S Sweet Lorraine
+S It's Always You
+S Moon Love
+S Like Someone In Love
+S I've Never Been In Love Before
+S Isn't it Romantic
+S I Fall In Love Too Easily
+R Grey December
+S Grey December
+S I Wish I Knew
+S Someone To Watch Over Me
+S Headline
+S Bockhanal
+S A Dandy Line
+S Pro Defunctus
+S Little Old Lady
+S Goodbye
+R The Route
+S Tynan Time
+S The Route
+S Minor Yours
+S Little Girl
+S Ol' Croix
+S The Great Lie
+S Sweet Lorrain
+S If I Should Lose You
+A John Coltrane
+R Blue Train
+S Blue Train
+S Moment's Notice
+S Locomotion
+S I'm Old Fashioned
+S Lazy Bird
+R Giant Steps
+S Giant Steps
+S Cousin Mary Steps
+S Countdown
+S Spiral
+S Syeeda's Song Flute
+S Naima
+S Mr. P.C.
+R My Favorite Things
+S My Favorite Things
+S Everytime We Say Goodbye
+S Summertime
+S But Not For Me
+R Crescent
+S Crescent
+S Wise One
+S Bessie's Blues
+S Lonnie's Lament
+S The Drum Thing
+R Interstellar Space
+S Mars
+S Leo
+S Venus
+S Jupiter Variation
+S Jupiter
+S Saturn
+A Miles Davis
+R Transition
+S Autumn Leaves
+S Two Bass Hit
+S Love, I've Found You
+S I Thought About You
+S All Blues
+S Seven Steps To Heaven
+R Quiet Nights
+S Once Upon a Summertime
+S Aos Pes Da Cruz
+S Wait Till You See Her
+S Corcovado
+S Summer Nights
+R My Funny Valentine
+S All of You
+S Stella By Starlight
+S All Blues
+S I Thought About You
+R Voodoo Down
+S Automn Leaves
+S Footprints
+S Directions
+S Bitches Brew
+S Hush
+C Rock
+A The Beatles
+R A Hard Day's Night
+S A Hard Day's Night
+S I Should Have Known Better
+S If I Fell
+S I'm Happy Just To Dance With You
+S And I Love Her
+S Tell Me Why
+S Can't Buy Me Love
+S Any Time At All
+S I'll Cry Instead
+S Things We Said Today
+S When I Get Home
+S You Can't Do That
+R Beatles For Sale
+S No Reply
+S I'm a Loser
+S Baby's In Black
+S Rock And Roll Music
+S I'll Follow the Sun
+S Mr. Moonlight
+S Kansas City/Hey Hey Hey Hey
+S Eight Days a Week
+S Words Of Love
+S Honey Don't
+S Every Little Thing
+S I Don't Want To Spoil the Party
+S What You're Doing
+S Everybody's Trying To Be My Baby
+R Help!
+S Help!
+S The Night Before
+S You've Got To Hide Your Love Away
+S I Need You
+S Another Girl
+S You're Going To Lose That Girl
+S Ticket To Ride
+S Act Naturally
+S It's Only Love
+S You Like Me Too Much
+S Tell Me What You See
+S I've Just Seen a Face
+S Yesterday
+S Dizzy Miss Lizzie
+R Rubber Soul
+S Drive My Car
+S Norwegian Wood
+S You Won't See Me
+S Nowhere Man
+S Think For Yourself
+S The Word
+S Michelle
+S What Goes On?
+S Girl
+S I'm Looking Through You
+S In My Life
+S Wait
+S If I Needed Someone
+S Run For Your Life
+R Revolver
+S Taxman
+S Rigby
+S I'm Only Sleeping
+S For You To
+S Here There And Everywhere
+S Yellow Submarine
+S She Said She Said
+S Good Day Sunshine
+S And Your Bird Can Sing
+S For No One
+S Doctor Robert
+S I Want To Tell You
+S Got To Get You Into My Life
+S Tomorrow Never Knows
+R Sgt. Pepper's Lonely Hearts Club Band
+S Sgt. Pepper's Lonely Hearts Club Band
+S With a Little Help From My Friends
+S Lucy in the Sky With Diamonds
+S Getting Better
+S Fixing a Hole
+S She's Leaving Home
+S Being For the Benefit of Mr. Kite
+S Within You Without You
+S When I'm Sixty Four
+S Lovely Rita
+S Good Morning
+S Sgt. Pepper's Reprise
+S A Day In The Life
+R Magical Mystery Tour
+S Magical Mystery Tour
+S Fool on the Hill
+S Flying
+S Blue Jay Way
+S Your Mother Should Know
+S I Am The Walrus
+S Hello Goodbye
+S Strawberry Fields Forever
+S Penny Lane
+S Baby You're a Rich Man
+S All You Need Is Love
+R The White Album
+S Back in the USSR
+S Dear Prudence
+S Glass Onion
+S Wild Honey Pie
+S Bungalow Bill
+S While My Guitar Gently Weeps
+S Martha My Dear
+S I'm So Tired
+S Blackbird
+S Piggies
+S Rocky Raccoon
+S Don't Pass Me By
+S Why Don't We Do It In The Road
+S I Will
+S Julia
+S Birthday
+S Yer Blues
+S Mother Nature's Son
+S Sexy Sadie
+S Helter Skelter
+S Long Long Long
+S Revolution 1
+S Honey Pie
+S Savoy Truffle
+S Cry Baby Cry
+S Revolution 9
+S Good Night
+R Abbey Road
+S Come Together
+S Something
+S Maxwell's Silver Hammer
+S Octopus's Garden
+S She's So Heavy
+S Here Comes The Sun
+S Because
+S You Never Give Me Your Money
+S Sun King
+S Mean Mr. Mustard
+S Polythene Pam
+S She Came In Through The Bathroom Window
+S Golden Slumbers
+S Carry That Weight
+S The End
+S Her Majesty
+R Let It Be
+S Two of Us
+S Dig A Pony
+S Across the Universe
+S I Me Mine
+S Dig It
+S Let It Be
+S Maggie Mae
+S I've Got A Feeling
+S One After 909
+S The Long and Winding Road
+S For You Blue
+S Get Back
+A Crowded House
+R Crowded House
+S Mean To Me
+S World Where You Live
+S Now We're Getting Somewhere
+S Don't Dream It's Over
+S Love You Til The Day I Die
+S Something So Strong
+S Hole In The River
+S Can't Carry On
+S I Walk Away
+S Tombstone
+S That's What I Call Live
+R Temple of Low Men
+S I Feel Possessed
+S Kill Eye
+S Into Temptation
+S Mansion In The Slums
+S When You Come
+S Never Be The Same
+S Love This Life
+S Sister Madly
+S In The Lowlands
+S Better Be Home Soon
+R Woodface
+S Chocolate Cake
+S It's Only Natural
+S Fall At Your Feet
+S Tall Trees
+S Weather With You
+S Whispers and Moans
+S Four Seasons in One Day
+S There Goes God
+S Fame Is
+S All I Ask
+S As Sure As I Am
+S Italian Plastic
+S She Goes On
+S How Will You Go
+R Together Alone
+S Kare Kare
+S In My Command
+S Nails In My Feet
+S Black & White Boy
+S Fingers of Love
+S Pineapple Head
+S Locked Out
+S Private Universe
+S Walking on the Spot
+S Distant Sun
+S Catherine Wheels
+S Skin Feeling
+S Together Alone
+A The Fixx
+R Shuttered Room
+S Some People
+S Stand or Fall
+S Cameras In Paris
+S Shuttered Room
+S The Fool
+S Lost Planes
+S I Live
+S Sinking Island
+S Time in a Glass
+S Red Skies
+R Reach The Beach
+S One Thing Leads To Another
+S The Sign of Fire
+S Running
+S Saved By Zero
+S Opinions
+S Reach The Beach
+S Changing
+S Liner
+S Privilege
+S Outside
+R Phantoms
+S Lose Face
+S Less Cities, More Moving People
+S Sunshine in the Shade
+S Woman on a Train
+S Wish
+S Lost in Battle Overseas
+S Question
+S In Suspense
+S Facing the Wind
+S Are We Ourselves
+S I Will
+S Phantom Living
+R Walkabout
+S Secret Separation
+S Built for the Future
+S Treasure It
+S Can't Finish
+S Walkabout
+S One Look Up
+S Read Between The Lines
+S Sense The Adventure
+S Camphor
+S Peace On Earth/Do What You Can
+R Calm Animals
+S I'm Life
+S Driven Out
+S Subterranean
+S Precious Stone
+S Gypsy Feet
+S Calm Animals
+S Shred of Evidence
+S The Flow
+S World Weary
+S Caused To Be Alarmed
+R Ink
+S All is Fair
+S How much Is Enough
+S No One Has To Cry
+S Crucified
+S Falling In Love
+S Shut It Out
+S Still Around
+S All The Best Things
+S Yesterday, Today
+S One Jungle
+S Climb The Hill
+S Make No Plans
+R Elemental
+S Two Different Views
+S Going Without
+S Is That It?
+S Happy Landings
+S Silent House
+S Fatal Shore
+S Ocean Blue
+S You Know Me
+S We Once Held Hands
+S Life's What's Killing Me
+A Harvin Garvel
+R Harvin Garvel I
+S Body
+S What You Said
+S All Rights Reserved
+S High Purity
+S Lies
+S Get Real
+S Gradma Cries
+S First Feel
+S Somethings wrong
+S Shoes
+S Spice Rack
+S Dark Feel
+S Tug of War
+S Ant Song
+R Harvin Garvel II
+S We Ain't Through
+S Trash and Spend
+S Kick
+S The Garden
+S One & Only
+S Squid Frenzy
+S Soul In Soul
+S The Desert
+S He Grew Up
+S Talk
+S Image
+S Tomorrow
+S R70
+R Full Grown Dog
+S I Am
+S Say
+S Is This Real
+S What She Said
+S Mirror Lies
+S Girls
+S Your Will
+S Slow Motion Sunday
+S Simple Life
+S The Road Song
+S The Same Way
+S Stop Tryin
+R Persia
+S Exonic
+S Drift
+S Cruise
+S MugWump
+S Smear
+S Everything
+S Keep
+S Circle
+R Sensative Beak
+S Whatcha Gotta Do
+S Somewhere In This World
+S Awaken
+S Just A Dog
+S I Can Dance
+S Tomorrow
+S Love Who?
+S Is There Something
+S I Like It
+S Easy Chair
+S As We Are One
+S Far Away
+S Leaving Science
+S What A Life
+A Komeda
+R Plan 714 Till
+S Fuego De La Vida
+S Herbamore
+S Som I Fjol
+S En Spricka I Taket
+R Genius Of
+S More Is More
+S Fire
+S Rocket Plane (Music On The Moon)
+S Boogie Woogie/Rock 'N' Roll
+S Disko
+S Top Star
+S Light O' My Life
+S If
+S Frolic
+S In Orbit
+S Arbogast
+S New New No
+R What Makes It Go
+S Binario
+S It's Alright, Baby
+S Curious
+S Cul de Sac
+S Living Things
+S Flabbergast
+S Campfire
+S Happyment
+S Our Hospitality
+S Focus
+S A Simple Formality
+A Steve Miller Band
+R Circle Of Love
+S Heart Like A Wheel
+S Get On Home
+S Baby Wanna Dance
+S Circle Of Love
+S Macho City
+R Fly Like An Eagle
+S Space Intro
+S Fly Like An Eagle
+S Wild Mountain Honey
+S Serenade
+S Dance, Dance, Dance
+S Mercury Blues
+S Take the Money and Run
+S Rockin' Me
+S You Send Me
+S Blue Odyssey
+S Sweet Maree
+S The Window
+R Book Of Dreams
+S Threshold
+S Jet Airliner
+S Winter Time
+S Swingtown
+S True Fine Love
+S Wish Upon A Star
+S Jungle Love
+S Electrolux Imbroglio
+S Sacrifice
+S The Stake
+S My Own Space
+S Babes In The Wood
+R Joker
+S Sugar, Babe
+S Mary Lou
+S Shu Ba Da Du Ma
+S Your Cash Ain't Nothin' But Trash
+S The Joker
+S The Lovin' Cup
+S Come On In My Kitchen
+S Evil
+S Something To Believe In
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/window/WindowDemo.java b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/window/WindowDemo.java
new file mode 100644
index 00000000000..cf83135d1e8
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/window/WindowDemo.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.swingset3.demos.window;
+
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.LineBorder;
+
+import com.sun.swingset3.DemoProperties;
+import com.sun.swingset3.demos.DemoUtilities;
+
+/**
+ * @author aim
+ */
+@DemoProperties(
+ value = "JWindow Demo",
+ category = "Toplevel Containers",
+ description = "Demonstrates JWindow, a toplevel container with no system border.",
+ sourceFiles = {
+ "com/sun/swingset3/demos/window/WindowDemo.java",
+ "com/sun/swingset3/demos/DemoUtilities.java",
+ "com/sun/swingset3/demos/window/resources/WindowDemo.html",
+ "com/sun/swingset3/demos/window/resources/images/WindowDemo.gif"
+ }
+)
+public final class WindowDemo extends JPanel {
+
+ public static final String SHOW_J_WINDOW = "Show JWindow...";
+ public static final String I_HAVE_NO_SYSTEM_BORDER = "I have no system border.";
+
+ private JWindow window;
+
+ private JComponent windowSpaceholder;
+
+ public WindowDemo() {
+ initComponents();
+ }
+
+ protected void initComponents() {
+ window = createWindow();
+
+ setLayout(new BorderLayout());
+ add(createControlPanel(), BorderLayout.WEST);
+ windowSpaceholder = createWindowSpaceholder(window);
+ add(windowSpaceholder, BorderLayout.CENTER);
+ }
+
+ protected JComponent createControlPanel() {
+ Box controlPanel = Box.createVerticalBox();
+ controlPanel.setBorder(new EmptyBorder(8, 8, 8, 8));
+
+ // Create button to control visibility of frame
+ JButton showButton = new JButton(SHOW_J_WINDOW);
+ showButton.addActionListener(new ShowActionListener());
+ controlPanel.add(showButton);
+
+ return controlPanel;
+ }
+
+ private static JComponent createWindowSpaceholder(JWindow window) {
+ JPanel windowPlaceholder = new JPanel();
+ Dimension prefSize = window.getPreferredSize();
+ prefSize.width += 12;
+ prefSize.height += 12;
+ windowPlaceholder.setPreferredSize(prefSize);
+
+ return windowPlaceholder;
+ }
+
+ private static JWindow createWindow() {
+
+ //Create window
+ JWindow window = new JWindow();
+ //
+
+ //Add a border to the window
+ window.getRootPane().setBorder(new LineBorder(Color.BLACK, 1));
+ //
+
+ //Add window's content
+ JLabel label = new JLabel(I_HAVE_NO_SYSTEM_BORDER);
+ label.setHorizontalAlignment(JLabel.CENTER);
+ label.setPreferredSize(new Dimension(250, 200));
+ window.add(label);
+ //
+
+ //Initialize window's size
+ // which will shrink-to-fit its contents
+ window.pack();
+ //
+
+ return window;
+ }
+
+ public void start() {
+ DemoUtilities.setToplevelLocation(window, windowSpaceholder, SwingConstants.CENTER);
+ showWindow();
+ }
+
+ public void stop() {
+ //Hide window
+ window.setVisible(false);
+ //
+ }
+
+ public void showWindow() {
+ //Show window
+ // if window already visible, then bring to the front
+ if (window.isShowing()) {
+ window.toFront();
+ } else {
+ window.setVisible(true);
+ }
+ //
+ }
+
+ private class ShowActionListener implements ActionListener {
+
+ @Override
+ public void actionPerformed(ActionEvent actionEvent) {
+ showWindow();
+ }
+ }
+
+ public static void main(String args[]) {
+ EventQueue.invokeLater(() -> {
+ JFrame frame = new JFrame();
+ WindowDemo demo = new WindowDemo();
+ frame.add(demo);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.pack();
+ frame.setVisible(true);
+ demo.start();
+ });
+ }
+}
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/window/resources/WindowDemo.html b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/window/resources/WindowDemo.html
new file mode 100644
index 00000000000..e075e5d4505
--- /dev/null
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/window/resources/WindowDemo.html
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+ Show how Swing's top-level container,
+ JWindow, can be used to create areas on the screen which
+ do not have system-supplied borders and therefore cannot be moved or resized
+ by the user like frames or dialogs. JWindow is commonly used to implement menus,
+ tooltips, and popups.
+
+
+
diff --git a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/window/resources/images/WindowDemo.gif b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/window/resources/images/WindowDemo.gif
new file mode 100644
index 00000000000..4eef882938b
Binary files /dev/null and b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/window/resources/images/WindowDemo.gif differ
diff --git a/jdk/test/sanity/client/lib/jemmy/README b/jdk/test/sanity/client/lib/jemmy/README
new file mode 100644
index 00000000000..b3318ecfcb6
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/README
@@ -0,0 +1,3 @@
+This src folder contains a copy of Jemmy 2 library sources from https://jemmy.java.net/.
+
+Do NOT modify files in it.
\ No newline at end of file
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Action.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Action.java
new file mode 100644
index 00000000000..1d5c359b533
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Action.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+/**
+ *
+ * Defines an action to be executed by {@code ActionProducer} instance.
+ *
+ * @see org.netbeans.jemmy.ActionProducer
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface Action {
+
+ /**
+ * Executes this action.
+ *
+ * @param obj action argument. This argument might be the method parameter
+ * in an invocation of {@code ActionProducer.produceAction(Object)}.
+ * @return action result.
+ */
+ public R launch(P obj);
+
+ /**
+ * Returns the description value.
+ *
+ * @return Action description.
+ */
+ public String getDescription();
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ActionProducer.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ActionProducer.java
new file mode 100644
index 00000000000..4af9d0d88c4
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ActionProducer.java
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.util.Optional;
+
+/**
+ *
+ * Runs actions with or without waiting.
+ *
+ *
Timeouts used:
+ * ActionProducer.MaxActionTime - time action should be finished in.
+ *
+ * @see Action
+ * @see Timeouts
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class ActionProducer extends Thread
+ implements Action, Waitable, P>, Timeoutable {
+
+ private final static long ACTION_TIMEOUT = 10000;
+
+ private Action action;
+ private boolean needWait = true;
+ private P parameter;
+ private boolean finished;
+ private R result = null;
+ private Timeouts timeouts;
+ private Waiter, P> waiter;
+ private TestOut output;
+ private Throwable exception;
+
+ /**
+ * Creates a producer for an action.
+ *
+ * @param a Action implementation.
+ */
+ public ActionProducer(Action a) {
+ super();
+ waiter = new Waiter<>(this);
+ action = a;
+ setTimeouts(JemmyProperties.getProperties().getTimeouts());
+ setOutput(JemmyProperties.getProperties().getOutput());
+ finished = false;
+ exception = null;
+ }
+
+ /**
+ * Creates a producer for an action.
+ *
+ * @param a Action implementation.
+ * @param nw Defines if {@code produceAction} method should wait for
+ * the end of action.
+ */
+ public ActionProducer(Action a, boolean nw) {
+ super();
+ waiter = new Waiter<>(this);
+ action = a;
+ needWait = nw;
+ setTimeouts(JemmyProperties.getProperties().getTimeouts());
+ setOutput(JemmyProperties.getProperties().getOutput());
+ finished = false;
+ exception = null;
+ }
+
+ /**
+ * Creates a producer. {@code produceAction} must be overridden.
+ */
+ protected ActionProducer() {
+ super();
+ waiter = new Waiter<>(this);
+ setTimeouts(JemmyProperties.getProperties().getTimeouts());
+ setOutput(JemmyProperties.getProperties().getOutput());
+ finished = false;
+ exception = null;
+ }
+
+ /**
+ * Creates a producer. {@code produceAction} must be overridden.
+ *
+ * @param nw Defines if {@code produceAction} method should wait for
+ * the end of action.
+ */
+ protected ActionProducer(boolean nw) {
+ super();
+ waiter = new Waiter<>(this);
+ needWait = nw;
+ setTimeouts(JemmyProperties.getProperties().getTimeouts());
+ setOutput(JemmyProperties.getProperties().getOutput());
+ finished = false;
+ exception = null;
+ }
+
+ static {
+ Timeouts.initDefault("ActionProducer.MaxActionTime", ACTION_TIMEOUT);
+ }
+
+ /**
+ * Set all the time outs used by sleeps or waits used by the launched
+ * action.
+ *
+ * @param ts An object containing timeout information.
+ * @see org.netbeans.jemmy.Timeouts
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see #getTimeouts
+ */
+ @Override
+ public void setTimeouts(Timeouts ts) {
+ timeouts = ts;
+ }
+
+ /**
+ * Get all the time outs used by sleeps or waits used by the launched
+ * action.
+ *
+ * @return an object containing information about timeouts.
+ * @see org.netbeans.jemmy.Timeouts
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see #setTimeouts
+ */
+ @Override
+ public Timeouts getTimeouts() {
+ return timeouts;
+ }
+
+ /**
+ * Identity of the streams or writers used for print output.
+ *
+ * @param out An object containing print output assignments for output and
+ * error streams.
+ * @see org.netbeans.jemmy.TestOut
+ * @see org.netbeans.jemmy.Outputable
+ */
+ public void setOutput(TestOut out) {
+ output = out;
+ waiter.setOutput(output);
+ }
+
+ /**
+ * Returns the exception value.
+ *
+ * @return a Throwable object representing the exception value
+ */
+ public Throwable getException() {
+ return exception;
+ }
+
+ /**
+ * Defines action priority in terms of thread priority. Increase (decrease)
+ * parameter value to Thread.MIN_PRIORITY(MAX_PRIORITY) in case if it is
+ * less(more) then it.
+ *
+ * @param newPriority New thread priority.
+ */
+ public void setActionPriority(int newPriority) {
+ int priority;
+ if (newPriority < Thread.MIN_PRIORITY) {
+ priority = MIN_PRIORITY;
+ } else if (newPriority > Thread.MAX_PRIORITY) {
+ priority = MAX_PRIORITY;
+ } else {
+ priority = newPriority;
+ }
+ try {
+ setPriority(priority);
+ } catch (IllegalArgumentException | SecurityException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Get the result of a launched action.
+ *
+ * @return a launched action's result. without waiting in case if
+ * {@code getFinished()}
+ * @see #getFinished()
+ */
+ public R getResult() {
+ return result;
+ }
+
+ /**
+ * Check if a launched action has finished.
+ *
+ * @return {@code true} if the launched action has completed, either
+ * normally or with an exception; {@code false} otherwise.
+ */
+ public boolean getFinished() {
+ synchronized (this) {
+ return finished;
+ }
+ }
+
+ /**
+ * Does nothing; the method should be overridden by inheritors.
+ *
+ * @param obj An object used to modify execution. This might be a
+ * {@code java.lang.String[]} that lists a test's command line
+ * arguments.
+ * @return An object - result of the action.
+ * @see org.netbeans.jemmy.Action
+ */
+ @Override
+ public R launch(P obj) {
+ return null;
+ }
+
+ /**
+ * @return this {@code ActionProducer}'s description.
+ * @see Action
+ */
+ @Override
+ public String getDescription() {
+ if (action != null) {
+ return action.getDescription();
+ } else {
+ return "Unknown action";
+ }
+ }
+
+ /**
+ * Starts execution. Uses ActionProducer.MaxActionTime timeout.
+ *
+ * @param obj Parameter to be passed into action's
+ * {@code launch(Object)} method. This parameter might be a
+ * {@code java.lang.String[]} that lists a test's command line
+ * arguments.
+ * @param actionTimeOrigin is used for timeout reporting, if non-null.
+ * @return {@code launch(Object)} result.
+ * @throws TimeoutExpiredException
+ * @exception InterruptedException
+ */
+ public R produceAction(P obj, String actionTimeOrigin) throws InterruptedException {
+ parameter = obj;
+ synchronized (this) {
+ finished = false;
+ }
+ start();
+ if (needWait) {
+ waiter.setTimeoutsToCloneOf(timeouts, "ActionProducer.MaxActionTime", actionTimeOrigin);
+ try {
+ waiter.waitAction(null);
+ } catch (TimeoutExpiredException e) {
+ output.printError("Timeout for \"" + getDescription()
+ + "\" action has been expired. Thread has been interrupted.");
+ interrupt();
+ throw (e);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Launch an action in a separate thread of execution. When the action
+ * finishes, record that fact. If the action finishes normally, store it's
+ * result. Use {@code getFinished()} and {@code getResult} to
+ * answer questions about test completion and return value, respectively.
+ *
+ * @see #getFinished()
+ * @see #getResult()
+ * @see java.lang.Runnable
+ */
+ @Override
+ public final void run() {
+ result = null;
+ try {
+ result = launchAction(parameter);
+ } catch (Throwable e) {
+ exception = e;
+ }
+ synchronized (this) {
+ finished = true;
+ }
+ }
+
+ /**
+ * Inquire for a reference to the object returned by a launched action.
+ *
+ * @param obj Not used.
+ * @return the result returned when a launched action finishes normally.
+ * @see org.netbeans.jemmy.Waitable
+ */
+ @Override
+ public final Optional actionProduced(P obj) {
+ synchronized (this) {
+ if (finished) {
+ return Optional.ofNullable(result);
+ } else {
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Launch some action. Pass the action parameters and get it's return value,
+ * too.
+ *
+ * @param obj Parameter used to configure the execution of whatever this
+ * {@code ActionProducer} puts into execution.
+ * @return the return value of the action.
+ */
+ private R launchAction(P obj) {
+ if (action != null) {
+ return action.launch(obj);
+ } else {
+ return launch(obj);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "ActionProducer{" + "action=" + action + ", needWait=" + needWait + ", parameter=" + parameter + ", finished=" + finished + ", result=" + result + ", exception=" + exception + '}';
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Bundle.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Bundle.java
new file mode 100644
index 00000000000..19a15024c92
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Bundle.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.jar.JarFile;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+/**
+ *
+ * Load string resources from file. Resources should be stored in
+ * {@code name=value} format.
+ *
+ * @see org.netbeans.jemmy.BundleManager
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class Bundle extends Object {
+
+ private Properties resources;
+
+ /**
+ * Bunble constructor.
+ */
+ public Bundle() {
+ resources = new Properties();
+ }
+
+ /**
+ * Loads resources from an input stream.
+ *
+ * @param stream Stream to load resources from.
+ * @exception IOException
+ */
+ public void load(InputStream stream)
+ throws IOException {
+ resources.load(stream);
+ }
+
+ /**
+ * Loads resources from a simple file.
+ *
+ * @param fileName Name of the file to load resources from.
+ * @exception IOException
+ * @exception FileNotFoundException
+ */
+ public void loadFromFile(String fileName)
+ throws IOException, FileNotFoundException {
+ try (FileInputStream fileInputStream = new FileInputStream(fileName)) {
+ load(fileInputStream);
+ }
+ }
+
+ /**
+ * Loads resources from a file in a jar archive.
+ *
+ * @param fileName Name of the jar archive.
+ * @param entryName ?enryName? Name of the file to load resources from.
+ * @exception IOException
+ * @exception FileNotFoundException
+ */
+ public void loadFromJar(String fileName, String entryName)
+ throws IOException, FileNotFoundException {
+ try (JarFile jFile = new JarFile(fileName);
+ InputStream inputStream = jFile.getInputStream(jFile.getEntry(entryName))) {
+ load(inputStream);
+ }
+ }
+
+ /**
+ * Loads resources from a file in a zip archive.
+ *
+ * @param fileName Name of the zip archive.
+ * @param entryName ?enryName? Name of the file to load resources from.
+ * @exception ZipException
+ * @exception IOException
+ * @exception FileNotFoundException
+ */
+ public void loadFromZip(String fileName, String entryName)
+ throws IOException, FileNotFoundException, ZipException {
+ try (ZipFile zFile = new ZipFile(fileName);
+ InputStream inputStream = zFile.getInputStream(zFile.getEntry(entryName))) {
+ load(inputStream);
+ }
+ }
+
+ /**
+ * Prints bundle contents.
+ *
+ * @param writer Writer to print data in.
+ */
+ public void print(PrintWriter writer) {
+ Enumeration keys = resources.keys();
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ writer.println(key + "=" + getResource(key));
+ }
+ }
+
+ /**
+ * Prints bundle contents.
+ *
+ * @param stream Stream to print data in.
+ */
+ public void print(PrintStream stream) {
+ print(new PrintWriter(stream));
+ }
+
+ /**
+ * Gets resource by key.
+ *
+ * @param key Resource key
+ * @return Resource value or null if resource was not found.
+ */
+ public String getResource(String key) {
+ return resources.getProperty(key);
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/BundleManager.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/BundleManager.java
new file mode 100644
index 00000000000..308f5b36ddb
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/BundleManager.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.zip.ZipException;
+
+/**
+ *
+ * Provides functionality to work with a bunch of resource files.
+ *
+ * @see org.netbeans.jemmy.Bundle
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class BundleManager {
+
+ private Hashtable bundles;
+
+ /**
+ * Bundle manager constructor.
+ */
+ public BundleManager() {
+ bundles = new Hashtable<>();
+ try {
+ load();
+ } catch (IOException ignored) {
+ }
+ }
+
+ /**
+ * Adds a Bundle to the managed collection of resource files.
+ *
+ * @param bundle Bundle object
+ * @param ID Symbolic bundle id
+ * @return First parameter or null if bundle with ID already exists.
+ * @see org.netbeans.jemmy.Bundle
+ */
+ public Bundle addBundle(Bundle bundle, String ID) {
+ if (getBundle(ID) != null) {
+ return null;
+ } else {
+ bundles.put(ID, bundle);
+ return bundle;
+ }
+ }
+
+ /**
+ * Removes a Bundle from the managed collection of resource files.
+ *
+ * @param ID Symbolic bundle id
+ * @return Removed bundle or null if no bundle ID is.
+ */
+ public Bundle removeBundle(String ID) {
+ Bundle value = getBundle(ID);
+ bundles.remove(ID);
+ return value;
+ }
+
+ /**
+ * Returns a Bundle given it's symbolic ID.
+ *
+ * @param ID Symbolic bundle ID
+ * @return the Bundle. A null reference is returned if no bundle with the
+ * symbolic ID was found.
+ */
+ public Bundle getBundle(String ID) {
+ return bundles.get(ID);
+ }
+
+ /**
+ * Create a new Bundle, load resources from a simple text file, and add the
+ * bundle. Load resources from a text file to a new Bundle object. The new
+ * Bundle is added to the collection of objects managed by this
+ * {@code BundleManager}.
+ *
+ * @param fileName Name of a file to load resources from.
+ * @param ID Symbolic bundle ID used to identify the new bundle used to
+ * manage the resources from the file.
+ * @return a newly created bundle.
+ * @exception IOException
+ * @exception FileNotFoundException
+ */
+ public Bundle loadBundleFromFile(String fileName, String ID)
+ throws IOException, FileNotFoundException {
+ if (getBundle(ID) != null) {
+ return null;
+ }
+ Bundle bundle = new Bundle();
+ bundle.loadFromFile(fileName);
+ return addBundle(bundle, ID);
+ }
+
+ public Bundle loadBundleFromStream(InputStream stream, String ID)
+ throws IOException, FileNotFoundException {
+ if (getBundle(ID) != null) {
+ return null;
+ }
+ Bundle bundle = new Bundle();
+ bundle.load(stream);
+ return addBundle(bundle, ID);
+ }
+
+ public Bundle loadBundleFromResource(ClassLoader cl, String resource, String ID)
+ throws IOException, FileNotFoundException {
+ return loadBundleFromStream(cl.getResourceAsStream(resource), ID);
+ }
+
+ /**
+ * Loads resources from simple text file pointed by jemmy.resources system
+ * property. The resources are loaded into the Bundle with ID "". Does not
+ * do anything if jemmy.resources has not been set or is empty.
+ *
+ * @return a newly created bundle.
+ * @exception IOException
+ * @exception FileNotFoundException
+ */
+ public Bundle load()
+ throws IOException, FileNotFoundException {
+ if (System.getProperty("jemmy.resources") != null
+ && !System.getProperty("jemmy.resources").equals("")) {
+ return loadBundleFromFile(System.getProperty("jemmy.resources"), "");
+ }
+ return null;
+ }
+
+ /**
+ * Loads resources from file in jar archive into new Bundle object and adds
+ * it.
+ *
+ * @param fileName Name of jar file.
+ * @param entryName ?enryName? Name of file to load resources from.
+ * @param ID Symbolic bundle id
+ * @return a newly created bundle.
+ * @exception IOException
+ * @exception FileNotFoundException
+ */
+ public Bundle loadBundleFromJar(String fileName, String entryName, String ID)
+ throws IOException, FileNotFoundException {
+ if (getBundle(ID) != null) {
+ return null;
+ }
+ Bundle bundle = new Bundle();
+ bundle.loadFromJar(fileName, entryName);
+ return addBundle(bundle, ID);
+ }
+
+ /**
+ * Loads resources from file in zip archive into new Bundle object and adds
+ * it.
+ *
+ * @param fileName Name of jar file.
+ * @param entryName ?enryName? Name of file to load resources from.
+ * @param ID Symbolic bundle id
+ * @return a newly created bundle.
+ * @exception ZipException
+ * @exception IOException
+ * @exception FileNotFoundException
+ */
+ public Bundle loadBundleFromZip(String fileName, String entryName, String ID)
+ throws IOException, FileNotFoundException, ZipException {
+ if (getBundle(ID) != null) {
+ return null;
+ }
+ Bundle bundle = new Bundle();
+ bundle.loadFromZip(fileName, entryName);
+ return addBundle(bundle, ID);
+ }
+
+ /**
+ * Prints bundles contents.
+ *
+ * @param writer Writer to print data in.
+ */
+ public void print(PrintWriter writer) {
+ Enumeration keys = bundles.keys();
+ Bundle bundle;
+ String key;
+ while (keys.hasMoreElements()) {
+ key = keys.nextElement();
+ writer.println("\"" + key + "\" bundle contents");
+ bundle = getBundle(key);
+ bundle.print(writer);
+ }
+ }
+
+ /**
+ * Prints bundles contents.
+ *
+ * @param stream Stream to print data in.
+ */
+ public void print(PrintStream stream) {
+ print(new PrintWriter(stream));
+ }
+
+ /**
+ * Returns resource from ID bundle.
+ *
+ * @param bundleID Bundle ID.
+ * @param key Resource key.
+ * @return the resource value. If the bundle ID does not exist if the
+ * resource with the given key cannot be found, a null reference is
+ * returned.
+ */
+ public String getResource(String bundleID, String key) {
+ Bundle bundle = getBundle(bundleID);
+ if (bundle != null) {
+ return bundle.getResource(key);
+ }
+ return null;
+ }
+
+ /**
+ * Searches for a resource in all the managed Bundles.
+ *
+ * @param key Resource key.
+ * @return first resource value found that is indexed by the given key. If
+ * no resource is found, return a null reference.
+ */
+ public String getResource(String key) {
+ Enumeration data = bundles.elements();
+ String value;
+ while (data.hasMoreElements()) {
+ value = data.nextElement().getResource(key);
+ if (value != null) {
+ return value;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Counts the number of resource occurences in all the managed Bundles.
+ *
+ * @param key Resource key
+ * @return the number of resource occurences with the given key among all
+ * the Bundles managed by this BundleManager.
+ */
+ public int calculateResources(String key) {
+ Enumeration data = bundles.elements();
+ int count = 0;
+ while (data.hasMoreElements()) {
+ if (data.nextElement().getResource(key) != null) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ /**
+ * Creates a shallow copy of this BundleManager. Does not copy bundles, only
+ * their references.
+ *
+ * @return a copy of this BundleManager.
+ */
+ public BundleManager cloneThis() {
+ BundleManager result = new BundleManager();
+ Enumeration keys = bundles.keys();
+ Enumeration elements = bundles.elements();
+ while (keys.hasMoreElements()) {
+ result.bundles.put(keys.nextElement(),
+ elements.nextElement());
+ }
+ return result;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/CharBindingMap.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/CharBindingMap.java
new file mode 100644
index 00000000000..6b6c51ef93b
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/CharBindingMap.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+/**
+ *
+ * Defines char-to-key binding. The generation of a symbol will, in general,
+ * require modifier keys to be pressed prior to pressing a primary key. Classes
+ * that implement {@code CharBindingMap} communicate what modifiers and
+ * primary key are required to generate a given symbol.
+ *
+ * @see org.netbeans.jemmy.DefaultCharBindingMap
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface CharBindingMap {
+
+ /**
+ * Returns the code of the primary key used to type a symbol.
+ *
+ * @param c Symbol code.
+ * @return a key code.
+ * @see java.awt.event.InputEvent
+ */
+ public int getCharKey(char c);
+
+ /**
+ * Returns the modifiers that should be pressed to type a symbol.
+ *
+ * @param c Symbol code.
+ * @return a combination of InputEvent MASK fields.
+ * @see java.awt.event.InputEvent
+ */
+ public int getCharModifiers(char c);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ClassReference.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ClassReference.java
new file mode 100644
index 00000000000..5347deb692c
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ClassReference.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ *
+ * Allows access to classes by reflection.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class ClassReference {
+
+ private Class> cl;
+ private Object instance;
+
+ /**
+ * Constructor.
+ *
+ * @param o Object to work with.
+ */
+ public ClassReference(Object o) {
+ super();
+ instance = o;
+ cl = o.getClass();
+ }
+
+ /**
+ * Contructor. The object created by this constructor can be used to access
+ * static methods and fields only.
+ *
+ * @param className name of class
+ * @exception ClassNotFoundException
+ */
+ public ClassReference(String className)
+ throws ClassNotFoundException {
+ super();
+ cl = Class.forName(className);
+ instance = null;
+ }
+
+ /**
+ * Executes class's {@code main(java.lang.String[])} method with a
+ * zero-length {@code java.lang.String} array as a parameter.
+ *
+ * @exception NoSuchMethodException
+ * @exception InvocationTargetException
+ */
+ public void startApplication()
+ throws InvocationTargetException, NoSuchMethodException {
+ String[] params = new String[0];
+ startApplication(params);
+ }
+
+ /**
+ * Executes class's {@code main(java.lang.String[])} method.
+ *
+ * @param params The {@code java.lang.String} array to pass to
+ * {@code main(java.lang.String[])}.
+ * @exception NoSuchMethodException
+ * @exception InvocationTargetException
+ */
+ public void startApplication(String[] params)
+ throws InvocationTargetException, NoSuchMethodException {
+ String[] real_params;
+ if (params == null) {
+ real_params = new String[0];
+ } else {
+ real_params = params;
+ }
+ String[][] methodParams = {real_params};
+ Class>[] classes = {real_params.getClass()};
+ try {
+ invokeMethod("main", methodParams, classes);
+ } catch (IllegalAccessException | IllegalStateException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Locates method by name and parameter types and executes it.
+ *
+ * @param method_name Name of method.
+ * @param params Method parameters.
+ * @param params_classes Method parameters types.
+ * @return the return value from an invocation of the Method.
+ * If {@code method_name} method is void, {@code null} is
+ * returned.
+ * If {@code method_name} method returns a primitive type, then return
+ * wrapper class instance.
+ * @throws InvocationTargetException when the invoked method throws an
+ * exception.
+ * @throws NoSuchMethodException when the method cannot be found.
+ * @throws IllegalAccessException when access to the class or method is
+ * lacking.
+ * @throws SecurityException if access to the package or method is denied.
+ * @exception IllegalAccessException
+ * @exception NoSuchMethodException
+ * @exception InvocationTargetException
+ */
+ public Object invokeMethod(String method_name, Object[] params, Class>[] params_classes)
+ throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+ if (params == null) {
+ params = new Object[0];
+ }
+ if (params_classes == null) {
+ params_classes = new Class>[0];
+ }
+ Method method = cl.getMethod(method_name,
+ params_classes);
+ return method.invoke(instance, params);
+ }
+
+ /**
+ * Locates constructor by parameter types and creates an instance.
+ *
+ * @param params An array of Method parameters.
+ * @param params_classes An array of Method parameter types.
+ * @return a new class instance.
+ * @throws InvocationTargetException when the invoked constructor throws an
+ * exception.
+ * @throws NoSuchMethodException when the constructor cannot be found.
+ * @throws IllegalAccessException when access to the class or constructor is
+ * lacking.
+ * @throws InstantiationException when the constructor is for an abstract
+ * class.
+ * @throws SecurityException if access to the package or constructor is
+ * denied.
+ * @exception IllegalAccessException
+ * @exception NoSuchMethodException
+ * @exception InstantiationException
+ * @exception InvocationTargetException
+ */
+ public Object newInstance(Object[] params, Class>[] params_classes)
+ throws InvocationTargetException, NoSuchMethodException,
+ IllegalAccessException, InstantiationException {
+ if (params == null) {
+ params = new Object[0];
+ }
+ if (params_classes == null) {
+ params_classes = new Class>[0];
+ }
+ Constructor> constructor = cl.getConstructor(params_classes);
+ return constructor.newInstance(params);
+ }
+
+ /**
+ * Returns the field value.
+ *
+ * @param field_name The name of the field.
+ * @return the field value
+ * @see #setField
+ * @throws NoSuchFieldException when the field cannot be found.
+ * @throws IllegalAccessException when access to the class or constructor is
+ * lacking.
+ * @throws SecurityException if access to the package or field is denied.
+ * @exception IllegalAccessException
+ * @exception NoSuchFieldException
+ */
+ public Object getField(String field_name)
+ throws NoSuchFieldException, IllegalAccessException {
+ return cl.getField(field_name).get(instance);
+ }
+
+ /**
+ * Change a field's value.
+ *
+ * @param field_name The name of the field.
+ * @param newValue The fields new value.
+ * @see #getField
+ * @throws NoSuchFieldException when the field cannot be found.
+ * @throws IllegalAccessException when access to the class or constructor is
+ * lacking.
+ * @throws SecurityException if access to the package or field is denied.
+ * @exception IllegalAccessException
+ * @exception NoSuchFieldException
+ */
+ public void setField(String field_name, Object newValue)
+ throws NoSuchFieldException, IllegalAccessException {
+ cl.getField(field_name).set(instance, newValue);
+ }
+
+ /**
+ * Returns all superclasses.
+ *
+ * @return an array of superclasses, starting with the reference class and
+ * ending with {@code java.lang.Object}.
+ */
+ public Class>[] getClasses() {
+ Class> cls = cl;
+ int count = 0;
+ do {
+ count++;
+ cls = cls.getSuperclass();
+ } while (cls != null);
+ Class>[] result = new Class>[count];
+ cls = cl;
+ for (int i = 0; i < count; i++) {
+ result[i] = cls;
+ cls = cls.getSuperclass();
+ }
+ return result;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ComponentChooser.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ComponentChooser.java
new file mode 100644
index 00000000000..945900d6825
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ComponentChooser.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.awt.Component;
+
+/**
+ *
+ * This interface should be implemented to define the criteria used to search
+ * for a component.
+ *
+ * @see org.netbeans.jemmy.ComponentSearcher
+ * @see org.netbeans.jemmy.WindowWaiter
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface ComponentChooser {
+
+ /**
+ * Check if the component argument meets the search criteria.
+ *
+ * @param comp Component to check.
+ * @return {@code true} when the component conforms to the search
+ * criteria; {@code false} otherwise.
+ */
+ public boolean checkComponent(Component comp);
+
+ /**
+ * Returns searched component description.
+ *
+ * @return a String representing the description value
+ */
+ public String getDescription();
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ComponentIsNotFocusedException.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ComponentIsNotFocusedException.java
new file mode 100644
index 00000000000..de6dc9a37dd
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ComponentIsNotFocusedException.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.awt.Component;
+
+/**
+ *
+ * Exception can be thrown as a result of attempt to produce a key operation for
+ * a component which does not have focus.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class ComponentIsNotFocusedException extends JemmyInputException {
+
+ private static final long serialVersionUID = 42L;
+
+ /**
+ * Constructs a ComponentIsNotFocusedException object.
+ *
+ * @param comp a Component.
+ */
+ public ComponentIsNotFocusedException(Component comp) {
+ super("Component do not have focus", comp);
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ComponentIsNotVisibleException.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ComponentIsNotVisibleException.java
new file mode 100644
index 00000000000..e4212c3cdd1
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ComponentIsNotVisibleException.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.awt.Component;
+
+/**
+ *
+ * Exception can be thrown as a result of attempt to produce a mouse operation
+ * for a component which is not visible.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class ComponentIsNotVisibleException extends JemmyInputException {
+
+ private static final long serialVersionUID = 42L;
+
+ /**
+ * Constructs a ComponentIsNotVisibleException object.
+ *
+ * @param comp a Component.
+ */
+ public ComponentIsNotVisibleException(Component comp) {
+ super("Component is not visible", comp);
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ComponentSearcher.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ComponentSearcher.java
new file mode 100644
index 00000000000..8c7b1ad2af9
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ComponentSearcher.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.util.Vector;
+
+/**
+ *
+ * Contains methods to search for components below a a given
+ * {@code java.awt.Container} in the display containment hierarchy. Uses a
+ * {@code ComponentChooser} interface implementation to find a component.
+ *
+ * @see ComponentChooser
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class ComponentSearcher implements Outputable {
+
+ private int ordinalIndex;
+ private Container container;
+ private TestOut out;
+ private QueueTool queueTool;
+ private String containerToString;
+
+ /**
+ * Contructor. The search is constrained so that only components that lie
+ * below the given container in the containment hierarchy are considered.
+ *
+ * @param c Container to find components in.
+ */
+ public ComponentSearcher(Container c) {
+ super();
+ container = c;
+ setOutput(JemmyProperties.getProperties().getOutput());
+ queueTool = new QueueTool();
+ }
+
+ /**
+ * Creates {@code ComponentChooser} implementation whose
+ * {@code checkComponent(Component)} method returns {@code true}
+ * for any component.
+ *
+ * @param description Component description.
+ * @return ComponentChooser instance.
+ */
+ public static ComponentChooser getTrueChooser(String description) {
+ class TrueChooser implements ComponentChooser {
+
+ private String description;
+
+ public TrueChooser(String desc) {
+ description = desc;
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ return true;
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public String toString() {
+ return "TrueChooser{" + "description=" + description + '}';
+ }
+ }
+ return new TrueChooser(description);
+ }
+
+ /**
+ * Defines print output streams or writers.
+ *
+ * @param output ?out? Identify the streams or writers used for print
+ * output.
+ * @see org.netbeans.jemmy.TestOut
+ * @see org.netbeans.jemmy.Outputable
+ * @see #getOutput
+ */
+ @Override
+ public void setOutput(TestOut output) {
+ out = output;
+ }
+
+ /**
+ * Returns print output streams or writers.
+ *
+ * @return an object that contains references to objects for printing to
+ * output and err streams.
+ * @see org.netbeans.jemmy.TestOut
+ * @see org.netbeans.jemmy.Outputable
+ * @see #setOutput
+ */
+ @Override
+ public TestOut getOutput() {
+ return out;
+ }
+
+ /**
+ * Returns container.toString(). It is called in dispatch thread.
+ *
+ * @return container.toString()
+ */
+ private String containerToString() {
+ if (containerToString == null) {
+ containerToString = container == null ? "null"
+ : queueTool.invokeSmoothly(
+ new QueueTool.QueueAction("container.toString()") {
+ @Override
+ public String launch() {
+ return container.toString();
+ }
+ }
+ );
+ }
+ return containerToString;
+ }
+
+ /**
+ * Searches for a component. The search for the component proceeds
+ * recursively in the component hierarchy rooted in this
+ * {@code ComponentChooser}'s container.
+ *
+ * @param chooser ComponentChooser instance, defining and applying the
+ * search criteria.
+ * @param index Ordinal component index. Indices start at 0.
+ * @return the {@code index}'th component from among those components
+ * for which the chooser's {@code checkComponent(Component)} method
+ * returns {@code true}. A {@code null} reference is returned if
+ * there are fewer than {@code index-1} components meeting the search
+ * criteria exist in the component hierarchy rooted in this
+ * {@code ComponentChooser}'s container.
+ */
+ public Component findComponent(ComponentChooser chooser, int index) {
+ ordinalIndex = 0;
+ final Component result = findComponentInContainer(container, chooser, index, null);
+ if (result != null) {
+ // get result.toString() - run in dispatch thread
+ String resultToString = queueTool.invokeSmoothly(
+ new QueueTool.QueueAction("result.toString()") {
+ @Override
+ public String launch() {
+ return result.toString();
+ }
+ }
+ );
+ out.printTrace("Component " + chooser.getDescription()
+ + "\n was found in container " + containerToString()
+ + "\n " + resultToString);
+ out.printGolden("Component \"" + chooser.getDescription() + "\" was found");
+ } else {
+ out.printTrace("Component " + chooser.getDescription()
+ + "\n was not found in container " + containerToString());
+ out.printGolden("Component \"" + chooser.getDescription() + "\" was not found");
+ }
+ return result;
+ }
+
+ /**
+ * Searches for a component. The search for the component proceeds
+ * recursively in the component hierarchy rooted in this
+ * {@code ComponentChooser}'s container.
+ *
+ * @param chooser ComponentChooser instance, defining and applying the
+ * search criteria.
+ * @return the first component for which the chooser's
+ * {@code checkComponent(Component)} method returns {@code true}.
+ * A {@code null} reference is returned if no component meeting the
+ * search criteria exist in the component hierarchy rooted in this
+ * {@code ComponentChooser}'s container.
+ */
+ public Component findComponent(ComponentChooser chooser) {
+ return findComponent(chooser, 0);
+ }
+
+ /**
+ * Searches for all components. The search for the components proceeds
+ * recursively in the component hierarchy rooted in this
+ * {@code ComponentChooser}'s container.
+ *
+ * @param chooser ComponentChooser instance, defining and applying the
+ * search criteria.
+ * @return the components for which the chooser's
+ * {@code checkComponent(Component)} method returns {@code true}.
+ * An empty array is returned if no component meeting the search criteria
+ * exists in the component hierarchy rooted in this
+ * {@code ComponentChooser}'s container.
+ */
+ public Component[] findComponents(ComponentChooser chooser) {
+ Vector allSeen = new Vector<>();
+ findComponentInContainer(container, chooser, 0, allSeen);
+ Component[] result = new Component[allSeen.size()];
+ for (int i = 0, n = allSeen.size(); i < n; i++) {
+ result[i] = allSeen.get(i);
+ }
+ return result;
+ }
+
+ private Component findComponentInContainer(final Container cont, final ComponentChooser chooser, final int index,
+ final Vector allSeen) {
+ return queueTool.invokeSmoothly(new QueueTool.QueueAction("findComponentInContainer with " + chooser.getDescription()) {
+
+ @Override
+ public Component launch() throws Exception {
+ Component[] components = cont.getComponents();
+ Component target;
+ for (Component component : components) {
+ if (component != null) {
+ if (chooser.checkComponent(component)) {
+ if (allSeen != null) {
+ allSeen.add(component);
+ } else if (ordinalIndex == index) {
+ return component;
+ } else {
+ ordinalIndex++;
+ }
+ }
+ if (component instanceof Container) {
+ if ((target = findComponentInContainer((Container) component,
+ chooser, index, allSeen)) != null) {
+ return target;
+ }
+ }
+ }
+ }
+ return null;
+ }
+ });
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/DefaultCharBindingMap.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/DefaultCharBindingMap.java
new file mode 100644
index 00000000000..36c9ca49880
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/DefaultCharBindingMap.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ *
+ * Default implementation of CharBindingMap interface. Provides a mapping for
+ * the following symbols:
+ *
+ * @see org.netbeans.jemmy.CharBindingMap
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class DefaultCharBindingMap implements CharBindingMap {
+
+ private Hashtable chars;
+
+ /**
+ * Constructor.
+ */
+ public DefaultCharBindingMap() {
+ initMap();
+ }
+
+ /**
+ * Returns the code of the primary key used to type a symbol.
+ *
+ * @param c Symbol code.
+ * @return a key code.
+ * @see CharBindingMap#getCharKey(char)
+ * @see java.awt.event.InputEvent
+ */
+ @Override
+ public int getCharKey(char c) {
+ return getKeyAndModifiers(c)[0];
+ }
+
+ /**
+ * Returns the modifiers that should be pressed to type a symbol.
+ *
+ * @param c Symbol code.
+ * @return a combination of InputEvent MASK fields.
+ * @see CharBindingMap#getCharModifiers(char)
+ * @see java.awt.event.InputEvent
+ */
+ @Override
+ public int getCharModifiers(char c) {
+ return getKeyAndModifiers(c)[1];
+ }
+
+ /**
+ * Returns key + modifiers pair.
+ *
+ * @param c Symbol code.
+ * @return an array of two elements: key code and modifiers mask - a
+ * combination of InputEvent MASK fields.
+ */
+ public int[] getKeyAndModifiers(char c) {
+ CharKey key = chars.get(c);
+ if (key != null) {
+ return new int[]{key.key, key.modifiers};
+ } else {
+ return new int[]{KeyEvent.VK_UNDEFINED, 0};
+ }
+ }
+
+ /**
+ * Returns an array of all supported chars.
+ *
+ * @return an array of chars representing the supported chars values.
+ */
+ public char[] getSupportedChars() {
+ char[] charArray = new char[chars.size()];
+ Enumeration keys = chars.keys();
+ int index = 0;
+ while (keys.hasMoreElements()) {
+ charArray[index] = keys.nextElement();
+ }
+ return charArray;
+ }
+
+ /**
+ * Removes a char from supported.
+ *
+ * @param c Symbol code.
+ */
+ public void removeChar(char c) {
+ chars.remove(c);
+ }
+
+ /**
+ * Adds a char to supported.
+ *
+ * @param c Symbol code.
+ * @param key key code.
+ * @param modifiers a combination of InputEvent MASK fields.
+ */
+ public void addChar(char c, int key, int modifiers) {
+ chars.put(c, new CharKey(key, modifiers));
+ }
+
+ private void initMap() {
+ chars = new Hashtable<>();
+ //first add latters and digits represented by KeyEvent.VK_. fields
+ Field[] fields = KeyEvent.class.getFields();
+ for (Field field : fields) {
+ String name = field.getName();
+ if ((field.getModifiers() & Modifier.PUBLIC) != 0
+ && (field.getModifiers() & Modifier.STATIC) != 0
+ && field.getType() == Integer.TYPE
+ && name.startsWith("VK_")
+ && name.length() == 4) {
+ String latter = name.substring(3, 4);
+ try {
+ int key = field.getInt(null);
+ addChar(latter.toLowerCase().charAt(0), key, 0);
+ if (!latter.toUpperCase().equals(latter.toLowerCase())) {
+ addChar(latter.toUpperCase().charAt(0), key, InputEvent.SHIFT_MASK);
+ }
+ } catch (IllegalAccessException e) {
+ throw new AssertionError("Never could happen!", e);
+ }
+ }
+ }
+ //add special simbols
+ addChar('\t', KeyEvent.VK_TAB, 0);
+ addChar(' ', KeyEvent.VK_SPACE, 0);
+ addChar('!', KeyEvent.VK_1, InputEvent.SHIFT_MASK);
+ addChar('"', KeyEvent.VK_QUOTE, InputEvent.SHIFT_MASK);
+ addChar('#', KeyEvent.VK_3, InputEvent.SHIFT_MASK);
+ addChar('$', KeyEvent.VK_4, InputEvent.SHIFT_MASK);
+ addChar('%', KeyEvent.VK_5, InputEvent.SHIFT_MASK);
+ addChar('&', KeyEvent.VK_7, InputEvent.SHIFT_MASK);
+ addChar('\'', KeyEvent.VK_QUOTE, 0);
+ addChar('(', KeyEvent.VK_9, InputEvent.SHIFT_MASK);
+ addChar(')', KeyEvent.VK_0, InputEvent.SHIFT_MASK);
+ addChar('*', KeyEvent.VK_8, InputEvent.SHIFT_MASK);
+ addChar('+', KeyEvent.VK_EQUALS, InputEvent.SHIFT_MASK);
+ addChar(',', KeyEvent.VK_COMMA, 0);
+ addChar('-', KeyEvent.VK_MINUS, 0);
+ addChar('.', KeyEvent.VK_PERIOD, 0);
+ addChar('/', KeyEvent.VK_SLASH, 0);
+ addChar(':', KeyEvent.VK_SEMICOLON, InputEvent.SHIFT_MASK);
+ addChar(';', KeyEvent.VK_SEMICOLON, 0);
+ addChar('<', KeyEvent.VK_COMMA, InputEvent.SHIFT_MASK);
+ addChar('=', KeyEvent.VK_EQUALS, 0);
+ addChar('>', KeyEvent.VK_PERIOD, InputEvent.SHIFT_MASK);
+ addChar('?', KeyEvent.VK_SLASH, InputEvent.SHIFT_MASK);
+ addChar('@', KeyEvent.VK_2, InputEvent.SHIFT_MASK);
+ addChar('[', KeyEvent.VK_OPEN_BRACKET, 0);
+ addChar('\\', KeyEvent.VK_BACK_SLASH, 0);
+ addChar(']', KeyEvent.VK_CLOSE_BRACKET, 0);
+ addChar('^', KeyEvent.VK_6, InputEvent.SHIFT_MASK);
+ addChar('_', KeyEvent.VK_MINUS, InputEvent.SHIFT_MASK);
+ addChar('`', KeyEvent.VK_BACK_QUOTE, 0);
+ addChar('{', KeyEvent.VK_OPEN_BRACKET, InputEvent.SHIFT_MASK);
+ addChar('|', KeyEvent.VK_BACK_SLASH, InputEvent.SHIFT_MASK);
+ addChar('}', KeyEvent.VK_CLOSE_BRACKET, InputEvent.SHIFT_MASK);
+ addChar('~', KeyEvent.VK_BACK_QUOTE, InputEvent.SHIFT_MASK);
+ addChar('\n', KeyEvent.VK_ENTER, 0);
+ }
+
+ private static class CharKey {
+
+ public int key;
+ public int modifiers;
+
+ public CharKey(int key, int modifiers) {
+ this.key = key;
+ this.modifiers = modifiers;
+ }
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/DialogWaiter.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/DialogWaiter.java
new file mode 100644
index 00000000000..2817d60decb
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/DialogWaiter.java
@@ -0,0 +1,672 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.awt.Component;
+import java.awt.Dialog;
+import java.awt.Window;
+
+/**
+ * A DialogWaiter is a utility class used to look or wait for Dialogs. It
+ * contains methods to search for a Dialog among the currently showing Dialogs
+ * as well as methods that wait for a Dialog to show within an allotted time
+ * period.
+ *
+ * Searches and waits can either involve search criteria applied by a
+ * ComponentChooser instance or a search criteria based on the Dialog title.
+ * Searches and waits can both be restricted to dialogs owned by a given window.
+ *
+ *
Timeouts used:
+ * DialogWaiter.WaitDialogTimeout - time to wait dialog displayed
+ * DialogWaiter.AfterDialogTimeout - time to sleep after dialog has been
+ * displayed
+ *
+ * @see org.netbeans.jemmy.Timeouts
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class DialogWaiter extends WindowWaiter implements Timeoutable, Outputable {
+
+ private final static long WAIT_TIME = 60000;
+ private final static long AFTER_WAIT_TIME = 0;
+
+ private Timeouts timeouts;
+ private TestOut output;
+
+ /**
+ * Constructor.
+ */
+ public DialogWaiter() {
+ super();
+ setTimeouts(JemmyProperties.getProperties().getTimeouts());
+ }
+
+ /**
+ * Searches for a dialog. Search among the currently showing dialogs for one
+ * that meets the search criteria applied by the
+ * {@code ComponentChooser} parameter.
+ *
+ * @param cc A component chooser used to define and apply the search
+ * criteria.
+ * @return a reference to the first dialog that is showing and that meets
+ * the search criteria. If no such dialog can be found, a {@code null}
+ * reference is returned.
+ */
+ public static Dialog getDialog(ComponentChooser cc) {
+ return (Dialog) WindowWaiter.getWindow(new DialogSubChooser(cc));
+ }
+
+ /**
+ * Searches for a dialog. The search proceeds among the currently showing
+ * dialogs for the {@code index+1}'th dialog that meets the criteria
+ * defined and applied by the {@code ComonentChooser} parameter.
+ *
+ * @param cc A component chooser used to define and apply the search
+ * criteria.
+ * @param index The ordinal index of the dialog in the set of currently
+ * displayed dialogs. The first index is 0.
+ * @return a reference to the {@code index+1}'th dialog that is showing
+ * and that meets the search criteria. If there are fewer than
+ * {@code index+1} dialogs, a {@code null} reference is returned.
+ */
+ public static Dialog getDialog(ComponentChooser cc, int index) {
+ return (Dialog) WindowWaiter.getWindow(new DialogSubChooser(cc), index);
+ }
+
+ /**
+ * Searches for a dialog by title. The search proceeds among the currently
+ * showing dialogs for the first with a suitable title.
+ *
+ * @param title Dialog title or subtitle.
+ * @param ce If {@code true} and the search is case sensitive, then a
+ * match occurs when the {@code title} argument is a substring of a
+ * dialog title. If {@code false} and the search is case sensitive,
+ * then the {@code title} argument and the dialog title must be the
+ * same. If {@code true} and the search is case insensitive, then a
+ * match occurs when the {@code title} argument is a substring of the
+ * dialog title after changing both to upper case. If {@code false} and
+ * the search is case insensitive, then a match occurs when the
+ * {@code title} argument is a substring of the dialog title after
+ * changing both to upper case.
+ * @param cc If {@code true} the search is case sensitive; otherwise,
+ * the search is case insensitive.
+ * @return a reference to the first dialog that is showing and that has a
+ * suitable title. If no such dialog can be found, a {@code null}
+ * reference is returned.
+ */
+ public static Dialog getDialog(String title, boolean ce, boolean cc) {
+ return (Dialog) WindowWaiter.getWindow(new DialogByTitleChooser(title, ce, cc));
+ }
+
+ /**
+ * Searches for a dialog by title. The search is for the
+ * {@code index+1}'th dialog among the currently showing dialogs that
+ * possess a suitable title.
+ *
+ * @param title Dialog title or subtitle.
+ * @param ce If {@code true} and the search is case sensitive, then a
+ * match occurs when the {@code title} argument is a substring of a
+ * dialog title. If {@code false} and the search is case sensitive,
+ * then the {@code title} argument and the dialog title must be the
+ * same. If {@code true} and the search is case insensitive, then a
+ * match occurs when the {@code title} argument is a substring of the
+ * dialog title after changing both to upper case. If {@code false} and
+ * the search is case insensitive, then a match occurs when the
+ * {@code title} argument is a substring of the dialog title after
+ * changing both to upper case.
+ * @param cc If {@code true} the search is case sensitive; otherwise,
+ * the search is case insensitive.
+ * @param index Ordinal index between appropriate dialogs
+ * @return a reference to the {@code index+1}'th dialog that is showing
+ * and that has a suitable title. If there are fewer than
+ * {@code index+1} dialogs, a {@code null} reference is returned.
+ */
+ public static Dialog getDialog(String title, boolean ce, boolean cc, int index) {
+ return getDialog(new DialogByTitleChooser(title, ce, cc), index);
+ }
+
+ /**
+ * Searches for a dialog. Search among the currently showing dialogs for the
+ * first that is both owned by the {@code java.awt.Window}
+ * {@code owner} and that meets the search criteria applied by the
+ * {@code ComponentChooser} parameter.
+ *
+ * @param owner The owner window of the dialogs to be searched.
+ * @param cc A component chooser used to define and apply the search
+ * criteria.
+ * @return a reference to the first dialog that is showing, has a proper
+ * owner window, and that meets the search criteria. If no such dialog can
+ * be found, a {@code null} reference is returned.
+ */
+ public static Dialog getDialog(Window owner, ComponentChooser cc) {
+ return (Dialog) WindowWaiter.getWindow(owner, new DialogSubChooser(cc));
+ }
+
+ /**
+ * Searches for a dialog. The search proceeds among the currently showing
+ * dialogs for the {@code index+1}'th dialog that is both owned by the
+ * {@code java.awt.Window} {@code owner} and that meets the
+ * criteria defined and applied by the {@code ComponentChooser}
+ * parameter.
+ *
+ * @param owner The owner window of all the dialogs to be searched.
+ * @param cc A component chooser used to define and apply the search
+ * criteria.
+ * @param index Ordinal index between appropriate dialogs
+ * @return a reference to the {@code index+1}'th dialog that is
+ * showing, has the proper window ownership, and that meets the search
+ * criteria. If there are fewer than {@code index+1} dialogs, a
+ * {@code null} reference is returned.
+ */
+ public static Dialog getDialog(Window owner, ComponentChooser cc, int index) {
+ return (Dialog) WindowWaiter.getWindow(owner, new DialogSubChooser(cc), index);
+ }
+
+ /**
+ * Searches for a dialog by title. The search proceeds among the currently
+ * showing dialogs that are owned by the {@code java.awt.Window}
+ * {@code owner} for the first with a suitable title.
+ *
+ * @param owner A window - owner of a dialods to be checked.
+ * @param title Dialog title or subtitle.
+ * @param ce If {@code true} and the search is case sensitive, then a
+ * match occurs when the {@code title} argument is a substring of a
+ * dialog title. If {@code false} and the search is case sensitive,
+ * then the {@code title} argument and the dialog title must be the
+ * same. If {@code true} and the search is case insensitive, then a
+ * match occurs when the {@code title} argument is a substring of the
+ * dialog title after changing both to upper case. If {@code false} and
+ * the search is case insensitive, then a match occurs when the
+ * {@code title} argument is a substring of the dialog title after
+ * changing both to upper case.
+ * @param cc If {@code true} the search is case sensitive; otherwise,
+ * the search is case insensitive.
+ * @return a reference to the first dialog that is showing, has the proper
+ * window ownership, and a suitable title. If no such dialog can be found, a
+ * {@code null} reference is returned.
+ */
+ public static Dialog getDialog(Window owner, String title, boolean ce, boolean cc) {
+ return (Dialog) WindowWaiter.getWindow(owner, new DialogByTitleChooser(title, ce, cc));
+ }
+
+ /**
+ * Searches for a dialog by title. The search is for the
+ * {@code index+1}'th dialog among the currently showing dialogs that
+ * are owned by the {@code java.awt.Window} {@code owner} and that
+ * have a suitable title.
+ *
+ * @param owner ?title? Dialog title or subtitle.
+ * @param title ?ce? If {@code true} and the search is case sensitive,
+ * then a match occurs when the {@code title} argument is a substring
+ * of a dialog title. If {@code false} and the search is case
+ * sensitive, then the {@code title} argument and the dialog title must
+ * be the same. If {@code true} and the search is case insensitive,
+ * then a match occurs when the {@code title} argument is a substring
+ * of the dialog title after changing both to upper case. If
+ * {@code false} and the search is case insensitive, then a match
+ * occurs when the {@code title} argument is a substring of the dialog
+ * title after changing both to upper case.
+ * @param ce ?cc? If {@code true} the search is case sensitive;
+ * otherwise, the search is case insensitive.
+ * @param cc ?index? The ordinal index of the dialog in the set of currently
+ * displayed dialogs with the proper window ownership and a suitable title.
+ * The first index is 0.
+ * @param index Ordinal index between appropriate dialogs
+ * @return a reference to the {@code index+1}'th dialog that is
+ * showing, has the proper window ownership, and a suitable title. If there
+ * are fewer than {@code index+1} dialogs, a {@code null}
+ * reference is returned.
+ */
+ public static Dialog getDialog(Window owner, String title, boolean ce, boolean cc, int index) {
+ return getDialog(owner, new DialogByTitleChooser(title, ce, cc), index);
+ }
+
+ static {
+ Timeouts.initDefault("DialogWaiter.WaitDialogTimeout", WAIT_TIME);
+ Timeouts.initDefault("DialogWaiter.AfterDialogTimeout", AFTER_WAIT_TIME);
+ }
+
+ /**
+ * Defines current timeouts.
+ *
+ * @param timeouts ?t? A collection of timeout assignments.
+ * @see org.netbeans.jemmy.Timeouts
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see #getTimeouts
+ */
+ @Override
+ public void setTimeouts(Timeouts timeouts) {
+ this.timeouts = timeouts;
+ Timeouts times = timeouts.cloneThis();
+ times.setTimeout("WindowWaiter.WaitWindowTimeout",
+ timeouts.getTimeout("DialogWaiter.WaitDialogTimeout"));
+ times.setTimeout("WindowWaiter.AfterWindowTimeout",
+ timeouts.getTimeout("DialogWaiter.AfterDialogTimeout"));
+ super.setTimeouts(times);
+ }
+
+ /**
+ * Return current timeouts.
+ *
+ * @return the collection of current timeout assignments.
+ * @see org.netbeans.jemmy.Timeouts
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see #setTimeouts
+ */
+ @Override
+ public Timeouts getTimeouts() {
+ return timeouts;
+ }
+
+ /**
+ * Defines print output streams or writers.
+ *
+ * @param output ?out? Identify the streams or writers used for print
+ * output.
+ * @see org.netbeans.jemmy.TestOut
+ * @see org.netbeans.jemmy.Outputable
+ * @see #getOutput
+ */
+ @Override
+ public void setOutput(TestOut output) {
+ this.output = output;
+ super.setOutput(output);
+ }
+
+ /**
+ * Returns print output streams or writers.
+ *
+ * @return an object that contains references to objects for printing to
+ * output and err streams.
+ * @see org.netbeans.jemmy.TestOut
+ * @see org.netbeans.jemmy.Outputable
+ * @see #setOutput
+ */
+ @Override
+ public TestOut getOutput() {
+ return output;
+ }
+
+ /**
+ * Waits for a dialog to show. Wait for the {@code index+1}'th dialog
+ * that meets the criteria defined and applied by the
+ * {@code ComonentChooser} parameter to show up.
+ *
+ * @param ch A component chooser used to define and apply the search
+ * criteria.
+ * @param index The ordinal index of the dialog in the set of currently
+ * displayed dialogs. The first index is 0.
+ * @return a reference to the {@code index+1}'th dialog that shows and
+ * that meets the search criteria. If fewer than {@code index+1}
+ * dialogs show up in the allotted time period then a {@code null}
+ * reference is returned.
+ * @throws TimeoutExpiredException
+ * @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
+ * @exception InterruptedException
+ */
+ public Dialog waitDialog(ComponentChooser ch, int index)
+ throws InterruptedException {
+ setTimeouts(timeouts);
+ return (Dialog) waitWindow(new DialogSubChooser(ch), index);
+ }
+
+ /**
+ * Waits for a dialog to show. Wait for a dialog that meets the search
+ * criteria applied by the {@code ComponentChooser} parameter to show
+ * up.
+ *
+ * @param ch A component chooser used to define and apply the search
+ * criteria.
+ * @return a reference to the first dialog that shows and that meets the
+ * search criteria. If no such dialog can be found within the time period
+ * allotted, a {@code null} reference is returned.
+ * @throws TimeoutExpiredException
+ * @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
+ * @exception InterruptedException
+ */
+ public Dialog waitDialog(ComponentChooser ch)
+ throws InterruptedException {
+ return waitDialog(ch, 0);
+ }
+
+ /**
+ * Waits for a dialog to show. Wait for the {@code index+1}'th dialog
+ * to show with a suitable title.
+ *
+ * @param title Dialog title or subtitle.
+ * @param compareExactly If {@code true} and the search is case
+ * sensitive, then a match occurs when the {@code title} argument is a
+ * substring of a dialog title. If {@code false} and the search is case
+ * sensitive, then the {@code title} argument and the dialog title must
+ * be the same. If {@code true} and the search is case insensitive,
+ * then a match occurs when the {@code title} argument is a substring
+ * of the dialog title after changing both to upper case. If
+ * {@code false} and the search is case insensitive, then a match
+ * occurs when the {@code title} argument is a substring of the dialog
+ * title after changing both to upper case.
+ * @param compareCaseSensitive If {@code true} the search is case
+ * sensitive; otherwise, the search is case insensitive.
+ * @param index The ordinal index of the dialog in the set of currently
+ * displayed dialogs with the proper window ownership and a suitable title.
+ * The first index is 0.
+ * @return a reference to the {@code index+1}'th dialog to show and
+ * that has a suitable title. If no such dialog can be found within the time
+ * period allotted, a {@code null} reference is returned.
+ * @throws TimeoutExpiredException
+ * @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
+ * @exception InterruptedException
+ */
+ public Dialog waitDialog(String title, boolean compareExactly, boolean compareCaseSensitive, int index)
+ throws InterruptedException {
+ return waitDialog(new DialogByTitleChooser(title, compareExactly, compareCaseSensitive), index);
+ }
+
+ /**
+ * Waits for a dialog to show. Wait for the first dialog to show with a
+ * suitable title.
+ *
+ * @param title Dialog title or subtitle.
+ * @param compareExactly If {@code true} and the search is case
+ * sensitive, then a match occurs when the {@code title} argument is a
+ * substring of a dialog title. If {@code false} and the search is case
+ * sensitive, then the {@code title} argument and the dialog title must
+ * be the same. If {@code true} and the search is case insensitive,
+ * then a match occurs when the {@code title} argument is a substring
+ * of the dialog title after changing both to upper case. If
+ * {@code false} and the search is case insensitive, then a match
+ * occurs when the {@code title} argument is a substring of the dialog
+ * title after changing both to upper case.
+ * @param compareCaseSensitive If {@code true} the search is case
+ * sensitive; otherwise, the search is case insensitive.
+ * @return a reference to the first dialog to show and that has a suitable
+ * title. If no such dialog can be found within the time period allotted, a
+ * {@code null} reference is returned.
+ * @throws TimeoutExpiredException
+ * @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
+ * @exception InterruptedException
+ */
+ public Dialog waitDialog(String title, boolean compareExactly, boolean compareCaseSensitive)
+ throws InterruptedException {
+ return waitDialog(title, compareExactly, compareCaseSensitive, 0);
+ }
+
+ /**
+ * Waits for a dialog to show. Wait for the {@code index+1}'th dialog
+ * to show that is both owned by the {@code java.awt.Window}
+ * {@code owner} and that meets the criteria defined and applied by the
+ * {@code ComponentChooser} parameter.
+ *
+ * @param owner The owner window of all the dialogs to be searched.
+ * @param ch A component chooser used to define and apply the search
+ * criteria.
+ * @param index The ordinal index of the dialog in the set of currently
+ * displayed dialogs with the proper window ownership and a suitable title.
+ * The first index is 0.
+ * @return a reference to the {@code index+1}'th dialog to show that
+ * has the proper window ownership, and that meets the search criteria. If
+ * there are fewer than {@code index+1} dialogs, a {@code null}
+ * reference is returned.
+ * @throws TimeoutExpiredException
+ * @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
+ * @exception InterruptedException
+ */
+ public Dialog waitDialog(Window owner, ComponentChooser ch, int index)
+ throws InterruptedException {
+ setTimeouts(timeouts);
+ return (Dialog) waitWindow(owner, new DialogSubChooser(ch), index);
+ }
+
+ /**
+ * Waits for a dialog to show. Wait for the first dialog to show that is
+ * both owned by the {@code java.awt.Window} {@code owner} and
+ * that meets the criteria defined and applied by the
+ * {@code ComponentChooser} parameter.
+ *
+ * @param owner The owner window of all the dialogs to be searched.
+ * @param ch A component chooser used to define and apply the search
+ * criteria.
+ * @return a reference to the first dialog to show that has the proper
+ * window ownership, and that meets the search criteria. If there is no such
+ * dialog, a {@code null} reference is returned.
+ * @throws TimeoutExpiredException
+ * @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
+ * @exception InterruptedException
+ */
+ public Dialog waitDialog(Window owner, ComponentChooser ch)
+ throws InterruptedException {
+ return waitDialog(owner, ch, 0);
+ }
+
+ /**
+ * Waits for a dialog to show. Wait for the {@code index+1}'th dialog
+ * to show with the proper owner and a suitable title.
+ *
+ * @param owner The owner window of all the dialogs to be searched.
+ * @param title Dialog title or subtitle.
+ * @param compareExactly If {@code true} and the search is case
+ * sensitive, then a match occurs when the {@code title} argument is a
+ * substring of a dialog title. If {@code false} and the search is case
+ * sensitive, then the {@code title} argument and the dialog title must
+ * be the same. If {@code true} and the search is case insensitive,
+ * then a match occurs when the {@code title} argument is a substring
+ * of the dialog title after changing both to upper case. If
+ * {@code false} and the search is case insensitive, then a match
+ * occurs when the {@code title} argument is a substring of the dialog
+ * title after changing both to upper case.
+ * @param compareCaseSensitive If {@code true} the search is case
+ * sensitive; otherwise, the search is case insensitive.
+ * @param index Ordinal index between appropriate dialogs
+ * @return a reference to the {@code index+1}'th dialog to show that
+ * has both the proper owner window and a suitable title. If no such dialog
+ * can be found within the time period allotted, a {@code null}
+ * reference is returned.
+ * @throws TimeoutExpiredException
+ * @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
+ * @exception InterruptedException
+ */
+ public Dialog waitDialog(Window owner, String title, boolean compareExactly, boolean compareCaseSensitive, int index)
+ throws InterruptedException {
+ return waitDialog(owner, new DialogByTitleChooser(title, compareExactly, compareCaseSensitive), index);
+ }
+
+ /**
+ * Waits for a dialog to show. Wait for the first dialog to show with the
+ * proper owner and a suitable title.
+ *
+ * @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
+ * @param owner The owner window of all the dialogs to be searched.
+ * @param title Dialog title or subtitle.
+ * @param compareExactly If {@code true} and the search is case
+ * sensitive, then a match occurs when the {@code title} argument is a
+ * substring of a dialog title. If {@code false} and the search is case
+ * sensitive, then the {@code title} argument and the dialog title must
+ * be the same. If {@code true} and the search is case insensitive,
+ * then a match occurs when the {@code title} argument is a substring
+ * of the dialog title after changing both to upper case. If
+ * {@code false} and the search is case insensitive, then a match
+ * occurs when the {@code title} argument is a substring of the dialog
+ * title after changing both to upper case.
+ * @param compareCaseSensitive If {@code true} the search is case
+ * sensitive; otherwise, the search is case insensitive.
+ * @return a reference to the first dialog to show and that has both the
+ * proper owner and a suitable title. If no such dialog can be found within
+ * the time period allotted, a {@code null} reference is returned.
+ * @throws TimeoutExpiredException
+ * @exception InterruptedException
+ */
+ public Dialog waitDialog(Window owner, String title, boolean compareExactly, boolean compareCaseSensitive)
+ throws InterruptedException {
+ return waitDialog(owner, title, compareExactly, compareCaseSensitive, 0);
+ }
+
+ /**
+ * @see org.netbeans.jemmy.Waiter#getWaitingStartedMessage()
+ */
+ @Override
+ protected String getWaitingStartedMessage() {
+ return "Start to wait dialog \"" + getComponentChooser().getDescription() + "\" opened";
+ }
+
+ /**
+ * Overrides WindowWaiter.getTimeoutExpiredMessage. Returns the timeout
+ * expired message value.
+ *
+ * @see org.netbeans.jemmy.Waiter#getTimeoutExpiredMessage(long)
+ * @param spendedTime Time spent for waiting
+ * @return A message string.
+ */
+ @Override
+ protected String getTimeoutExpiredMessage(long spendedTime) {
+ return ("Dialog \"" + getComponentChooser().getDescription() + "\" has not been opened in "
+ + spendedTime + " milliseconds");
+ }
+
+ /**
+ * Overrides WindowWaiter.getActionProducedMessage. Returns the action
+ * produced message value.
+ *
+ * @see org.netbeans.jemmy.Waiter#getActionProducedMessage(long, Object)
+ * @param spendedTime Time spent for waiting
+ * @param result A result of the action
+ * @return A message string.
+ */
+ @Override
+ protected String getActionProducedMessage(long spendedTime, final Object result) {
+ String resultToString;
+ if (result instanceof Component) {
+ // run toString in dispatch thread
+ resultToString = new QueueTool().invokeSmoothly(
+ new QueueTool.QueueAction("result.toString()") {
+ @Override
+ public String launch() {
+ return result.toString();
+ }
+ }
+ );
+ } else {
+ resultToString = result.toString();
+ }
+ return ("Dialog \"" + getComponentChooser().getDescription() + "\" has been opened in "
+ + spendedTime + " milliseconds"
+ + "\n " + resultToString);
+ }
+
+ /**
+ * @see org.netbeans.jemmy.Waiter#getGoldenWaitingStartedMessage()
+ */
+ @Override
+ protected String getGoldenWaitingStartedMessage() {
+ return "Start to wait dialog \"" + getComponentChooser().getDescription() + "\" opened";
+ }
+
+ /**
+ * @see org.netbeans.jemmy.Waiter#getGoldenTimeoutExpiredMessage()
+ */
+ @Override
+ protected String getGoldenTimeoutExpiredMessage() {
+ return "Dialog \"" + getComponentChooser().getDescription() + "\" has not been opened";
+ }
+
+ /**
+ * @see org.netbeans.jemmy.Waiter#getGoldenActionProducedMessage()
+ */
+ @Override
+ protected String getGoldenActionProducedMessage() {
+ return "Dialog \"" + getComponentChooser().getDescription() + "\" has been opened";
+ }
+
+ private static class DialogSubChooser implements ComponentChooser {
+
+ private ComponentChooser chooser;
+
+ public DialogSubChooser(ComponentChooser c) {
+ super();
+ chooser = c;
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ if (comp instanceof Dialog) {
+ return ((FIND_INVISIBLE_WINDOWS || (comp.isShowing() && comp.isVisible()))
+ && chooser.checkComponent(comp));
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return chooser.getDescription();
+ }
+
+ @Override
+ public String toString() {
+ return "DialogSubChooser{" + "chooser=" + chooser + '}';
+ }
+ }
+
+ private static class DialogByTitleChooser implements ComponentChooser {
+
+ String title;
+ boolean compareExactly;
+ boolean compareCaseSensitive;
+
+ public DialogByTitleChooser(String t, boolean ce, boolean cc) {
+ super();
+ title = t;
+ compareExactly = ce;
+ compareCaseSensitive = cc;
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ if (comp instanceof Dialog) {
+ if ((FIND_INVISIBLE_WINDOWS || (comp.isShowing() && comp.isVisible()))
+ && ((Dialog) comp).getTitle() != null) {
+ String titleToComp = ((Dialog) comp).getTitle();
+ String contextToComp = title;
+ if (compareCaseSensitive) {
+ titleToComp = titleToComp.toUpperCase();
+ contextToComp = contextToComp.toUpperCase();
+ }
+ if (compareExactly) {
+ return titleToComp.equals(contextToComp);
+ } else {
+ return titleToComp.contains(contextToComp);
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getDescription() {
+ return title;
+ }
+
+ @Override
+ public String toString() {
+ return "DialogByTitleChooser{" + "title=" + title + ", compareExactly=" + compareExactly + ", compareCaseSensitive=" + compareCaseSensitive + '}';
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/EventDispatcher.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/EventDispatcher.java
new file mode 100644
index 00000000000..65fef2552db
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/EventDispatcher.java
@@ -0,0 +1,1134 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.Toolkit;
+import java.awt.Window;
+import java.awt.event.AWTEventListener;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.WindowEvent;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Provides low level functions for reproducing user actions. One dispatch model
+ * uses the managed component's event queue to dispatch events. The other
+ * dispatch model uses {@code java.awt.Robot} to generate native events. It
+ * is an option in the Robot dispatch model to wait for the managed component's
+ * event queue to empty before dispatching events.
+ *
+ * Timeouts used:
+ * EventDispatcher.WaitQueueEmptyTimeout - to wait event queue empty.
+ * EventDispatcher.RobotAutoDelay - param for java.awt.Robot.setAutoDelay
+ * method.
+ * EventDispatcher.WaitComponentUnderMouseTimeout - time to wait component under
+ * mouse.
+ *
+ * @see org.netbeans.jemmy.Timeouts
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ *
+ */
+public class EventDispatcher implements Outputable, Timeoutable {
+
+ private static final long WAIT_QUEUE_EMPTY_TIMEOUT = 180000;
+ private static final long ROBOT_AUTO_DELAY = 10;
+ private static final long WAIT_COMPONENT_UNDER_MOUSE_TIMEOUT = 60000;
+
+ private static Field[] keyFields;
+ private static volatile MotionListener motionListener = null;
+
+ /**
+ * Component to dispatch events to.
+ */
+ protected Component component;
+ private TestOut output;
+ private Timeouts timeouts;
+ private final ClassReference reference;
+ private int model;
+ private ClassReference robotReference = null;
+ private boolean outsider = false;
+ private final QueueTool queueTool;
+
+ /**
+ * Constructor.
+ *
+ * @param comp Component to operate with.
+ */
+ public EventDispatcher(Component comp) {
+ super();
+ component = comp;
+ reference = new ClassReference(comp);
+ queueTool = new QueueTool();
+ setOutput(JemmyProperties.getProperties().getOutput());
+ setTimeouts(JemmyProperties.getProperties().getTimeouts());
+ setDispatchingModel(JemmyProperties.getProperties().getDispatchingModel());
+ }
+
+ /**
+ * Waits for the managed component's {@code java.awt.EventQueue} to
+ * empty. The timeout for this wait is
+ * EventDispatcher.WaitQueueEmptyTimeout.
+ *
+ * @param output Output to print exception into.
+ * @param timeouts A collection of timeout assignments.
+ * @throws TimeoutExpiredException
+ * @see org.netbeans.jemmy.QueueTool
+ */
+ public static void waitQueueEmpty(TestOut output, Timeouts timeouts) {
+ QueueTool qt = new QueueTool();
+ qt.setTimeouts(timeouts.cloneThis());
+ qt.getTimeouts().
+ setTimeout("QueueTool.WaitQueueEmptyTimeout",
+ JemmyProperties.
+ getCurrentTimeout("EventDispatcher.WaitQueueEmptyTimeout"));
+ qt.setOutput(output);
+ qt.waitEmpty();
+ }
+
+ /**
+ * Waits for the managed component's {@code java.awt.EventQueue} to
+ * empty. Uses default output and timeouts. The timeout for this wait is
+ * EventDispatcher.WaitQueueEmptyTimeout.
+ *
+ * @see QueueTool
+ * @throws TimeoutExpiredException
+ */
+ public static void waitQueueEmpty() {
+ waitQueueEmpty(JemmyProperties.getCurrentOutput(),
+ JemmyProperties.getCurrentTimeouts());
+ }
+
+ /**
+ * Waits for the managed component's {@code java.awt.EventQueue} to
+ * stay empty. The timeout for this wait is
+ * EventDispatcher.WaitQueueEmptyTimeout.
+ *
+ * @param emptyTime The time that the event queue has to stay empty to avoid
+ * a TimeoutExpiredException.
+ * @param output Output to print exception into
+ * @param timeouts A collection of timeout assignments.
+ * @throws TimeoutExpiredException
+ * @see org.netbeans.jemmy.QueueTool
+ */
+ public static void waitQueueEmpty(long emptyTime, TestOut output, Timeouts timeouts) {
+ QueueTool qt = new QueueTool();
+ qt.setTimeouts(timeouts.cloneThis());
+ qt.getTimeouts().
+ setTimeout("QueueTool.WaitQueueEmptyTimeout",
+ JemmyProperties.
+ getCurrentTimeout("EventDispatcher.WaitQueueEmptyTimeout"));
+ qt.setOutput(output);
+ qt.waitEmpty(emptyTime);
+ }
+
+ /**
+ * Waits for the managed component's {@code java.awt.EventQueue} to
+ * stay empty. Uses default output and timeouts. The timeout for this wait
+ * is EventDispatcher.WaitQueueEmptyTimeout.
+ *
+ * @param emptyTime The time that the event queue has to stay empty to avoid
+ * a TimeoutExpiredException.
+ * @throws TimeoutExpiredException
+ * @see org.netbeans.jemmy.QueueTool
+ */
+ public static void waitQueueEmpty(long emptyTime) {
+ waitQueueEmpty(emptyTime,
+ JemmyProperties.getCurrentOutput(),
+ JemmyProperties.getCurrentTimeouts());
+ }
+
+ /**
+ * Get a string representation for key modifiers. Used to print trace.
+ *
+ * @param modifiers Bit mask of keyboard event modifiers.
+ * @return a string representation for the keyboard event modifiers.
+ */
+ public static String getModifiersString(int modifiers) {
+ String result = "";
+ if ((modifiers & InputEvent.CTRL_MASK) != 0) {
+ result = result + "CTRL_MASK | ";
+ }
+ if ((modifiers & InputEvent.META_MASK) != 0) {
+ result = result + "META_MASK | ";
+ }
+ if ((modifiers & InputEvent.ALT_MASK) != 0) {
+ result = result + "ALT_MASK | ";
+ }
+ if ((modifiers & InputEvent.ALT_GRAPH_MASK) != 0) {
+ result = result + "ALT_GRAPH_MASK | ";
+ }
+ if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
+ result = result + "SHIFT_MASK | ";
+ }
+ if (result.length() > 0) {
+ return result.substring(0, result.length() - 3);
+ }
+ return result;
+ }
+
+ /**
+ * Returns a string representation for a keyboard event. Used to print
+ * trace.
+ *
+ * @param keyCode Key code ({@code KeyEvent.VK_*} value)
+ * @return the KeyEvent field name.
+ */
+ public static String getKeyDescription(int keyCode) {
+ for (Field keyField : keyFields) {
+ try {
+ if (keyField.getName().startsWith("VK_")
+ && keyField.getInt(null) == keyCode) {
+ return keyField.getName();
+ }
+ } catch (IllegalAccessException e) {
+ JemmyProperties.getCurrentOutput().printStackTrace(e);
+ }
+ }
+ return "VK_UNKNOWN";
+ }
+
+ /**
+ * Returns a mouse button string representation. Used to print trace.
+ *
+ * @param button Mouse button ({@code InputEvent.BUTTON1/2/3_MASK}
+ * value).
+ * @return InputEvent field name.
+ */
+ public static String getMouseButtonDescription(int button) {
+ String result;
+ if ((button & InputEvent.BUTTON1_MASK) != 0) {
+ result = "BUTTON1";
+ } else if ((button & InputEvent.BUTTON2_MASK) != 0) {
+ result = "BUTTON2";
+ } else if ((button & InputEvent.BUTTON3_MASK) != 0) {
+ result = "BUTTON3";
+ } else {
+ result = "UNKNOWN_BUTTON";
+ }
+ return result;
+ }
+
+ public static void performInit() {
+ Timeouts.initDefault("EventDispatcher.WaitQueueEmptyTimeout", WAIT_QUEUE_EMPTY_TIMEOUT);
+ Timeouts.initDefault("EventDispatcher.RobotAutoDelay", ROBOT_AUTO_DELAY);
+ Timeouts.initDefault("EventDispatcher.WaitComponentUnderMouseTimeout", WAIT_COMPONENT_UNDER_MOUSE_TIMEOUT);
+ try {
+ keyFields = Class.forName("java.awt.event.KeyEvent").getFields();
+ } catch (ClassNotFoundException e) {
+ JemmyProperties.getCurrentOutput().printStackTrace(e);
+ }
+ }
+
+ static {
+ performInit();
+ }
+
+ /**
+ * Wait (or not) for the mouse to move over a Java component before
+ * pressing. This option is relevant when using {@code java.awt.Robot}
+ * to generate mouse events. If a mouse press occurs at a position not
+ * occupied by a known Java component then a
+ * {@code NoComponentUnderMouseException} will be thrown.
+ *
+ * @param yesOrNo if {@code true} then the test system will wait for
+ * the mouse to move over a Java component before pressing. therwise, mouse
+ * presses can take place anywhere on the screen.
+ */
+ public void checkComponentUnderMouse(boolean yesOrNo) {
+ outsider = !yesOrNo;
+ }
+
+ /**
+ * Defines print output streams or writers.
+ *
+ * @param out Identify the streams or writers used for print output.
+ * @see org.netbeans.jemmy.Outputable
+ * @see org.netbeans.jemmy.TestOut
+ * @see #getOutput
+ */
+ @Override
+ public void setOutput(TestOut out) {
+ output = out;
+ queueTool.setOutput(out);
+ }
+
+ /**
+ * Returns print output streams or writers.
+ *
+ * @return an object that contains references to objects for printing to
+ * output and err streams.
+ * @see org.netbeans.jemmy.Outputable
+ * @see org.netbeans.jemmy.TestOut
+ * @see #setOutput
+ */
+ @Override
+ public TestOut getOutput() {
+ return output;
+ }
+
+ /**
+ * Defines current timeouts.
+ *
+ * @param timeouts A collection of timeout assignments.
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see org.netbeans.jemmy.Timeouts
+ * @see #getTimeouts
+ */
+ @Override
+ public void setTimeouts(Timeouts timeouts) {
+ this.timeouts = timeouts;
+ queueTool.setTimeouts(timeouts);
+ queueTool.getTimeouts().
+ setTimeout("QueueTool.WaitQueueEmptyTimeout",
+ timeouts.
+ getTimeout("EventDispatcher.WaitQueueEmptyTimeout"));
+ if (robotReference != null) {
+ try {
+ Object[] params = {(int) timeouts.getTimeout("EventDispatcher.RobotAutoDelay")};
+ Class>[] paramClasses = {Integer.TYPE};
+ robotReference.invokeMethod("setAutoDelay", params, paramClasses);
+ } catch (InvocationTargetException
+ | IllegalStateException
+ | NoSuchMethodException
+ | IllegalAccessException e) {
+ output.printStackTrace(e);
+ }
+ }
+ }
+
+ /**
+ * Return current timeouts.
+ *
+ * @return the collection of current timeout assignments.
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see org.netbeans.jemmy.Timeouts
+ * @see #setTimeouts
+ */
+ @Override
+ public Timeouts getTimeouts() {
+ return timeouts;
+ }
+
+ /**
+ * Defines dispatching model.
+ *
+ * @param m New model value.
+ * @see #getDispatchingModel()
+ * @see org.netbeans.jemmy.JemmyProperties#QUEUE_MODEL_MASK
+ * @see org.netbeans.jemmy.JemmyProperties#ROBOT_MODEL_MASK
+ * @see org.netbeans.jemmy.JemmyProperties#getCurrentDispatchingModel()
+ * @see org.netbeans.jemmy.JemmyProperties#setCurrentDispatchingModel(int)
+ * @see org.netbeans.jemmy.JemmyProperties#initDispatchingModel(boolean,
+ * boolean)
+ * @see org.netbeans.jemmy.JemmyProperties#initDispatchingModel()
+ */
+ public void setDispatchingModel(int m) {
+ model = m;
+ if ((model & JemmyProperties.ROBOT_MODEL_MASK) != 0) {
+ createRobot();
+ try {
+ Object[] params = {(model & JemmyProperties.QUEUE_MODEL_MASK) != 0 ? Boolean.TRUE : Boolean.FALSE};
+ Class>[] paramClasses = {Boolean.TYPE};
+ robotReference.invokeMethod("setAutoWaitForIdle", params, paramClasses);
+ } catch (InvocationTargetException
+ | IllegalStateException
+ | NoSuchMethodException
+ | IllegalAccessException e) {
+ output.printStackTrace(e);
+ }
+ }
+ }
+
+ /**
+ * Gets the dispatching model value.
+ *
+ * @return the model value.
+ * @see #setDispatchingModel(int)
+ * @see org.netbeans.jemmy.JemmyProperties#QUEUE_MODEL_MASK
+ * @see org.netbeans.jemmy.JemmyProperties#ROBOT_MODEL_MASK
+ * @see org.netbeans.jemmy.JemmyProperties#getCurrentDispatchingModel()
+ * @see org.netbeans.jemmy.JemmyProperties#setCurrentDispatchingModel(int)
+ * @see org.netbeans.jemmy.JemmyProperties#initDispatchingModel(boolean,
+ * boolean)
+ * @see org.netbeans.jemmy.JemmyProperties#initDispatchingModel()
+ */
+ public int getDispatchingModel() {
+ return model;
+ }
+
+ /**
+ * Dispatches {@code AWTEvent} to component passed in constructor. If
+ * {@code (getDispatchingModel & JemmyProperties.QUEUE_MODEL_MASK) == 0}
+ * dispatched event directly, otherwise uses
+ * {@code javax.swing.SwingUtilities.invokeAndWait(Runnable)}
+ *
+ * @param event AWTEvent instance to be dispatched.
+ * @throws ComponentIsNotVisibleException
+ * @throws ComponentIsNotFocusedException
+ */
+ public void dispatchEvent(final AWTEvent event) {
+ // run in dispatch thread
+ String eventToString = queueTool.invokeSmoothly(
+ new QueueTool.QueueAction("event.toString()") {
+ @Override
+ public String launch() {
+ return event.toString();
+ }
+ }
+ );
+ output.printLine("Dispatch event " + eventToString);
+ output.printGolden("Dispatch event " + event.getClass().toString());
+ Dispatcher disp = new Dispatcher<>(event);
+ queueTool.invokeAndWait(disp);
+ }
+
+ /**
+ * Dispatches a MouseEvent.
+ *
+ * @see #dispatchEvent(AWTEvent)
+ * @param id {@code MouseEvent.MOUSE_*} value
+ * @param mods {@code InputEvent.MOUSE1/2/3_BUTTON} | (modifiers value)
+ * @param clickCount Click count
+ * @param x Horizontal click point coordinate.
+ * @param y vertical click point coordinate.
+ * @param popup Defines if mouse event is a popup event.
+ */
+ public void dispatchMouseEvent(int id, int mods, int clickCount, int x, int y,
+ boolean popup) {
+ MouseEvent event = new MouseEvent(component, id, System.currentTimeMillis(),
+ mods, x, y, clickCount, popup);
+ dispatchEvent(event);
+ }
+
+ /**
+ * Dispatches MouseEvent at the center of component.
+ *
+ * @see #dispatchEvent(AWTEvent)
+ * @param id {@code MouseEvent.MOUSE_*} value
+ * @param mods {@code InputEvent.MOUSE1/2/3_BUTTON} | (modiviers value)
+ * @param clickCount Click count
+ * @param popup Difines if mouse event is popup event.
+ */
+ public void dispatchMouseEvent(int id, int mods, int clickCount,
+ boolean popup) {
+ int x = component.getWidth() / 2;
+ int y = component.getHeight() / 2;
+ dispatchMouseEvent(id, mods, clickCount, x, y, popup);
+ }
+
+ /**
+ * Dispatches WindowEvent.
+ *
+ * @see #dispatchEvent(AWTEvent)
+ * @param id {@code WindowEvent.WINDOW_*} value
+ */
+ public void dispatchWindowEvent(int id) {
+ WindowEvent event = new WindowEvent((Window) component, id);
+ dispatchEvent(event);
+ }
+
+ /**
+ * Dispatches KeyEvent.
+ *
+ * @see #dispatchEvent(AWTEvent)
+ * @param id {@code KeyEvent.KEY_PRESSED} or
+ * {@code KeyEvent.KEY_RELEASED} value.
+ * @param mods Modifiers.
+ * @param keyCode Key code,
+ */
+ @Deprecated
+ public void dispatchKeyEvent(int id, int mods, int keyCode) {
+ KeyEvent event = new KeyEvent(component, id, System.currentTimeMillis(), mods, keyCode);
+ dispatchEvent(event);
+ }
+
+ /**
+ * Dispatches KeyEvent.
+ *
+ * @see #dispatchEvent(AWTEvent)
+ * @param id {@code KeyEvent.KEY_TYPED} value.
+ * @param mods Modifiers.
+ * @param keyCode Key code,
+ * @param keyChar Char to be tiped
+ */
+ public void dispatchKeyEvent(int id, int mods, int keyCode, char keyChar) {
+ KeyEvent event = new KeyEvent(component, id, System.currentTimeMillis(),
+ mods, keyCode, keyChar);
+ dispatchEvent(event);
+ }
+
+ /**
+ * Waits until all events currently on the event queue have been processed.
+ */
+ public void waitForIdle() {
+ makeRobotOperation("waitForIdle", null, null);
+ }
+
+ /**
+ * Bind horizontal relative cursor coordinate to screen coordinate.
+ *
+ * @param x Relative coordinate
+ * @return Absolute coordinate
+ */
+ protected int getAbsoluteX(int x) {
+ return (int) component.getLocationOnScreen().getX() + x;
+ }
+
+ /**
+ * Bind vertical relative cursor coordinate to screen coordinate.
+ *
+ * @param y Relative coordinate
+ * @return Absolute coordinate
+ */
+ protected int getAbsoluteY(int y) {
+ return (int) component.getLocationOnScreen().getY() + y;
+ }
+
+ /**
+ * Delays robot.
+ *
+ * @param time Time to dalay robot for.
+ */
+ public void delayRobot(long time) {
+ Object[] params = {(int) time};
+ Class>[] paramClasses = {Integer.TYPE};
+ makeRobotOperation("delay", params, paramClasses);
+ }
+
+ /**
+ * Moves mouse by robot.
+ *
+ * @param x Component relative horizontal coordinate.
+ * @param y Component relative vertical coordinate.
+ * @throws ComponentIsNotVisibleException
+ */
+ public void robotMoveMouse(int x, int y) {
+ if (motionListener == null) {
+ initMotionListener();
+ }
+ output.printLine("Move mouse to (" + Integer.toString(x) + ","
+ + Integer.toString(y) + ")");
+ Object[] params = {getAbsoluteX(x), getAbsoluteY(y)};
+ Class>[] paramClasses = {Integer.TYPE, Integer.TYPE};
+ makeRobotOperation("mouseMove", params, paramClasses);
+ }
+
+ /**
+ * Press mouse button by robot.
+ *
+ * @param button Mouse button (InputEvent.MOUSE1/2/3_BUTTON value)
+ * @param modifiers Modifiers
+ * @throws ComponentIsNotVisibleException
+ */
+ public void robotPressMouse(int button, int modifiers) {
+ if (!outsider) {
+ waitMouseOver();
+ }
+ robotPressModifiers(modifiers);
+ output.printLine("Press " + getMouseButtonDescription(button) + " mouse button");
+ Object[] params = {button};
+ Class>[] paramClasses = {Integer.TYPE};
+ makeRobotOperation("mousePress", params, paramClasses);
+ }
+
+ /**
+ * Press mouse button with 0 modifiers.
+ *
+ * @param button Mouse button ({@code InputEvent.MOUSE1/2/3_BUTTON}
+ * value)
+ * @see #robotPressMouse(int, int)
+ */
+ public void robotPressMouse(int button) {
+ robotPressMouse(button, 0);
+ }
+
+ /**
+ * Releases mouse button by robot.
+ *
+ * @param button Mouse button ({@code InputEvent.MOUSE1/2/3_BUTTON}
+ * value)
+ * @param modifiers Modifiers
+ * @throws ComponentIsNotVisibleException
+ */
+ public void robotReleaseMouse(int button, int modifiers) {
+ output.printLine("Release " + getMouseButtonDescription(button) + " mouse button");
+ Object[] params = {button};
+ Class>[] paramClasses = {Integer.TYPE};
+ makeRobotOperation("mouseRelease", params, paramClasses);
+ robotReleaseModifiers(modifiers);
+ }
+
+ /**
+ * Releases mouse button with 0 modifiers.
+ *
+ * @param button Mouse button ({@code InputEvent.MOUSE1/2/3_BUTTON}
+ * value)
+ * @see #robotReleaseMouse(int, int)
+ */
+ public void robotReleaseMouse(int button) {
+ robotReleaseMouse(button, 0);
+ }
+
+ /**
+ * Press a key using {@code java.awt.Robot}.
+ *
+ * @param keyCode Key ({@code KeyEvent.VK_*} value)
+ * @param modifiers Mask of KeyEvent modifiers.
+ * @throws ComponentIsNotVisibleException
+ * @throws ComponentIsNotFocusedException
+ */
+ public void robotPressKey(int keyCode, int modifiers) {
+ robotPressModifiers(modifiers);
+ output.printLine("Press " + getKeyDescription(keyCode) + " key");
+ Object[] params = {keyCode};
+ Class>[] paramClasses = {Integer.TYPE};
+ makeRobotOperation("keyPress", params, paramClasses);
+ }
+
+ /**
+ * Press key with no modifiers using {@code java.awt.Robot}.
+ *
+ * @param keyCode Key ({@code KeyEvent.VK_*} value)
+ * @see #robotPressKey(int, int)
+ */
+ public void robotPressKey(int keyCode) {
+ robotPressKey(keyCode, 0);
+ }
+
+ /**
+ * Releases key by robot.
+ *
+ * @param keyCode Key ({@code KeyEvent.VK_*} value)
+ * @param modifiers Mask of KeyEvent modifiers.
+ * @throws ComponentIsNotVisibleException
+ * @throws ComponentIsNotFocusedException
+ */
+ public void robotReleaseKey(int keyCode, int modifiers) {
+ output.printLine("Release " + getKeyDescription(keyCode) + " key");
+ Object[] params = {keyCode};
+ Class>[] paramClasses = {Integer.TYPE};
+ makeRobotOperation("keyRelease", params, paramClasses);
+ robotReleaseModifiers(modifiers);
+ }
+
+ /**
+ * Releases key with 0 modifiers.
+ *
+ * @param keyCode Key ({@code KeyEvent.VK_*} value)
+ * @see #robotPressKey(int, int)
+ */
+ public void robotReleaseKey(int keyCode) {
+ robotReleaseKey(keyCode, 0);
+ }
+
+ /**
+ * Invokes component method through
+ * {@code SwingUtilities.invokeAndWait(Runnable)}.
+ *
+ * @param method_name Name of a method to be invoked
+ * @param params Method params
+ * @param params_classes Method params' classes
+ * @return an Object - methods result.
+ * @see org.netbeans.jemmy.ClassReference
+ * @exception IllegalAccessException
+ * @exception NoSuchMethodException
+ * @exception IllegalStateException
+ * @exception InvocationTargetException
+ */
+ public Object invokeMethod(String method_name, Object[] params, Class>[] params_classes)
+ throws InvocationTargetException, IllegalStateException, NoSuchMethodException, IllegalAccessException {
+ Invoker invk = new Invoker(method_name, params, params_classes);
+ try {
+ return queueTool.invokeAndWait(invk);
+ } catch (JemmyException e) {
+ Exception ex = invk.getException();
+ if (ex != null) {
+ if (ex instanceof InvocationTargetException) {
+ InvocationTargetException ite = (InvocationTargetException) ex;
+ ite.addSuppressed(e);
+ throw ite;
+ } else if (ex instanceof IllegalStateException) {
+ IllegalStateException ise = (IllegalStateException) ex;
+ ise.addSuppressed(e);
+ throw ise;
+ } else if (ex instanceof NoSuchMethodException) {
+ NoSuchMethodException nsme = (NoSuchMethodException) ex;
+ nsme.addSuppressed(e);
+ throw nsme;
+ } else if (ex instanceof IllegalAccessException) {
+ IllegalAccessException iae = (IllegalAccessException) ex;
+ iae.addSuppressed(e);
+ throw iae;
+ } else {
+ e.addSuppressed(ex);
+ }
+ }
+ throw (e);
+ }
+ }
+
+ /**
+ * Gets component field value through
+ * {@code SwingUtilities.invokeAndWait(Runnable)}.
+ *
+ * @param field_name Name of a field
+ * @see #setField(String, Object)
+ * @see org.netbeans.jemmy.ClassReference
+ * @return an Object - field value
+ * @exception IllegalAccessException
+ * @exception IllegalStateException
+ * @exception InvocationTargetException
+ * @exception NoSuchFieldException
+ */
+ public Object getField(String field_name)
+ throws InvocationTargetException, IllegalStateException, NoSuchFieldException, IllegalAccessException {
+ Getter gtr = new Getter(field_name);
+ try {
+ return queueTool.invokeAndWait(gtr);
+ } catch (JemmyException e) {
+ Exception ex = gtr.getException();
+ if (ex != null) {
+ if (ex instanceof InvocationTargetException) {
+ InvocationTargetException ite = (InvocationTargetException) ex;
+ ite.addSuppressed(e);
+ throw ite;
+ } else if (ex instanceof IllegalStateException) {
+ IllegalStateException ise = (IllegalStateException) ex;
+ ise.addSuppressed(e);
+ throw ise;
+ } else if (ex instanceof NoSuchFieldException) {
+ NoSuchFieldException nsfe = (NoSuchFieldException) ex;
+ nsfe.addSuppressed(e);
+ throw nsfe;
+ } else if (ex instanceof IllegalAccessException) {
+ IllegalAccessException iae = (IllegalAccessException) ex;
+ iae.addSuppressed(e);
+ throw iae;
+ } else {
+ e.addSuppressed(ex);
+ }
+ }
+ throw (e);
+ }
+ }
+
+ /**
+ * Sets component field value through
+ * {@code SwingUtilities.invokeAndWait(Runnable)}.
+ *
+ * @param field_name Name of a field
+ * @param newValue New field value
+ * @see #getField(String)
+ * @see org.netbeans.jemmy.ClassReference
+ * @exception IllegalAccessException
+ * @exception IllegalStateException
+ * @exception InvocationTargetException
+ * @exception NoSuchFieldException
+ */
+ public void setField(String field_name, Object newValue)
+ throws InvocationTargetException, IllegalStateException, NoSuchFieldException, IllegalAccessException {
+ Setter str = new Setter(field_name, newValue);
+ try {
+ queueTool.invokeAndWait(str);
+ } catch (JemmyException e) {
+ Exception ex = str.getException();
+ if (ex != null) {
+ if (ex instanceof InvocationTargetException) {
+ InvocationTargetException ite = (InvocationTargetException) ex;
+ ite.addSuppressed(e);
+ throw ite;
+ } else if (ex instanceof IllegalStateException) {
+ IllegalStateException ise = (IllegalStateException) ex;
+ ise.addSuppressed(e);
+ throw ise;
+ } else if (ex instanceof NoSuchFieldException) {
+ NoSuchFieldException nsfe = (NoSuchFieldException) ex;
+ nsfe.addSuppressed(e);
+ throw nsfe;
+ } else if (ex instanceof IllegalAccessException) {
+ IllegalAccessException iae = (IllegalAccessException) ex;
+ iae.addSuppressed(e);
+ throw iae;
+ } else {
+ e.addSuppressed(ex);
+ }
+ }
+ throw (e);
+ }
+ }
+
+ /**
+ * Invokes component method through
+ * {@code SwingUtilities.invokeAndWait(Runnable)}. and catch all
+ * exceptions.
+ *
+ * @param method_name Name of a method to be invoked
+ * @param params Method params
+ * @param params_classes Method params' classes
+ * @param out TestOut instance to print exceptions stack trace to.
+ * @return an Object - method result
+ * @see #invokeMethod(String, Object[], Class[])
+ * @see org.netbeans.jemmy.ClassReference
+ */
+ public Object invokeExistingMethod(String method_name, Object[] params, Class>[] params_classes,
+ TestOut out) {
+ try {
+ return invokeMethod(method_name, params, params_classes);
+ } catch (InvocationTargetException
+ | IllegalStateException
+ | NoSuchMethodException
+ | IllegalAccessException e) {
+ out.printStackTrace(e);
+ }
+ return null;
+ }
+
+ /**
+ * Gets component field value through
+ * {@code SwingUtilities.invokeAndWait(Runnable)}. and catch all
+ * exceptions.
+ *
+ * @param field_name Name of a field
+ * @param out TestOut instance to print exceptions stack trace to.
+ * @return an Object - fields value
+ * @see #getField(String)
+ * @see #setExistingField(String, Object, TestOut)
+ * @see org.netbeans.jemmy.ClassReference
+ */
+ public Object getExistingField(String field_name,
+ TestOut out) {
+ try {
+ return getField(field_name);
+ } catch (InvocationTargetException
+ | IllegalStateException
+ | NoSuchFieldException
+ | IllegalAccessException e) {
+ out.printStackTrace(e);
+ }
+ return null;
+ }
+
+ /**
+ * Sets component field value through
+ * {@code SwingUtilities.invokeAndWait(Runnable)}. and catch all
+ * exceptions.
+ *
+ * @param field_name Name of a field
+ * @param newValue New field value
+ * @param out TestOut instance to print exceptions stack trace to.
+ * @see #setField(String, Object)
+ * @see #getExistingField(String, TestOut)
+ * @see org.netbeans.jemmy.ClassReference
+ */
+ public void setExistingField(String field_name, Object newValue,
+ TestOut out) {
+ try {
+ setField(field_name, newValue);
+ } catch (InvocationTargetException
+ | IllegalStateException
+ | NoSuchFieldException
+ | IllegalAccessException e) {
+ out.printStackTrace(e);
+ }
+ }
+
+ /**
+ * Invokes component method through
+ * {@code SwingUtilities.invokeAndWait(Runnable)}. and catch all
+ * exceptions. Exceptions are printed into TestOut object defined by
+ * setOutput(TestOut) method.
+ *
+ * @param method_name Name of a method to be invoked
+ * @param params Method params
+ * @param params_classes Method params' classes
+ * @return an Object - method result
+ * @see #invokeExistingMethod(String, Object[], Class[], TestOut)
+ * @see org.netbeans.jemmy.ClassReference
+ */
+ public Object invokeExistingMethod(String method_name, Object[] params, Class>[] params_classes) {
+ return invokeExistingMethod(method_name, params, params_classes, output);
+ }
+
+ /**
+ * Gets component field value through
+ * {@code SwingUtilities.invokeAndWait(Runnable)}. and catch all
+ * exceptions. Exceptions are printed into TestOut object defined by
+ * setOutput(TestOut) method.
+ *
+ * @param field_name Name of a field
+ * @return an Object - fields value
+ * @see #getExistingField(String, TestOut)
+ * @see #setExistingField(String, Object)
+ * @see org.netbeans.jemmy.ClassReference
+ */
+ public Object getExistingField(String field_name) {
+ return getExistingField(field_name, output);
+ }
+
+ /**
+ * Sets component field value through
+ * {@code SwingUtilities.invokeAndWait(Runnable)}. and catch all
+ * exceptions. Exceptions are printed into TestOut object defined by
+ * setOutput(TestOut) method.
+ *
+ * @param field_name Name of a field
+ * @param newValue New field value
+ * @see #setExistingField(String, Object, TestOut)
+ * @see #getExistingField(String)
+ * @see org.netbeans.jemmy.ClassReference
+ */
+ public void setExistingField(String field_name, Object newValue) {
+ setExistingField(field_name, newValue, output);
+ }
+
+ //recursivelly releases all modifiers keys
+ private void robotReleaseModifiers(int modifiers) {
+ if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
+ robotReleaseKey(KeyEvent.VK_SHIFT, modifiers - (InputEvent.SHIFT_MASK & modifiers));
+ } else if ((modifiers & InputEvent.ALT_GRAPH_MASK) != 0) {
+ robotReleaseKey(KeyEvent.VK_ALT_GRAPH, modifiers - (InputEvent.ALT_GRAPH_MASK & modifiers));
+ } else if ((modifiers & InputEvent.ALT_MASK) != 0) {
+ robotReleaseKey(KeyEvent.VK_ALT, modifiers - (InputEvent.ALT_MASK & modifiers));
+ } else if ((modifiers & InputEvent.META_MASK) != 0) {
+ robotReleaseKey(KeyEvent.VK_META, modifiers - (InputEvent.META_MASK & modifiers));
+ } else if ((modifiers & InputEvent.CTRL_MASK) != 0) {
+ robotReleaseKey(KeyEvent.VK_CONTROL, modifiers - (InputEvent.CTRL_MASK & modifiers));
+ }
+ }
+
+ //throws ComponentIsNotVisibleException if component is not visible
+ private void checkVisibility() {
+ if (!component.isVisible()) {
+ throw (new ComponentIsNotVisibleException(component));
+ }
+ }
+
+ //throws ComponentIsNotFocusedException if component has not focus
+ private void checkFocus() {
+ if (!component.hasFocus()) {
+ throw (new ComponentIsNotFocusedException(component));
+ }
+ }
+
+ //creates java.awt.Robot instance
+ private void createRobot() {
+ try {
+ ClassReference robotClassReverence = new ClassReference("java.awt.Robot");
+ robotReference = new ClassReference(robotClassReverence.newInstance(null, null));
+ } catch (ClassNotFoundException
+ | InstantiationException
+ | InvocationTargetException
+ | IllegalStateException
+ | NoSuchMethodException
+ | IllegalAccessException e) {
+ output.printStackTrace(e);
+ }
+ }
+
+ private void waitMouseOver() {
+ try {
+ Waiter wt = new Waiter<>(new Waitable() {
+ @Override
+ public String actionProduced(Component obj) {
+ if (motionListener.getComponent() != null) {
+ return "";
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "Mouse over component";
+ }
+
+ @Override
+ public String toString() {
+ return "waitMouseOver.Waiter{" + getDescription() + '}';
+ }
+ });
+ wt.setTimeoutsToCloneOf(timeouts, "EventDispatcher.WaitComponentUnderMouseTimeout");
+ wt.setOutput(output.createErrorOutput());
+ wt.waitAction(component);
+ } catch (InterruptedException e) {
+ output.printStackTrace(e);
+ } catch (TimeoutExpiredException e) {
+ throw (new NoComponentUnderMouseException());
+ }
+ }
+
+ //produce a robot operations through reflection
+ private void makeRobotOperation(String method, Object[] params, Class>[] paramClasses) {
+ try {
+ robotReference.invokeMethod(method, params, paramClasses);
+ } catch (InvocationTargetException
+ | IllegalStateException
+ | NoSuchMethodException
+ | IllegalAccessException e) {
+ output.printStackTrace(e);
+ }
+ if ((model & JemmyProperties.QUEUE_MODEL_MASK) != 0) {
+ try {
+ waitQueueEmpty(output.createErrorOutput(), timeouts);
+ } catch (TimeoutExpiredException e) {
+ output.printStackTrace(e);
+ }
+ }
+ }
+
+ //recursivelly presses all modifiers keys
+ private void robotPressModifiers(int modifiers) {
+ if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
+ robotPressKey(KeyEvent.VK_SHIFT, modifiers & ~InputEvent.SHIFT_MASK);
+ } else if ((modifiers & InputEvent.ALT_GRAPH_MASK) != 0) {
+ robotPressKey(KeyEvent.VK_ALT_GRAPH, modifiers & ~InputEvent.ALT_GRAPH_MASK);
+ } else if ((modifiers & InputEvent.ALT_MASK) != 0) {
+ robotPressKey(KeyEvent.VK_ALT, modifiers & ~InputEvent.ALT_MASK);
+ } else if ((modifiers & InputEvent.META_MASK) != 0) {
+ robotPressKey(KeyEvent.VK_META, modifiers & ~InputEvent.META_MASK);
+ } else if ((modifiers & InputEvent.CTRL_MASK) != 0) {
+ robotPressKey(KeyEvent.VK_CONTROL, modifiers & ~InputEvent.CTRL_MASK);
+ }
+ }
+
+ private void initMotionListener() {
+ synchronized(EventDispatcher.class) {
+ if (motionListener == null) {
+ motionListener = new MotionListener();
+ Toolkit.getDefaultToolkit().addAWTEventListener(motionListener, AWTEvent.MOUSE_EVENT_MASK);
+ Object[] params = new Object[2];
+ Class>[] paramClasses = {Integer.TYPE, Integer.TYPE};
+ params[0] = getAbsoluteX(-1);
+ params[1] = getAbsoluteX(-1);
+ makeRobotOperation("mouseMove", params, paramClasses);
+ params[0] = getAbsoluteX(0);
+ params[1] = getAbsoluteX(0);
+ makeRobotOperation("mouseMove", params, paramClasses);
+ }
+ }
+ }
+
+ private class Dispatcher extends QueueTool.QueueAction {
+
+ AWTEvent event;
+
+ public Dispatcher(AWTEvent e) {
+ super(e.getClass().getName() + " event dispatching");
+ event = e;
+ }
+
+ @Override
+ public R launch() {
+ if (event instanceof MouseEvent || event instanceof KeyEvent) {
+ checkVisibility();
+ }
+ component.dispatchEvent(event);
+ return null;
+ }
+ }
+
+ private class Invoker extends QueueTool.QueueAction {
+
+ protected String methodName;
+ protected Object[] params;
+ protected Class>[] paramClasses;
+
+ public Invoker(String mn, Object[] p, Class>[] pc) {
+ super(mn + " method invocation");
+ methodName = mn;
+ params = p;
+ paramClasses = pc;
+ }
+
+ @Override
+ public Object launch()
+ throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+ checkVisibility();
+ if (methodName.equals("keyPress") || methodName.equals("keyRelease")) {
+ checkFocus();
+ }
+ return reference.invokeMethod(methodName, params, paramClasses);
+ }
+ }
+
+ private class Getter extends QueueTool.QueueAction {
+
+ String fieldName;
+
+ public Getter(String fn) {
+ super(fn + " field receiving");
+ fieldName = fn;
+ }
+
+ @Override
+ public Object launch()
+ throws InvocationTargetException, NoSuchFieldException, IllegalAccessException {
+ return reference.getField(fieldName);
+ }
+ }
+
+ private class Setter extends QueueTool.QueueAction {
+
+ String fieldName;
+ Object newValue;
+
+ public Setter(String fn, Object nv) {
+ super(fn + " field changing");
+ fieldName = fn;
+ newValue = nv;
+ }
+
+ @Override
+ public Object launch()
+ throws InvocationTargetException, NoSuchFieldException, IllegalAccessException {
+ reference.setField(fieldName, newValue);
+ return null;
+ }
+ }
+
+ private static class MotionListener implements AWTEventListener {
+
+ private volatile Component mouseComponent;
+
+ @Override
+ public void eventDispatched(AWTEvent event) {
+ if (event instanceof MouseEvent) {
+ MouseEvent e = (MouseEvent) event;
+ if (e.getID() == MouseEvent.MOUSE_ENTERED) {
+ mouseComponent = e.getComponent();
+ } else if (e.getID() == MouseEvent.MOUSE_EXITED) {
+ mouseComponent = null;
+ }
+ }
+ }
+
+ public Component getComponent() {
+ return mouseComponent;
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/EventTool.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/EventTool.java
new file mode 100644
index 00000000000..5cd2e4d2b1a
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/EventTool.java
@@ -0,0 +1,538 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.awt.AWTEvent;
+import java.awt.Toolkit;
+import java.awt.event.AWTEventListener;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Vector;
+
+/**
+ *
+ * Provides methods to check last dispatched events, to wait for events of
+ * specific types, or to guarantee that events of specific types are not
+ * dispatched during some time frame.
+ *
+ * All possible listeners are added during this class initialization in case if
+ * "jemmy.event_listening" system property is not equal to "no", so, by default,
+ * all events are listened.
+ *
+ * Uses timeouts:
+ * EventTool.WaitEventTimeout - time to wait for AWT events.
+ * EventTool.WaitNoEventTimeout - when checking for the absence of incoming AWT
+ * events.
+ * EventTool.EventCheckingDelta - time delta between checks for AWT events.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class EventTool implements Timeoutable, Outputable {
+
+ private static final long WAIT_EVENT_TIMEOUT = 60000;
+ private static final long WAIT_NO_EVENT_TIMEOUT = 180000;
+ private static final long EVENT_CHECKING_DELTA = 10;
+
+ private static ListenerSet listenerSet;
+ private static long currentEventMask = 0;
+
+ private TestOut output;
+ private Timeouts timeouts;
+
+ /**
+ * Constructor.
+ */
+ public EventTool() {
+ setOutput(JemmyProperties.getProperties().getOutput());
+ setTimeouts(JemmyProperties.getProperties().getTimeouts());
+ }
+
+ /**
+ * Returns time of the last dispatched event under mask.
+ *
+ * @param eventMask Events types to be searched.
+ * {@code AWTEvent.*_EVENT_MASK} fields combination.
+ * @return time in milliseconds
+ * @see #addListeners(long)
+ */
+ public static long getLastEventTime(long eventMask) {
+ return listenerSet.getLastEventTime(eventMask);
+ }
+
+ /**
+ * Returns last dispatched event under mask.
+ *
+ * @param eventMask Events types to be searched.
+ * {@code AWTEvent.*_EVENT_MASK} fields combination.
+ * @return AWTEvent
+ * @see #addListeners(long)
+ */
+ public static AWTEvent getLastEvent(long eventMask) {
+ return listenerSet.getLastEvent(eventMask);
+ }
+
+ /**
+ * Returns time of the last dispatched event.
+ *
+ * @return time in milliseconds
+ * @see #addListeners(long)
+ */
+ public static long getLastEventTime() {
+ return getLastEventTime(listenerSet.getTheWholeMask());
+ }
+
+ /**
+ * Returns last dispatched event.
+ *
+ * @return AWTEvent
+ * @see #addListeners(long)
+ */
+ public static AWTEvent getLastEvent() {
+ return getLastEvent(listenerSet.getTheWholeMask());
+ }
+
+ /**
+ * Adds listeners to listen events under mask. Invokes
+ * {@code removeListeners()} first, so any event history is lost.
+ *
+ * @param eventMask Mask to listen events under.
+ * {@code AWTEvent.*_EVENT_MASK} fields combination.
+ * @see #addListeners()
+ * @see #removeListeners()
+ */
+ public static void addListeners(long eventMask) {
+ removeListeners();
+ listenerSet.addListeners(eventMask);
+ currentEventMask = eventMask;
+ }
+
+ /**
+ * Adds listeners to listen all types of events. Invokes
+ * {@code removeListeners()} first, so any event history is lost. This
+ * method is invoked during static section of this class.
+ *
+ * @see #addListeners(long)
+ * @see #removeListeners()
+ * @see #getTheWholeEventMask()
+ */
+ public static void addListeners() {
+ addListeners(listenerSet.getTheWholeMask());
+ }
+
+ /**
+ * Removes all listeners.
+ *
+ * @see #addListeners(long)
+ * @see #addListeners()
+ */
+ public static void removeListeners() {
+ listenerSet.removeListeners();
+ }
+
+ /**
+ * Returns event mask last time used by {@code addListeners(long)}
+ * method. In case if {@code addListeners()} method was used last,
+ * {@code getTheWholeEventMask() } result is returned.
+ *
+ * @return a long representing the current event mask value
+ * @see #getTheWholeEventMask()
+ */
+ public static long getCurrentEventMask() {
+ return currentEventMask;
+ }
+
+ /**
+ * Returns a combination of all {@code AWTEvent.*_EVENT_MASK} fields..
+ *
+ * @return a combination of all {@code AWTEvent.*_EVENT_MASK} fields.
+ */
+ public static long getTheWholeEventMask() {
+ return listenerSet.getTheWholeMask();
+ }
+
+ static {
+ Timeouts.initDefault("EventTool.WaitEventTimeout", WAIT_EVENT_TIMEOUT);
+ Timeouts.initDefault("EventTool.WaitNoEventTimeout", WAIT_NO_EVENT_TIMEOUT);
+ Timeouts.initDefault("EventTool.EventCheckingDelta", EVENT_CHECKING_DELTA);
+ listenerSet = new ListenerSet();
+ if (System.getProperty("jemmy.event_listening") == null
+ || !System.getProperty("jemmy.event_listening").equals("no")) {
+ listenerSet.addListeners();
+ }
+ }
+
+ /**
+ * Defines current timeouts.
+ *
+ * @param ts ?t? A collection of timeout assignments.
+ * @see org.netbeans.jemmy.Timeouts
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see #getTimeouts
+ */
+ @Override
+ public void setTimeouts(Timeouts ts) {
+ timeouts = ts;
+ }
+
+ /**
+ * Return current timeouts.
+ *
+ * @return the collection of current timeout assignments.
+ * @see org.netbeans.jemmy.Timeouts
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see #setTimeouts
+ */
+ @Override
+ public Timeouts getTimeouts() {
+ return timeouts;
+ }
+
+ /**
+ * Defines print output streams or writers.
+ *
+ * @param out Identify the streams or writers used for print output.
+ * @see org.netbeans.jemmy.Outputable
+ * @see org.netbeans.jemmy.TestOut
+ * @see #getOutput
+ */
+ @Override
+ public void setOutput(TestOut out) {
+ output = out;
+ }
+
+ /**
+ * Returns print output streams or writers.
+ *
+ * @return an object that contains references to objects for printing to
+ * output and err streams.
+ * @see org.netbeans.jemmy.Outputable
+ * @see org.netbeans.jemmy.TestOut
+ * @see #setOutput
+ */
+ @Override
+ public TestOut getOutput() {
+ return output;
+ }
+
+ /**
+ * Waits for the first event under mask. Waits during
+ * {@code EventTool.WaitEventTimeout} milliseconds.
+ *
+ * @param eventMask Mask to wait events under.
+ * {@code AWTEvent.*_EVENT_MASK} fields combination.
+ * @return an AWTEvent object
+ * @see #waitEvent()
+ * @throws TimeoutExpiredException
+ */
+ public AWTEvent waitEvent(long eventMask) {
+ return (waitEvent(eventMask,
+ timeouts.getTimeout("EventTool.WaitEventTimeout"),
+ output.createErrorOutput()));
+ }
+
+ /**
+ * Waits for the first event. Waits during
+ * {@code EventTool.WaitEventTimeout} milliseconds.
+ *
+ * @return an AWTEvent object
+ * @see #waitEvent(long)
+ * @see #getTheWholeEventMask()
+ * @throws TimeoutExpiredException
+ */
+ public AWTEvent waitEvent() {
+ return waitEvent(listenerSet.getTheWholeMask());
+ }
+
+ /**
+ * Check that no event under mask will be dispatched during time specified.
+ *
+ * @param eventMask Mask to wait events under.
+ * {@code AWTEvent.*_EVENT_MASK} fields combination.
+ * @param waitTime Quiet time (millisecons).
+ * @return true if no event ahs found.
+ * @see #checkNoEvent(long)
+ */
+ public boolean checkNoEvent(long eventMask, long waitTime) {
+ return checkNoEvent(eventMask, waitTime, output);
+ }
+
+ /**
+ * Check that no event will be dispatched during time specified.
+ *
+ * @param waitTime Quiet time (millisecons).
+ * @return true if no event ahs found.
+ * @see #checkNoEvent(long, long)
+ * @see #getTheWholeEventMask()
+ */
+ public boolean checkNoEvent(long waitTime) {
+ return checkNoEvent(listenerSet.getTheWholeMask(), waitTime);
+ }
+
+ /**
+ * During {@code EventTool.WaitNoEventTimeout} time waits for true
+ * result of checkNoEvent(long, long) method.
+ *
+ * @param eventMask Mask to wait events under.
+ * {@code AWTEvent.*_EVENT_MASK} fields combination.
+ * @param waitTime Quiet time (millisecons).
+ * @see #checkNoEvent(long, long)
+ * @see #waitNoEvent(long)
+ * @throws TimeoutExpiredException
+ */
+ public void waitNoEvent(long eventMask, long waitTime) {
+ NoEventWaiter waiter = new NoEventWaiter(eventMask, waitTime);
+ waiter.setTimeouts(timeouts.cloneThis());
+ waiter.getTimeouts().
+ setTimeout("Waiter.WaitingTime",
+ timeouts.getTimeout("EventTool.WaitNoEventTimeout"));
+ waiter.getTimeouts().
+ setTimeout("Waiter.TimeDelta",
+ timeouts.getTimeout("EventTool.EventCheckingDelta"));
+ try {
+ waiter.waitAction(null);
+ } catch (InterruptedException e) {
+ output.printStackTrace(e);
+ }
+ }
+
+ /**
+ * During {@code EventTool.WaitNoEventTimeout} time waits for true
+ * result of {@code checkNoEvent(long)} method.
+ *
+ * @param waitTime Quiet time (millisecons).
+ * @see #checkNoEvent(long)
+ * @see #waitNoEvent(long, long)
+ * @throws TimeoutExpiredException
+ */
+ public void waitNoEvent(long waitTime) {
+ ListenerSet ls = listenerSet;
+ if (ls != null) {
+ // surprisingly this field can be null in case of massive
+ // garbage collecting efforts like in NbTestCase.assertGC
+ waitNoEvent(ls.getTheWholeMask(), waitTime);
+ }
+ }
+
+ private AWTEvent waitEvent(long eventMask, long waitTime, TestOut waiterOutput) {
+ EventWaiter waiter = new EventWaiter(eventMask);
+ waiter.setTimeouts(timeouts.cloneThis());
+ waiter.setOutput(waiterOutput);
+ waiter.getTimeouts().
+ setTimeout("Waiter.WaitingTime",
+ waitTime);
+ waiter.getTimeouts().
+ setTimeout("Waiter.TimeDelta",
+ timeouts.getTimeout("EventTool.EventCheckingDelta"));
+ try {
+ return waiter.waitAction(null);
+ } catch (InterruptedException e) {
+ output.printStackTrace(e);
+ return null;
+ }
+ }
+
+ private boolean checkNoEvent(long eventMask, long waitTime, TestOut waiterOutput) {
+ try {
+ AWTEvent event = waitEvent(eventMask, waitTime, TestOut.getNullOutput());
+ waiterOutput.printLine("AWT event was produced during waiting: ");
+ // used instead of event.toString() because it is not thread safe
+ waiterOutput.printLine(event.getClass().getName());
+ return false;
+ } catch (TimeoutExpiredException e) {
+ return true;
+ }
+ }
+
+ private static class EventType implements AWTEventListener {
+
+ long eventMask;
+ long eventTime;
+ private Reference eventRef;
+
+ public EventType(long eventMask) {
+ this.eventMask = eventMask;
+ eventRef = new WeakReference<>(null);
+ eventTime = -1;
+ }
+
+ @Override
+ public void eventDispatched(AWTEvent event) {
+ eventRef = new WeakReference<>(event);
+ eventTime = System.currentTimeMillis();
+ }
+
+ public AWTEvent getEvent() {
+ return eventRef.get();
+ }
+
+ public long getTime() {
+ return eventTime;
+ }
+
+ public long getEventMask() {
+ return eventMask;
+ }
+ }
+
+ private static class ListenerSet {
+
+ private Vector eventTypes;
+ private long theWholeMask;
+
+ public ListenerSet() {
+ eventTypes = new Vector<>();
+ try {
+ Class> eventClass = Class.forName("java.awt.AWTEvent");
+ Field[] fields = eventClass.getFields();
+ theWholeMask = 0;
+ long eventMask;
+ for (Field field : fields) {
+ if ((field.getModifiers()
+ & (Modifier.PUBLIC | Modifier.STATIC)) != 0
+ && field.getType().equals(Long.TYPE)
+ && field.getName().endsWith("_EVENT_MASK")) {
+ eventMask = (Long) field.get(null);
+ eventTypes.add(new EventType(eventMask));
+ theWholeMask = theWholeMask | eventMask;
+ }
+ }
+ } catch (ClassNotFoundException | IllegalAccessException e) {
+ JemmyProperties.getCurrentOutput().printStackTrace(e);
+ }
+ }
+
+ public void addListeners(long eventMask) {
+ Toolkit dtk = Toolkit.getDefaultToolkit();
+ for (EventType et : eventTypes) {
+ if ((et.getEventMask() & eventMask) != 0) {
+ dtk.addAWTEventListener(et, et.getEventMask());
+ }
+ }
+ }
+
+ public void addListeners() {
+ addListeners(getTheWholeMask());
+ }
+
+ public void removeListeners() {
+ Toolkit dtk = Toolkit.getDefaultToolkit();
+ for (EventType eventType : eventTypes) {
+ dtk.removeAWTEventListener(eventType);
+ }
+ }
+
+ public long getTheWholeMask() {
+ return theWholeMask;
+ }
+
+ public long getLastEventTime(long eventMask) {
+ EventType et = getLastEventType(eventMask);
+ return (et == null) ? -1 : et.getTime();
+ }
+
+ public AWTEvent getLastEvent(long eventMask) {
+ EventType et = getLastEventType(eventMask);
+ return (et == null) ? null : et.getEvent();
+ }
+
+ private EventType getLastEventType(long eventMask) {
+ long maxTime = -1;
+ EventType maxType = null;
+ for (EventType et : eventTypes) {
+ if ((eventMask & et.getEventMask()) != 0
+ && et.getTime() > maxTime) {
+ maxType = et;
+ maxTime = maxType.getTime();
+ }
+ }
+ return maxType;
+ }
+ }
+
+ private static class EventWaiter extends Waiter {
+
+ long eventMask;
+ long startTime;
+
+ public EventWaiter(long eventMask) {
+ this.eventMask = eventMask;
+ startTime = getLastEventTime(eventMask);
+ }
+
+ @Override
+ public AWTEvent actionProduced(Void obj) {
+ EventType et = listenerSet.getLastEventType(eventMask);
+ if (et != null
+ && et.getTime() > startTime) {
+ return et.getEvent();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return ("Last event under "
+ + Long.toString(eventMask, 2) + " event mask");
+ }
+
+ @Override
+ public String toString() {
+ return "EventWaiter{" + "eventMask=" + Long.toString(eventMask, 2) + ", startTime=" + startTime + '}';
+ }
+ }
+
+ private class NoEventWaiter extends Waiter {
+
+ long eventMask;
+ long waitTime;
+
+ public NoEventWaiter(long eventMask, long waitTime) {
+ this.eventMask = eventMask;
+ this.waitTime = waitTime;
+ }
+
+ @Override
+ public String actionProduced(Void obj) {
+ return (checkNoEvent(eventMask, waitTime, TestOut.getNullOutput())
+ ? "Reached!"
+ : null);
+ }
+
+ @Override
+ public String getDescription() {
+ return ("No event under "
+ + Long.toString(eventMask, 2)
+ + " event mask during "
+ + Long.toString(waitTime)
+ + " milliseconds");
+ }
+
+ @Override
+ public String toString() {
+ return "NoEventWaiter{" + "eventMask=" + Long.toString(eventMask, 2) + ", waitTime=" + waitTime + '}';
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/FrameWaiter.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/FrameWaiter.java
new file mode 100644
index 00000000000..3ca7c5408cd
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/FrameWaiter.java
@@ -0,0 +1,465 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.awt.Component;
+import java.awt.Frame;
+
+/**
+ *
+ * Contains methods to search and wait Frame. A FrameWaiter is a utility class
+ * used to look or wait for Frames. It contains methods to search for a Frame
+ * among the currently showing Frames as well as methods that wait for a Frame
+ * to show within an allotted time period.
+ *
+ *
Timeouts used:
+ * FrameWaiter.WaitFrameTimeout - time to wait frame displayed.
+ * FrameWaiter.AfterFrameTimeout - time to sleep after frame has been displayed.
+ *
+ *
+ * @see org.netbeans.jemmy.Timeouts
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class FrameWaiter extends WindowWaiter implements Timeoutable, Outputable {
+
+ private final static long WAIT_TIME = 60000;
+ private final static long AFTER_WAIT_TIME = 0;
+
+ private Timeouts timeouts;
+ private TestOut output;
+
+ /**
+ * Constructor.
+ */
+ public FrameWaiter() {
+ super();
+ setTimeouts(JemmyProperties.getProperties().getTimeouts());
+ setOutput(JemmyProperties.getProperties().getOutput());
+ }
+
+ /**
+ * Searches for a Frame. Search among the currently showing Frames for one
+ * that meets the search criteria applied by the
+ * {@code ComponentChooser} parameter.
+ *
+ * @param cc A component chooser used to define and apply the search
+ * criteria.
+ * @return a reference to the first Frame that is showing and that meets the
+ * search criteria. If no such Frame can be found, a {@code null}
+ * reference is returned.
+ */
+ public static Frame getFrame(ComponentChooser cc) {
+ return (Frame) WindowWaiter.getWindow(new FrameSubChooser(cc));
+ }
+
+ /**
+ * Searches for a Frame. The search proceeds among the currently showing
+ * Frames for the {@code index+1}'th Frame that meets the criteria
+ * defined and applied by the {@code ComonentChooser} parameter.
+ *
+ * @param cc A component chooser used to define and apply the search
+ * criteria.
+ * @param index The ordinal index of the Frame in the set of currently
+ * displayed Frames. The first index is 0.
+ * @return a reference to the {@code index+1}'th Frame that is showing
+ * and that meets the search criteria. If there are fewer than
+ * {@code index+1} Frames, a {@code null} reference is returned.
+ */
+ public static Frame getFrame(ComponentChooser cc, int index) {
+ return (Frame) WindowWaiter.getWindow(new FrameSubChooser(cc), index);
+ }
+
+ /**
+ * Searches for a Frame by title. The search proceeds among the currently
+ * showing Frames for the first with a suitable title.
+ *
+ * @param title Frame title or subtitle.
+ * @param ce If {@code true} and the search is case sensitive, then a
+ * match occurs when the {@code title} argument is a substring of a
+ * Frame title. If {@code false} and the search is case sensitive, then
+ * the {@code title} argument and the Frame title must be the same. If
+ * {@code true} and the search is case insensitive, then a match occurs
+ * when the {@code title} argument is a substring of the Frame title
+ * after changing both to upper case. If {@code false} and the search
+ * is case insensitive, then a match occurs when the {@code title}
+ * argument is a substring of the Frame title after changing both to upper
+ * case.
+ * @param cc If {@code true} the search is case sensitive; otherwise,
+ * the search is case insensitive.
+ * @return a reference to the first Frame that is showing and that has a
+ * suitable title. If no such Frame can be found, a {@code null}
+ * reference is returned.
+ */
+ public static Frame getFrame(String title, boolean ce, boolean cc) {
+ return (Frame) WindowWaiter.getWindow(new FrameByTitleChooser(title, ce, cc));
+ }
+
+ /**
+ * Searches for a Frame by title. The search is for the
+ * {@code index+1}'th Frame among the currently showing Frames that
+ * possess a suitable title.
+ *
+ * @param title Frame title or subtitle.
+ * @param ce If {@code true} and the search is case sensitive, then a
+ * match occurs when the {@code title} argument is a substring of a
+ * Frame title. If {@code false} and the search is case sensitive, then
+ * the {@code title} argument and the Frame title must be the same. If
+ * {@code true} and the search is case insensitive, then a match occurs
+ * when the {@code title} argument is a substring of the Frame title
+ * after changing both to upper case. If {@code false} and the search
+ * is case insensitive, then a match occurs when the {@code title}
+ * argument is a substring of the Frame title after changing both to upper
+ * case.
+ * @param cc If {@code true} the search is case sensitive; otherwise,
+ * the search is case insensitive.
+ * @param index The ordinal index of the Frame in the set of currently
+ * displayed Frames. The first index is 0.
+ * @return a reference to the {@code index+1}'th Frame that is showing
+ * and that has a suitable title. If there are fewer than
+ * {@code index+1} Frames, a {@code null} reference is returned.
+ */
+ public static Frame getFrame(String title, boolean ce, boolean cc, int index) {
+ return (Frame) WindowWaiter.getWindow(new FrameByTitleChooser(title, ce, cc), index);
+ }
+
+ static {
+ Timeouts.initDefault("FrameWaiter.WaitFrameTimeout", WAIT_TIME);
+ Timeouts.initDefault("FrameWaiter.AfterFrameTimeout", AFTER_WAIT_TIME);
+ }
+
+ /**
+ * Defines current timeouts.
+ *
+ * @param timeouts A collection of timeout assignments.
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see org.netbeans.jemmy.Timeouts
+ * @see #getTimeouts
+ */
+ @Override
+ public void setTimeouts(Timeouts timeouts) {
+ this.timeouts = timeouts;
+ Timeouts times = timeouts.cloneThis();
+ times.setTimeout("WindowWaiter.WaitWindowTimeout",
+ timeouts.getTimeout("FrameWaiter.WaitFrameTimeout"));
+ times.setTimeout("WindowWaiter.AfterWindowTimeout",
+ timeouts.getTimeout("FrameWaiter.AfterFrameTimeout"));
+ super.setTimeouts(times);
+ }
+
+ /**
+ * Return current timeouts.
+ *
+ * @return the collection of current timeout assignments.
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see org.netbeans.jemmy.Timeouts
+ * @see #setTimeouts
+ */
+ @Override
+ public Timeouts getTimeouts() {
+ return timeouts;
+ }
+
+ /**
+ * Defines print output streams or writers.
+ *
+ * @param output Identify the streams or writers used for print output.
+ * @see org.netbeans.jemmy.Outputable
+ * @see org.netbeans.jemmy.TestOut
+ * @see #getOutput
+ */
+ @Override
+ public void setOutput(TestOut output) {
+ this.output = output;
+ super.setOutput(output);
+ }
+
+ /**
+ * Returns print output streams or writers.
+ *
+ * @return an object that contains references to objects for printing to
+ * output and err streams.
+ * @see org.netbeans.jemmy.Outputable
+ * @see org.netbeans.jemmy.TestOut
+ * @see #setOutput
+ */
+ @Override
+ public TestOut getOutput() {
+ return output;
+ }
+
+ /**
+ * Waits for a Frame to show. Wait for the {@code index+1}'th Frame
+ * that meets the criteria defined and applied by the
+ * {@code ComonentChooser} parameter to show up.
+ *
+ * @param ch A component chooser used to define and apply the search
+ * criteria.
+ * @param index The ordinal index of the Frame in the set of currently
+ * displayed Frames. The first index is 0.
+ * @return a reference to the {@code index+1}'th Frame that shows and
+ * that meets the search criteria. If fewer than {@code index+1} Frames
+ * show up in the allotted time period then a {@code null} reference is
+ * returned.
+ * @throws TimeoutExpiredException
+ * @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
+ * @exception InterruptedException
+ */
+ public Frame waitFrame(ComponentChooser ch, int index)
+ throws InterruptedException {
+ setTimeouts(timeouts);
+ return (Frame) waitWindow(new FrameSubChooser(ch), index);
+ }
+
+ /**
+ * Waits for a Frame to show. Wait for a Frame that meets the search
+ * criteria applied by the {@code ComponentChooser} parameter to show
+ * up.
+ *
+ * @param ch A component chooser used to define and apply the search
+ * criteria.
+ * @return a reference to the first Frame that shows and that meets the
+ * search criteria. If no such Frame can be found within the time period
+ * allotted, a {@code null} reference is returned.
+ * @throws TimeoutExpiredException
+ * @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
+ * @exception InterruptedException
+ */
+ public Frame waitFrame(ComponentChooser ch)
+ throws InterruptedException {
+ return waitFrame(ch, 0);
+ }
+
+ /**
+ * Waits for a Frame to show. Wait for the {@code index+1}'th Frame to
+ * show with a suitable title.
+ *
+ * @param title Frame title or subtitle.
+ * @param compareExactly If {@code true} and the search is case
+ * sensitive, then a match occurs when the {@code title} argument is a
+ * substring of a Frame title. If {@code false} and the search is case
+ * sensitive, then the {@code title} argument and the Frame title must
+ * be the same. If {@code true} and the search is case insensitive,
+ * then a match occurs when the {@code title} argument is a substring
+ * of the Frame title after changing both to upper case. If
+ * {@code false} and the search is case insensitive, then a match
+ * occurs when the {@code title} argument is a substring of the Frame
+ * title after changing both to upper case.
+ * @param compareCaseSensitive If {@code true} the search is case
+ * sensitive; otherwise, the search is case insensitive.
+ * @param index The ordinal index of the Frame in the set of currently
+ * displayed Frames with the proper window ownership and a suitable title.
+ * The first index is 0.
+ * @return a reference to the {@code index+1}'th Frame to show and that
+ * has a suitable title. If no such Frame can be found within the time
+ * period allotted, a {@code null} reference is returned.
+ * @throws TimeoutExpiredException
+ * @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
+ * @exception InterruptedException
+ */
+ public Frame waitFrame(String title, boolean compareExactly, boolean compareCaseSensitive, int index)
+ throws InterruptedException {
+ return waitFrame(new FrameByTitleChooser(title, compareExactly, compareCaseSensitive), index);
+ }
+
+ /**
+ * Waits for a Frame to show. Wait for the first Frame to show with a
+ * suitable title.
+ *
+ * @param title Frame title or subtitle.
+ * @param compareExactly If {@code true} and the search is case
+ * sensitive, then a match occurs when the {@code title} argument is a
+ * substring of a Frame title. If {@code false} and the search is case
+ * sensitive, then the {@code title} argument and the Frame title must
+ * be the same. If {@code true} and the search is case insensitive,
+ * then a match occurs when the {@code title} argument is a substring
+ * of the Frame title after changing both to upper case. If
+ * {@code false} and the search is case insensitive, then a match
+ * occurs when the {@code title} argument is a substring of the Frame
+ * title after changing both to upper case.
+ * @param compareCaseSensitive If {@code true} the search is case
+ * sensitive; otherwise, the search is case insensitive.
+ * @return a reference to the first Frame to show and that has a suitable
+ * title. If no such Frame can be found within the time period allotted, a
+ * {@code null} reference is returned.
+ * @throws TimeoutExpiredException
+ * @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
+ * @exception InterruptedException
+ */
+ public Frame waitFrame(String title, boolean compareExactly, boolean compareCaseSensitive)
+ throws InterruptedException {
+ return waitFrame(title, compareExactly, compareCaseSensitive, 0);
+ }
+
+ /**
+ * @see Waiter#getWaitingStartedMessage()
+ */
+ @Override
+ protected String getWaitingStartedMessage() {
+ return "Start to wait frame \"" + getComponentChooser().getDescription() + "\" opened";
+ }
+
+ /**
+ * Overrides WindowWaiter.getTimeoutExpiredMessage. Returns the timeout
+ * expired message value.
+ *
+ * @param timeSpent Time spent for waiting
+ * @return a message tring
+ * @see Waiter#getTimeoutExpiredMessage(long)
+ */
+ @Override
+ protected String getTimeoutExpiredMessage(long timeSpent) {
+ return ("Frame \"" + getComponentChooser().getDescription() + "\" has not been opened in "
+ + timeSpent + " milliseconds");
+ }
+
+ /**
+ * Overrides WindowWaiter.getActionProducedMessage. Returns the action
+ * produced message value.
+ *
+ * @param timeSpent Time spent for waiting.
+ * @param result A message string.
+ * @return a message tring
+ * @see Waiter#getActionProducedMessage(long, Object)
+ */
+ @Override
+ protected String getActionProducedMessage(long timeSpent, final Object result) {
+ String resultToString = null;
+ if (result instanceof Component) {
+ // run toString in dispatch thread
+ resultToString = new QueueTool().invokeSmoothly(
+ new QueueTool.QueueAction("result.toString()") {
+ @Override
+ public String launch() {
+ return result.toString();
+ }
+ }
+ );
+ } else {
+ resultToString = result.toString();
+ }
+ return ("Frame \"" + getComponentChooser().getDescription() + "\" has been opened in "
+ + timeSpent + " milliseconds"
+ + "\n " + resultToString);
+ }
+
+ /**
+ * @see Waiter#getGoldenWaitingStartedMessage()
+ */
+ @Override
+ protected String getGoldenWaitingStartedMessage() {
+ return "Start to wait frame \"" + getComponentChooser().getDescription() + "\" opened";
+ }
+
+ /**
+ * @see Waiter#getGoldenTimeoutExpiredMessage()
+ */
+ @Override
+ protected String getGoldenTimeoutExpiredMessage() {
+ return "Frame \"" + getComponentChooser().getDescription() + "\" has not been opened";
+ }
+
+ /**
+ * @see Waiter#getGoldenActionProducedMessage()
+ */
+ @Override
+ protected String getGoldenActionProducedMessage() {
+ return "Frame \"" + getComponentChooser().getDescription() + "\" has been opened";
+ }
+
+ private static class FrameSubChooser implements ComponentChooser {
+
+ private ComponentChooser chooser;
+
+ public FrameSubChooser(ComponentChooser c) {
+ super();
+ chooser = c;
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ if (comp instanceof Frame) {
+ return ((FIND_INVISIBLE_WINDOWS || (comp.isShowing() && comp.isVisible()))
+ && chooser.checkComponent(comp));
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return chooser.getDescription();
+ }
+
+ @Override
+ public String toString() {
+ return "FrameSubChooser{" + "chooser=" + chooser + '}';
+ }
+ }
+
+ private static class FrameByTitleChooser implements ComponentChooser {
+
+ String title;
+ boolean compareExactly;
+ boolean compareCaseSensitive;
+
+ public FrameByTitleChooser(String t, boolean ce, boolean cc) {
+ super();
+ title = t;
+ compareExactly = ce;
+ compareCaseSensitive = cc;
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ if (comp instanceof Frame) {
+ if ((FIND_INVISIBLE_WINDOWS || (comp.isShowing() && comp.isVisible()))
+ && ((Frame) comp).getTitle() != null) {
+ String titleToComp = ((Frame) comp).getTitle();
+ String contextToComp = title;
+ if (compareCaseSensitive) {
+ titleToComp = titleToComp.toUpperCase();
+ contextToComp = contextToComp.toUpperCase();
+ }
+ if (compareExactly) {
+ return titleToComp.equals(contextToComp);
+ } else {
+ return titleToComp.contains(contextToComp);
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getDescription() {
+ return title;
+ }
+
+ @Override
+ public String toString() {
+ return "FrameByTitleChooser{" + "title=" + title + ", compareExactly=" + compareExactly + ", compareCaseSensitive=" + compareCaseSensitive + '}';
+ }
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/JemmyException.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/JemmyException.java
new file mode 100644
index 00000000000..a704af0cfea
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/JemmyException.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ *
+ * Parent of all Jemmy exceptions. Exception can be throught from inside jemmy
+ * methods, if some exception occurs from code invoked from jemmy.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class JemmyException extends RuntimeException {
+
+ private static final long serialVersionUID = 42L;
+ private Throwable innerException = null;
+ private Object object = null;
+
+ /**
+ * Constructor.
+ *
+ * @param description An exception description.
+ */
+ public JemmyException(String description) {
+ super(description);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param description An exception description.
+ * @param innerException Exception from code invoked from jemmy.
+ */
+ public JemmyException(String description, Throwable innerException) {
+ this(description);
+ this.innerException = innerException;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param description An exception description.
+ * @param object Object regarding which exception is thrown.
+ */
+ public JemmyException(String description, Object object) {
+ this(description);
+ this.object = object;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param description An exception description.
+ * @param innerException Exception from code invoked from jemmy.
+ * @param object Object regarding which exception is thrown.
+ */
+ public JemmyException(String description, Throwable innerException, Object object) {
+ this(description, innerException);
+ this.object = object;
+ }
+
+ /**
+ * Returns "object" constructor parameter.
+ *
+ * @return the Object value associated with the exception.
+ */
+ public Object getObject() {
+ return object;
+ }
+
+ /**
+ * Returns inner exception.
+ *
+ * @return An inner exception.
+ * @deprecated Use getInnerThrowable()
+ */
+ @Deprecated
+ public Exception getInnerException() {
+ if (innerException instanceof Exception) {
+ return (Exception) innerException;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns inner throwable.
+ *
+ * @return An inner throwable.
+ */
+ public Throwable getInnerThrowable() {
+ return innerException;
+ }
+
+ /**
+ * Prints stack trace into System.out.
+ */
+ @Override
+ public void printStackTrace() {
+ printStackTrace(System.out);
+ }
+
+ /**
+ * Prints stack trace.
+ *
+ * @param ps PrintStream to print stack trace into.
+ */
+ @Override
+ public void printStackTrace(PrintStream ps) {
+ super.printStackTrace(ps);
+ if (innerException != null) {
+ ps.println("Inner exception:");
+ innerException.printStackTrace(ps);
+ }
+ if (object != null) {
+ ps.println("Object:");
+ ps.println(object.toString());
+ }
+ }
+
+ /**
+ * Prints stack trace.
+ *
+ * @param pw PrintWriter to print stack trace into.
+ *
+ */
+ @Override
+ public void printStackTrace(PrintWriter pw) {
+ super.printStackTrace(pw);
+ if (innerException != null) {
+ pw.println("Inner exception:");
+ innerException.printStackTrace(pw);
+ }
+ if (object != null) {
+ pw.println("Object:");
+ pw.println(object.toString());
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/JemmyInputException.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/JemmyInputException.java
new file mode 100644
index 00000000000..f38fed9a9a0
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/JemmyInputException.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.awt.Component;
+
+/**
+ *
+ * Exception can be thrown as a result of incorrect input operations.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class JemmyInputException extends JemmyException {
+
+ private static final long serialVersionUID = 42L;
+
+ /**
+ * Constructor.
+ *
+ * @param comp Component regarding which exception is thrown.
+ */
+ public JemmyInputException(Component comp) {
+ super("Input exception", comp);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param message A descriptive message.
+ * @param comp Component regarding which exception is thrown.
+ */
+ public JemmyInputException(String message, Component comp) {
+ super(message, comp);
+ }
+
+ /**
+ * Returns component.
+ *
+ * @return the Component associated with the exception.
+ */
+ public Component getComponent() {
+ return (Component) getObject();
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/JemmyProperties.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/JemmyProperties.java
new file mode 100644
index 00000000000..02633b2f305
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/JemmyProperties.java
@@ -0,0 +1,985 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.Stack;
+import java.util.StringTokenizer;
+
+import org.netbeans.jemmy.drivers.APIDriverInstaller;
+import org.netbeans.jemmy.drivers.DefaultDriverInstaller;
+import org.netbeans.jemmy.drivers.DriverInstaller;
+import org.netbeans.jemmy.drivers.InputDriverInstaller;
+import org.netbeans.jemmy.explorer.GUIBrowser;
+
+/**
+ *
+ * Keeps default Jemmy properties.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ *
+ */
+public class JemmyProperties {
+
+ /**
+ * The event queue model mask.
+ *
+ * @see #getCurrentDispatchingModel()
+ * @see #setCurrentDispatchingModel(int)
+ */
+ public static final int QUEUE_MODEL_MASK = 1;
+
+ /**
+ * The robot using model mask.
+ *
+ * @see #getCurrentDispatchingModel()
+ * @see #setCurrentDispatchingModel(int)
+ */
+ public static final int ROBOT_MODEL_MASK = 2;
+
+ /**
+ * Event shorcutting model mask. Should not be used together with robot
+ * mask.
+ *
+ * @see #getCurrentDispatchingModel()
+ * @see #setCurrentDispatchingModel(int)
+ */
+ public static final int SHORTCUT_MODEL_MASK = 4;
+
+ /**
+ * The robot using model mask.
+ *
+ * @see #getCurrentDispatchingModel()
+ * @see #setCurrentDispatchingModel(int)
+ */
+ public static final int SMOOTH_ROBOT_MODEL_MASK = 8;
+
+ private static final int DEFAULT_DRAG_AND_DROP_STEP_LENGTH = 100;
+ private static final Stack propStack = new Stack<>();
+
+ Hashtable properties;
+
+ /**
+ *
+ */
+ protected JemmyProperties() {
+ super();
+ properties = new Hashtable<>();
+ setProperty("timeouts", new Timeouts());
+ setProperty("output", new TestOut());
+ setProperty("resources", new BundleManager());
+ setProperty("binding.map", new DefaultCharBindingMap());
+ setProperty("dispatching.model", getDefaultDispatchingModel());
+ setProperty("drag_and_drop.step_length", DEFAULT_DRAG_AND_DROP_STEP_LENGTH);
+ }
+
+ /**
+ * Returns major version (like 1.0).
+ *
+ * @return a String representing the major version value.
+ */
+ public static String getMajorVersion() {
+ return (extractValue(getProperties().getClass().
+ getClassLoader().getResourceAsStream("org/netbeans/jemmy/version_info"),
+ "Jemmy-MajorVersion"));
+ }
+
+ /**
+ * Returns minor version (like 1).
+ *
+ * @return a String representing the minor version value.
+ */
+ public static String getMinorVersion() {
+ return (extractValue(getProperties().getClass().
+ getClassLoader().getResourceAsStream("org/netbeans/jemmy/version_info"),
+ "Jemmy-MinorVersion"));
+ }
+
+ /**
+ * Returns build (like 20011231 (yyyymmdd)).
+ *
+ * @return a String representing the build value.
+ */
+ public static String getBuild() {
+ return (extractValue(getProperties().getClass().
+ getClassLoader().getResourceAsStream("org/netbeans/jemmy/version_info"),
+ "Jemmy-Build"));
+ }
+
+ /**
+ * Returns full version string (like 1.0.1-20011231).
+ *
+ * @return a String representing the full version value.
+ */
+ public static String getFullVersion() {
+ return (getMajorVersion() + "."
+ + getMinorVersion() + "-"
+ + getBuild());
+ }
+
+ /**
+ * Returns version string (like 1.0.1).
+ *
+ * @return a String representing the short version value.
+ */
+ public static String getVersion() {
+ return (getMajorVersion() + "."
+ + getMinorVersion());
+ }
+
+ /**
+ * Creates a copy of the current JemmyProperties object and pushes it into
+ * the properties stack.
+ *
+ * @return New current properties.
+ */
+ public static JemmyProperties push() {
+ return push(getProperties().cloneThis());
+ }
+
+ /**
+ * Pops last pushed properties from the properties stack. If stack has just
+ * one element, does nothing.
+ *
+ * @return Poped properties.
+ */
+ public static JemmyProperties pop() {
+ JemmyProperties result = propStack.pop();
+ if (propStack.isEmpty()) {
+ propStack.push(result);
+ }
+ return result;
+ }
+
+ /**
+ * Just like getProperties().getProperty(propertyName).
+ *
+ * @param propertyName a property key
+ * @return a property value
+ * @see #setCurrentProperty
+ * @see #setCurrentTimeout
+ */
+ public static Object getCurrentProperty(String propertyName) {
+ return getProperties().getProperty(propertyName);
+ }
+
+ /**
+ * Just like getProperties().setProperty(propertyName, propertyValue).
+ *
+ * @param propertyName a property key
+ * @param propertyValue a property value
+ * @return previous property value
+ * @see #getCurrentProperty
+ * @see #getCurrentTimeout
+ */
+ public static Object setCurrentProperty(String propertyName, Object propertyValue) {
+ return getProperties().setProperty(propertyName, propertyValue);
+ }
+
+ /**
+ * Removes a property from current properties list.
+ *
+ * @param propertyName a property key.
+ * @return previous property value
+ */
+ public static Object removeCurrentProperty(String propertyName) {
+ return getProperties().removeProperty(propertyName);
+ }
+
+ /**
+ * Returns the current key values.
+ *
+ * @return an array of Strings representing the current key values
+ */
+ public static String[] getCurrentKeys() {
+ return getProperties().getKeys();
+ }
+
+ /**
+ * Just like getProperties().getTimeouts().
+ *
+ * @return a Timeouts object representing the current timeouts.
+ * @see #setCurrentTimeouts
+ */
+ public static Timeouts getCurrentTimeouts() {
+ return getProperties().getTimeouts();
+ }
+
+ /**
+ * Just like getProperties().setTimeouts(to).
+ *
+ * @param to New timeouts
+ * @return old timeouts.
+ * @see #getCurrentTimeouts
+ */
+ public static Timeouts setCurrentTimeouts(Timeouts to) {
+ return getProperties().setTimeouts(to);
+ }
+
+ /**
+ * Just like getProperties().getTimeouts().setTimeout(name, newValue).
+ *
+ * @param name a timeout name
+ * @param newValue a timeout value
+ * @return previous timeout value
+ * @see #getCurrentTimeout
+ */
+ public static long setCurrentTimeout(String name, long newValue) {
+ return getProperties().getTimeouts().setTimeout(name, newValue);
+ }
+
+ /**
+ * Just like getProperties().getTimeouts().getTimeout(name).
+ *
+ * @param name a timeout name
+ * @return a timeout value
+ * @see #setCurrentTimeout
+ */
+ public static long getCurrentTimeout(String name) {
+ return getProperties().getTimeouts().getTimeout(name);
+ }
+
+ /**
+ * Just like getProperties().getTimeouts().initTimeout(name, newValue).
+ *
+ * @param name a timeout name
+ * @param newValue a timeout value
+ * @return a timeout value
+ * @see #setCurrentTimeout
+ */
+ public static long initCurrentTimeout(String name, long newValue) {
+ return getProperties().getTimeouts().initTimeout(name, newValue);
+ }
+
+ /**
+ * Just like getProperties().getOutput().
+ *
+ * @return a TestOut object representing the current output.
+ * @see #setCurrentOutput
+ */
+ public static TestOut getCurrentOutput() {
+ return getProperties().getOutput();
+ }
+
+ /**
+ * Just like getProperties().setOutput(out).
+ *
+ * @param out new output
+ * @return a TestOut object representing the current output.
+ * @see #getCurrentOutput
+ */
+ public static TestOut setCurrentOutput(TestOut out) {
+ return getProperties().setOutput(out);
+ }
+
+ /**
+ * Just like getProperties().getBundleManager().
+ *
+ * @return a BundleManager object representing the current bundle manager.
+ * @see #setCurrentBundleManager
+ */
+ public static BundleManager getCurrentBundleManager() {
+ return getProperties().getBundleManager();
+ }
+
+ /**
+ * Just like getProperties().setBundleManager(resources).
+ *
+ * @param resources new BundleManager
+ * @return a BundleManager object representing the current bundle manager.
+ * @see #getCurrentBundleManager
+ */
+ public static BundleManager setCurrentBundleManager(BundleManager resources) {
+ return getProperties().setBundleManager(resources);
+ }
+
+ /**
+ * Just like getProperties().getBundleManager().getResource(key).
+ *
+ * @param key a resource key.
+ * @return a resource value
+ */
+ public static String getCurrentResource(String key) {
+ return getProperties().getBundleManager().getResource(key);
+ }
+
+ /**
+ * Just like getProperties().getBundleManager().getResource(bundleID, key).
+ *
+ * @param key a resource key.
+ * @param bundleID a bundle ID
+ * @return a resource value
+ */
+ public static String getCurrentResource(String bundleID, String key) {
+ return getProperties().getBundleManager().getResource(bundleID, key);
+ }
+
+ /**
+ * Just like getProperties().getCharBindingMap().
+ *
+ * @return a CharBindingMap object representing the current char binding
+ * map.
+ * @see #setCurrentCharBindingMap
+ */
+ public static CharBindingMap getCurrentCharBindingMap() {
+ return getProperties().getCharBindingMap();
+ }
+
+ /**
+ * Just like getProperties().setCharBindingMap(map).
+ *
+ * @param map new CharBindingMap.
+ * @return old CharBindingMap object.
+ * @see #getCurrentCharBindingMap
+ */
+ public static CharBindingMap setCurrentCharBindingMap(CharBindingMap map) {
+ return getProperties().setCharBindingMap(map);
+ }
+
+ /**
+ * Returns the current dispatching model.
+ *
+ * @return Event dispatching model.
+ * @see #getDispatchingModel()
+ * @see #setCurrentDispatchingModel(int)
+ * @see #QUEUE_MODEL_MASK
+ * @see #ROBOT_MODEL_MASK
+ */
+ public static int getCurrentDispatchingModel() {
+ return getProperties().getDispatchingModel();
+ }
+
+ /**
+ * Defines event dispatching model. If (model & ROBOT_MODEL_MASK) != 0
+ * java.awt.Robot class is used to reproduce user actions, otherwise actions
+ * are reproduced by event posting. If (model & QUEUE_MODEL_MASK) != 0
+ * actions are reproduced through event queue.
+ *
+ * @param model New dispatching model value.
+ * @return Previous dispatching model value.
+ * @see #setDispatchingModel(int)
+ * @see #getCurrentDispatchingModel()
+ * @see #QUEUE_MODEL_MASK
+ * @see #ROBOT_MODEL_MASK
+ * @see #initDispatchingModel(boolean, boolean)
+ * @see #initDispatchingModel()
+ */
+ public static int setCurrentDispatchingModel(int model) {
+ return getProperties().setDispatchingModel(model);
+ }
+
+ /**
+ * Returns default event dispatching model.
+ *
+ * @return QUEUE_MODEL_MASK
+ * @see #setCurrentDispatchingModel(int)
+ * @see #QUEUE_MODEL_MASK
+ * @see #ROBOT_MODEL_MASK
+ */
+ public static int getDefaultDispatchingModel() {
+ return SHORTCUT_MODEL_MASK | QUEUE_MODEL_MASK;
+ }
+
+ /**
+ * Returns the current drag and drop step length value.
+ *
+ * @return Pixel count to move mouse during one drag'n'drop step.
+ * @see #getDragAndDropStepLength()
+ * @see #setCurrentDragAndDropStepLength(int)
+ */
+ public static int getCurrentDragAndDropStepLength() {
+ return getProperties().getDragAndDropStepLength();
+ }
+
+ /**
+ * Specifies the current drag and drop step length value.
+ *
+ * @param model Pixel count to move mouse during one drag'n'drop step.
+ * @return Previous value.
+ * @see #setDragAndDropStepLength(int)
+ * @see #getCurrentDragAndDropStepLength()
+ */
+ public static int setCurrentDragAndDropStepLength(int model) {
+ return getProperties().setDragAndDropStepLength(model);
+ }
+
+ /**
+ * Peeks upper JemmyProperties instance from stack.
+ *
+ * @return a JemmyProperties object representing the properties value.
+ */
+ public static JemmyProperties getProperties() {
+ if (propStack.empty()) {
+ propStack.add(new JemmyProperties());
+ }
+ return propStack.peek();
+ }
+
+ /**
+ * Prints full version into standard output.
+ *
+ * @param argv Application args.
+ */
+ public static void main(String[] argv) {
+ if (argv.length == 0) {
+ System.out.println("Jemmy version : " + getVersion());
+ } else if (argv.length == 1
+ && argv[0].equals("-f")) {
+ System.out.println("Jemmy full version : " + getFullVersion());
+ } else if (argv.length > 0
+ && argv[0].equals("-e")) {
+ String[] newArgv = new String[argv.length - 1];
+ System.arraycopy(argv, 1, newArgv, 0, argv.length - 1);
+ GUIBrowser.main(newArgv);
+ } else {
+ System.out.println("Parameters: ");
+ System.out.println(" - report Jemmy version.");
+ System.out.println("\"-f\" - report full jemmy version.");
+ }
+ }
+
+ /**
+ * Pushes properties stack.
+ *
+ * @param props a JemmyProperties instance to put into the stack head.
+ * @return a JemmyProperties object.
+ */
+ protected static JemmyProperties push(JemmyProperties props) {
+ return propStack.push(props);
+ }
+
+ static {
+ setCurrentDispatchingModel(getDefaultDispatchingModel());
+ }
+
+ /**
+ * Method to initialize timeouts and resources.
+ *
+ * @param prop_file File to get filenames from.
+ * Can contain definition of variables TIMEOUTS_FILE - full path to timeouts
+ * file,
+ * RESOURCE_FILE - full path to resource file.
+ * @see org.netbeans.jemmy.JemmyProperties#initProperties()
+ */
+ public void initProperties(String prop_file) {
+ try {
+ getOutput().printLine("Loading properties from " + prop_file + " file");
+ Properties props = new Properties();
+ try (FileInputStream fileStream = new FileInputStream(prop_file)) {
+ props.load(fileStream);
+ }
+ if (props.getProperty("TIMEOUTS_FILE") != null
+ && !props.getProperty("TIMEOUTS_FILE").equals("")) {
+ getOutput().printLine("Loading timeouts from " + props.getProperty("TIMEOUTS_FILE")
+ + " file");
+ getTimeouts().loadDefaults(props.getProperty("TIMEOUTS_FILE"));
+ }
+ if (props.getProperty("RESOURCE_FILE") != null
+ && !props.getProperty("RESOURCE_FILE").equals("")) {
+ getOutput().printLine("Loading resources from " + props.getProperty("RESOURCE_FILE")
+ + " file");
+ getBundleManager().loadBundleFromFile(props.getProperty("RESOURCE_FILE"), "");
+ }
+ } catch (IOException e) {
+ getOutput().printStackTrace(e);
+ }
+ }
+
+ /**
+ * Method to initialize timeouts and resources.
+ * Uses jemmy.properties system property to find file.
+ *
+ * @see org.netbeans.jemmy.JemmyProperties#initProperties(String)
+ */
+ public void initProperties() {
+ if (System.getProperty("jemmy.properties") != null
+ && !System.getProperty("jemmy.properties").equals("")) {
+ initProperties(System.getProperty("jemmy.properties"));
+ } else {
+ try {
+ getTimeouts().load();
+ getBundleManager().load();
+ } catch (IOException e) {
+ getOutput().printStackTrace(e);
+ }
+ }
+ }
+
+ /**
+ * Initializes dispatching model.
+ *
+ * @param queue Notifies that event queue dispatching should be used.
+ * @param robot Notifies that robot dispatching should be used.
+ * @param shortcut Notifies that event shorcutting should be used.
+ */
+ public void initDispatchingModel(boolean queue, boolean robot, boolean shortcut) {
+ initDispatchingModel(queue, robot, shortcut, false);
+ }
+
+ /**
+ * Initializes dispatching model.
+ *
+ * @param queue Notifies that event queue dispatching should be used.
+ * @param robot Notifies that robot dispatching should be used.
+ * @param shortcut Notifies that event shorcutting should be used.
+ */
+ public void initDispatchingModel(boolean queue, boolean robot, boolean shortcut, boolean smooth) {
+ int model = getDefaultDispatchingModel();
+ getOutput().print("Reproduce user actions ");
+ if (queue) {
+ model = QUEUE_MODEL_MASK;
+ getOutput().printLine("through event queue.");
+ } else {
+ model = model - (model & QUEUE_MODEL_MASK);
+ getOutput().printLine("directly.");
+ }
+ getOutput().print("Use ");
+ if (robot) {
+ model = model | ROBOT_MODEL_MASK;
+ getOutput().print("java.awt.Robot class");
+ } else {
+ model = model - (model & ROBOT_MODEL_MASK);
+ getOutput().print("event dispatching");
+ }
+ if (smooth) {
+ model = model | SMOOTH_ROBOT_MODEL_MASK;
+ } else {
+ model = model - (model & SMOOTH_ROBOT_MODEL_MASK);
+ }
+ getOutput().printLine(" to reproduce user actions");
+ if (shortcut) {
+ model = model | SHORTCUT_MODEL_MASK;
+ getOutput().print("Shortcut");
+ } else {
+ model = model - (model & SHORTCUT_MODEL_MASK);
+ getOutput().print("Dispatch");
+ }
+ getOutput().printLine(" test events");
+ setDispatchingModel(model);
+ }
+
+ /**
+ * Initializes dispatching model.
+ *
+ * @param queue Notifies that event queue dispatching should be used.
+ * @param robot Notifies that robot dispatching should be used.
+ */
+ public void initDispatchingModel(boolean queue, boolean robot) {
+ this.initDispatchingModel(queue, robot, false);
+ }
+
+ /**
+ * Initializes dispatching model. Uses "jemmy.queue_dispatching" and
+ * "jemmy.robot_dispatching" system properties to determine what model
+ * should be used. Possible values for the both properties:
+ * "off" - switch mode off.
+ * "on" - switch mode on.
+ * "" - use default value.
+ *
+ * @see #getDefaultDispatchingModel()
+ */
+ public void initDispatchingModel() {
+ boolean qmask = ((getDefaultDispatchingModel() & QUEUE_MODEL_MASK) != 0);
+ boolean rmask = ((getDefaultDispatchingModel() & ROBOT_MODEL_MASK) != 0);
+ boolean srmask = ((getDefaultDispatchingModel() & SMOOTH_ROBOT_MODEL_MASK) != 0);
+ boolean smask = ((getDefaultDispatchingModel() & SHORTCUT_MODEL_MASK) != 0);
+ if (System.getProperty("jemmy.queue_dispatching") != null
+ && !System.getProperty("jemmy.queue_dispatching").equals("")) {
+ qmask = System.getProperty("jemmy.queue_dispatching").equals("on");
+ }
+ if (System.getProperty("jemmy.robot_dispatching") != null
+ && !System.getProperty("jemmy.robot_dispatching").equals("")) {
+ rmask = System.getProperty("jemmy.robot_dispatching").equals("on");
+ }
+ if (System.getProperty("jemmy.smooth_robot_dispatching") != null
+ && !System.getProperty("jemmy.smooth_robot_dispatching").equals("")) {
+ srmask = System.getProperty("jemmy.smooth_robot_dispatching").equals("on");
+ }
+ if (System.getProperty("jemmy.shortcut_events") != null
+ && !System.getProperty("jemmy.shortcut_events").equals("")) {
+ smask = System.getProperty("jemmy.shortcut_events").equals("on");
+ }
+ initDispatchingModel(qmask, rmask, smask, srmask);
+ }
+
+ /**
+ * Inits properties and dispatching model from system environment variables.
+ *
+ * @see #initProperties()
+ * @see #initDispatchingModel()
+ */
+ public void init() {
+ initProperties();
+ initDispatchingModel();
+ }
+
+ /**
+ * Returns timeouts.
+ *
+ * @return the Timeouts value.
+ * @see #setTimeouts
+ */
+ public Timeouts getTimeouts() {
+ return (Timeouts) getProperty("timeouts");
+ }
+
+ /**
+ * Changes timeouts.
+ *
+ * @param to new timeouts.
+ * @return old timeouts.
+ * @see #getTimeouts
+ */
+ public Timeouts setTimeouts(Timeouts to) {
+ return (Timeouts) setProperty("timeouts", to);
+ }
+
+ /**
+ * Changes a timeouts value.
+ *
+ * @param name Timeout name
+ * @param newValue New timeout value
+ * @return previous timeout value
+ * @see #getTimeout
+ */
+ public long setTimeout(String name, long newValue) {
+ return getTimeouts().setTimeout(name, newValue);
+ }
+
+ /**
+ * Returns a timeouts value.
+ *
+ * @param name Timeout name
+ * @return a timeout value
+ * @see #setTimeout
+ */
+ public long getTimeout(String name) {
+ return getTimeouts().getTimeout(name);
+ }
+
+ /**
+ * Inits a timeouts value.
+ *
+ * @param name Timeout name
+ * @param newValue New timeout value
+ * @return a timeout value
+ */
+ public long initTimeout(String name, long newValue) {
+ return getTimeouts().initTimeout(name, newValue);
+ }
+
+ /**
+ * Returns output.
+ *
+ * @return a TestOut object representing the output value
+ * @see #setOutput
+ */
+ public TestOut getOutput() {
+ return (TestOut) getProperty("output");
+ }
+
+ /**
+ * Changes output.
+ *
+ * @param out new output.
+ * @return old output.
+ * @see #getOutput
+ */
+ public TestOut setOutput(TestOut out) {
+ return (TestOut) setProperty("output", out);
+ }
+
+ /**
+ * Returns bundle manager.
+ *
+ * @return a BundleManager object representing the bundle manager value.
+ * @see #setBundleManager
+ */
+ public BundleManager getBundleManager() {
+ return (BundleManager) getProperty("resources");
+ }
+
+ /**
+ * Changes bundle manager.
+ *
+ * @param resources new bundle manager.
+ * @return old bundle manager
+ * @see #getBundleManager
+ */
+ public BundleManager setBundleManager(BundleManager resources) {
+ return (BundleManager) setProperty("resources", resources);
+ }
+
+ /**
+ * Returns resource value.
+ *
+ * @param key Resource key.
+ * @return resource value
+ */
+ public String getResource(String key) {
+ return getBundleManager().getResource(key);
+ }
+
+ /**
+ * Returns resource value from the specified bundle.
+ *
+ * @param bundleID Id of a bundle to get resource from.
+ * @param key Resource key.
+ * @return resource value
+ */
+ public String getResource(String bundleID, String key) {
+ return getBundleManager().getResource(bundleID, key);
+ }
+
+ /**
+ * Returns char binding map.
+ *
+ * @return the char binding map.
+ * @see #setCharBindingMap
+ */
+ public CharBindingMap getCharBindingMap() {
+ return (CharBindingMap) getProperty("binding.map");
+ }
+
+ /**
+ * Changes char binding map.
+ *
+ * @param map new char binding map.
+ * @return old char binding map.
+ * @see #getCharBindingMap
+ */
+ public CharBindingMap setCharBindingMap(CharBindingMap map) {
+ return (CharBindingMap) setProperty("binding.map", map);
+ }
+
+ /**
+ * Returns the dispatching model.
+ *
+ * @return Event dispatching model.
+ * @see #getCurrentDispatchingModel()
+ * @see #setDispatchingModel(int)
+ * @see #QUEUE_MODEL_MASK
+ * @see #ROBOT_MODEL_MASK
+ */
+ public int getDispatchingModel() {
+ return (Integer) getProperty("dispatching.model");
+ }
+
+ private static DriverInstaller getDriverInstaller(int model) {
+ String name = System.getProperty("jemmy.drivers.installer");
+ DriverInstaller installer = null;
+ try {
+ if (name != null && !(name.length() == 0)) {
+ installer = (DriverInstaller) new ClassReference(name).newInstance(null, null);
+ }
+ } catch (ClassNotFoundException
+ | IllegalAccessException
+ | NoSuchMethodException
+ | InstantiationException
+ | InvocationTargetException e) {
+ getCurrentOutput().printLine("Cannot init driver installer:");
+ getCurrentOutput().printStackTrace(e);
+ }
+ if (installer == null) {
+ if (System.getProperty("os.name").startsWith("Mac OS X")) {
+ installer = new APIDriverInstaller((model & SHORTCUT_MODEL_MASK) != 0);
+ } else {
+ installer = new DefaultDriverInstaller((model & SHORTCUT_MODEL_MASK) != 0);
+ }
+ }
+ getCurrentOutput().printLine("Using " + installer.getClass().getName() + " driver installer");
+ return installer;
+ }
+
+ /**
+ * Specifies the dispatching model value.
+ *
+ * @param model New dispatching model value.
+ * @return Previous dispatching model value.
+ * @see #setCurrentDispatchingModel(int)
+ * @see #getDispatchingModel()
+ * @see #QUEUE_MODEL_MASK
+ * @see #ROBOT_MODEL_MASK
+ */
+ public int setDispatchingModel(int model) {
+ new InputDriverInstaller((model & ROBOT_MODEL_MASK) == 0, (model & SMOOTH_ROBOT_MODEL_MASK) != 0).install();
+ getDriverInstaller(model).install();
+ return (Integer) setProperty("dispatching.model", model);
+ }
+
+ /**
+ * Returns the drag and drop step length value.
+ *
+ * @return Pixel count to move mouse during one drag'n'drop step.
+ * @see #getCurrentDragAndDropStepLength()
+ * @see #setDragAndDropStepLength(int)
+ */
+ public int getDragAndDropStepLength() {
+ return (Integer) getProperty("drag_and_drop.step_length");
+ }
+
+ /**
+ * Specifies the drag and drop step length value.
+ *
+ * @param length Pixel count to move mouse during one drag'n'drop step.
+ * @return Previous value.
+ * @see #setCurrentDragAndDropStepLength(int)
+ * @see #getDragAndDropStepLength()
+ */
+ public int setDragAndDropStepLength(int length) {
+ return (Integer) setProperty("drag_and_drop.step_length", length);
+ }
+
+ /**
+ * Checks if "name" propery currently has a value.
+ *
+ * @param name Property name. Should by unique.
+ * @return true if property was defined.
+ * @see #setProperty(String, Object)
+ * @see #getProperty(String)
+ */
+ public boolean contains(String name) {
+ return properties.containsKey(name);
+ }
+
+ /**
+ * Saves object as a static link to be used by other objects.
+ *
+ * @param name Property name. Should by unique.
+ * @param newValue Property value.
+ * @return Previous value of "name" property.
+ * @see #setCurrentProperty(String, Object)
+ * @see #getProperty(String)
+ * @see #contains(String)
+ */
+ public Object setProperty(String name, Object newValue) {
+ Object oldValue = null;
+ if (contains(name)) {
+ oldValue = properties.get(name);
+ properties.remove(name);
+ }
+ properties.put(name, newValue);
+ return oldValue;
+ }
+
+ /**
+ * Returns the property value.
+ *
+ * @param name Property name. Should by unique.
+ * @return Property value stored by setProperty(String, Object) method.
+ * @see #getCurrentProperty(String)
+ * @see #setProperty(String, Object)
+ * @see #contains(String)
+ */
+ public Object getProperty(String name) {
+ if (contains(name)) {
+ return properties.get(name);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Removes the property.
+ *
+ * @param name A name of the property to be removed.
+ * @return previous property value
+ */
+ public Object removeProperty(String name) {
+ if (contains(name)) {
+ return properties.remove(name);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the key values.
+ *
+ * @return an array of Strings representing the key values.
+ */
+ public String[] getKeys() {
+ Enumeration keys = properties.keys();
+ String[] result = new String[properties.size()];
+ int i = 0;
+ while (keys.hasMoreElements()) {
+ result[i] = keys.nextElement();
+ i++;
+ }
+ return result;
+ }
+
+ /**
+ * Copy all properties from this instance into another.
+ *
+ * @param properties a JemmyProperties instance to copy properties into.
+ */
+ public void copyTo(JemmyProperties properties) {
+ String[] keys = getKeys();
+ for (String key : keys) {
+ properties.setProperty(key, getProperty(key));
+ }
+ //some should be cloned
+ properties.setTimeouts(getTimeouts().cloneThis());
+ properties.setBundleManager(getBundleManager().cloneThis());
+ }
+
+ /**
+ * Creates an exact copy on this instance.
+ *
+ * @return new JemmyProperties object.
+ */
+ protected JemmyProperties cloneThis() {
+ JemmyProperties result = new JemmyProperties();
+ copyTo(result);
+ return result;
+ }
+
+ private static String extractValue(InputStream stream, String varName) {
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+ StringTokenizer token;
+ String nextLine;
+ while ((nextLine = reader.readLine()) != null) {
+ token = new StringTokenizer(nextLine, ":");
+ String nextToken = token.nextToken();
+ if (nextToken.trim().equals(varName)) {
+ return token.nextToken().trim();
+ }
+ }
+ return "";
+ } catch (IOException e) {
+ getCurrentOutput().printStackTrace(e);
+ return "";
+ }
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/NoComponentUnderMouseException.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/NoComponentUnderMouseException.java
new file mode 100644
index 00000000000..4bc7b1c0005
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/NoComponentUnderMouseException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+/**
+ *
+ * Exception can be throwht as a result of attempt to produce a mouse pressing
+ * when mouse is not over the java component.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class NoComponentUnderMouseException extends RuntimeException {
+
+ private static final long serialVersionUID = 42L;
+
+ /**
+ * Constructor.
+ */
+ public NoComponentUnderMouseException() {
+ super("No component under the mouse!");
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ObjectBrowser.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ObjectBrowser.java
new file mode 100644
index 00000000000..bf17fe8e361
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/ObjectBrowser.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ *
+ * Class to display information about object: fields, methods, ancestors and so
+ * on.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class ObjectBrowser implements Outputable {
+
+ private Object object;
+
+ private TestOut output;
+
+ /**
+ * Constructor.
+ */
+ public ObjectBrowser() {
+ }
+
+ /**
+ * Defines print output streams or writers.
+ *
+ * @param out Identify the streams or writers used for print output.
+ * @see org.netbeans.jemmy.Outputable
+ * @see org.netbeans.jemmy.TestOut
+ * @see #getOutput
+ */
+ @Override
+ public void setOutput(TestOut out) {
+ output = out;
+ }
+
+ /**
+ * Returns print output streams or writers.
+ *
+ * @return an object that contains references to objects for printing to
+ * output and err streams.
+ * @see org.netbeans.jemmy.Outputable
+ * @see org.netbeans.jemmy.TestOut
+ * @see #setOutput
+ */
+ @Override
+ public TestOut getOutput() {
+ return output;
+ }
+
+ /**
+ * Specifies the object value.
+ *
+ * @param obj Object to work with.
+ * @see #getObject
+ */
+ public void setObject(Object obj) {
+ object = obj;
+ }
+
+ /**
+ * Returns the object value.
+ *
+ * @return Current object.
+ * @see #setObject
+ */
+ public Object getObject() {
+ return object;
+ }
+
+ /**
+ * Prints {@code toString()} information.
+ */
+ public void printToString() {
+ output.printLine(object.toString());
+ }
+
+ /**
+ * Prints object fields names and values.
+ */
+ public void printFields() {
+ Class> cl = object.getClass();
+ output.printLine("Class: " + cl.getName());
+ output.printLine("Fields: ");
+ Field[] fields = cl.getFields();
+ for (Field field : fields) {
+ output.printLine(Modifier.toString(field.getModifiers()) + " "
+ + field.getType().getName() + " "
+ + field.getName());
+ Object value = "Inaccessible";
+ try {
+ value = field.get(object);
+ } catch (IllegalAccessException ignored) {
+ }
+ output.printLine(" Value: " + value.toString());
+ }
+ }
+
+ /**
+ * Prints object methods names and parameters.
+ */
+ public void printMethods() {
+ Class> cl = object.getClass();
+ output.printLine("Class: " + cl.getName());
+ output.printLine("Methods: ");
+ Method[] methods = cl.getMethods();
+ for (Method method : methods) {
+ output.printLine(Modifier.toString(method.getModifiers()) + " "
+ + method.getReturnType().getName() + " "
+ + method.getName());
+ Class>[] params = method.getParameterTypes();
+ for (Class> param : params) {
+ output.printLine(" " + param.getName());
+ }
+ }
+ }
+
+ /**
+ * Prints allsuperclasses names.
+ */
+ public void printClasses() {
+ Class> cl = object.getClass();
+ do {
+ output.printLine(cl.getName());
+ } while ((cl = cl.getSuperclass()) != null);
+ }
+
+ /**
+ * Prints everything.
+ */
+ public void printFull() {
+ printFields();
+ printMethods();
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Outputable.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Outputable.java
new file mode 100644
index 00000000000..832b311921f
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Outputable.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+/**
+ * Communicate the identity of the output streams or writers used by the
+ * application. Communicate the identity of the input stream, too. Any object
+ * with methods that generates print output should implement this interface.
+ *
+ * @see org.netbeans.jemmy.TestOut
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface Outputable {
+
+ /**
+ * Defines print output streams or writers.
+ *
+ * @param out Identify the streams or writers used for print output.
+ * @see #getOutput
+ */
+ public void setOutput(TestOut out);
+
+ /**
+ * Returns print output streams or writers.
+ *
+ * @return an object that contains references to objects for printing to
+ * output and err streams.
+ * @see #setOutput
+ */
+ public TestOut getOutput();
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/QueueTool.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/QueueTool.java
new file mode 100644
index 00000000000..dbb9d58f494
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/QueueTool.java
@@ -0,0 +1,818 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.awt.AWTEvent;
+import java.awt.EventQueue;
+import java.awt.Toolkit;
+import java.awt.event.InvocationEvent;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ *
+ * Provides functionality to work with java.awt.EventQueue empty.
+ *
+ *
Timeouts used:
+ * QueueTool.WaitQueueEmptyTimeout - timeout to wait queue emptied
+ * QueueTool.QueueCheckingDelta - time delta to check result
+ * QueueTool.LockTimeout - time to wait queue locked after lock action has been
+ * put there
+ * QueueTool.InvocationTimeout - time for action was put into queue to be
+ * started
+ * QueueTool.MaximumLockingTime - maximum time to lock queue.
+ *
+ * @see Timeouts
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ *
+ */
+public class QueueTool implements Outputable, Timeoutable {
+
+ private final static long WAIT_QUEUE_EMPTY_TIMEOUT = 180000;
+ private final static long QUEUE_CHECKING_DELTA = 10;
+ private final static long LOCK_TIMEOUT = 180000;
+ private final static long MAXIMUM_LOCKING_TIME = 180000;
+ private final static long INVOCATION_TIMEOUT = 180000;
+
+ private static JemmyQueue jemmyQueue = null;
+
+ private TestOut output;
+ private Timeouts timeouts;
+ private Locker locker;
+ private Waiter lockWaiter;
+
+ /**
+ * Constructor.
+ */
+ public QueueTool() {
+ locker = new Locker();
+ lockWaiter = new Waiter(new Waitable() {
+ @Override
+ public String actionProduced(Void obj) {
+ return locker.isLocked() ? "" : null;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Event queue to be locked";
+ }
+
+ @Override
+ public String toString() {
+ return "QueueTool.Waiter{" + getDescription() + '}';
+ }
+ });
+ setOutput(JemmyProperties.getProperties().getOutput());
+ setTimeouts(JemmyProperties.getProperties().getTimeouts());
+ }
+
+ /**
+ * Returns system EventQueue.
+ *
+ * @return system EventQueue.
+ */
+ public static EventQueue getQueue() {
+ return Toolkit.getDefaultToolkit().getSystemEventQueue();
+ }
+
+ /**
+ * Map to {@code EventQueue.isDispatchThread()}.
+ *
+ * @return true if this thread is the AWT dispatching thread.
+ */
+ public static boolean isDispatchThread() {
+ return EventQueue.isDispatchThread();
+ }
+
+ /**
+ * Checks if system event queue is empty.
+ *
+ * @return true if EventQueue is empty.
+ */
+ public static boolean checkEmpty() {
+ return getQueue().peekEvent() == null;
+ }
+
+ /**
+ * Shortcuts event if
+ * {@code ((JemmyProperties.getCurrentDispatchingModel() & JemmyProperties.SHORTCUT_MODEL_MASK) != 0)}
+ * and if executed in the dispatch thread. Otherwise posts event.
+ *
+ * @param event Event to dispatch.
+ */
+ public static void processEvent(AWTEvent event) {
+ if ((JemmyProperties.getCurrentDispatchingModel()
+ & JemmyProperties.SHORTCUT_MODEL_MASK) != 0) {
+ installQueue();
+ }
+ if ((JemmyProperties.getCurrentDispatchingModel()
+ & JemmyProperties.SHORTCUT_MODEL_MASK) != 0
+ && isDispatchThread()) {
+ shortcutEvent(event);
+ } else {
+ postEvent(event);
+ }
+ }
+
+ /**
+ * Simply posts events into the system event queue.
+ *
+ * @param event Event to dispatch.
+ */
+ public static void postEvent(AWTEvent event) {
+ getQueue().postEvent(event);
+ }
+
+ /**
+ * Dispatches event ahead of all events staying in the event queue.
+ *
+ * @param event an event to be shortcut.
+ */
+ public static void shortcutEvent(AWTEvent event) {
+ installQueue();
+ jemmyQueue.shortcutEvent(event);
+ }
+
+ /**
+ * Installs own Jemmy EventQueue implementation. The method is executed in
+ * dispatchmode only.
+ *
+ * @see #uninstallQueue
+ */
+ public static void installQueue() {
+ if (jemmyQueue == null) {
+ jemmyQueue = new JemmyQueue();
+ }
+ jemmyQueue.install();
+ }
+
+ /**
+ * Uninstalls own Jemmy EventQueue implementation.
+ *
+ * @see #installQueue
+ */
+ public static void uninstallQueue() {
+ if (jemmyQueue != null) {
+ jemmyQueue.uninstall();
+ }
+ }
+
+ static {
+ Timeouts.initDefault("QueueTool.WaitQueueEmptyTimeout", WAIT_QUEUE_EMPTY_TIMEOUT);
+ Timeouts.initDefault("QueueTool.QueueCheckingDelta", QUEUE_CHECKING_DELTA);
+ Timeouts.initDefault("QueueTool.LockTimeout", LOCK_TIMEOUT);
+ Timeouts.initDefault("QueueTool.InvocationTimeout", INVOCATION_TIMEOUT);
+ Timeouts.initDefault("QueueTool.MaximumLockingTime", MAXIMUM_LOCKING_TIME);
+ }
+
+ /**
+ * Defines current timeouts.
+ *
+ * @param ts ?t? A collection of timeout assignments.
+ * @see org.netbeans.jemmy.Timeouts
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see #getTimeouts
+ */
+ @Override
+ public void setTimeouts(Timeouts ts) {
+ timeouts = ts;
+ lockWaiter.setTimeouts(getTimeouts().cloneThis());
+ }
+
+ /**
+ * Return current timeouts.
+ *
+ * @return the collection of current timeout assignments.
+ * @see org.netbeans.jemmy.Timeouts
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see #setTimeouts
+ */
+ @Override
+ public Timeouts getTimeouts() {
+ return timeouts;
+ }
+
+ /**
+ * Defines print output streams or writers.
+ *
+ * @param out Identify the streams or writers used for print output.
+ * @see org.netbeans.jemmy.Outputable
+ * @see org.netbeans.jemmy.TestOut
+ * @see #getOutput
+ */
+ @Override
+ public void setOutput(TestOut out) {
+ output = out;
+ lockWaiter.setOutput(output.createErrorOutput());
+ }
+
+ /**
+ * Returns print output streams or writers.
+ *
+ * @return an object that contains references to objects for printing to
+ * output and err streams.
+ * @see org.netbeans.jemmy.Outputable
+ * @see org.netbeans.jemmy.TestOut
+ * @see #setOutput
+ */
+ @Override
+ public TestOut getOutput() {
+ return output;
+ }
+
+ /**
+ * Waits for system event queue empty. Uses
+ * "QueueTool.WaitQueueEmptyTimeout" milliseconds to wait.
+ *
+ * @throws TimeoutExpiredException
+ */
+ public void waitEmpty() {
+ Waiter waiter = new Waiter<>(new Waitable() {
+ @Override
+ public String actionProduced(Void obj) {
+ if (checkEmpty()) {
+ return "Empty";
+ }
+ return null;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Wait event queue empty";
+ }
+
+ @Override
+ public String toString() {
+ return "waitEmpty.Waiter{" + getDescription() + '}';
+ }
+ });
+ waiter.setTimeoutsToCloneOf(timeouts, "QueueTool.WaitQueueEmptyTimeout");
+ waiter.setOutput(output);
+ try {
+ waiter.waitAction(null);
+ } catch (TimeoutExpiredException e) {
+ final AWTEvent event = getQueue().peekEvent();
+ // if event != null run toString in dispatch thread
+ String eventToString = (event == null) ? "null" : invokeSmoothly(
+ new QueueTool.QueueAction("event.toString()") {
+ @Override
+ public String launch() {
+ return event.toString();
+ }
+ }
+ );
+ getOutput().printErrLine("Event at the top of stack: " + eventToString);
+ throw (e);
+ } catch (InterruptedException e) {
+ output.printStackTrace(e);
+ }
+ }
+
+ /**
+ * Waits for system event queue be empty for {@code emptyTime}
+ * milliseconds. Uses "QueueTool.WaitQueueEmptyTimeout" milliseconds to
+ * wait.
+ *
+ * @param emptyTime time for the queue to stay empty.
+ * @throws TimeoutExpiredException
+ */
+ public void waitEmpty(long emptyTime) {
+
+ StayingEmptyWaiter waiter = new StayingEmptyWaiter(emptyTime);
+ waiter.setTimeoutsToCloneOf(timeouts, "QueueTool.WaitQueueEmptyTimeout");
+ waiter.setOutput(output);
+ try {
+ waiter.waitAction(null);
+ } catch (TimeoutExpiredException e) {
+ final AWTEvent event = getQueue().peekEvent();
+ String eventToString = (event == null) ? "null" : invokeSmoothly(
+ new QueueTool.QueueAction("event.toString()") {
+ @Override
+ public String launch() {
+ return event.toString();
+ }
+ }
+ );
+ getOutput().printErrLine("Event at the top of stack: " + eventToString);
+ throw (e);
+ } catch (InterruptedException e) {
+ output.printStackTrace(e);
+ }
+ }
+
+ /**
+ * Invokes action through EventQueue. Does not wait for it execution.
+ *
+ * @param action an action to be invoked.
+ */
+ public void invoke(QueueAction> action) {
+ output.printTrace("Invoking \"" + action.getDescription() + "\" action through event queue");
+ EventQueue.invokeLater(action);
+ }
+
+ /**
+ * Invokes runnable through EventQueue. Does not wait for it execution.
+ *
+ * @param runnable a runnable to be invoked.
+ * @return QueueAction instance which can be use for execution monitoring.
+ * @see QueueTool.QueueAction
+ */
+ public QueueAction invoke(Runnable runnable) {
+ QueueAction result = new RunnableRunnable(runnable);
+ invoke(result);
+ return result;
+ }
+
+ /**
+ * Invokes action through EventQueue. Does not wait for it execution.
+ *
+ * @param action an action to be invoked.
+ * @param param {@code action.launch(Object)} method parameter.
+ * @return QueueAction instance which can be use for execution monitoring.
+ * @see QueueTool.QueueAction
+ */
+ public QueueAction invoke(Action action, P param) {
+ QueueAction result = new ActionRunnable<>(action, param);
+ invoke(result);
+ return result;
+ }
+
+ /**
+ * Being executed outside of AWT dispatching thread, invokes an action
+ * through the event queue. Otherwise executes {@code action.launch()}
+ * method directly.
+ *
+ * @param action anaction to be executed.
+ * @return Action result.
+ */
+ public R invokeSmoothly(QueueAction action) {
+ if (!EventQueue.isDispatchThread()) {
+ return invokeAndWait(action);
+ } else {
+ try {
+ return action.launch();
+ } catch (Exception e) {
+ throw (new JemmyException("Exception in " + action.getDescription(), e));
+ }
+ }
+ }
+
+ /**
+ * Being executed outside of AWT dispatching thread, invokes a runnable
+ * through the event queue. Otherwise executes {@code runnable.run()}
+ * method directly.
+ *
+ * @param runnable a runnable to be executed.
+ */
+ public void invokeSmoothly(Runnable runnable) {
+ if (!EventQueue.isDispatchThread()) {
+ invokeAndWait(runnable);
+ } else {
+ runnable.run();
+ }
+ }
+
+ /**
+ * Being executed outside of AWT dispatching thread, invokes an action
+ * through the event queue. Otherwise executes
+ * {@code action.launch(Object)} method directly.
+ *
+ * @param action anaction to be executed.
+ * @param param an action parameter
+ * @return Action result.
+ */
+ public R invokeSmoothly(Action action, P param) {
+ if (!EventQueue.isDispatchThread()) {
+ return invokeAndWait(action, param);
+ } else {
+ return action.launch(param);
+ }
+ }
+
+ /**
+ * Invokes action through EventQueue. Waits for it execution.
+ *
+ * @param action an action to be invoked.
+ * @return a result of action
+ * @throws TimeoutExpiredException if action was not executed in
+ * "QueueTool.InvocationTimeout" milliseconds.
+ */
+ public R invokeAndWait(QueueAction action) {
+
+ class JemmyInvocationLock {
+ }
+ Object lock = new JemmyInvocationLock();
+ InvocationEvent event
+ = new JemmyInvocationEvent(Toolkit.getDefaultToolkit(),
+ action,
+ lock,
+ true);
+ try {
+ synchronized (lock) {
+ getQueue().postEvent(event);
+ while (!action.getFinished()) {
+ lock.wait();
+ }
+ }
+ } catch (InterruptedException e) {
+ throw (new JemmyException("InterruptedException during "
+ + action.getDescription()
+ + " execution", e));
+ }
+ if (action.getException() != null) {
+ throw (new JemmyException("Exception in " + action.getDescription(),
+ action.getException()));
+ }
+ if (event.getException() != null) {
+ throw (new JemmyException("Exception in " + action.getDescription(),
+ event.getException()));
+ }
+ return action.getResult();
+ }
+
+ public static final class JemmyInvocationEvent extends InvocationEvent {
+
+ private static final long serialVersionUID = 42L;
+
+ public JemmyInvocationEvent(Object source, Runnable runnable,
+ Object notifier, boolean catchThrowables) {
+ super(source, runnable, notifier, catchThrowables);
+ }
+ }
+
+ /**
+ * Invokes runnable through EventQueue. Waits for it execution.
+ *
+ * @param runnable a runnable to be invoked.
+ * @throws TimeoutExpiredException if runnable was not executed in
+ * "QueueTool.InvocationTimeout" milliseconds.
+ */
+ public void invokeAndWait(Runnable runnable) {
+ invokeAndWait(new RunnableRunnable(runnable));
+ }
+
+ /**
+ * Invokes action through EventQueue. Waits for it execution. May throw
+ * TimeoutExpiredException if action was not executed in
+ * "QueueTool.InvocationTimeout" milliseconds.
+ *
+ * @param action an action to be invoked.
+ * @param param action.launch(Object method parameter.
+ * @return a result of action
+ * @throws TimeoutExpiredException if action was not executed in
+ * "QueueTool.InvocationTimeout" milliseconds.
+ */
+ public R invokeAndWait(Action action, P param) {
+ return invokeAndWait(new ActionRunnable<>(action, param));
+ }
+
+ /**
+ * Locks EventQueue. Locking will be automatically aborted after
+ * "QueueTool.MaximumLockingTime" milliseconds.
+ *
+ * @see #unlock()
+ * @throws TimeoutExpiredException
+ */
+ public void lock() {
+ output.printTrace("Locking queue.");
+ invoke(locker);
+ try {
+ lockWaiter.
+ getTimeouts().
+ setTimeout("Waiter.WaitingTime",
+ timeouts.
+ getTimeout("QueueTool.LockTimeout"));
+ lockWaiter.
+ getTimeouts().
+ setTimeout("Waiter.TimeDelta",
+ timeouts.
+ getTimeout("QueueTool.QueueCheckingDelta"));
+ lockWaiter.waitAction(null);
+ } catch (InterruptedException e) {
+ output.printStackTrace(e);
+ }
+ }
+
+ /**
+ * Unlocks EventQueue.
+ *
+ * @see #lock()
+ */
+ public void unlock() {
+ output.printTrace("Unlocking queue.");
+ locker.setLocked(false);
+ }
+
+ /**
+ * Locks event queue for "time" milliseconds. Returns immediately after
+ * locking.
+ *
+ * @param time a time to lock the queue for.
+ */
+ public void lock(long time) {
+ output.printTrace("Locking queue for " + Long.toString(time) + " milliseconds");
+ lock();
+ invoke(new UnlockPostponer(time));
+ }
+
+ /**
+ * Sais if last locking was expired.
+ *
+ * @return true if last locking had beed expired.
+ */
+ public boolean wasLockingExpired() {
+ return locker.expired;
+ }
+
+ /**
+ * Action to be executed through event queue. Even if it was executed without
+ * waiting by {@code invoke(QueueAction)} execution process can be
+ * monitored by {@code getResult()}, {@code getException()},
+ * {@code getFinished()} methods.
+ */
+ public static abstract class QueueAction implements Runnable {
+
+ private volatile boolean finished;
+ private Exception exception;
+ private R result;
+ private String description;
+
+ /**
+ * Constructor.
+ *
+ * @param description a description.
+ */
+ public QueueAction(String description) {
+ this.description = description;
+ finished = false;
+ exception = null;
+ result = null;
+ }
+
+ /**
+ * Method to implement action functionality.
+ *
+ * @return an Object - action result
+ * @throws Exception
+ */
+ public abstract R launch()
+ throws Exception;
+
+ /**
+ */
+ @Override
+ public final void run() {
+ finished = false;
+ exception = null;
+ result = null;
+ try {
+ result = launch();
+ } catch (Exception e) {
+ exception = e;
+ } finally {
+ finished = true;
+ }
+ }
+
+ /**
+ * Action description.
+ *
+ * @return the description.
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Returns action result if action has already been finished, null
+ * otherwise.
+ *
+ * @return an action result.
+ */
+ public R getResult() {
+ return result;
+ }
+
+ /**
+ * Returns exception occured during action execution (if any).
+ *
+ * @return the Exception happened inside {@code launch()} method.
+ */
+ public Exception getException() {
+ return exception;
+ }
+
+ /**
+ * Informs whether action has been finished or not.
+ *
+ * @return true if this action have been finished
+ */
+ public boolean getFinished() {
+ return finished;
+ }
+
+ @Override
+ public String toString() {
+ return "QueueAction{description=" + description + ", result=" + result + ", finished=" + finished + ", exception=" + exception + '}';
+ }
+ }
+
+ private static class JemmyQueue extends EventQueue {
+
+ private boolean installed = false;
+
+ public void shortcutEvent(AWTEvent event) {
+ super.dispatchEvent(event);
+ }
+
+ @Override
+ protected void dispatchEvent(AWTEvent event) {
+ //it's necessary to catch exception here.
+ //because test might already fail by timeout
+ //but generated events are still in stack
+ try {
+ super.dispatchEvent(event);
+ } catch (Exception e) {
+ //the exceptions should be printed into
+ //Jemmy output - not System.out
+ JemmyProperties.getCurrentOutput().printStackTrace(e);
+ }
+ }
+
+ public synchronized void install() {
+ if (!installed) {
+ getQueue().push(this);
+ installed = true;
+ }
+ }
+
+ public synchronized void uninstall() {
+ if (installed) {
+ pop();
+ installed = false;
+ }
+ }
+ }
+
+ private class EventWaiter implements Runnable {
+
+ boolean empty = true;
+ long emptyTime;
+
+ public EventWaiter(long emptyTime) {
+ this.emptyTime = emptyTime;
+ }
+
+ @Override
+ public void run() {
+ long startTime = System.currentTimeMillis();
+ while ((empty = checkEmpty())
+ && (System.currentTimeMillis() - startTime) < emptyTime) {
+ timeouts.sleep("QueueTool.QueueCheckingDelta");
+ }
+ }
+ }
+
+ private class StayingEmptyWaiter extends Waiter {
+
+ long emptyTime;
+
+ public StayingEmptyWaiter(long emptyTime) {
+ this.emptyTime = emptyTime;
+ }
+
+ @Override
+ public String actionProduced(Void obj) {
+ try {
+ EventWaiter eventWaiter = new EventWaiter(emptyTime);
+ EventQueue.invokeAndWait(eventWaiter);
+ if (eventWaiter.empty
+ && timeFromStart() <= super.getTimeouts().getTimeout("Waiter.WaitingTime")) {
+ return "Reached";
+ }
+ } catch (InterruptedException | InvocationTargetException e) {
+ output.printStackTrace(e);
+ }
+ return null;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Wait event queue staying empty for " + emptyTime;
+ }
+
+ @Override
+ public String toString() {
+ return "StayingEmptyWaiter{" + "emptyTime=" + emptyTime + '}';
+ }
+ }
+
+ private class ActionRunnable extends QueueAction {
+
+ Action action;
+ P param;
+
+ public ActionRunnable(Action action, P param) {
+ super(action.getDescription());
+ this.action = action;
+ this.param = param;
+ }
+
+ @Override
+ public R launch() throws Exception {
+ return action.launch(param);
+ }
+ }
+
+ private class RunnableRunnable extends QueueAction {
+
+ Runnable action;
+
+ public RunnableRunnable(Runnable action) {
+ super("Runnable");
+ this.action = action;
+ }
+
+ @Override
+ public Void launch() throws Exception {
+ action.run();
+ return null;
+ }
+ }
+
+ private class Locker extends QueueAction {
+
+ volatile boolean locked = false;
+ long wholeTime, deltaTime;
+ boolean expired;
+
+ public Locker() {
+ super("Event queue locking");
+ }
+
+ @Override
+ public Void launch() {
+ wholeTime = timeouts.getTimeout("QueueTool.MaximumLockingTime");
+ deltaTime = timeouts.getTimeout("QueueTool.QueueCheckingDelta");
+ setLocked(true);
+ expired = false;
+ long startTime = System.currentTimeMillis();
+ while (isLocked()) {
+ try {
+ Thread.sleep(deltaTime);
+ } catch (InterruptedException e) {
+ getOutput().printStackTrace(e);
+ }
+ if (System.currentTimeMillis() - startTime > wholeTime) {
+ getOutput().printLine("Locking has been expired!");
+ expired = true;
+ break;
+ }
+ }
+ return null;
+ }
+
+ public void setLocked(boolean locked) {
+ this.locked = locked;
+ }
+
+ public boolean isLocked() {
+ return locked;
+ }
+ }
+
+ private class UnlockPostponer implements Runnable {
+
+ long time;
+
+ public UnlockPostponer(long time) {
+ this.time = time;
+ }
+
+ @Override
+ public void run() {
+ new Timeout("", time).sleep();
+ unlock();
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Scenario.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Scenario.java
new file mode 100644
index 00000000000..216bd1c30c0
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Scenario.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+/**
+ *
+ * A test scenario. This interface provides a mechanism for putting something
+ * into execution. The execution is conditioned in a very general way by passing
+ * a {@code java.lang.Object} to it's {@code runIt} method.
+ *
+ * @see Test
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface Scenario {
+
+ /**
+ * Defines a way to execute this test scenario.
+ *
+ * @param param An object passed to configure the test scenario execution.
+ * For example, this parameter might be a java.lang.String[] object that lists the
+ * command line arguments to the Java application corresponding
+ * to a test.
+ * @return an int that tells something about the execution. For, example, a
+ * status code.
+ */
+ public int runIt(Object param);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Test.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Test.java
new file mode 100644
index 00000000000..1cfa549ec0c
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Test.java
@@ -0,0 +1,441 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ *
+ * Jemmy itself provides a way to create tests. Test should implement
+ * org.netbeans.jemmy.Scenario interface.
+ *
+ * Test can be executed from command line:
+ * {@code java [application options] [jemmy options] org.netbeans.jemmy.Test [full name of test class] [test args]}
+ * Test elso can be executed by one of the run(...) methods or by
+ * {@code new Test([test class name]).startTest([test args]);}
+ *
+ *
Timeouts used:
+ * Test.WholeTestTimeout - time for the whole test
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class Test extends ActionProducer
+ implements Timeoutable, Outputable, Scenario {
+
+ private final static long WHOLE_TEST_TIMEOUT = 3600000;
+
+ /**
+ * Status returned by test if wrong parameter was passed.
+ */
+ public static int WRONG_PARAMETERS_STATUS = 101;
+
+ /**
+ * Status returned by test if exception appeared inside scenario.
+ */
+ public static int SCENARIO_EXCEPTION_STATUS = 102;
+
+ /**
+ * Positive test status.
+ */
+ public static int TEST_PASSED_STATUS = 0;
+
+ /**
+ * Test timeouts.
+ */
+ protected Timeouts timeouts;
+
+ /**
+ * Test output.
+ */
+ protected TestOut output;
+
+ private Scenario scenario;
+
+ /**
+ * Constructor for tests requiring only a class instance. Creates a subclass
+ * of {@code ActionProducer} and {@code java.lang.Thread} that
+ * runs in a separate thread of execution and waits for execution to finish.
+ * The current output stream assignments and timeouts are used.
+ *
+ * @param testClassName Full test class name
+ */
+ public Test(String testClassName) {
+ super(true);
+ setOutput(JemmyProperties.getCurrentOutput());
+ setTimeouts(JemmyProperties.getCurrentTimeouts());
+ scenario = testForName(testClassName);
+ }
+
+ /**
+ * Constructor for scenarios that require an instance and might require an
+ * argument. Creates a subclass of {@code ActionProducer} and
+ * {@code java.lang.Thread} that runs in a separate thread of execution
+ * and waits for execution to finish. The current output stream assignments
+ * and timeouts are used.
+ *
+ * @param scenario a test scenario
+ * @see org.netbeans.jemmy.Scenario
+ */
+ public Test(Scenario scenario) {
+ super(true);
+ setOutput(JemmyProperties.getCurrentOutput());
+ setTimeouts(JemmyProperties.getCurrentTimeouts());
+ this.scenario = scenario;
+ }
+
+ /**
+ * No argument constructor. Used by subclasses of this {@code Test}
+ * class. Creates a subclass of {@code ActionProducer} and
+ * {@code java.lang.Thread} that runs in a separate thread of execution
+ * and waits for execution to finish. The current output stream assignments
+ * and timeouts are used.
+ */
+ protected Test() {
+ super(true);
+ setOutput(JemmyProperties.getCurrentOutput());
+ setTimeouts(JemmyProperties.getCurrentTimeouts());
+ }
+
+ /**
+ * Throws TestCompletedException exception. The exception thrown contains a
+ * pass/fail status and a short status {@code java.lang.String}. Can by
+ * invoked from test to abort test execution.
+ *
+ * @param status If 0 - test passed, otherwise failed.
+ * @throws TestCompletedException all of the time.
+ */
+ public static void closeDown(int status) {
+ if (status == 0) {
+ throw (new TestCompletedException(status, "Test passed"));
+ } else {
+ throw (new TestCompletedException(status, "Test failed with status "
+ + Integer.toString(status)));
+ }
+ }
+
+ /**
+ * Executes a test.
+ *
+ * @param argv First element should be a test class name, all others - test
+ * args.
+ * @return test status.
+ */
+ public static int run(String[] argv) {
+ String[] args = argv;
+ JemmyProperties.getProperties().init();
+ if (argv.length < 1) {
+ JemmyProperties.getCurrentOutput().
+ printErrLine("First element of String array should be test classname");
+ return WRONG_PARAMETERS_STATUS;
+ }
+ JemmyProperties.getCurrentOutput().printLine("Executed test " + argv[0]);
+ Test test = new Test(argv[0]);
+ if (argv.length >= 1) {
+ args = shiftArray(args);
+ }
+ if (argv.length >= 2) {
+ JemmyProperties.getCurrentOutput().printLine("Work directory: " + argv[1]);
+ System.setProperty("user.dir", argv[1]);
+ args = shiftArray(args);
+ }
+ int status;
+ status = test.startTest(args);
+ JemmyProperties.getCurrentOutput().flush();
+ return status;
+ }
+
+ /**
+ * Executes a test.
+ *
+ * @param argv First element should be a test class name, all others - test
+ * args.
+ * @param output Stream to put test output and errput into.
+ * @return test status.
+ */
+ public static int run(String[] argv, PrintStream output) {
+ JemmyProperties.setCurrentOutput(new TestOut(System.in, output, output));
+ return run(argv);
+ }
+
+ /**
+ * Executes a test.
+ *
+ * @param argv First element should be a test class name, all others - test
+ * args.
+ * @param output Stream to put test output into.
+ * @param errput Stream to put test errput into.
+ * @return test status.
+ */
+ public static int run(String[] argv, PrintStream output, PrintStream errput) {
+ JemmyProperties.setCurrentOutput(new TestOut(System.in, output, errput));
+ return run(argv);
+ }
+
+ /**
+ * Executes a test.
+ *
+ * @param argv First element should be a test class name, all others - test
+ * args.
+ * @param output Writer to put test output and errput into.
+ * @return test status.
+ */
+ public static int run(String[] argv, PrintWriter output) {
+ JemmyProperties.setCurrentOutput(new TestOut(System.in, output, output));
+ return run(argv);
+ }
+
+ /**
+ * Executes a test.
+ *
+ * @param argv First element should be a test class name, all others - test
+ * args.
+ * @param output Writer to put test output into.
+ * @param errput Writer to put test errput into.
+ * @return test status.
+ */
+ public static int run(String[] argv, PrintWriter output, PrintWriter errput) {
+ JemmyProperties.setCurrentOutput(new TestOut(System.in, output, errput));
+ return run(argv);
+ }
+
+ /**
+ * Invoke this {@code Test}. The call might be directly from the
+ * command line.
+ *
+ * @param argv First element should be a test class name, all others - test
+ * args.
+ */
+ public static void main(String[] argv) {
+ System.exit(run(argv, System.out));
+ }
+
+ static {
+ Timeouts.initDefault("Test.WholeTestTimeout", WHOLE_TEST_TIMEOUT);
+ }
+
+ /**
+ * Creates an instance of a class named by the parameter.
+ *
+ * @param testName Full test class name
+ * @return an instance of the test {@code Scenario} to launch.
+ * @see org.netbeans.jemmy.Scenario
+ */
+ public Scenario testForName(String testName) {
+ try {
+ return ((Scenario) (Class.forName(testName).
+ getConstructor(new Class>[0]).
+ newInstance()));
+ } catch (ClassNotFoundException e) {
+ output.printErrLine("Class " + testName + " does not exist!");
+ output.printStackTrace(e);
+ } catch (NoSuchMethodException e) {
+ output.printErrLine("Class " + testName + " has not constructor!");
+ output.printStackTrace(e);
+ } catch (InvocationTargetException e) {
+ output.printErrLine("Exception inside " + testName + " constructor:");
+ output.printStackTrace(e.getTargetException());
+ } catch (IllegalAccessException e) {
+ output.printErrLine("Cannot access to " + testName + " constructor!");
+ output.printStackTrace(e);
+ } catch (InstantiationException e) {
+ output.printErrLine("Cannot instantiate " + testName + " class!");
+ output.printStackTrace(e);
+ }
+ return null;
+ }
+
+ /**
+ * Set the timeouts used by this {@code Test}.
+ *
+ * @param timeouts A collection of timeout assignments.
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see org.netbeans.jemmy.Timeouts
+ * @see #getTimeouts
+ */
+ @Override
+ public void setTimeouts(Timeouts timeouts) {
+ this.timeouts = timeouts;
+ Timeouts times = timeouts.cloneThis();
+ times.setTimeout("ActionProducer.MaxActionTime",
+ timeouts.getTimeout("Test.WholeTestTimeout"));
+ super.setTimeouts(times);
+ }
+
+ /**
+ * Get the timeouts used by this {@code Test}.
+ *
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see org.netbeans.jemmy.Timeouts
+ * @see #setTimeouts
+ */
+ @Override
+ public Timeouts getTimeouts() {
+ return timeouts;
+ }
+
+ /**
+ * Set the streams or writers used for print output.
+ *
+ * @param out An object used to identify both output and error print
+ * streams.
+ * @see org.netbeans.jemmy.Outputable
+ * @see org.netbeans.jemmy.TestOut
+ * @see #getOutput
+ */
+ @Override
+ public void setOutput(TestOut out) {
+ output = out;
+ super.setOutput(out);
+ }
+
+ /**
+ * Get the streams or writers used for print output.
+ *
+ * @return an object containing references to both output and error print
+ * streams.
+ * @see org.netbeans.jemmy.Outputable
+ * @see org.netbeans.jemmy.TestOut
+ * @see #setOutput
+ */
+ @Override
+ public TestOut getOutput() {
+ return output;
+ }
+
+ /**
+ * Executes test.
+ *
+ * @param param Object to be passed into this test's launch(Object) method.
+ * @return test status.
+ */
+ public int startTest(Object param) {
+ if (scenario != null) {
+ output.printLine("Test " + scenario.getClass().getName()
+ + " has been started");
+ } else {
+ output.printLine("Test " + getClass().getName()
+ + " has been started");
+ }
+ try {
+ return ((Integer) produceAction(param, "Test.WholeTestTimeout")).intValue();
+ } catch (InterruptedException e) {
+ output.printErrLine("Test was interrupted.");
+ output.printStackTrace(e);
+ } catch (TimeoutExpiredException e) {
+ output.printErrLine("Test was not finished in "
+ + Long.toString(timeouts.getTimeout("Test.WholeTestTimeout"))
+ + " milliseconds");
+ output.printStackTrace(e);
+ } catch (Exception e) {
+ output.printStackTrace(e);
+ }
+ return 1;
+ }
+
+ /**
+ * Launch an action. Pass arguments to and execute a test
+ * {@code Scenario}.
+ *
+ * @param obj An argument object that controls test execution. This might be
+ * a {@code java.lang.String[]} containing command line arguments.
+ * @see org.netbeans.jemmy.Action
+ * @return an Integer containing test status.
+ */
+ @Override
+ public final Object launch(Object obj) {
+ setTimeouts(timeouts);
+ try {
+ if (scenario != null) {
+ closeDown(scenario.runIt(obj));
+ } else {
+ closeDown(runIt(obj));
+ }
+ } catch (TestCompletedException e) {
+ output.printStackTrace(e);
+ return e.getStatus();
+ } catch (Throwable e) {
+ output.printStackTrace(e);
+ return SCENARIO_EXCEPTION_STATUS;
+ }
+ return TEST_PASSED_STATUS;
+ }
+
+ /**
+ * Supposed to be overridden to print a synopsys into test output.
+ */
+ public void printSynopsis() {
+ output.printLine("Here should be a test synopsis.");
+ }
+
+ /**
+ * @see org.netbeans.jemmy.Action
+ */
+ @Override
+ public final String getDescription() {
+ return "Test " + scenario.getClass().getName() + " finished";
+ }
+
+ @Override
+ public String toString() {
+ return "Test{" + "scenario=" + scenario + '}';
+ }
+
+ /**
+ * Defines a way to execute this {@code Test}.
+ *
+ * @param param An object passed to configure the test scenario execution.
+ * For example, this parameter might be a java.lang.String[] object that lists the
+ * command line arguments to the Java application corresponding
+ * to a test.
+ * @return an int that tells something about the execution. For, example, a
+ * status code.
+ * @see org.netbeans.jemmy.Scenario
+ */
+ @Override
+ public int runIt(Object param) {
+ return 0;
+ }
+
+ /**
+ * Sleeps.
+ *
+ * @param time The sleep time in milliseconds.
+ */
+ protected void doSleep(long time) {
+ try {
+ Thread.sleep(time);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ private static String[] shiftArray(String[] orig) {
+ String[] result = new String[orig.length - 1];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = orig[i + 1];
+ }
+ return result;
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/TestCompletedException.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/TestCompletedException.java
new file mode 100644
index 00000000000..7cff80dd669
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/TestCompletedException.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+/**
+ *
+ * Exception is throught as a result of test. either test failed or passed.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class TestCompletedException extends JemmyException {
+
+ private static final long serialVersionUID = 42L;
+
+ private int status;
+
+ /**
+ * Constructor.
+ *
+ * @param st Exit status.
+ * @param ex Exception provoked test failure.
+ */
+ public TestCompletedException(int st, Exception ex) {
+ super("Test "
+ + ((st == 0)
+ ? "passed"
+ : "failed with status " + Integer.toString(st)),
+ ex);
+ status = st;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param st Exit status.
+ * @param description Failure reason
+ */
+ public TestCompletedException(int st, String description) {
+ super("Test "
+ + ((st == 0)
+ ? "passed"
+ : "failed with status " + Integer.toString(st)
+ + "\n" + description));
+ status = st;
+ }
+
+ /**
+ * Returns status.
+ *
+ * @return test status
+ */
+ public int getStatus() {
+ return status;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/TestOut.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/TestOut.java
new file mode 100644
index 00000000000..c3552c045e9
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/TestOut.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ *
+ * Test output.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class TestOut {
+
+ private InputStream input;
+ private PrintWriter output;
+ private PrintWriter errput;
+ private PrintWriter golden_output;
+ private BufferedReader buffInput;
+ private boolean autoFlushMode = true;
+
+ /**
+ * Constructor.
+ *
+ * @param in Input stream
+ * @param out Output stream
+ * @param err Errput stream
+ */
+ public TestOut(InputStream in, PrintStream out, PrintStream err) {
+ this(in, out, err, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param in Input stream
+ * @param out Output stream
+ * @param err Errput stream
+ * @param golden Golgen output stream
+ */
+ public TestOut(InputStream in, PrintStream out, PrintStream err, PrintStream golden) {
+ super();
+ PrintWriter tout = null;
+ if (out != null) {
+ tout = new PrintWriter(out);
+ }
+ PrintWriter terr = null;
+ if (err != null) {
+ terr = new PrintWriter(err);
+ }
+ PrintWriter tgolden = null;
+ if (golden != null) {
+ tgolden = new PrintWriter(golden);
+ }
+ initStreams(in, tout, terr, tgolden);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param in Input stream
+ * @param out Output stream
+ * @param err Errput stream
+ */
+ public TestOut(InputStream in, PrintWriter out, PrintWriter err) {
+ this(in, out, err, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param in Input stream
+ * @param out Output stream
+ * @param err Errput stream
+ * @param golden Golgen output stream
+ */
+ public TestOut(InputStream in, PrintWriter out, PrintWriter err, PrintWriter golden) {
+ super();
+ initStreams(in, out, err, golden);
+ autoFlushMode = true;
+ }
+
+ /**
+ * Creates unstance using System.in, System.out and System.err streams.
+ */
+ public TestOut() {
+ this(System.in,
+ new PrintWriter(System.out),
+ new PrintWriter(System.err),
+ null);
+ }
+
+ /**
+ * Creates output which does not print any message anywhere.
+ *
+ * @return a TestOut object which does not print any message anywhere.
+ */
+ public static TestOut getNullOutput() {
+ return new TestOut((InputStream) null, (PrintWriter) null, (PrintWriter) null);
+ }
+
+ /**
+ * Specifies either flush is invoked after each output.
+ *
+ * @param autoFlushMode If true flush is invoking after each output.
+ * @return Old value of the auto flush mode.
+ * @see #getAutoFlushMode
+ */
+ public boolean setAutoFlushMode(boolean autoFlushMode) {
+ boolean oldValue = getAutoFlushMode();
+ this.autoFlushMode = autoFlushMode;
+ return oldValue;
+ }
+
+ /**
+ * Says if flush is invoked after each output.
+ *
+ * @return Value of the auto flush mode.
+ * @see #setAutoFlushMode
+ */
+ public boolean getAutoFlushMode() {
+ return autoFlushMode;
+ }
+
+ /**
+ * Read one byte from input.
+ *
+ * @return an int from input stream.
+ * @exception IOException
+ */
+ public int read() throws IOException {
+ if (input != null) {
+ return input.read();
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * Read a line from input.
+ *
+ * @return a line from input stream.
+ * @exception IOException
+ */
+ public String readLine() throws IOException {
+ if (buffInput != null) {
+ return buffInput.readLine();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Prints a line into output.
+ *
+ * @param line a string to print into output stream.
+ */
+ public void print(String line) {
+ if (output != null) {
+ output.print(line);
+ }
+ }
+
+ /**
+ * Prints a line and then terminate the line by writing the line separator
+ * string.
+ *
+ * @param line a string to print into output stream.
+ */
+ public void printLine(String line) {
+ if (output != null) {
+ output.println(line);
+ if (autoFlushMode) {
+ output.flush();
+ }
+ }
+ }
+
+ /**
+ * Prints a line into golden output.
+ *
+ * @param line a string to print into golden output stream.
+ */
+ public void printGolden(String line) {
+ if (golden_output != null) {
+ golden_output.println(line);
+ if (autoFlushMode) {
+ golden_output.flush();
+ }
+ }
+ }
+
+ /**
+ * Prints a line into error output.
+ *
+ * @param line a string to print into error output stream.
+ */
+ public void printErrLine(String line) {
+ if (errput != null) {
+ errput.println(line);
+ if (autoFlushMode) {
+ errput.flush();
+ }
+ }
+ }
+
+ /**
+ * Prints a line into either output or errput.
+ *
+ * @param toOut If true prints a line into output.
+ * @param line a string to print.
+ */
+ public void printLine(boolean toOut, String line) {
+ if (toOut) {
+ printLine(line);
+ } else {
+ printErrLine(line);
+ }
+ }
+
+ /**
+ * Prints a trace line.
+ *
+ * @param text a trace text.
+ */
+ public void printTrace(String text) {
+ printLine("Trace:");
+ printLine(text);
+ }
+
+ /**
+ * Prints a error line.
+ *
+ * @param text a error text.
+ */
+ public void printError(String text) {
+ printErrLine("Error:");
+ printErrLine(text);
+ }
+
+ /**
+ * Prints an exception stack trace into error stream.
+ *
+ * @param e exception
+ */
+ public void printStackTrace(Throwable e) {
+ if (errput != null) {
+ e.printStackTrace(errput);
+ if (autoFlushMode) {
+ errput.flush();
+ }
+ }
+ }
+
+ /**
+ * Returns input stream.
+ *
+ * @return an input stream
+ */
+ public InputStream getInput() {
+ return input;
+ }
+
+ /**
+ * Returns output writer.
+ *
+ * @return an output stream
+ */
+ public PrintWriter getOutput() {
+ return output;
+ }
+
+ /**
+ * Returns errput writer.
+ *
+ * @return a error stream
+ */
+ public PrintWriter getErrput() {
+ return errput;
+ }
+
+ /**
+ * Returns golden output writer.
+ *
+ * @return a golden output stream
+ */
+ public PrintWriter getGolden() {
+ return golden_output;
+ }
+
+ /**
+ * Creates an output which prints only error messages.
+ *
+ * @return a TestOut instance which has only error stream.
+ */
+ public TestOut createErrorOutput() {
+ return new TestOut(null, null, getErrput());
+ }
+
+ /**
+ * Flushes all output threads.
+ */
+ public void flush() {
+ if (output != null) {
+ output.flush();
+ }
+ if (errput != null) {
+ errput.flush();
+ }
+ if (golden_output != null) {
+ golden_output.flush();
+ }
+ }
+
+ private void initStreams(InputStream in, PrintWriter out, PrintWriter err, PrintWriter golden) {
+ input = in;
+ output = out;
+ errput = err;
+ golden_output = golden;
+ if (input != null) {
+ buffInput = new BufferedReader(new InputStreamReader(in));
+ } else {
+ buffInput = null;
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Timeout.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Timeout.java
new file mode 100644
index 00000000000..ca47fde5916
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Timeout.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+/**
+ * Represents one timeout.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class Timeout extends Object {
+
+ private String name;
+ private long value;
+ private long startTime;
+
+ /**
+ * Constructor.
+ *
+ * @param name Timeout name.
+ * @param value Timeout value in milliseconds.
+ */
+ public Timeout(String name, long value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ /**
+ * Returns timeout name.
+ *
+ * @return timeout name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns timeout value.
+ *
+ * @return timeout value.
+ */
+ public long getValue() {
+ return value;
+ }
+
+ /**
+ * Sleeps for timeout value.
+ */
+ public void sleep() {
+ if (getValue() > 0) {
+ try {
+ Thread.sleep(getValue());
+ } catch (InterruptedException e) {
+ throw (new JemmyException("Sleep "
+ + getName()
+ + " was interrupted!",
+ e));
+ }
+ }
+ }
+
+ /**
+ * Starts timeout measuring.
+ */
+ public void start() {
+ startTime = System.currentTimeMillis();
+ }
+
+ /**
+ * Checks if timeout has been expired after start() invocation.
+ *
+ * @return true if timeout has been expired.
+ */
+ public boolean expired() {
+ return System.currentTimeMillis() - startTime > getValue();
+ }
+
+ /**
+ * Throws a TimeoutExpiredException exception if timeout has been expired.
+ *
+ * @throws TimeoutExpiredException if timeout has been expired after start()
+ * invocation.
+ */
+ public void check() {
+ if (expired()) {
+ throw (new TimeoutExpiredException(getName()
+ + " timeout expired!"));
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/TimeoutExpiredException.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/TimeoutExpiredException.java
new file mode 100644
index 00000000000..90c6fca4f84
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/TimeoutExpiredException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+/**
+ *
+ * Exception is supposed to be used to notice that some waiting was expired.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class TimeoutExpiredException extends JemmyException {
+
+ private static final long serialVersionUID = 42L;
+
+ /**
+ * Constructor.
+ *
+ * @param description Waiting description.
+ */
+ public TimeoutExpiredException(String description) {
+ super(description);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Timeoutable.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Timeoutable.java
new file mode 100644
index 00000000000..a1c428cb443
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Timeoutable.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+/**
+ *
+ * Any class which contains methods requiring waiting or sleeping should
+ * implement this interface. Waiting and sleeping operations have time limits
+ * that can be set or returned using the methods of this interface.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface Timeoutable {
+
+ /**
+ * Defines current timeouts.
+ *
+ * @param t A collection of timeout assignments.
+ * @see #getTimeouts
+ */
+ public void setTimeouts(Timeouts t);
+
+ /**
+ * Return current timeouts.
+ *
+ * @return the collection of current timeout assignments.
+ * @see #setTimeouts
+ */
+ public Timeouts getTimeouts();
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Timeouts.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Timeouts.java
new file mode 100644
index 00000000000..652f31ea3a9
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Timeouts.java
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+
+/**
+ *
+ * Class to store and process a set of timeout values.
+ *
+ * @see #setDefault(String, long)
+ * @see #getDefault(String)
+ * @see #setTimeout(String, long)
+ * @see #getTimeout(String)
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class Timeouts {
+
+ private static final long DELTA_TIME = 100;
+
+ private static Timeouts defaults;
+
+ private Hashtable timeouts;
+ private static double timeoutsScale = -1;
+
+ /**
+ * Creates empty Timeouts object.
+ */
+ public Timeouts() {
+ super();
+ timeouts = new Hashtable<>();
+ setTimeout("Timeouts.DeltaTimeout", DELTA_TIME);
+ try {
+ load();
+ } catch (IOException ignored) {
+ }
+ }
+
+ /**
+ * Stores default timeout value.
+ *
+ * @param name Timeout name.
+ * @param newValue Timeout value.
+ * @see #getDefault(String)
+ * @see #initDefault(String, long)
+ * @see #containsDefault(String)
+ */
+ public static void setDefault(String name, long newValue) {
+ defaults.setTimeout(name, newValue);
+ }
+
+ /**
+ * Sets default timeout value if it was not set before.
+ *
+ * @param name Timeout name.
+ * @param newValue Timeout value.
+ * @see #setDefault(String, long)
+ * @see #getDefault(String)
+ * @see #containsDefault(String)
+ */
+ public static void initDefault(String name, long newValue) {
+ defaults.initTimeout(name, newValue);
+ }
+
+ /**
+ * Gets default timeout value.
+ *
+ * @param name Timeout name.
+ * @return Timeout value or -1 if timeout is not defined.
+ * @see #setDefault(String, long)
+ * @see #initDefault(String, long)
+ * @see #containsDefault(String)
+ */
+ public static long getDefault(String name) {
+ return defaults.getTimeout(name);
+ }
+
+ /**
+ * Check that default timeout value was defined.
+ *
+ * @param name Timeout name.
+ * @return True if timeout has been defined, false otherwise.
+ * @see #setDefault(String, long)
+ * @see #getDefault(String)
+ * @see #initDefault(String, long)
+ */
+ public static boolean containsDefault(String name) {
+ return defaults.contains(name);
+ }
+
+ static {
+ defaults = new Timeouts();
+ }
+
+ /**
+ * Loads default timeouts values.
+ *
+ * @param stream Stream to load timeouts from.
+ * @see org.netbeans.jemmy.Timeouts#loadDefaults(String)
+ * @see org.netbeans.jemmy.Timeouts#loadDefaults()
+ * @exception IOException
+ */
+ public void loadDefaults(InputStream stream)
+ throws IOException {
+ defaults.load(stream);
+ }
+
+ /**
+ * Loads default timeouts values from file.
+ *
+ * @param fileName File to load timeouts from.
+ * @see org.netbeans.jemmy.Timeouts#loadDefaults(InputStream)
+ * @see org.netbeans.jemmy.Timeouts#loadDefaults(String)
+ * @exception IOException
+ * @exception FileNotFoundException
+ */
+ public void loadDefaults(String fileName)
+ throws FileNotFoundException, IOException {
+ defaults.load(fileName);
+ }
+
+ /**
+ * Loads default timeouts values. Uses jemmy.timeouts system property to get
+ * timeouts file.
+ *
+ * @see org.netbeans.jemmy.Timeouts#loadDefaults(InputStream)
+ * @see org.netbeans.jemmy.Timeouts#loadDefaults(String)
+ * @exception IOException
+ * @exception FileNotFoundException
+ */
+ public void loadDefaults()
+ throws FileNotFoundException, IOException {
+ defaults.load();
+ }
+
+ /**
+ * Creates Timeout new object by name and getTimeout(name) value.
+ *
+ * @param name Timeout name.
+ * @return a Timeout instance.
+ */
+ public Timeout create(String name) {
+ return new Timeout(name, getTimeout(name));
+ }
+
+ /**
+ * Create timeout for "Timeouts.DeltaTimeout" name.
+ *
+ * @return a Timeout instance.
+ */
+ public Timeout createDelta() {
+ return create("Timeouts.DeltaTimeout");
+ }
+
+ /**
+ * Checks if timeout has already been defined in this timeout instance.
+ *
+ * @param name Timeout name.
+ * @return True if timeout has been defined, false otherwise.
+ * @see #containsDefault(String)
+ */
+ public boolean contains(String name) {
+ return timeouts.containsKey(name);
+ }
+
+ /**
+ * Sets new timeout value.
+ *
+ * @param name Timeout name.
+ * @param newValue Timeout value.
+ * @return old timeout value
+ * @see #getTimeout
+ */
+ public long setTimeout(String name, long newValue) {
+ long oldValue = -1;
+ if (contains(name)) {
+ oldValue = getTimeout(name);
+ timeouts.remove(name);
+ }
+ timeouts.put(name, newValue);
+ return oldValue;
+ }
+
+ /**
+ * Gets timeout value. It timeout was not defined in this instance, returns
+ * default timeout value.
+ *
+ * @param name Timeout name.
+ * @return Timeout value.
+ * @see #getDefault(String)
+ * @see #setTimeout
+ */
+ public long getTimeout(String name) {
+ long timeout;
+ if (contains(name) && timeouts.get(name) != null) {
+ timeout = timeouts.get(name);
+ timeout = (long) ((double) timeout * getTimeoutsScale());
+ } else if (this != defaults) {
+ timeout = getDefault(name);
+ } else {
+ timeout = -1;
+ }
+ return timeout;
+ }
+
+ /**
+ * Gets "Timeouts.DeltaTimeout" timeout value.
+ *
+ * @return Timeout value.
+ * @see #getDefault(String)
+ */
+ public long getDeltaTimeout() {
+ return getTimeout("Timeouts.DeltaTimeout");
+ }
+
+ /**
+ * Sets timeout value if it was not set before.
+ *
+ * @param name Timeout name.
+ * @param newValue Timeout value.
+ * @return old timeout value
+ */
+ public long initTimeout(String name, long newValue) {
+ long result = getTimeout(name);
+ if (!contains(name)) {
+ setTimeout(name, newValue);
+ }
+ return result;
+ }
+
+ /**
+ * Creates a copy of the current timeouts set.
+ *
+ * @return A copy.
+ */
+ public Timeouts cloneThis() {
+ Timeouts t = new Timeouts();
+ Enumeration e = timeouts.keys();
+ String name = "";
+ while (e.hasMoreElements()) {
+ name = e.nextElement();
+ t.setTimeout(name,
+ getTimeout(name));
+ }
+ return t;
+ }
+
+ /**
+ * Sleeps for the "name" timeout value. Can throw InterruptedException if
+ * current thread was interrupted.
+ *
+ * @param name Timeout name.
+ * @exception InterruptedException
+ */
+ public void eSleep(String name) throws InterruptedException {
+ if (contains(name)
+ || defaults.contains(name)) {
+ Thread.sleep(getTimeout(name));
+ }
+ }
+
+ /**
+ * Sleeps for the "name" timeout value. Does not throw InterruptedException
+ * anyway.
+ *
+ * @param name Timeout name.
+ */
+ public void sleep(String name) {
+ create(name).sleep();
+ }
+
+ /**
+ * Prints all defined timeouts.
+ *
+ * @param pw PrintWriter to print into.
+ */
+ public void print(PrintWriter pw) {
+ Enumeration e = timeouts.keys();
+ String name = "";
+ while (e.hasMoreElements()) {
+ name = e.nextElement();
+ pw.println(name + " = " + Long.toString(getTimeout(name)));
+ }
+ pw.println("Default values:");
+ e = defaults.timeouts.keys();
+ name = "";
+ while (e.hasMoreElements()) {
+ name = e.nextElement();
+ if (!contains(name)) {
+ pw.println(name + " = " + Long.toString(getDefault(name)));
+ }
+ }
+ }
+
+ /**
+ * Prins all defined timeouts.
+ *
+ * @param ps PrintStream to print into.
+ */
+ public void print(PrintStream ps) {
+ print(new PrintWriter(ps));
+ }
+
+ /**
+ * Loads timeouts values.
+ *
+ * @param stream Stream to load timeouts from.
+ * @see org.netbeans.jemmy.Timeouts#load(String)
+ * @see org.netbeans.jemmy.Timeouts#load()
+ * @exception IOException
+ */
+ public void load(InputStream stream)
+ throws IOException {
+ Properties props = new Properties();
+ props.load(stream);
+ Enumeration> propNames = props.propertyNames();
+ long propValue;
+ String propName = null;
+ while (propNames.hasMoreElements()) {
+ propName = (String) propNames.nextElement();
+ propValue = Long.parseLong(props.getProperty(propName));
+ setTimeout(propName, propValue);
+ }
+ }
+
+ /**
+ * Loads timeouts values from file.
+ *
+ * @param fileName File to load timeouts from.
+ * @see org.netbeans.jemmy.Timeouts#load(InputStream)
+ * @see org.netbeans.jemmy.Timeouts#load(String)
+ * @exception IOException
+ * @exception FileNotFoundException
+ */
+ public void load(String fileName)
+ throws FileNotFoundException, IOException {
+ try (FileInputStream fileInputStream = new FileInputStream(fileName)) {
+ load(fileInputStream);
+ }
+ }
+
+ /**
+ * Loads timeouts values. Uses jemmy.timeouts system property to get
+ * timeouts file.
+ *
+ * @see org.netbeans.jemmy.Timeouts#load(InputStream)
+ * @see org.netbeans.jemmy.Timeouts#load(String)
+ * @exception IOException
+ * @exception FileNotFoundException
+ */
+ public void load()
+ throws FileNotFoundException, IOException {
+ if (System.getProperty("jemmy.timeouts") != null
+ && !System.getProperty("jemmy.timeouts").equals("")) {
+ load(System.getProperty("jemmy.timeouts"));
+ }
+ }
+
+ /**
+ * Loads debug timeouts values.
+ *
+ * @exception IOException
+ */
+ public void loadDebugTimeouts() throws IOException {
+ load(getClass().getClassLoader().getResourceAsStream("org/netbeans/jemmy/debug.timeouts"));
+ }
+
+ /**
+ * Get timeouts scale. Uses jemmy.timeouts.scale system property to get the
+ * value.
+ *
+ * @return timeouts scale or 1 if the property is not set.
+ */
+ public static double getTimeoutsScale() {
+ if (timeoutsScale == -1) {
+ String s = System.getProperty("jemmy.timeouts.scale", "1");
+ try {
+ timeoutsScale = Double.parseDouble(s);
+ } catch (NumberFormatException e) {
+ timeoutsScale = 1;
+ }
+ }
+ if (timeoutsScale < 0) {
+ timeoutsScale = 1;
+ }
+ return timeoutsScale;
+ }
+
+ /**
+ * This method is designed to be used by unit test for testing purpose.
+ */
+ static void resetTimeoutScale() {
+ timeoutsScale = -1;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Waitable.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Waitable.java
new file mode 100644
index 00000000000..e9dbabead5f
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Waitable.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+/**
+ *
+ * Defines criteria for waiting.
+ *
+ * @see org.netbeans.jemmy.Waiter
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface Waitable {
+
+ /**
+ * Checks if wait criteria have been met.
+ *
+ * @param obj optional waiting parameter.
+ * @return null is criteria have not been met.
+ */
+ public R actionProduced(P obj);
+
+ /**
+ * Returns description.
+ *
+ * @return a description of the wait criteria.
+ */
+ public String getDescription();
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Waiter.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Waiter.java
new file mode 100644
index 00000000000..9aaa68c0e42
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Waiter.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.awt.Component;
+
+/**
+ *
+ * Waits for something defined by Waitable interface to be happened.
+ *
+ *
Timeouts used:
+ * Waiter.TimeDelta - time delta to check actionProduced result.
+ * Waiter.WaitingTime - maximal waiting time
+ * Waiter.AfterWaitingTime - time to sleep after waiting has been finished.
+ *
+ * @see Timeouts
+ * @see Waitable
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class Waiter implements Waitable, Timeoutable, Outputable {
+
+ private final static long TIME_DELTA = 10;
+ private final static long WAIT_TIME = 60000;
+ private final static long AFTER_WAIT_TIME = 0;
+
+ private final Waitable waitable;
+ private long startTime = 0;
+ private long endTime = -1;
+ private R result;
+ private Timeouts timeouts;
+ private String waitingTimeOrigin;
+ private TestOut out;
+
+ /**
+ * Replace the fine-grained timeouts with a global flag which can be set,
+ * for instance, by a separate thread when a global timeout runs out.
+ */
+ public static volatile boolean USE_GLOBAL_TIMEOUT = false;
+ public static volatile boolean globalTimeoutExpired = false;
+
+ /**
+ * Constructor.
+ *
+ * @param w Waitable object defining waiting criteria.
+ */
+ public Waiter(Waitable w) {
+ super();
+ if (w == null) {
+ throw new NullPointerException("Waitable cannot be null");
+ }
+ setTimeouts(JemmyProperties.getProperties().getTimeouts());
+ setOutput(JemmyProperties.getProperties().getOutput());
+ waitable = w;
+ }
+
+ /**
+ * Can be used from subclass. actionProduced() method must be overriden in
+ * a class that uses this super constructor. actionProduced() method in
+ * Waiter will throw UnsupportedOperationException whenever invoked.
+ */
+ protected Waiter() {
+ super();
+ setTimeouts(JemmyProperties.getProperties().getTimeouts());
+ setOutput(JemmyProperties.getProperties().getOutput());
+ waitable = null;
+ }
+
+ static {
+ Timeouts.initDefault("Waiter.TimeDelta", TIME_DELTA);
+ Timeouts.initDefault("Waiter.WaitingTime", WAIT_TIME);
+ Timeouts.initDefault("Waiter.AfterWaitingTime", AFTER_WAIT_TIME);
+ }
+
+ /**
+ * Defines current timeouts.
+ *
+ * @param timeouts A collection of timeout assignments.
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see org.netbeans.jemmy.Timeouts
+ * @see #getTimeouts
+ */
+ @Override
+ public void setTimeouts(Timeouts timeouts) {
+ this.timeouts = timeouts;
+ }
+
+ /**
+ * Like {@link #setTimeouts(Timeouts)}, but clones the timeouts first, then
+ * sets "Waiter.WaitingTime" to the timeout whose name is passed in. This
+ * name is remembered for display in timeout error messages so people know
+ * what to adjust.
+ *
+ * @param timeouts to be cloned and in which to look up "useAsWaitingTime".
+ * @param useAsWaitingTime the name of the timeout to apply to
+ * "Waiter.WaitingTime".
+ * @param waitingTimeOrigin overrides {@code useAsWaitingTime} in timeout
+ * reporting if non-null.
+ * @return the cloned timeouts.
+ */
+ public Timeouts setTimeoutsToCloneOf(Timeouts timeouts,
+ String useAsWaitingTime, String waitingTimeOrigin) {
+ Timeouts t = timeouts.cloneThis();
+ t.setTimeout("Waiter.WaitingTime", t.getTimeout(useAsWaitingTime));
+ setTimeouts(t);
+ setWaitingTimeOrigin((null != waitingTimeOrigin) ? waitingTimeOrigin : useAsWaitingTime);
+ return t;
+ }
+
+ /**
+ * @see #setTimeoutsToCloneOf(Timeouts, String, String)
+ */
+ public Timeouts setTimeoutsToCloneOf(Timeouts timeouts,
+ String useAsWaitingTime) {
+ return setTimeoutsToCloneOf(timeouts, useAsWaitingTime, null);
+ }
+
+ /**
+ * Sets the origin of the current "Waiter.WaitingTime" to be shown in
+ * timeout error messages
+ *
+ * @param origin is the name of the origin.
+ */
+ public void setWaitingTimeOrigin(String origin) {
+ waitingTimeOrigin = origin;
+ }
+
+ /**
+ * Return current timeouts.
+ *
+ * @return the collection of current timeout assignments.
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see org.netbeans.jemmy.Timeouts
+ * @see #setTimeouts
+ */
+ @Override
+ public Timeouts getTimeouts() {
+ return timeouts;
+ }
+
+ /**
+ * Defines print output streams or writers.
+ *
+ * @param out Identify the streams or writers used for print output.
+ * @see org.netbeans.jemmy.Outputable
+ * @see org.netbeans.jemmy.TestOut
+ * @see #getOutput
+ */
+ @Override
+ public void setOutput(TestOut out) {
+ this.out = out;
+ }
+
+ /**
+ * Returns print output streams or writers.
+ *
+ * @return an object that contains references to objects for printing to
+ * output and err streams.
+ * @see org.netbeans.jemmy.Outputable
+ * @see org.netbeans.jemmy.TestOut
+ * @see #setOutput
+ */
+ @Override
+ public TestOut getOutput() {
+ return out;
+ }
+
+ /**
+ * Waits for not null result of actionProduced method of Waitable
+ * implementation passed into constructor.
+ *
+ * @param waitableObject Object to be passed into actionProduced method.
+ * @return non null result of action.
+ * @throws TimeoutExpiredException
+ * @exception InterruptedException
+ */
+ public R waitAction(P waitableObject)
+ throws InterruptedException {
+ startTime = System.currentTimeMillis();
+ out.printTrace(getWaitingStartedMessage());
+ out.printGolden(getGoldenWaitingStartedMessage());
+ long timeDelta = timeouts.getTimeout("Waiter.TimeDelta");
+ while ((result = actionProduced(waitableObject)) == null) {
+ Thread.sleep(timeDelta);
+ if (timeoutExpired()) {
+ out.printError(getTimeoutExpiredMessage(timeFromStart()));
+ out.printGolden(getGoldenTimeoutExpiredMessage());
+ throw (new TimeoutExpiredException(getActualDescription()));
+ }
+ }
+ endTime = System.currentTimeMillis();
+ out.printTrace(getActionProducedMessage(endTime - startTime, result));
+ out.printGolden(getGoldenActionProducedMessage());
+ Thread.sleep(timeouts.getTimeout("Waiter.AfterWaitingTime"));
+ return result;
+ }
+
+ /**
+ * This method delegates call to the waitable passed in constructor. If a
+ * subclass was created using protected no-parameters constructor, it should
+ * implement its own actionProduced method() as this one will throw an
+ * UnsupportedOperationException.
+ * @see Waitable
+ * @param obj
+ */
+ @Override
+ public R actionProduced(P obj) {
+ if (waitable != null) {
+ return waitable.actionProduced(obj);
+ } else {
+ throw new UnsupportedOperationException("actionProduced() return "
+ + "value is not defined. It used to return Boolean.TRUE "
+ + "in previous versions of Jemmy.");
+ }
+ }
+
+ /**
+ * @see Waitable
+ */
+ @Override
+ public String getDescription() {
+ return "Unknown waiting";
+ }
+
+ @Override
+ public String toString() {
+ return "Waiter{" + "description = " + getDescription() + ", waitable=" + waitable + ", startTime=" + startTime + ", endTime=" + endTime + ", result=" + result + ", waitingTimeOrigin=" + waitingTimeOrigin + '}';
+ }
+
+ /**
+ * Returns message to be printed before waiting start.
+ *
+ * @return a message.
+ */
+ protected String getWaitingStartedMessage() {
+ return "Start to wait action \"" + getActualDescription() + "\"";
+ }
+
+ /**
+ * Returns message to be printed when waiting timeout has been expired.
+ *
+ * @param timeSpent time from waiting start (milliseconds)
+ * @return a message.
+ */
+ protected String getTimeoutExpiredMessage(long timeSpent) {
+ return ("\"" + getActualDescription() + "\" action has not been produced in "
+ + timeSpent + " milliseconds");
+ }
+
+ /**
+ * Returns message to be printed when waiting has been successfully
+ * finished.
+ *
+ * @param timeSpent time from waiting start (milliseconds)
+ * @param result result of Waitable.actionproduced method.
+ * @return a message.
+ */
+ protected String getActionProducedMessage(long timeSpent, final Object result) {
+ String resultToString;
+ if (result instanceof Component) {
+ // run toString in dispatch thread
+ resultToString = new QueueTool().invokeSmoothly(
+ new QueueTool.QueueAction("result.toString()") {
+ @Override
+ public String launch() {
+ return result.toString();
+ }
+ }
+ );
+ } else {
+ resultToString = result.toString();
+ }
+ return ("\"" + getActualDescription() + "\" action has been produced in "
+ + timeSpent + " milliseconds with result "
+ + "\n : " + resultToString);
+ }
+
+ /**
+ * Returns message to be printed int golden output before waiting start.
+ *
+ * @return a message.
+ */
+ protected String getGoldenWaitingStartedMessage() {
+ return "Start to wait action \"" + getActualDescription() + "\"";
+ }
+
+ /**
+ * Returns message to be printed int golden output when waiting timeout has
+ * been expired.
+ *
+ * @return a message.
+ */
+ protected String getGoldenTimeoutExpiredMessage() {
+ return "\"" + getActualDescription() + "\" action has not been produced";
+ }
+
+ /**
+ * Returns message to be printed int golden output when waiting has been
+ * successfully finished.
+ *
+ * @return a message.
+ */
+ protected String getGoldenActionProducedMessage() {
+ return "\"" + getActualDescription() + "\" action has been produced";
+ }
+
+ /**
+ * Returns time from waiting start.
+ *
+ * @return Time spent for waiting already.
+ */
+ protected long timeFromStart() {
+ return System.currentTimeMillis() - startTime;
+ }
+
+ private String getActualDescription() {
+ final String suffix = (null == waitingTimeOrigin) ? "" : " (" + waitingTimeOrigin + ")";
+ if (waitable != null) {
+ return waitable.getDescription() + suffix;
+ } else {
+ return getDescription() + suffix;
+ }
+ }
+
+ private boolean timeoutExpired() {
+ if (USE_GLOBAL_TIMEOUT) {
+ return globalTimeoutExpired;
+ }
+ return timeFromStart() > timeouts.getTimeout("Waiter.WaitingTime");
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/WindowWaiter.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/WindowWaiter.java
new file mode 100644
index 00000000000..7d480000fd6
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/WindowWaiter.java
@@ -0,0 +1,483 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy;
+
+import java.awt.Component;
+import java.awt.Frame;
+import java.awt.Window;
+
+/**
+ * A WindowWaiter is a utility class used to look or wait for Windows. It
+ * contains methods to search for a Window among the currently showing Windows
+ * as well as methods that wait for a Window to show within an allotted time
+ * period.
+ *
+ * Searches and waits always involve search criteria applied by a
+ * ComponentChooser instance. Searches and waits can both be restricted to
+ * windows owned by a given window.
+ *
+ * Timeouts used:
+ * WindowWaiter.WaitWindowTimeout - time to wait window displayed
+ * WindowWaiter.AfterWindowTimeout - time to sleep after window has been
+ * dispayed
+ *
+ * @see org.netbeans.jemmy.Timeouts
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class WindowWaiter extends Waiter implements Timeoutable {
+
+ public static boolean FIND_INVISIBLE_WINDOWS = false;
+
+ private final static long WAIT_TIME = 60000;
+ private final static long AFTER_WAIT_TIME = 0;
+
+ private ComponentChooser chooser;
+ private Window owner = null;
+ private int index = 0;
+ private Timeouts timeouts;
+
+ /**
+ * Constructor.
+ */
+ public WindowWaiter() {
+ super();
+ setTimeouts(JemmyProperties.getProperties().getTimeouts());
+ }
+
+ /**
+ * Searches for a window. The search proceeds among the currently showing
+ * windows for the {@code index+1}'th window that is both owned by the
+ * {@code java.awt.Window} {@code owner} and that meets the
+ * criteria defined and applied by the {@code ComponentChooser}
+ * parameter.
+ *
+ * @param owner The owner window of all the windows to be searched.
+ * @param cc A component chooser used to define and apply the search
+ * criteria.
+ * @param index The ordinal index of the window in the set of currently
+ * displayed windows with the proper window ownership and a suitable title.
+ * The first index is 0.
+ * @return a reference to the {@code index+1}'th window that is
+ * showing, has the proper window ownership, and that meets the search
+ * criteria. If there are fewer than {@code index+1} windows, a
+ * {@code null} reference is returned.
+ */
+ public static Window getWindow(Window owner, ComponentChooser cc, int index) {
+ return getAWindow(owner, new IndexChooser(cc, index));
+ }
+
+ /**
+ * Searches for a window. Search among the currently showing windows for the
+ * first that is both owned by the {@code java.awt.Window}
+ * {@code owner} and that meets the search criteria applied by the
+ * {@code ComponentChooser} parameter.
+ *
+ * @param owner The owner window of the windows to be searched.
+ * @param cc A component chooser used to define and apply the search
+ * criteria.
+ * @return a reference to the first window that is showing, has a proper
+ * owner window, and that meets the search criteria. If no such window can
+ * be found, a {@code null} reference is returned.
+ */
+ public static Window getWindow(Window owner, ComponentChooser cc) {
+ return getWindow(owner, cc, 0);
+ }
+
+ /**
+ * Searches for a window. The search proceeds among the currently showing
+ * windows for the {@code index+1}'th window that meets the criteria
+ * defined and applied by the {@code ComonentChooser} parameter.
+ *
+ * @param cc A component chooser used to define and apply the search
+ * criteria.
+ * @param index The ordinal index of the window in the set of currently
+ * displayed windows. The first index is 0.
+ * @return a reference to the {@code index+1}'th window that is showing
+ * and that meets the search criteria. If there are fewer than
+ * {@code index+1} windows, a {@code null} reference is returned.
+ */
+ public static Window getWindow(ComponentChooser cc, int index) {
+ return getAWindow(new IndexChooser(cc, index));
+ }
+
+ /**
+ * Searches for a window. Search among the currently showing windows for one
+ * that meets the search criteria applied by the
+ * {@code ComponentChooser} parameter.
+ *
+ * @param cc A component chooser used to define and apply the search
+ * criteria.
+ * @return a reference to the first window that is showing and that meets
+ * the search criteria. If no such window can be found, a {@code null}
+ * reference is returned.
+ */
+ public static Window getWindow(ComponentChooser cc) {
+ return getWindow(cc, 0);
+ }
+
+ static {
+ Timeouts.initDefault("WindowWaiter.WaitWindowTimeout", WAIT_TIME);
+ Timeouts.initDefault("WindowWaiter.AfterWindowTimeout", AFTER_WAIT_TIME);
+ }
+
+ /**
+ * Defines current timeouts.
+ *
+ * @param timeouts A collection of timeout assignments.
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see org.netbeans.jemmy.Timeouts
+ * @see #getTimeouts
+ */
+ @Override
+ public void setTimeouts(Timeouts timeouts) {
+ this.timeouts = timeouts;
+ Timeouts times = timeouts.cloneThis();
+ times.setTimeout("Waiter.WaitingTime",
+ timeouts.getTimeout("WindowWaiter.WaitWindowTimeout"));
+ times.setTimeout("Waiter.AfterWaitingTime",
+ timeouts.getTimeout("WindowWaiter.AfterWindowTimeout"));
+ setWaitingTimeOrigin("WindowWaiter.WaitWindowTimeout");
+ super.setTimeouts(times);
+ }
+
+ /**
+ * Return current timeouts.
+ *
+ * @return the collection of current timeout assignments.
+ * @see org.netbeans.jemmy.Timeoutable
+ * @see org.netbeans.jemmy.Timeouts
+ * @see #setTimeouts
+ */
+ @Override
+ public Timeouts getTimeouts() {
+ return timeouts;
+ }
+
+ /**
+ * Action producer--get a window. Get a window. The search uses constraints
+ * on window ownership, ordinal index, and search criteria defined by an
+ * instance of {@code org.netbeans.jemmy.ComponentChooser}.
+ *
+ * @param obj Not used.
+ * @return the window waited upon. If a window cannot be found then a
+ * {@code null} reference is returned.
+ * @see org.netbeans.jemmy.Action
+ */
+ @Override
+ public Window actionProduced(Void obj) {
+ return WindowWaiter.getWindow(owner, chooser, index);
+ }
+
+ /**
+ * Waits for a window to show. Wait for the {@code index+1}'th window
+ * that meets the criteria defined and applied by the
+ * {@code ComonentChooser} parameter to show up.
+ *
+ * @param ch A component chooser used to define and apply the search
+ * criteria.
+ * @param index The ordinal index of the window in the set of currently
+ * displayed windows. The first index is 0.
+ * @return a reference to the {@code index+1}'th window that shows and
+ * that meets the search criteria. If fewer than {@code index+1}
+ * windows show up in the allotted time period then a {@code null}
+ * reference is returned.
+ * @throws TimeoutExpiredException
+ * @see #actionProduced(Object)
+ * @exception InterruptedException
+ */
+ public Window waitWindow(ComponentChooser ch, int index)
+ throws InterruptedException {
+ chooser = ch;
+ owner = null;
+ this.index = index;
+ return waitWindow();
+ }
+
+ /**
+ * Waits for a window to show. Wait for a window that meets the search
+ * criteria applied by the {@code ComponentChooser} parameter to show
+ * up.
+ *
+ * @param ch A component chooser used to define and apply the search
+ * criteria.
+ * @return a reference to the first window that shows and that meets the
+ * search criteria. If no such window can be found within the time period
+ * allotted, a {@code null} reference is returned.
+ * @throws TimeoutExpiredException
+ * @see #actionProduced(Object)
+ * @exception InterruptedException
+ */
+ public Window waitWindow(ComponentChooser ch)
+ throws InterruptedException {
+ return waitWindow(ch, 0);
+ }
+
+ /**
+ * Waits for a window to show. Wait for the {@code index+1}'th window
+ * to show that is both owned by the {@code java.awt.Window}
+ * {@code o} and that meets the criteria defined and applied by the
+ * {@code ComponentChooser} parameter.
+ *
+ * @param o The owner window of all the windows to be searched.
+ * @param ch A component chooser used to define and apply the search
+ * criteria.
+ * @param index The ordinal index of the window in the set of currently
+ * displayed windows with the proper window ownership and a suitable title.
+ * The first index is 0.
+ * @return a reference to the {@code index+1}'th window to show that
+ * has the proper window ownership, and that meets the search criteria. If
+ * there are fewer than {@code index+1} windows, a {@code null}
+ * reference is returned.
+ * @throws TimeoutExpiredException
+ * @see #actionProduced(Object)
+ * @exception InterruptedException
+ */
+ public Window waitWindow(Window o, ComponentChooser ch, int index)
+ throws InterruptedException {
+ owner = o;
+ chooser = ch;
+ this.index = index;
+ return waitAction(null);
+ }
+
+ /**
+ * Waits for a window to show. Wait for the first window to show that is
+ * both owned by the {@code java.awt.Window} {@code o} and that
+ * meets the criteria defined and applied by the
+ * {@code ComponentChooser} parameter.
+ *
+ * @param o The owner window of all the windows to be searched.
+ * @param ch A component chooser used to define and apply the search
+ * criteria.
+ * @return a reference to the first window to show that has the proper
+ * window ownership, and that meets the search criteria. If there is no such
+ * window, a {@code null} reference is returned.
+ * @throws TimeoutExpiredException
+ * @see #actionProduced(Object)
+ * @exception InterruptedException
+ */
+ public Window waitWindow(Window o, ComponentChooser ch)
+ throws InterruptedException {
+ return waitWindow(o, ch, 0);
+ }
+
+ @Override
+ public String getDescription() {
+ return chooser.getDescription();
+ }
+
+ @Override
+ public String toString() {
+ return "WindowWaiter{" + "chooser=" + chooser + ", owner=" + owner + ", index=" + index + '}';
+ }
+
+ /**
+ * Method can be used by a subclass to define chooser.
+ *
+ * @param ch a chooser specifying searching criteria.
+ * @see #getComponentChooser
+ */
+ protected void setComponentChooser(ComponentChooser ch) {
+ chooser = ch;
+ }
+
+ /**
+ * Method can be used by a subclass to define chooser.
+ *
+ * @return a chooser specifying searching criteria.
+ * @see #setComponentChooser
+ */
+ protected ComponentChooser getComponentChooser() {
+ return chooser;
+ }
+
+ /**
+ * Method can be used by a subclass to define window owner.
+ *
+ * @param owner Window-owner of the set of windows.
+ * @see #getOwner
+ */
+ protected void setOwner(Window owner) {
+ this.owner = owner;
+ }
+
+ /**
+ * Method can be used by a subclass to define window owner.
+ *
+ * @return Window-owner of the set of windows.
+ * @see #setOwner
+ */
+ protected Window getOwner() {
+ return owner;
+ }
+
+ /**
+ * @see org.netbeans.jemmy.Waiter#getWaitingStartedMessage()
+ */
+ @Override
+ protected String getWaitingStartedMessage() {
+ return "Start to wait window \"" + chooser.getDescription() + "\" opened";
+ }
+
+ /**
+ * Overrides Waiter.getTimeoutExpiredMessage.
+ *
+ * @see org.netbeans.jemmy.Waiter#getTimeoutExpiredMessage(long)
+ * @param timeSpent time from waiting start (milliseconds)
+ * @return a message.
+ */
+ @Override
+ protected String getTimeoutExpiredMessage(long timeSpent) {
+ return ("Window \"" + chooser.getDescription() + "\" has not been opened in "
+ + timeSpent + " milliseconds");
+ }
+
+ /**
+ * Overrides Waiter.getActionProducedMessage.
+ *
+ * @see org.netbeans.jemmy.Waiter#getActionProducedMessage(long, Object)
+ * @param timeSpent time from waiting start (milliseconds)
+ * @param result result of Waitable.actionproduced method.
+ * @return a message.
+ */
+ @Override
+ protected String getActionProducedMessage(long timeSpent, final Object result) {
+ String resultToString;
+ if (result instanceof Component) {
+ // run toString in dispatch thread
+ resultToString = new QueueTool().invokeSmoothly(
+ new QueueTool.QueueAction("result.toString()") {
+ @Override
+ public String launch() {
+ return result.toString();
+ }
+ }
+ );
+ } else {
+ resultToString = result.toString();
+ }
+ return ("Window \"" + chooser.getDescription() + "\" has been opened in "
+ + timeSpent + " milliseconds"
+ + "\n " + resultToString);
+ }
+
+ /**
+ * @return a message.
+ * @see org.netbeans.jemmy.Waiter#getGoldenWaitingStartedMessage()
+ */
+ @Override
+ protected String getGoldenWaitingStartedMessage() {
+ return "Start to wait window \"" + chooser.getDescription() + "\" opened";
+ }
+
+ /**
+ * @return a message.
+ * @see org.netbeans.jemmy.Waiter#getGoldenTimeoutExpiredMessage()
+ */
+ @Override
+ protected String getGoldenTimeoutExpiredMessage() {
+ return "Window \"" + chooser.getDescription() + "\" has not been opened";
+ }
+
+ /**
+ * @return a message.
+ * @see org.netbeans.jemmy.Waiter#getGoldenActionProducedMessage()
+ */
+ @Override
+ protected String getGoldenActionProducedMessage() {
+ return "Window \"" + chooser.getDescription() + "\" has been opened";
+ }
+
+ private static Window getAWindow(Window owner, ComponentChooser cc) {
+ if (owner == null) {
+ return WindowWaiter.getAWindow(cc);
+ } else {
+ Window result = null;
+ Window[] windows = owner.getOwnedWindows();
+ for (Window window : windows) {
+ if (cc.checkComponent(window)) {
+ return window;
+ }
+ if ((result = WindowWaiter.getWindow(window, cc)) != null) {
+ return result;
+ }
+ }
+ return null;
+ }
+ }
+
+ private static Window getAWindow(ComponentChooser cc) {
+ Window result = null;
+ Frame[] frames = Frame.getFrames();
+ for (Frame frame : frames) {
+ if (cc.checkComponent(frame)) {
+ return frame;
+ }
+ if ((result = WindowWaiter.getWindow(frame, cc)) != null) {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ private Window waitWindow()
+ throws InterruptedException {
+ return waitAction(null);
+ }
+
+ private static class IndexChooser implements ComponentChooser {
+
+ private int curIndex = 0;
+ private int index;
+ private ComponentChooser chooser;
+
+ public IndexChooser(ComponentChooser ch, int i) {
+ index = i;
+ chooser = ch;
+ curIndex = 0;
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ if ((FIND_INVISIBLE_WINDOWS || (comp.isShowing() && comp.isVisible()))
+ && chooser.checkComponent(comp)) {
+ if (curIndex == index) {
+ return true;
+ }
+ curIndex++;
+ }
+ return false;
+ }
+
+ @Override
+ public String getDescription() {
+ return chooser.getDescription();
+ }
+
+ @Override
+ public String toString() {
+ return "IndexChooser{" + "curIndex=" + curIndex + ", index=" + index + ", chooser=" + chooser + '}';
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/accessibility/AccessibilityChooser.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/accessibility/AccessibilityChooser.java
new file mode 100644
index 00000000000..2e9aa1e6330
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/accessibility/AccessibilityChooser.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.accessibility;
+
+import java.awt.Component;
+
+import javax.accessibility.AccessibleContext;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JWindow;
+
+import org.netbeans.jemmy.ComponentChooser;
+
+public abstract class AccessibilityChooser implements ComponentChooser {
+
+ @Override
+ public final boolean checkComponent(Component comp) {
+ if (comp instanceof JComponent) {
+ return checkContext(comp.getAccessibleContext());
+ } else if (comp instanceof JDialog) {
+ return checkContext(comp.getAccessibleContext());
+ } else if (comp instanceof JFrame) {
+ return checkContext(comp.getAccessibleContext());
+ } else if (comp instanceof JWindow) {
+ return checkContext(comp.getAccessibleContext());
+ } else {
+ return false;
+ }
+ }
+
+ public abstract boolean checkContext(AccessibleContext context);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/accessibility/AccessibleDescriptionChooser.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/accessibility/AccessibleDescriptionChooser.java
new file mode 100644
index 00000000000..984637c339b
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/accessibility/AccessibleDescriptionChooser.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.accessibility;
+
+import javax.accessibility.AccessibleContext;
+
+import org.netbeans.jemmy.operators.Operator;
+import org.netbeans.jemmy.operators.Operator.StringComparator;
+
+public class AccessibleDescriptionChooser extends AccessibilityChooser {
+
+ private final String description;
+ private final StringComparator comparator;
+
+ public AccessibleDescriptionChooser(String description, StringComparator comparator) {
+ this.description = description;
+ this.comparator = comparator;
+ }
+
+ public AccessibleDescriptionChooser(String description) {
+ this(description, Operator.getDefaultStringComparator());
+ }
+
+ @Override
+ public final boolean checkContext(AccessibleContext context) {
+ return comparator.equals(context.getAccessibleDescription(), description);
+ }
+
+ @Override
+ public String getDescription() {
+ return "JComponent with \"" + description + "\" accessible description";
+ }
+
+ @Override
+ public String toString() {
+ return "AccessibleDescriptionChooser{" + "description=" + description + ", comparator=" + comparator + '}';
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/accessibility/AccessibleNameChooser.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/accessibility/AccessibleNameChooser.java
new file mode 100644
index 00000000000..8a173e5d1d7
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/accessibility/AccessibleNameChooser.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.accessibility;
+
+import javax.accessibility.AccessibleContext;
+
+import org.netbeans.jemmy.operators.Operator;
+import org.netbeans.jemmy.operators.Operator.StringComparator;
+
+public class AccessibleNameChooser extends AccessibilityChooser {
+
+ String name;
+ StringComparator comparator;
+
+ public AccessibleNameChooser(String name, StringComparator comparator) {
+ this.name = name;
+ this.comparator = comparator;
+ }
+
+ public AccessibleNameChooser(String name) {
+ this(name, Operator.getDefaultStringComparator());
+ }
+
+ @Override
+ public final boolean checkContext(AccessibleContext context) {
+ return comparator.equals(context.getAccessibleName(), name);
+ }
+
+ @Override
+ public String getDescription() {
+ return "JComponent with \"" + name + "\" accessible name";
+ }
+
+ @Override
+ public String toString() {
+ return "AccessibleNameChooser{" + "name=" + name + ", comparator=" + comparator + '}';
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/debug.timeouts b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/debug.timeouts
new file mode 100644
index 00000000000..215b7d04f16
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/debug.timeouts
@@ -0,0 +1,19 @@
+AbstractButtonOperator.PushButtonTimeout=100
+ComponentOperator.AfterDragTimeout=100
+ComponentOperator.BeforeDragTimeout=100
+ComponentOperator.MouseClickTimeout=100
+ComponentOperator.PushKeyTimeout=100
+DialogWaiter.AfterDialogTimeout=3000
+EventDispatcher.RobotAutoDelay=100
+FrameWaiter.AfterFrameTimeout=3000
+JComboBoxOperator.BeforeSelectingTimeout=100
+JComponentOperator.ShowToolTipTimeout=1000
+JMenuItemOperator.PushMenuTimeout=100
+JMenuOperator.WaitBeforePopupTimeout=100
+JScrollBarOperator.OneScrollClickTimeout=10
+JSplitPaneOperator.ScrollClickTimeout=10
+JTextComponentOperator.BetweenKeysTimeout=100
+JTextComponentOperator.PushKeyTimeout=100
+JTextComponentOperator.TypeTextTimeout=60000
+JTreeOperator.WaitAfterNodeExpandedTimeout=100
+WindowWaiter.AfterWindowTimeout=3000
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/APIDriverInstaller.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/APIDriverInstaller.java
new file mode 100644
index 00000000000..b85dfe70425
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/APIDriverInstaller.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.JemmyException;
+import org.netbeans.jemmy.JemmyProperties;
+import org.netbeans.jemmy.drivers.buttons.ButtonMouseDriver;
+import org.netbeans.jemmy.drivers.focus.APIFocusDriver;
+import org.netbeans.jemmy.drivers.focus.MouseFocusDriver;
+import org.netbeans.jemmy.drivers.lists.ChoiceDriver;
+import org.netbeans.jemmy.drivers.lists.JComboMouseDriver;
+import org.netbeans.jemmy.drivers.lists.JListMouseDriver;
+import org.netbeans.jemmy.drivers.lists.JTabAPIDriver;
+import org.netbeans.jemmy.drivers.lists.JTableHeaderDriver;
+import org.netbeans.jemmy.drivers.lists.ListKeyboardDriver;
+import org.netbeans.jemmy.drivers.menus.AppleMenuDriver;
+import org.netbeans.jemmy.drivers.menus.DefaultJMenuDriver;
+import org.netbeans.jemmy.drivers.menus.QueueJMenuDriver;
+import org.netbeans.jemmy.drivers.scrolling.JScrollBarAPIDriver;
+import org.netbeans.jemmy.drivers.scrolling.JSliderAPIDriver;
+import org.netbeans.jemmy.drivers.scrolling.JSplitPaneDriver;
+import org.netbeans.jemmy.drivers.scrolling.ScrollPaneDriver;
+import org.netbeans.jemmy.drivers.scrolling.ScrollbarDriver;
+import org.netbeans.jemmy.drivers.tables.JTableMouseDriver;
+import org.netbeans.jemmy.drivers.text.AWTTextKeyboardDriver;
+import org.netbeans.jemmy.drivers.text.SwingTextKeyboardDriver;
+import org.netbeans.jemmy.drivers.trees.JTreeAPIDriver;
+import org.netbeans.jemmy.drivers.windows.DefaultFrameDriver;
+import org.netbeans.jemmy.drivers.windows.DefaultInternalFrameDriver;
+import org.netbeans.jemmy.drivers.windows.DefaultWindowDriver;
+
+/**
+ * Installs all necessary drivers for Jemmy operators except low-level drivers
+ * which are installed by
+ * InputDriverInstaller.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class APIDriverInstaller extends ArrayDriverInstaller {
+
+ /**
+ * Constructs a DefaultDriverInstaller object.
+ *
+ * @param shortcutEvents Signals whether shortcut mode is used.
+ */
+ public APIDriverInstaller(boolean shortcutEvents) {
+ super(new String[]{
+ DriverManager.LIST_DRIVER_ID,
+ DriverManager.MULTISELLIST_DRIVER_ID,
+ DriverManager.TREE_DRIVER_ID,
+ DriverManager.TEXT_DRIVER_ID,
+ DriverManager.TEXT_DRIVER_ID,
+ DriverManager.SCROLL_DRIVER_ID,
+ DriverManager.SCROLL_DRIVER_ID,
+ DriverManager.SCROLL_DRIVER_ID,
+ DriverManager.SCROLL_DRIVER_ID,
+ DriverManager.SCROLL_DRIVER_ID,
+ DriverManager.SCROLL_DRIVER_ID,
+ DriverManager.BUTTON_DRIVER_ID,
+ DriverManager.LIST_DRIVER_ID,
+ DriverManager.LIST_DRIVER_ID,
+ DriverManager.MULTISELLIST_DRIVER_ID,
+ DriverManager.LIST_DRIVER_ID,
+ DriverManager.LIST_DRIVER_ID,
+ DriverManager.MULTISELLIST_DRIVER_ID,
+ DriverManager.TABLE_DRIVER_ID,
+ DriverManager.LIST_DRIVER_ID,
+ DriverManager.FRAME_DRIVER_ID,
+ DriverManager.WINDOW_DRIVER_ID,
+ DriverManager.FRAME_DRIVER_ID,
+ DriverManager.INTERNAL_FRAME_DRIVER_ID,
+ DriverManager.WINDOW_DRIVER_ID,
+ DriverManager.FOCUS_DRIVER_ID,
+ DriverManager.FOCUS_DRIVER_ID,
+ DriverManager.MENU_DRIVER_ID,
+ DriverManager.MENU_DRIVER_ID,
+ DriverManager.ORDEREDLIST_DRIVER_ID},
+ new Object[]{
+ new JTreeAPIDriver(),
+ new JTreeAPIDriver(),
+ new JTreeAPIDriver(),
+ new AWTTextKeyboardDriver(),
+ new SwingTextKeyboardDriver(),
+ new ScrollbarDriver(),
+ new ScrollPaneDriver(),
+ new JScrollBarAPIDriver(),
+ new JSplitPaneDriver(),
+ new JSliderAPIDriver(),
+ createSpinnerDriver(),
+ new ButtonMouseDriver(),
+ new JTabAPIDriver(),
+ new ListKeyboardDriver(),
+ new ListKeyboardDriver(),
+ new JComboMouseDriver(),
+ new JListMouseDriver(),
+ new JListMouseDriver(),
+ new JTableMouseDriver(),
+ new ChoiceDriver(),
+ new DefaultFrameDriver(),
+ new DefaultWindowDriver(),
+ new DefaultInternalFrameDriver(),
+ new DefaultInternalFrameDriver(),
+ new DefaultInternalFrameDriver(),
+ new APIFocusDriver(),
+ new MouseFocusDriver(),
+ (shortcutEvents ? new QueueJMenuDriver() : new DefaultJMenuDriver()),
+ ((System.getProperty("apple.laf.useScreenMenuBar") != null
+ && System.getProperty("apple.laf.useScreenMenuBar").equals("true")) ? new AppleMenuDriver()
+ : (shortcutEvents ? new QueueJMenuDriver() : new DefaultJMenuDriver())),
+ new JTableHeaderDriver()});
+ }
+
+ /**
+ * Constructs a DefaultDriverInstaller object with shortcut mode flag taken
+ * from {@code JemmyProperties}.
+ */
+ public APIDriverInstaller() {
+ this((JemmyProperties.getCurrentDispatchingModel()
+ & JemmyProperties.SHORTCUT_MODEL_MASK) != 0);
+ }
+
+ private static LightDriver createSpinnerDriver() {
+ if (System.getProperty("java.specification.version").compareTo("1.3") > 0) {
+ try {
+ return ((LightDriver) new ClassReference("org.netbeans.jemmy.drivers.scrolling.JSpinnerDriver").
+ newInstance(null, null));
+ } catch (ClassNotFoundException e) {
+ JemmyProperties.getCurrentOutput().
+ printErrLine("ATTENTION! you are using Jemmy built by Java earlier then 1.4, under "
+ + "Java 1.4. \nImpossible to create JSpinnerDriver");
+ return createEmptyDriver();
+ } catch (Exception e) {
+ throw (new JemmyException("Impossible to create JSpinnerDriver although java version is "
+ + System.getProperty("java.version"),
+ e));
+ }
+ } else {
+ return createEmptyDriver();
+ }
+ }
+
+ private static LightDriver createEmptyDriver() {
+ return (new LightDriver() {
+ @Override
+ public String[] getSupported() {
+ return new String[]{Object.class.getName()};
+ }
+ });
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/ArrayDriverInstaller.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/ArrayDriverInstaller.java
new file mode 100644
index 00000000000..fa57275eb7f
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/ArrayDriverInstaller.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+/**
+ * Auxiliary class making driver registration easier.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class ArrayDriverInstaller implements DriverInstaller {
+
+ String[] ids;
+ Object[] drivers;
+
+ /**
+ * Constructs an ArrayDriverInstaller object. Both parameter arrays mush
+ * have same length, {@code drivers} must keep instances of
+ * Driver or
+ * LightDriver implementations.
+ *
+ * @param ids an array of driver IDs
+ * @param drivers an array of drivers.
+ */
+ public ArrayDriverInstaller(String[] ids, Object[] drivers) {
+ this.ids = ids;
+ this.drivers = drivers;
+ }
+
+ /**
+ * Installs drivers from the array passed into constructor.
+ */
+ @Override
+ public void install() {
+ for (int i = 0; i < ids.length; i++) {
+ DriverManager.setDriver(ids[i], drivers[i]);
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/ButtonDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/ButtonDriver.java
new file mode 100644
index 00000000000..befd9b1bc8a
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/ButtonDriver.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Defines how to work with buttons.
+ */
+public interface ButtonDriver {
+
+ /**
+ * Presses a button.
+ *
+ * @param oper Button operator.
+ */
+ public void press(ComponentOperator oper);
+
+ /**
+ * Releases a button.
+ *
+ * @param oper Button operator.
+ */
+ public void release(ComponentOperator oper);
+
+ /**
+ * Pushes a button.
+ *
+ * @param oper Button operator.
+ */
+ public void push(ComponentOperator oper);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/DefaultDriverInstaller.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/DefaultDriverInstaller.java
new file mode 100644
index 00000000000..15c8a5a3fec
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/DefaultDriverInstaller.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.JemmyException;
+import org.netbeans.jemmy.JemmyProperties;
+import org.netbeans.jemmy.drivers.buttons.ButtonMouseDriver;
+import org.netbeans.jemmy.drivers.focus.APIFocusDriver;
+import org.netbeans.jemmy.drivers.focus.MouseFocusDriver;
+import org.netbeans.jemmy.drivers.lists.ChoiceDriver;
+import org.netbeans.jemmy.drivers.lists.JComboMouseDriver;
+import org.netbeans.jemmy.drivers.lists.JListMouseDriver;
+import org.netbeans.jemmy.drivers.lists.JTabMouseDriver;
+import org.netbeans.jemmy.drivers.lists.JTableHeaderDriver;
+import org.netbeans.jemmy.drivers.lists.ListKeyboardDriver;
+import org.netbeans.jemmy.drivers.menus.DefaultJMenuDriver;
+import org.netbeans.jemmy.drivers.menus.QueueJMenuDriver;
+import org.netbeans.jemmy.drivers.scrolling.JScrollBarDriver;
+import org.netbeans.jemmy.drivers.scrolling.JSliderDriver;
+import org.netbeans.jemmy.drivers.scrolling.JSplitPaneDriver;
+import org.netbeans.jemmy.drivers.scrolling.ScrollPaneDriver;
+import org.netbeans.jemmy.drivers.scrolling.ScrollbarDriver;
+import org.netbeans.jemmy.drivers.tables.JTableMouseDriver;
+import org.netbeans.jemmy.drivers.text.AWTTextKeyboardDriver;
+import org.netbeans.jemmy.drivers.text.SwingTextKeyboardDriver;
+import org.netbeans.jemmy.drivers.trees.JTreeMouseDriver;
+import org.netbeans.jemmy.drivers.windows.DefaultFrameDriver;
+import org.netbeans.jemmy.drivers.windows.DefaultInternalFrameDriver;
+import org.netbeans.jemmy.drivers.windows.DefaultWindowDriver;
+
+/**
+ * Installs all necessary drivers for Jemmy operators except low-level drivers
+ * which are installed by
+ * InputDriverInstaller.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class DefaultDriverInstaller extends ArrayDriverInstaller {
+
+ /**
+ * Constructs a DefaultDriverInstaller object.
+ *
+ * @param shortcutEvents Signals whether shortcut mode is used.
+ */
+ public DefaultDriverInstaller(boolean shortcutEvents) {
+ super(new String[]{
+ DriverManager.LIST_DRIVER_ID,
+ DriverManager.MULTISELLIST_DRIVER_ID,
+ DriverManager.TREE_DRIVER_ID,
+ DriverManager.TEXT_DRIVER_ID,
+ DriverManager.TEXT_DRIVER_ID,
+ DriverManager.SCROLL_DRIVER_ID,
+ DriverManager.SCROLL_DRIVER_ID,
+ DriverManager.SCROLL_DRIVER_ID,
+ DriverManager.SCROLL_DRIVER_ID,
+ DriverManager.SCROLL_DRIVER_ID,
+ DriverManager.SCROLL_DRIVER_ID,
+ DriverManager.BUTTON_DRIVER_ID,
+ DriverManager.LIST_DRIVER_ID,
+ DriverManager.LIST_DRIVER_ID,
+ DriverManager.MULTISELLIST_DRIVER_ID,
+ DriverManager.LIST_DRIVER_ID,
+ DriverManager.LIST_DRIVER_ID,
+ DriverManager.MULTISELLIST_DRIVER_ID,
+ DriverManager.TABLE_DRIVER_ID,
+ DriverManager.LIST_DRIVER_ID,
+ DriverManager.FRAME_DRIVER_ID,
+ DriverManager.WINDOW_DRIVER_ID,
+ DriverManager.FRAME_DRIVER_ID,
+ DriverManager.INTERNAL_FRAME_DRIVER_ID,
+ DriverManager.WINDOW_DRIVER_ID,
+ DriverManager.FOCUS_DRIVER_ID,
+ DriverManager.FOCUS_DRIVER_ID,
+ DriverManager.MENU_DRIVER_ID,
+ DriverManager.ORDEREDLIST_DRIVER_ID},
+ new Object[]{
+ new JTreeMouseDriver(),
+ new JTreeMouseDriver(),
+ new JTreeMouseDriver(),
+ new AWTTextKeyboardDriver(),
+ new SwingTextKeyboardDriver(),
+ new ScrollbarDriver(),
+ new ScrollPaneDriver(),
+ new JScrollBarDriver(),
+ new JSplitPaneDriver(),
+ new JSliderDriver(),
+ createSpinnerDriver(),
+ new ButtonMouseDriver(),
+ new JTabMouseDriver(),
+ new ListKeyboardDriver(),
+ new ListKeyboardDriver(),
+ new JComboMouseDriver(),
+ new JListMouseDriver(),
+ new JListMouseDriver(),
+ new JTableMouseDriver(),
+ new ChoiceDriver(),
+ new DefaultFrameDriver(),
+ new DefaultWindowDriver(),
+ new DefaultInternalFrameDriver(),
+ new DefaultInternalFrameDriver(),
+ new DefaultInternalFrameDriver(),
+ new APIFocusDriver(),
+ new MouseFocusDriver(),
+ (shortcutEvents ? new QueueJMenuDriver() : new DefaultJMenuDriver()),
+ new JTableHeaderDriver()});
+ }
+
+ /**
+ * Constructs a DefaultDriverInstaller object with shortcut mode flag taken
+ * from {@code JemmyProperties}.
+ */
+ public DefaultDriverInstaller() {
+ this((JemmyProperties.getCurrentDispatchingModel()
+ & JemmyProperties.SHORTCUT_MODEL_MASK) != 0);
+ }
+
+ private static LightDriver createSpinnerDriver() {
+ if (System.getProperty("java.specification.version").compareTo("1.3") > 0) {
+ try {
+ return ((LightDriver) new ClassReference("org.netbeans.jemmy.drivers.scrolling.JSpinnerDriver").
+ newInstance(null, null));
+ } catch (ClassNotFoundException e) {
+ JemmyProperties.getCurrentOutput().
+ printErrLine("ATTENTION! you are using Jemmy built by Java earlier then 1.4, under "
+ + "Java 1.4. \nImpossible to create JSpinnerDriver");
+ return createEmptyDriver();
+ } catch (Exception e) {
+ throw (new JemmyException("Impossible to create JSpinnerDriver although java version is "
+ + System.getProperty("java.version"),
+ e));
+ }
+ } else {
+ return createEmptyDriver();
+ }
+ }
+
+ private static LightDriver createEmptyDriver() {
+ return (new LightDriver() {
+ @Override
+ public String[] getSupported() {
+ return new String[]{Object.class.getName()};
+ }
+ });
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/DescriptablePathChooser.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/DescriptablePathChooser.java
new file mode 100644
index 00000000000..8c6ddcea6a8
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/DescriptablePathChooser.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+/**
+ * Specifies an interface for objects defining path searching criteria.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public interface DescriptablePathChooser extends PathChooser {
+
+ /**
+ * Gives path description.
+ */
+ public String getDescription();
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/Driver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/Driver.java
new file mode 100644
index 00000000000..7ea0d174205
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/Driver.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+/**
+ * Implements "heavy" model of driver because requires to load classes for all
+ * supported operator types.
+ *
+ * @see LightDriver
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface Driver {
+
+ /**
+ * Returns an array of operator classes which are supported by this driver.
+ *
+ * @return an array of supported operators' classes.
+ */
+ public Class>[] getSupported();
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/DriverInstaller.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/DriverInstaller.java
new file mode 100644
index 00000000000..af50e0257cc
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/DriverInstaller.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+/**
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface DriverInstaller {
+
+ public void install();
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/DriverManager.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/DriverManager.java
new file mode 100644
index 00000000000..f38d836f81a
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/DriverManager.java
@@ -0,0 +1,810 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.JemmyException;
+import org.netbeans.jemmy.JemmyProperties;
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Manages driver set.
+ */
+public class DriverManager {
+
+ /**
+ * Symbolic constant - prefix for drivers names.
+ */
+ public static final String DRIVER_ID = "drivers.";
+ /**
+ * Symbolic constant for tree drivers.
+ */
+ public static final String TREE_DRIVER_ID = DRIVER_ID + "tree";
+ /**
+ * Symbolic constant for text drivers.
+ */
+ public static final String TEXT_DRIVER_ID = DRIVER_ID + "text";
+ /**
+ * Symbolic constant for key drivers.
+ */
+ public static final String KEY_DRIVER_ID = DRIVER_ID + "key";
+ /**
+ * Symbolic constant for mouse drivers.
+ */
+ public static final String MOUSE_DRIVER_ID = DRIVER_ID + "mouse";
+ /**
+ * Symbolic constant for scroll drivers.
+ */
+ public static final String SCROLL_DRIVER_ID = DRIVER_ID + "scroll";
+ /**
+ * Symbolic constant for button drivers.
+ */
+ public static final String BUTTON_DRIVER_ID = DRIVER_ID + "button";
+ /**
+ * Symbolic constant for list drivers.
+ */
+ public static final String LIST_DRIVER_ID = DRIVER_ID + "list";
+ /**
+ * Symbolic constant for multiselection list drivers.
+ */
+ public static final String MULTISELLIST_DRIVER_ID = DRIVER_ID + "multisellist";
+ /**
+ * Symbolic constant for reorderable list drivers.
+ */
+ public static final String ORDEREDLIST_DRIVER_ID = DRIVER_ID + "orderedlist";
+ /**
+ * Symbolic constant for table drivers.
+ */
+ public static final String TABLE_DRIVER_ID = DRIVER_ID + "table";
+ /**
+ * Symbolic constant for window drivers.
+ */
+ public static final String WINDOW_DRIVER_ID = DRIVER_ID + "window";
+ /**
+ * Symbolic constant for window drivers.
+ */
+ public static final String FRAME_DRIVER_ID = DRIVER_ID + "frame";
+ /**
+ * Symbolic constant for window drivers.
+ */
+ public static final String INTERNAL_FRAME_DRIVER_ID = DRIVER_ID + "internal_frame";
+ /**
+ * Symbolic constant for frame drivers.
+ */
+ public static final String FOCUS_DRIVER_ID = DRIVER_ID + "focus";
+ /**
+ * Symbolic constant for menu drivers.
+ */
+ public static final String MENU_DRIVER_ID = DRIVER_ID + "menu";
+
+ //cannot be instantiated!
+ private DriverManager() {
+ }
+
+ /**
+ * Searches a driver.
+ *
+ * @param id Driver type id.
+ * @param operatorClass Class to get an driver for.
+ * @param props Instance to get driver from.
+ * @return a driver.
+ * @see #setDriver
+ */
+ public static Object getDriver(String id, Class> operatorClass, JemmyProperties props) {
+ Object result = getADriver(id, operatorClass, props);
+ if (result == null) {
+ return getDriver(id, operatorClass);
+ } else {
+ return result;
+ }
+ }
+
+ /**
+ * Searches a driver. Uses {@code operator.getProperties()} to receive
+ * JemmyProperties instance.
+ *
+ * @param id Driver type id.
+ * @param operator Operator to get an driver for.
+ * @return a driver.
+ * @see #setDriver
+ */
+ public static Object getDriver(String id, ComponentOperator operator) {
+ return getDriver(id, operator.getClass(), operator.getProperties());
+ }
+
+ /**
+ * Searches a driver. Uses current JemmyProperties.
+ *
+ * @param id Driver type id.
+ * @param operatorClass Class to get an driver for.
+ * @return a driver.
+ * @see #setDriver
+ */
+ public static Object getDriver(String id, Class> operatorClass) {
+ Object result = getADriver(id, operatorClass, JemmyProperties.getProperties());
+ if (result == null) {
+ throw (new JemmyException("No \"" + id + "\" driver registered for "
+ + operatorClass.getName() + " class!"));
+ } else {
+ return result;
+ }
+ }
+
+ /**
+ * Sets driver for an operator class.
+ *
+ * @param id Driver type id.
+ * @param driver A driver to be installed.
+ * @param operatorClass Class to set driver for.
+ * @see #getDriver
+ */
+ public static void setDriver(String id, Object driver, Class> operatorClass) {
+ JemmyProperties.
+ setCurrentProperty(makeID(id, operatorClass), driver);
+ if (Boolean.getBoolean(DRIVER_ID + "trace_output")) {
+ JemmyProperties.getCurrentOutput().printLine("Installing "
+ + driver.getClass().getName()
+ + " drifer for "
+ + operatorClass.getName()
+ + " operators.");
+ }
+ }
+
+ /**
+ * Sets driver for an operator class name.
+ *
+ * @param id Driver type id.
+ * @param driver A driver to be installed.
+ * @param operatorClassName A name of operator class.
+ * @see #getDriver
+ */
+ public static void setDriver(String id, Object driver, String operatorClassName) {
+ JemmyProperties.
+ setCurrentProperty(makeID(id, operatorClassName), driver);
+ if (Boolean.getBoolean(DRIVER_ID + "trace_output")) {
+ JemmyProperties.getCurrentOutput().printLine("Installing "
+ + driver.getClass().getName()
+ + " drifer for "
+ + operatorClassName
+ + " operators.");
+ }
+ }
+
+ /**
+ * Sets driver for all classes supported by driver.
+ *
+ * @param id Driver type id.
+ * @param driver A driver to be installed.
+ * @see #getDriver
+ */
+ public static void setDriver(String id, Driver driver) {
+ Class>[] supported = driver.getSupported();
+ for (Class> aSupported : supported) {
+ setDriver(id, driver, aSupported);
+ }
+ }
+
+ /**
+ * Sets driver for all classes supported by driver.
+ *
+ * @param id Driver type id.
+ * @param driver A driver to be installed.
+ * @see #getDriver
+ */
+ public static void setDriver(String id, LightDriver driver) {
+ String[] supported = driver.getSupported();
+ for (String aSupported : supported) {
+ setDriver(id, driver, aSupported);
+ }
+ }
+
+ /**
+ * Removes driver for operator class.
+ *
+ * @param id Driver type to remove.
+ * @param operatorClass Class to remove driver for.
+ */
+ public static void removeDriver(String id, Class> operatorClass) {
+ JemmyProperties.
+ removeCurrentProperty(makeID(id, operatorClass));
+ if (Boolean.getBoolean(DRIVER_ID + "trace_output")) {
+ JemmyProperties.getCurrentOutput().printLine("Uninstalling a drifer for "
+ + operatorClass.getName()
+ + " operators.");
+ }
+ }
+
+ /**
+ * Removes driver for operator class.
+ *
+ * @param id Driver type to remove.
+ * @param operatorClassName A name of operator class.
+ */
+ public static void removeDriver(String id, String operatorClassName) {
+ JemmyProperties.
+ removeCurrentProperty(makeID(id, operatorClassName));
+ if (Boolean.getBoolean(DRIVER_ID + "trace_output")) {
+ JemmyProperties.getCurrentOutput().printLine("Uninstalling a drifer for "
+ + operatorClassName
+ + " operators.");
+ }
+ }
+
+ /**
+ * Removes driver for operator classes.
+ *
+ * @param id Driver type to remove.
+ * @param operatorClasses Classes to remove driver for.
+ */
+ public static void removeDriver(String id, Class>[] operatorClasses) {
+ for (Class> operatorClass : operatorClasses) {
+ removeDriver(id, operatorClass);
+ }
+ }
+
+ /**
+ * Removes driver for operator classes.
+ *
+ * @param id Driver type to remove.
+ * @param operatorClassNames Names of operator classes.
+ */
+ public static void removeDriver(String id, String[] operatorClassNames) {
+ for (String operatorClassName : operatorClassNames) {
+ removeDriver(id, operatorClassName);
+ }
+ }
+
+ /**
+ * Removes driver for all supported classes.
+ *
+ * @param id Driver type to remove.
+ */
+ public static void removeDrivers(String id) {
+ String[] keys = JemmyProperties.getCurrentKeys();
+ for (String key : keys) {
+ if (key.startsWith(id)) {
+ JemmyProperties.
+ removeCurrentProperty(key);
+ }
+ }
+ }
+
+ /**
+ * Returns {@code TREE_DRIVER_ID} driver.
+ *
+ * @param operatorClass Class to find driver for.
+ * @return a driver
+ * @see #setTreeDriver
+ */
+ public static TreeDriver getTreeDriver(Class> operatorClass) {
+ return (TreeDriver) getDriver(TREE_DRIVER_ID, operatorClass);
+ }
+
+ /**
+ * Returns {@code TREE_DRIVER_ID} driver.
+ *
+ * @param operator Operator to find driver for.
+ * @return a driver
+ * @see #setTreeDriver
+ */
+ public static TreeDriver getTreeDriver(ComponentOperator operator) {
+ return (TreeDriver) getDriver(TREE_DRIVER_ID, operator.getClass());
+ }
+
+ /**
+ * Defines {@code TREE_DRIVER_ID} driver.
+ *
+ * @param driver a driver
+ * @see #getTreeDriver
+ */
+ public static void setTreeDriver(TreeDriver driver) {
+ setDriver(TREE_DRIVER_ID, driver);
+ }
+
+ /**
+ * Returns {@code TEXT_DRIVER_ID} driver.
+ *
+ * @param operatorClass Class to find driver for.
+ * @return a driver
+ * @see #setTextDriver
+ */
+ public static TextDriver getTextDriver(Class> operatorClass) {
+ return (TextDriver) getDriver(TEXT_DRIVER_ID, operatorClass);
+ }
+
+ /**
+ * Returns {@code TEXT_DRIVER_ID} driver.
+ *
+ * @param operator Operator to find driver for.
+ * @return a driver
+ * @see #setTextDriver
+ */
+ public static TextDriver getTextDriver(ComponentOperator operator) {
+ return (TextDriver) getDriver(TEXT_DRIVER_ID, operator.getClass());
+ }
+
+ /**
+ * Defines {@code TEXT_DRIVER_ID} driver.
+ *
+ * @param driver a driver
+ * @see #getTextDriver
+ */
+ public static void setTextDriver(TextDriver driver) {
+ setDriver(TEXT_DRIVER_ID, driver);
+ }
+
+ /**
+ * Returns {@code KEY_DRIVER_ID} driver.
+ *
+ * @param operatorClass Class to find driver for.
+ * @return a driver
+ * @see #setKeyDriver
+ */
+ public static KeyDriver getKeyDriver(Class> operatorClass) {
+ return (KeyDriver) getDriver(KEY_DRIVER_ID, operatorClass);
+ }
+
+ /**
+ * Returns {@code KEY_DRIVER_ID} driver.
+ *
+ * @param operator Operator to find driver for.
+ * @return a driver
+ * @see #setKeyDriver
+ */
+ public static KeyDriver getKeyDriver(ComponentOperator operator) {
+ return (KeyDriver) getDriver(KEY_DRIVER_ID, operator.getClass());
+ }
+
+ /**
+ * Defines {@code KEY_DRIVER_ID} driver.
+ *
+ * @param driver a driver
+ * @see #getKeyDriver
+ */
+ public static void setKeyDriver(KeyDriver driver) {
+ setDriver(KEY_DRIVER_ID, driver);
+ }
+
+ /**
+ * Returns {@code MOUSE_DRIVER_ID} driver.
+ *
+ * @param operatorClass Class to find driver for.
+ * @return a driver
+ * @see #setMouseDriver
+ */
+ public static MouseDriver getMouseDriver(Class> operatorClass) {
+ return (MouseDriver) getDriver(MOUSE_DRIVER_ID, operatorClass);
+ }
+
+ /**
+ * Returns {@code MOUSE_DRIVER_ID} driver.
+ *
+ * @param operator Operator to find driver for.
+ * @return a driver
+ * @see #setMouseDriver
+ */
+ public static MouseDriver getMouseDriver(ComponentOperator operator) {
+ return (MouseDriver) getDriver(MOUSE_DRIVER_ID, operator.getClass());
+ }
+
+ /**
+ * Defines {@code MOUSE_DRIVER_ID} driver.
+ *
+ * @param driver a driver
+ * @see #getMouseDriver
+ */
+ public static void setMouseDriver(MouseDriver driver) {
+ setDriver(MOUSE_DRIVER_ID, driver);
+ }
+
+ /**
+ * Returns {@code SCROLL_DRIVER_ID} driver.
+ *
+ * @param operatorClass Class to find driver for.
+ * @return a driver
+ * @see #setScrollDriver
+ */
+ public static ScrollDriver getScrollDriver(Class> operatorClass) {
+ return (ScrollDriver) getDriver(SCROLL_DRIVER_ID, operatorClass);
+ }
+
+ /**
+ * Returns {@code SCROLL_DRIVER_ID} driver.
+ *
+ * @param operator Operator to find driver for.
+ * @return a driver
+ * @see #setScrollDriver
+ */
+ public static ScrollDriver getScrollDriver(ComponentOperator operator) {
+ return (ScrollDriver) getDriver(SCROLL_DRIVER_ID, operator.getClass());
+ }
+
+ /**
+ * Defines {@code SCROLL_DRIVER_ID} driver.
+ *
+ * @param driver a driver
+ * @see #getScrollDriver
+ */
+ public static void setScrollDriver(ScrollDriver driver) {
+ setDriver(SCROLL_DRIVER_ID, driver);
+ }
+
+ /**
+ * Returns {@code BUTTON_DRIVER_ID} driver.
+ *
+ * @param operatorClass Class to find driver for.
+ * @return a driver
+ * @see #setButtonDriver
+ */
+ public static ButtonDriver getButtonDriver(Class> operatorClass) {
+ return (ButtonDriver) getDriver(BUTTON_DRIVER_ID, operatorClass);
+ }
+
+ /**
+ * Returns {@code BUTTON_DRIVER_ID} driver.
+ *
+ * @param operator Operator to find driver for.
+ * @return a driver
+ * @see #setButtonDriver
+ */
+ public static ButtonDriver getButtonDriver(ComponentOperator operator) {
+ return (ButtonDriver) getDriver(BUTTON_DRIVER_ID, operator.getClass());
+ }
+
+ /**
+ * Defines {@code BUTTON_DRIVER_ID} driver.
+ *
+ * @param driver a driver
+ * @see #getButtonDriver
+ */
+ public static void setButtonDriver(ButtonDriver driver) {
+ setDriver(BUTTON_DRIVER_ID, driver);
+ }
+
+ /**
+ * Returns {@code LIST_DRIVER_ID} driver.
+ *
+ * @param operatorClass Class to find driver for.
+ * @return a driver
+ * @see #setListDriver
+ */
+ public static ListDriver getListDriver(Class> operatorClass) {
+ return (ListDriver) getDriver(LIST_DRIVER_ID, operatorClass);
+ }
+
+ /**
+ * Returns {@code LIST_DRIVER_ID} driver.
+ *
+ * @param operator Operator to find driver for.
+ * @return a driver
+ * @see #setListDriver
+ */
+ public static ListDriver getListDriver(ComponentOperator operator) {
+ return (ListDriver) getDriver(LIST_DRIVER_ID, operator.getClass());
+ }
+
+ /**
+ * Defines {@code LIST_DRIVER_ID} driver.
+ *
+ * @param driver a driver
+ * @see #getListDriver
+ */
+ public static void setListDriver(ListDriver driver) {
+ setDriver(LIST_DRIVER_ID, driver);
+ }
+
+ /**
+ * Returns {@code MULTISELLIST_DRIVER_ID} driver.
+ *
+ * @param operatorClass Class to find driver for.
+ * @return a driver
+ * @see #setMultiSelListDriver
+ */
+ public static MultiSelListDriver getMultiSelListDriver(Class> operatorClass) {
+ return (MultiSelListDriver) getDriver(MULTISELLIST_DRIVER_ID, operatorClass);
+ }
+
+ /**
+ * Returns {@code MULTISELLIST_DRIVER_ID} driver.
+ *
+ * @param operator Operator to find driver for.
+ * @return a driver
+ * @see #setMultiSelListDriver
+ */
+ public static MultiSelListDriver getMultiSelListDriver(ComponentOperator operator) {
+ return (MultiSelListDriver) getDriver(MULTISELLIST_DRIVER_ID, operator.getClass());
+ }
+
+ /**
+ * Defines {@code MULTISELLIST_DRIVER_ID} driver.
+ *
+ * @param driver a driver
+ * @see #getMultiSelListDriver
+ */
+ public static void setMultiSelListDriver(MultiSelListDriver driver) {
+ setDriver(MULTISELLIST_DRIVER_ID, driver);
+ }
+
+ /**
+ * Returns {@code ORDEREDLIST_DRIVER_ID} driver.
+ *
+ * @param operatorClass Class to find driver for.
+ * @return a driver
+ * @see #setOrderedListDriver
+ */
+ public static OrderedListDriver getOrderedListDriver(Class> operatorClass) {
+ return (OrderedListDriver) getDriver(ORDEREDLIST_DRIVER_ID, operatorClass);
+ }
+
+ /**
+ * Returns {@code ORDEREDLIST_DRIVER_ID} driver.
+ *
+ * @param operator Operator to find driver for.
+ * @return a driver
+ * @see #setOrderedListDriver
+ */
+ public static OrderedListDriver getOrderedListDriver(ComponentOperator operator) {
+ return (OrderedListDriver) getDriver(ORDEREDLIST_DRIVER_ID, operator.getClass());
+ }
+
+ /**
+ * Defines {@code ORDEREDLIST_DRIVER_ID} driver.
+ *
+ * @param driver a driver
+ * @see #getOrderedListDriver
+ */
+ public static void setOrderedListDriver(OrderedListDriver driver) {
+ setDriver(ORDEREDLIST_DRIVER_ID, driver);
+ }
+
+ /**
+ * Returns {@code TABLE_DRIVER_ID} driver.
+ *
+ * @param operatorClass Class to find driver for.
+ * @return a driver
+ * @see #setTableDriver
+ */
+ public static TableDriver getTableDriver(Class> operatorClass) {
+ return (TableDriver) getDriver(TABLE_DRIVER_ID, operatorClass);
+ }
+
+ /**
+ * Returns {@code TABLE_DRIVER_ID} driver.
+ *
+ * @param operator Operator to find driver for.
+ * @return a driver
+ * @see #setTableDriver
+ */
+ public static TableDriver getTableDriver(ComponentOperator operator) {
+ return (TableDriver) getDriver(TABLE_DRIVER_ID, operator.getClass());
+ }
+
+ /**
+ * Defines {@code TABLE_DRIVER_ID} driver.
+ *
+ * @param driver a driver
+ * @see #getTableDriver
+ */
+ public static void setTableDriver(TableDriver driver) {
+ setDriver(TABLE_DRIVER_ID, driver);
+ }
+
+ /**
+ * Returns {@code WINDOW_DRIVER_ID} driver.
+ *
+ * @param operatorClass Class to find driver for.
+ * @return a driver
+ * @see #setWindowDriver
+ */
+ public static WindowDriver getWindowDriver(Class> operatorClass) {
+ return (WindowDriver) getDriver(WINDOW_DRIVER_ID, operatorClass);
+ }
+
+ /**
+ * Returns {@code WINDOW_DRIVER_ID} driver.
+ *
+ * @param operator Operator to find driver for.
+ * @return a driver
+ * @see #setWindowDriver
+ */
+ public static WindowDriver getWindowDriver(ComponentOperator operator) {
+ return (WindowDriver) getDriver(WINDOW_DRIVER_ID, operator.getClass());
+ }
+
+ /**
+ * Defines {@code WINDOW_DRIVER_ID} driver.
+ *
+ * @param driver a driver
+ * @see #getWindowDriver
+ */
+ public static void setWindowDriver(WindowDriver driver) {
+ setDriver(WINDOW_DRIVER_ID, driver);
+ }
+
+ /**
+ * Returns {@code FRAME_DRIVER_ID} driver.
+ *
+ * @param operatorClass Class to find driver for.
+ * @return a driver
+ * @see #setFrameDriver
+ */
+ public static FrameDriver getFrameDriver(Class> operatorClass) {
+ return (FrameDriver) getDriver(FRAME_DRIVER_ID, operatorClass);
+ }
+
+ /**
+ * Returns {@code FRAME_DRIVER_ID} driver.
+ *
+ * @param operator Operator to find driver for.
+ * @return a driver
+ * @see #setFrameDriver
+ */
+ public static FrameDriver getFrameDriver(ComponentOperator operator) {
+ return (FrameDriver) getDriver(FRAME_DRIVER_ID, operator.getClass());
+ }
+
+ /**
+ * Defines {@code FRAME_DRIVER_ID} driver.
+ *
+ * @param driver a driver
+ * @see #getFrameDriver
+ */
+ public static void setFrameDriver(FrameDriver driver) {
+ setDriver(FRAME_DRIVER_ID, driver);
+ }
+
+ /**
+ * Returns {@code INTERNAL_FRAME_DRIVER_ID} driver.
+ *
+ * @param operatorClass Class to find driver for.
+ * @return a driver
+ * @see #setInternalFrameDriver
+ */
+ public static InternalFrameDriver getInternalFrameDriver(Class> operatorClass) {
+ return (InternalFrameDriver) getDriver(INTERNAL_FRAME_DRIVER_ID, operatorClass);
+ }
+
+ /**
+ * Returns {@code INTERNAL_FRAME_DRIVER_ID} driver.
+ *
+ * @param operator Operator to find driver for.
+ * @return a driver
+ * @see #setInternalFrameDriver
+ */
+ public static InternalFrameDriver getInternalFrameDriver(ComponentOperator operator) {
+ return (InternalFrameDriver) getDriver(INTERNAL_FRAME_DRIVER_ID, operator.getClass());
+ }
+
+ /**
+ * Defines {@code INTERNAL_FRAME_DRIVER_ID} driver.
+ *
+ * @param driver a driver
+ * @see #getInternalFrameDriver
+ */
+ public static void setInternalFrameDriver(InternalFrameDriver driver) {
+ setDriver(INTERNAL_FRAME_DRIVER_ID, driver);
+ }
+
+ /**
+ * Returns {@code FOCUS_DRIVER_ID} driver.
+ *
+ * @param operatorClass Class to find driver for.
+ * @return a driver
+ * @see #setFocusDriver
+ */
+ public static FocusDriver getFocusDriver(Class> operatorClass) {
+ return (FocusDriver) getDriver(FOCUS_DRIVER_ID, operatorClass);
+ }
+
+ /**
+ * Returns {@code FOCUS_DRIVER_ID} driver.
+ *
+ * @param operator Operator to find driver for.
+ * @return a driver
+ * @see #setFocusDriver
+ */
+ public static FocusDriver getFocusDriver(ComponentOperator operator) {
+ return (FocusDriver) getDriver(FOCUS_DRIVER_ID, operator.getClass());
+ }
+
+ /**
+ * Defines {@code FOCUS_DRIVER_ID} driver.
+ *
+ * @param driver a driver
+ * @see #getFocusDriver
+ */
+ public static void setFocusDriver(FocusDriver driver) {
+ setDriver(FOCUS_DRIVER_ID, driver);
+ }
+
+ /**
+ * Returns {@code MENU_DRIVER_ID} driver.
+ *
+ * @param operatorClass Class to find driver for.
+ * @return a driver
+ * @see #setMenuDriver
+ */
+ public static MenuDriver getMenuDriver(Class> operatorClass) {
+ return (MenuDriver) getDriver(MENU_DRIVER_ID, operatorClass);
+ }
+
+ /**
+ * Returns {@code MENU_DRIVER_ID} driver.
+ *
+ * @param operator Operator to find driver for.
+ * @return a driver
+ * @see #setMenuDriver
+ */
+ public static MenuDriver getMenuDriver(ComponentOperator operator) {
+ return (MenuDriver) getDriver(MENU_DRIVER_ID, operator.getClass());
+ }
+
+ /**
+ * Defines {@code MENU_DRIVER_ID} driver.
+ *
+ * @param driver a driver
+ * @see #getMenuDriver
+ */
+ public static void setMenuDriver(MenuDriver driver) {
+ setDriver(MENU_DRIVER_ID, driver);
+ }
+
+ static void setDriver(String id, Object driver) {
+ if (driver instanceof Driver) {
+ setDriver(id, (Driver) driver);
+ } else if (driver instanceof LightDriver) {
+ setDriver(id, (LightDriver) driver);
+ } else {
+ throw (new JemmyException("Driver is neither Driver nor LightDriver "
+ + driver.toString()));
+ }
+ }
+
+ //creates driver id
+ private static String makeID(String id, Class> operatorClass) {
+ return makeID(id, operatorClass.getName());
+ }
+
+ private static String makeID(String id, String operatorClassName) {
+ return id + "." + operatorClassName;
+ }
+
+ //returns a driver
+ private static Object getADriver(String id, Class> operatorClass, JemmyProperties props) {
+ Class> superClass = operatorClass;
+ Object drvr;
+ do {
+ drvr = props.
+ getProperty(makeID(id, superClass));
+ if (drvr != null) {
+ return drvr;
+ }
+ } while (ComponentOperator.class.
+ isAssignableFrom(superClass = superClass.getSuperclass()));
+ return null;
+ }
+
+ static {
+ new InputDriverInstaller().install();
+ new DefaultDriverInstaller().install();
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/EditorDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/EditorDriver.java
new file mode 100644
index 00000000000..852790d5d49
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/EditorDriver.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Interface of objects to be used for value changing (editing).
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public interface EditorDriver {
+
+ /**
+ * Changes value.
+ *
+ * @param oper Operator to change value for.
+ * @param newValue a new value.
+ */
+ public void enterNewValue(ComponentOperator oper, Object newValue);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/FocusDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/FocusDriver.java
new file mode 100644
index 00000000000..7f87905fb7f
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/FocusDriver.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Defines how to manage focus.
+ */
+public interface FocusDriver {
+
+ /**
+ * Makes a compoennt having focus.
+ *
+ * @param operator Component operator.
+ */
+ public void giveFocus(ComponentOperator operator);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/FrameDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/FrameDriver.java
new file mode 100644
index 00000000000..d0123d6bfb5
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/FrameDriver.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Defines how to work with frames.
+ */
+public interface FrameDriver {
+
+ /**
+ * Iconifies a frame.
+ *
+ * @param oper Frame operator.
+ */
+ public void iconify(ComponentOperator oper);
+
+ /**
+ * Deiconifies a frame.
+ *
+ * @param oper Frame operator.
+ */
+ public void deiconify(ComponentOperator oper);
+
+ /**
+ * Maximizes a frame.
+ *
+ * @param oper Frame operator.
+ */
+ public void maximize(ComponentOperator oper);
+
+ /**
+ * Demaximizes a frame.
+ *
+ * @param oper Frame operator.
+ */
+ public void demaximize(ComponentOperator oper);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/InputDriverInstaller.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/InputDriverInstaller.java
new file mode 100644
index 00000000000..c42d8d0bb83
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/InputDriverInstaller.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.EventDispatcher;
+import org.netbeans.jemmy.JemmyException;
+import org.netbeans.jemmy.JemmyProperties;
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.input.KeyEventDriver;
+import org.netbeans.jemmy.drivers.input.KeyRobotDriver;
+import org.netbeans.jemmy.drivers.input.MouseEventDriver;
+import org.netbeans.jemmy.drivers.input.MouseRobotDriver;
+
+/**
+ * Installs drivers for low-level drivers.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class InputDriverInstaller {
+
+ Timeout robotAutoDelay;
+ boolean useEventDrivers;
+ boolean smooth = false;
+
+ /**
+ * Constructs an InputDriverInstaller object.
+ *
+ * @param useEventDrivers Tells whether to use event drivers, otherwise
+ * robot drivers.
+ * @param robotAutoDelay Time for {@code Robot.setAutoDelay(long)}
+ * method.
+ */
+ public InputDriverInstaller(boolean useEventDrivers, Timeout robotAutoDelay) {
+ this.robotAutoDelay = robotAutoDelay;
+ this.useEventDrivers = useEventDrivers;
+ }
+
+ /**
+ * Constructs an InputDriverInstaller object. Takes autodelay time from
+ * JemmyProperties' timeouts.
+ *
+ * @param useEventDrivers Tells whether to use event drivers, otherwise
+ * robot drivers.
+ */
+ public InputDriverInstaller(boolean useEventDrivers) {
+ this(useEventDrivers,
+ JemmyProperties.getCurrentTimeouts().
+ create("EventDispatcher.RobotAutoDelay"));
+ }
+
+ /**
+ * Constructs an InputDriverInstaller object. Takes autodelay time from
+ * JemmyProperties' timeouts.
+ *
+ * @param useEventDrivers Tells whether to use event drivers, otherwise
+ * robot drivers.
+ * @param smooth whether to move mouse smoothly.
+ */
+ public InputDriverInstaller(boolean useEventDrivers, boolean smooth) {
+ this(useEventDrivers);
+ this.smooth = smooth;
+ }
+
+ /**
+ * Constructs an InputDriverInstaller object. Uses event drivers.
+ *
+ * @param robotAutoDelay Time for {@code Robot.setAutoDelay(long)}
+ * method.
+ */
+ public InputDriverInstaller(Timeout robotAutoDelay) {
+ this(true,
+ robotAutoDelay);
+ }
+
+ /**
+ * Constructs an InputDriverInstaller object. Takes autodelay time from
+ * JemmyProperties' timeouts. Uses event drivers.
+ */
+ public InputDriverInstaller() {
+ this(true);
+ }
+
+ static {
+ EventDispatcher.performInit();
+ }
+
+ /**
+ * Installs input drivers.
+ */
+ public void install() {
+ if (useEventDrivers) {
+ LightDriver keyE = new KeyEventDriver();
+ LightDriver mouseE = new MouseEventDriver();
+ DriverManager.removeDriver(DriverManager.KEY_DRIVER_ID,
+ keyE.getSupported());
+ DriverManager.removeDriver(DriverManager.MOUSE_DRIVER_ID,
+ mouseE.getSupported());
+ DriverManager.setDriver(DriverManager.KEY_DRIVER_ID, keyE);
+ DriverManager.setDriver(DriverManager.MOUSE_DRIVER_ID, mouseE);
+ try {
+ String[] awtOperators
+ = {
+ "org.netbeans.jemmy.operators.ButtonOperator",
+ "org.netbeans.jemmy.operators.CheckboxOperator",
+ "org.netbeans.jemmy.operators.ChoiceOperator",
+ "org.netbeans.jemmy.operators.LabelOperator",
+ "org.netbeans.jemmy.operators.ListOperator",
+ "org.netbeans.jemmy.operators.ScrollPaneOperator",
+ "org.netbeans.jemmy.operators.ScrollbarOperator",
+ "org.netbeans.jemmy.operators.TextAreaOperator",
+ "org.netbeans.jemmy.operators.TextComponentOperator",
+ "org.netbeans.jemmy.operators.TextFieldOperator"
+ };
+ LightDriver keyR = new KeyRobotDriver(robotAutoDelay, awtOperators);
+ LightDriver mouseR = new MouseRobotDriver(robotAutoDelay, awtOperators);
+ DriverManager.removeDriver(DriverManager.KEY_DRIVER_ID,
+ keyR.getSupported());
+ DriverManager.removeDriver(DriverManager.MOUSE_DRIVER_ID,
+ mouseR.getSupported());
+ DriverManager.setDriver(DriverManager.KEY_DRIVER_ID, keyR);
+ DriverManager.setDriver(DriverManager.MOUSE_DRIVER_ID, mouseR);
+ } catch (JemmyException e) {
+ if (!(e.getInnerThrowable() instanceof ClassNotFoundException)) {
+ throw (e);
+ }
+ }
+ } else {
+ LightDriver keyR = new KeyRobotDriver(robotAutoDelay);
+ LightDriver mouseR = new MouseRobotDriver(robotAutoDelay, smooth);
+ DriverManager.removeDriver(DriverManager.KEY_DRIVER_ID,
+ keyR.getSupported());
+ DriverManager.removeDriver(DriverManager.MOUSE_DRIVER_ID,
+ mouseR.getSupported());
+ DriverManager.setDriver(DriverManager.KEY_DRIVER_ID, keyR);
+ DriverManager.setDriver(DriverManager.MOUSE_DRIVER_ID, mouseR);
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/InternalFrameDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/InternalFrameDriver.java
new file mode 100644
index 00000000000..cc297809e45
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/InternalFrameDriver.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import java.awt.Component;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Defines the way to get a title pane.
+ */
+public interface InternalFrameDriver {
+
+ /**
+ * Returns the title pane component.
+ *
+ * @param oper operator for an internal frame.
+ * @return a component - title pane.
+ */
+ public Component getTitlePane(ComponentOperator oper);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/KeyDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/KeyDriver.java
new file mode 100644
index 00000000000..f006050efe7
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/KeyDriver.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Defines how to simulate keyboard operations.
+ */
+public interface KeyDriver {
+
+ /**
+ * Presses a key.
+ *
+ * @param oper Component operator.
+ * @param keyCode Key code ({@code KeyEvent.VK_*} value)
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ */
+ public void pressKey(ComponentOperator oper, int keyCode, int modifiers);
+
+ /**
+ * Typed a key.
+ *
+ * @param oper Component operator.
+ * @param keyChar Symbol to be typed.
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ */
+ public void typedKey(ComponentOperator oper, int keyCode, char keyChar, int modifiers);
+
+ /**
+ * Releases a key.
+ *
+ * @param oper Component operator.
+ * @param keyCode Key code ({@code KeyEvent.VK_*} value)
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ */
+ public void releaseKey(ComponentOperator oper, int keyCode, int modifiers);
+
+ /**
+ * Pushes a key.
+ *
+ * @param oper Component operator.
+ * @param keyCode Key code ({@code KeyEvent.VK_*} value)
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ * @param pushTime Time between pressing and releasing.
+ */
+ public void pushKey(ComponentOperator oper, int keyCode, int modifiers, Timeout pushTime);
+
+ /**
+ * Types a symbol.
+ *
+ * @param oper Component operator.
+ * @param keyCode Key code ({@code KeyEvent.VK_*} value)
+ * @param keyChar Symbol to be typed.
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ * @param pushTime Time between pressing and releasing.
+ */
+ public void typeKey(ComponentOperator oper, int keyCode, char keyChar, int modifiers, Timeout pushTime);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/LightDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/LightDriver.java
new file mode 100644
index 00000000000..9e39c72ae36
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/LightDriver.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+/**
+ * Implements "light" model of driver because does not require to load classes
+ * for all supported operator types.
+ *
+ * @see Driver
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface LightDriver {
+
+ /**
+ * Returns array of operator classes which are supported by this driver.
+ *
+ * @return an array of supported operator classes' names.
+ */
+ public String[] getSupported();
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/LightSupportiveDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/LightSupportiveDriver.java
new file mode 100644
index 00000000000..06c2d737de7
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/LightSupportiveDriver.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Allows to declare supported operator classes.
+ */
+abstract public class LightSupportiveDriver implements LightDriver {
+
+ private String[] supported;
+
+ /**
+ * Creates an instance.
+ *
+ * @param supported Array of operator classes which are supported by this
+ * driver.
+ */
+ public LightSupportiveDriver(String[] supported) {
+ this.supported = supported;
+ }
+
+ /**
+ * Throws {@code UnsupportedOperatorException} exception if parameter's
+ * class is not in list of supported classes.
+ *
+ * @param oper Operator whose class should be checked.
+ * @throws UnsupportedOperatorException
+ */
+ public void checkSupported(ComponentOperator oper) {
+ UnsupportedOperatorException.checkSupported(getClass(), supported, oper.getClass());
+ }
+
+ /**
+ * Returns array of operator classes which are supported by this driver.
+ */
+ @Override
+ public String[] getSupported() {
+ return supported;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/ListDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/ListDriver.java
new file mode 100644
index 00000000000..609ee44765b
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/ListDriver.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Defines how to work with lists.
+ */
+public interface ListDriver {
+
+ /**
+ * Selects an item.
+ *
+ * @param oper List operator.
+ * @param index Item index.
+ */
+ public void selectItem(ComponentOperator oper, int index);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/MenuDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/MenuDriver.java
new file mode 100644
index 00000000000..b006a9ab48b
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/MenuDriver.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Defines how to work with menus.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface MenuDriver {
+
+ /**
+ * Pushes menu.
+ *
+ * @param oper Menu operator.
+ * @param chooser Object defining menupath.
+ * @return a result of menu pushing. It could be last pushed menuitem or
+ * anything else.
+ */
+ public Object pushMenu(ComponentOperator oper, PathChooser chooser);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/MouseDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/MouseDriver.java
new file mode 100644
index 00000000000..94738edac8a
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/MouseDriver.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Defines how to simulate mouse operations.
+ */
+public interface MouseDriver {
+
+ /**
+ * Presses mouse.
+ *
+ * @param oper Component operator.
+ * @param x Relative x coordinate.
+ * @param y Relative y coordinate.
+ * @param mouseButton mouse button ({@code InputEvent.BUTTON*_MASK}
+ * field)
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ */
+ public void pressMouse(ComponentOperator oper, int x, int y, int mouseButton, int modifiers);
+
+ /**
+ * Releases mouse.
+ *
+ * @param oper Component operator.
+ * @param x Relative x coordinate.
+ * @param y Relative y coordinate.
+ * @param mouseButton mouse button ({@code InputEvent.BUTTON*_MASK}
+ * field)
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ */
+ public void releaseMouse(ComponentOperator oper, int x, int y, int mouseButton, int modifiers);
+
+ /**
+ * Clicks mouse.
+ *
+ * @param oper Component operator.
+ * @param x Relative x coordinate.
+ * @param y Relative y coordinate.
+ * @param clickCount How many times to click.
+ * @param mouseButton mouse button ({@code InputEvent.BUTTON*_MASK}
+ * field)
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ * @param mouseClick Time between pressing and releasing mouse.
+ */
+ public void clickMouse(ComponentOperator oper, int x, int y, int clickCount, int mouseButton,
+ int modifiers, Timeout mouseClick);
+
+ /**
+ * Moves mouse.
+ *
+ * @param oper Component operator.
+ * @param x Relative x coordinate.
+ * @param y Relative y coordinate.
+ */
+ public void moveMouse(ComponentOperator oper, int x, int y);
+
+ /**
+ * Drags mouse.
+ *
+ * @param oper Component operator.
+ * @param x Relative x coordinate.
+ * @param y Relative y coordinate.
+ * @param mouseButton mouse button ({@code InputEvent.BUTTON*_MASK}
+ * field)
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ */
+ public void dragMouse(ComponentOperator oper, int x, int y, int mouseButton, int modifiers);
+
+ /**
+ * Performs drag'n'drop.
+ *
+ * @param oper Component operator.
+ * @param start_x Relative x coordinate of start point.
+ * @param start_y Relative y coordinate of start point.
+ * @param end_x Relative x coordinate of end point.
+ * @param end_y Relative y coordinate of end point.
+ * @param mouseButton mouse button ({@code InputEvent.BUTTON*_MASK}
+ * field)
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ * @param before Time to sleep after taking (before dragging)
+ * @param after Time to sleep before dropping (after dragging)
+ */
+ public void dragNDrop(ComponentOperator oper, int start_x, int start_y, int end_x, int end_y,
+ int mouseButton, int modifiers, Timeout before, Timeout after);
+
+ /**
+ * Moves mouse inside a component.
+ *
+ * @param oper Component operator.
+ */
+ public void enterMouse(ComponentOperator oper);
+
+ /**
+ * Moves mouse outside a component.
+ *
+ * @param oper Component operator.
+ */
+ public void exitMouse(ComponentOperator oper);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/MultiSelListDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/MultiSelListDriver.java
new file mode 100644
index 00000000000..eea518aa68a
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/MultiSelListDriver.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Defines how to work with lists allowing multiple selection.
+ */
+public interface MultiSelListDriver extends ListDriver {
+
+ /**
+ * Selects some items.
+ *
+ * @param oper List operator.
+ * @param indices Item indices.
+ */
+ public void selectItems(ComponentOperator oper, int[] indices);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/OrderedListDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/OrderedListDriver.java
new file mode 100644
index 00000000000..db80dfa2687
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/OrderedListDriver.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Defines how to work with lists allowing items reordering.
+ */
+public interface OrderedListDriver extends MultiSelListDriver {
+
+ /**
+ * Changes item index.
+ *
+ * @param oper List operator.
+ * @param itemIndex Current item index.
+ * @param newIndex Ne witem index.
+ */
+ public void moveItem(ComponentOperator oper, int itemIndex, int newIndex);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/PathChooser.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/PathChooser.java
new file mode 100644
index 00000000000..876457f835c
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/PathChooser.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+/**
+ * Specifies an interface for objects defining path searching criteria.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public interface PathChooser {
+
+ /**
+ * Checks if {@code depth}'th path components fits the requirements.
+ *
+ * @param depth A depth of the component.
+ * @param component A path component to be checked.
+ * @return true if the component fits the requirements.
+ */
+ public boolean checkPathComponent(int depth, Object component);
+
+ /**
+ * Return requiered depth of the path.
+ *
+ * @return depth.
+ */
+ public int getDepth();
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/ScrollDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/ScrollDriver.java
new file mode 100644
index 00000000000..dfbcf057255
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/ScrollDriver.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.drivers.scrolling.ScrollAdjuster;
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Defines how to work with scrollable components such as
+ * {@code javax.swing.JScrollBar}, {@code javax.swing.JScrollPane},
+ * {@code javax.swing.JSlider}, ...
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface ScrollDriver {
+
+ /**
+ * Changes value to a minimum.
+ *
+ * @param oper Scroller operator.
+ * @param orientation {@code java.awt.Adjustable.HORIZONTAL} or
+ * {@code java.awt.Adjustable.VERTICAL}
+ */
+ public void scrollToMinimum(ComponentOperator oper, int orientation);
+
+ /**
+ * Changes value to a maximum.
+ *
+ * @param oper Scroller operator.
+ * @param orientation {@code java.awt.Adjustable.HORIZONTAL} or
+ * {@code java.awt.Adjustable.VERTICAL}
+ */
+ public void scrollToMaximum(ComponentOperator oper, int orientation);
+
+ /**
+ * Changes value.
+ *
+ * @param oper Scroller operator.
+ * @param adj Object defines scroll position.
+ */
+ public void scroll(ComponentOperator oper, ScrollAdjuster adj);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/SupportiveDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/SupportiveDriver.java
new file mode 100644
index 00000000000..cc4ae68a165
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/SupportiveDriver.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Allows to declare supported operator classes.
+ */
+abstract public class SupportiveDriver implements Driver {
+
+ private Class>[] supported;
+
+ /**
+ * Creates an instance.
+ *
+ * @param supported Array of operator classes which are supported by this
+ * driver.
+ */
+ public SupportiveDriver(Class>[] supported) {
+ this.supported = supported;
+ }
+
+ /**
+ * Throws {@code UnsupportedOperatorException} exception if parameter's
+ * class is not in list of supported classes.
+ *
+ * @param oper Operator whose class should be checked.
+ * @throws UnsupportedOperatorException
+ */
+ public void checkSupported(ComponentOperator oper) {
+ UnsupportedOperatorException.checkSupported(getClass(), supported, oper.getClass());
+ }
+
+ /**
+ * Returns array of operator classes which are supported by this driver.
+ */
+ @Override
+ public Class>[] getSupported() {
+ return supported;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/TableDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/TableDriver.java
new file mode 100644
index 00000000000..5243666abdb
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/TableDriver.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Defines how to work with tables.
+ */
+public interface TableDriver {
+
+ /**
+ * Selects a cell.
+ *
+ * @param oper Table operator.
+ * @param row Cell row index.
+ * @param column Cell column index.
+ */
+ public void selectCell(ComponentOperator oper, int row, int column);
+
+ /**
+ * Edits a cell.
+ *
+ * @param oper Table operator.
+ * @param row Cell row index.
+ * @param column Cell column index.
+ * @param value New value.
+ */
+ public void editCell(ComponentOperator oper, int row, int column, Object value);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/TextDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/TextDriver.java
new file mode 100644
index 00000000000..7866072fb75
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/TextDriver.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Defines how to work with text components.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface TextDriver {
+
+ /**
+ * Moves caret.
+ *
+ * @param oper Text component operator.
+ * @param position Position to move caret to.
+ */
+ public void changeCaretPosition(ComponentOperator oper, int position);
+
+ /**
+ * Selects text.
+ *
+ * @param oper Text component operator.
+ * @param startPosition a posistion of selction start
+ * @param finalPosition a posistion of selction end
+ */
+ public void selectText(ComponentOperator oper, int startPosition, int finalPosition);
+
+ /**
+ * Clears component text.
+ *
+ * @param oper Text component operator.
+ */
+ public void clearText(ComponentOperator oper);
+
+ /**
+ * Types new text.
+ *
+ * @param oper Text component operator.
+ * @param text New text to type.
+ * @param caretPosition Type text at that position.
+ */
+ public void typeText(ComponentOperator oper, String text, int caretPosition);
+
+ /**
+ * Replace component text.
+ *
+ * @param oper Text component operator.
+ * @param text New text to type.
+ */
+ public void changeText(ComponentOperator oper, String text);
+
+ /**
+ * Type text and push enter.
+ *
+ * @param oper Text component operator.
+ * @param text New text to type.
+ */
+ public void enterText(ComponentOperator oper, String text);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/TreeDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/TreeDriver.java
new file mode 100644
index 00000000000..fdb90c27d48
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/TreeDriver.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Defines how to work with trees.
+ */
+public interface TreeDriver extends MultiSelListDriver {
+
+ /**
+ * Expandes a node.
+ *
+ * @param oper Tree operator.
+ * @param index Node index.
+ */
+ public void expandItem(ComponentOperator oper, int index);
+
+ /**
+ * Collapses a node.
+ *
+ * @param oper Tree operator.
+ * @param index Node index.
+ */
+ public void collapseItem(ComponentOperator oper, int index);
+
+ /**
+ * Edits a node.
+ *
+ * @param oper Tree operator.
+ * @param index Node index.
+ * @param newValue New node value
+ * @param waitEditorTime Time to wait node editor.
+ */
+ public void editItem(ComponentOperator oper, int index, Object newValue, Timeout waitEditorTime);
+
+ /**
+ * Starts node editing.
+ *
+ * @param oper Tree operator.
+ * @param index Node index.
+ * @param waitEditorTime Time to wait node editor.
+ */
+ public void startEditing(ComponentOperator oper, int index, Timeout waitEditorTime);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/UnsupportedOperatorException.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/UnsupportedOperatorException.java
new file mode 100644
index 00000000000..31522d0ebd7
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/UnsupportedOperatorException.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.JemmyException;
+
+/**
+ * Is thrown as a result of attempt to use driver for unsupported operator type.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class UnsupportedOperatorException extends JemmyException {
+
+ private static final long serialVersionUID = 42L;
+
+ /**
+ * Constructor.
+ *
+ * @param driver a driver
+ * @param operator an operator
+ */
+ public UnsupportedOperatorException(Class> driver, Class> operator) {
+ super(driver.getName() + " operators are not supported by "
+ + operator.getName() + " driver!");
+ }
+
+ /**
+ * Checks if operator class is in the list of supported classes.
+ *
+ * @param driver Driver class
+ * @param supported Supported classes.
+ * @param operator Operator class.
+ * @throws UnsupportedOperatorException if class is not supported.
+ */
+ public static void checkSupported(Class> driver, Class>[] supported, Class> operator) {
+ for (Class> aSupported : supported) {
+ if (aSupported.isAssignableFrom(operator)) {
+ return;
+ }
+ }
+ throw (new UnsupportedOperatorException(driver, operator));
+ }
+
+ /**
+ * Checks if operator class name is in the list of supported classes names.
+ *
+ * @param driver Driver class
+ * @param supported Supported classes names.
+ * @param operator Operator class.
+ * @throws UnsupportedOperatorException if class is not supported.
+ */
+ public static void checkSupported(Class> driver, String[] supported, Class> operator) {
+ Class> opClass = operator;
+ do {
+ for (String aSupported : supported) {
+ if (opClass.getName().equals(aSupported)) {
+ return;
+ }
+ }
+ } while ((opClass = opClass.getSuperclass()) != null);
+ throw (new UnsupportedOperatorException(driver, operator));
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/WindowDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/WindowDriver.java
new file mode 100644
index 00000000000..1f554c68127
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/WindowDriver.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Defines how to work with windows.
+ */
+public interface WindowDriver {
+
+ /**
+ * Activates a window.
+ *
+ * @param oper Window operator.
+ */
+ public void activate(ComponentOperator oper);
+
+ /**
+ * Requests a window to close.
+ *
+ * @param oper Window operator.
+ */
+ public void requestClose(ComponentOperator oper);
+
+ /**
+ * Closes a window by requesting it to close and then hiding it.
+ *
+ * @param oper Window operator.
+ */
+ public void requestCloseAndThenHide(ComponentOperator oper);
+
+ /**
+ * Closes a window by requesting it to close and then hiding it.
+ *
+ * @param oper Window operator.
+ * @deprecated Use requestClose(ComponentOperator) instead.
+ */
+ @Deprecated
+ public void close(ComponentOperator oper);
+
+ /**
+ * Change window location.
+ *
+ * @param oper Window operator.
+ * @param x New x coordinate
+ * @param y New y coordinate
+ */
+ public void move(ComponentOperator oper, int x, int y);
+
+ /**
+ * Change window size.
+ *
+ * @param oper Window operator.
+ * @param width New window width.
+ * @param height New window height.
+ */
+ public void resize(ComponentOperator oper, int width, int height);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/buttons/ButtonMouseDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/buttons/ButtonMouseDriver.java
new file mode 100644
index 00000000000..e546665face
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/buttons/ButtonMouseDriver.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.buttons;
+
+import org.netbeans.jemmy.drivers.ButtonDriver;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.MouseDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.Operator;
+
+/**
+ * Driver to push a button by mouse click.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class ButtonMouseDriver extends LightSupportiveDriver implements ButtonDriver {
+
+ public ButtonMouseDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.ComponentOperator"});
+ }
+
+ @Override
+ public void press(ComponentOperator oper) {
+ MouseDriver mdriver = DriverManager.getMouseDriver(oper);
+ mdriver.moveMouse(oper,
+ oper.getCenterXForClick(),
+ oper.getCenterYForClick());
+ mdriver.pressMouse(oper,
+ oper.getCenterXForClick(),
+ oper.getCenterYForClick(),
+ Operator.getDefaultMouseButton(),
+ 0);
+ }
+
+ @Override
+ public void release(ComponentOperator oper) {
+ DriverManager.
+ getMouseDriver(oper).
+ releaseMouse(oper,
+ oper.getCenterXForClick(),
+ oper.getCenterYForClick(),
+ Operator.getDefaultMouseButton(),
+ 0);
+ }
+
+ @Override
+ public void push(ComponentOperator oper) {
+ DriverManager.
+ getMouseDriver(oper).
+ clickMouse(oper,
+ oper.getCenterXForClick(),
+ oper.getCenterYForClick(),
+ 1,
+ Operator.getDefaultMouseButton(),
+ 0,
+ oper.getTimeouts().
+ create("ComponentOperator.MouseClickTimeout"));
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/buttons/package-info.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/buttons/package-info.java
new file mode 100644
index 00000000000..f937529f082
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/buttons/package-info.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ *
Button drivers
+ * Different drivers to push a button.
+ *
+ * @since 4/17/2002
+ *
+ */
+package org.netbeans.jemmy.drivers.buttons;
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/focus/APIFocusDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/focus/APIFocusDriver.java
new file mode 100644
index 00000000000..4f76f0731e1
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/focus/APIFocusDriver.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.focus;
+
+import java.awt.event.FocusEvent;
+
+import org.netbeans.jemmy.drivers.FocusDriver;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.input.EventDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+public class APIFocusDriver extends LightSupportiveDriver implements FocusDriver {
+
+ EventDriver eDriver;
+
+ public APIFocusDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.ComponentOperator"});
+ eDriver = new EventDriver();
+ }
+
+ @Override
+ public void giveFocus(ComponentOperator operator) {
+ operator.requestFocus();
+ eDriver.dispatchEvent(operator.getSource(),
+ new FocusEvent(operator.getSource(),
+ FocusEvent.FOCUS_GAINED));
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/focus/MouseFocusDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/focus/MouseFocusDriver.java
new file mode 100644
index 00000000000..4eb21fd704d
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/focus/MouseFocusDriver.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.focus;
+
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.FocusDriver;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.Operator;
+
+public class MouseFocusDriver extends LightSupportiveDriver implements FocusDriver {
+
+ private QueueTool queueTool;
+
+ public MouseFocusDriver() {
+ super(new String[]{
+ "org.netbeans.jemmy.operators.JListOperator",
+ "org.netbeans.jemmy.operators.JScrollBarOperator",
+ "org.netbeans.jemmy.operators.JSliderOperator",
+ "org.netbeans.jemmy.operators.JTableOperator",
+ "org.netbeans.jemmy.operators.JTextComponentOperator",
+ "org.netbeans.jemmy.operators.JTreeOperator",
+ "org.netbeans.jemmy.operators.ListOperator",
+ "org.netbeans.jemmy.operators.ScrollbarOperator",
+ "org.netbeans.jemmy.operators.TextAreaOperator",
+ "org.netbeans.jemmy.operators.TextComponentOperator",
+ "org.netbeans.jemmy.operators.TextFieldOperator"});
+ queueTool = new QueueTool();
+ }
+
+ @Override
+ public void giveFocus(final ComponentOperator oper) {
+ if (!oper.hasFocus()) {
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Mouse click to get focus") {
+ @Override
+ public Void launch() {
+ DriverManager.getMouseDriver(oper).
+ clickMouse(oper, oper.getCenterXForClick(), oper.getCenterYForClick(),
+ 1, Operator.getDefaultMouseButton(), 0,
+ oper.getTimeouts().create("ComponentOperator.MouseClickTimeout"));
+ return null;
+ }
+ });
+ oper.waitHasFocus();
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/focus/package-info.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/focus/package-info.java
new file mode 100644
index 00000000000..71f9b43be6a
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/focus/package-info.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ *
Focus drivers.
+ * Different drivers to give input focus to a component.
+ *
+ */
+package org.netbeans.jemmy.drivers.focus;
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/EventDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/EventDriver.java
new file mode 100644
index 00000000000..b88b6c0b5f4
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/EventDriver.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.input;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+
+import org.netbeans.jemmy.ComponentIsNotVisibleException;
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+
+/**
+ * Superclass for all drivers using event dispatching.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class EventDriver extends LightSupportiveDriver {
+
+ /**
+ * Constructs an EventDriver object.
+ *
+ * @param supported an array of supported class names
+ */
+ public EventDriver(String[] supported) {
+ super(supported);
+ }
+
+ /**
+ * Constructs an EventDriver object suporting ComponentOperator.
+ */
+ public EventDriver() {
+ this(new String[]{"org.netbeans.jemmy.operators.ComponentOperator"});
+ }
+
+ /**
+ * Dispatches an event to the component.
+ *
+ * @param comp Component to dispatch events to.
+ * @param event an event to dispatch.
+ */
+ public void dispatchEvent(Component comp, AWTEvent event) {
+// checkVisibility(comp);
+ QueueTool.processEvent(event);
+ }
+
+ /**
+ * Checks component visibility.
+ *
+ * @param component a component.
+ */
+ protected void checkVisibility(Component component) {
+ if (!component.isVisible()) {
+ throw (new ComponentIsNotVisibleException(component));
+ }
+ }
+
+ /**
+ * Class used fot execution of an event through the dispatching thread.
+ */
+ protected class Dispatcher extends QueueTool.QueueAction {
+
+ AWTEvent event;
+ Component component;
+
+ /**
+ * Constructs an EventDriver$Dispatcher object.
+ *
+ * @param component a component to dispatch event to.
+ * @param e an event to dispatch.
+ */
+ public Dispatcher(Component component, AWTEvent e) {
+ super(e.getClass().getName() + " event dispatching");
+ this.component = component;
+ event = e;
+ }
+
+ @Override
+ public Void launch() {
+ checkVisibility(component);
+ component.dispatchEvent(event);
+ return null;
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/KeyEventDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/KeyEventDriver.java
new file mode 100644
index 00000000000..ef6976f9106
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/KeyEventDriver.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.input;
+
+import java.awt.Component;
+import java.awt.event.KeyEvent;
+
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.KeyDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * KeyDriver using event dispatching.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class KeyEventDriver extends EventDriver implements KeyDriver {
+
+ /**
+ * Constructs a KeyEventDriver object.
+ *
+ * @param supported an array of supported class names
+ */
+ public KeyEventDriver(String[] supported) {
+ super(supported);
+ }
+
+ /**
+ * Constructs an KeyEventDriver object suporting ComponentOperator.
+ */
+ public KeyEventDriver() {
+ super();
+ }
+
+ @Override
+ public void pressKey(ComponentOperator oper, int keyCode, int modifiers) {
+ pressKey(findNativeParent(oper.getSource()), keyCode, modifiers);
+ }
+
+ @Override
+ public void typedKey(ComponentOperator oper, int keyCode, char keyChar, int modifiers) {
+ typedKey(findNativeParent(oper.getSource()), keyChar, modifiers);
+ }
+
+ @Override
+ public void releaseKey(ComponentOperator oper, int keyCode, int modifiers) {
+ releaseKey(findNativeParent(oper.getSource()), keyCode, modifiers);
+ }
+
+ @Override
+ public void pushKey(ComponentOperator oper, int keyCode, int modifiers, Timeout pushTime) {
+ Component nativeContainer = findNativeParent(oper.getSource());
+ pressKey(nativeContainer, keyCode, modifiers);
+ pushTime.sleep();
+ releaseKey(nativeContainer, keyCode, modifiers);
+ }
+
+ @Override
+ public void typeKey(ComponentOperator oper, int keyCode, char keyChar, int modifiers, Timeout pushTime) {
+ Component nativeContainer = findNativeParent(oper.getSource());
+ pressKey(nativeContainer, keyCode, modifiers);
+ pushTime.sleep();
+ typedKey(nativeContainer, keyChar, modifiers);
+ releaseKey(nativeContainer, keyCode, modifiers);
+ }
+
+ @Deprecated
+ private void pressKey(Component nativeContainer, int keyCode, int modifiers) {
+ dispatchEvent(nativeContainer,
+ new KeyEvent(nativeContainer,
+ KeyEvent.KEY_PRESSED,
+ System.currentTimeMillis(),
+ modifiers, keyCode));
+ }
+
+ private void typedKey(Component nativeContainer, char keyChar, int modifiers) {
+ dispatchEvent(nativeContainer,
+ new KeyEvent(nativeContainer,
+ KeyEvent.KEY_TYPED,
+ System.currentTimeMillis(),
+ modifiers, KeyEvent.VK_UNDEFINED, keyChar));
+ }
+
+ @Deprecated
+ private void releaseKey(Component nativeContainer, int keyCode, int modifiers) {
+ dispatchEvent(nativeContainer,
+ new KeyEvent(nativeContainer,
+ KeyEvent.KEY_RELEASED,
+ System.currentTimeMillis(),
+ modifiers, keyCode));
+ }
+
+ private Component findNativeParent(Component source) {
+ Component nativeOne = source;
+ while (nativeOne != null) {
+ if (!nativeOne.isLightweight()) {
+ return nativeOne;
+ }
+ nativeOne = nativeOne.getParent();
+ }
+ return source;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/KeyRobotDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/KeyRobotDriver.java
new file mode 100644
index 00000000000..63d75f4bd8e
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/KeyRobotDriver.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.input;
+
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.KeyDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * KeyDriver using robot operations.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class KeyRobotDriver extends RobotDriver implements KeyDriver {
+
+ /**
+ * Constructs a KeyRobotDriver object.
+ *
+ * @param autoDelay Time for {@code Robot.setAutoDelay(long)} method.
+ */
+ public KeyRobotDriver(Timeout autoDelay) {
+ super(autoDelay);
+ }
+
+ /**
+ * Constructs a KeyRobotDriver object.
+ *
+ * @param autoDelay Time for {@code Robot.setAutoDelay(long)} method.
+ * @param supported an array of supported class names
+ */
+ public KeyRobotDriver(Timeout autoDelay, String[] supported) {
+ super(autoDelay, supported);
+ }
+
+ @Override
+ public void pushKey(ComponentOperator oper, int keyCode, int modifiers, Timeout pushTime) {
+ pressKey(oper, keyCode, modifiers);
+ pushTime.sleep();
+ releaseKey(oper, keyCode, modifiers);
+ }
+
+ @Override
+ public void typeKey(ComponentOperator oper, int keyCode, char keyChar, int modifiers, Timeout pushTime) {
+ pushKey(oper, keyCode, modifiers, pushTime);
+ }
+
+ /**
+ * Presses a key.
+ *
+ * @param oper Operator to press a key on.
+ * @param keyCode Key code ({@code KeyEventVK_*} field.
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ */
+ @Override
+ public void pressKey(ComponentOperator oper, int keyCode, int modifiers) {
+ pressKey(keyCode, modifiers);
+ }
+
+ @Override
+ public void typedKey(ComponentOperator oper, int keyCode, char keyChar, int modifiers) {
+ releaseKey(oper, keyCode, modifiers);
+ }
+
+ /**
+ * Releases a key.
+ *
+ * @param oper Operator to release a key on.
+ * @param keyCode Key code ({@code KeyEventVK_*} field.
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ */
+ @Override
+ public void releaseKey(ComponentOperator oper, int keyCode, int modifiers) {
+ releaseKey(keyCode, modifiers);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/MouseEventDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/MouseEventDriver.java
new file mode 100644
index 00000000000..705239b35be
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/MouseEventDriver.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.input;
+
+import java.awt.Component;
+import java.awt.event.MouseEvent;
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.MouseDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.Operator;
+
+/**
+ * MouseDriver using event dispatching.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class MouseEventDriver extends EventDriver implements MouseDriver {
+
+ /**
+ * Constructs a MouseEventDriver object.
+ *
+ * @param supported an array of supported class names
+ */
+ public MouseEventDriver(String[] supported) {
+ super(supported);
+ }
+
+ /**
+ * Constructs a MouseEventDriver object.
+ */
+ public MouseEventDriver() {
+ super();
+ }
+
+ @Override
+ public void pressMouse(ComponentOperator oper, int x, int y, int mouseButton, int modifiers) {
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_PRESSED,
+ modifiers, x, y, 1,
+ mouseButton);
+ }
+
+ @Override
+ public void releaseMouse(ComponentOperator oper, int x, int y, int mouseButton, int modifiers) {
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_RELEASED,
+ modifiers, x, y, 1,
+ mouseButton);
+ }
+
+ @Override
+ public void moveMouse(ComponentOperator oper, int x, int y) {
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_MOVED,
+ 0, x, y, 0,
+ Operator.getDefaultMouseButton());
+ }
+
+ @Override
+ public void clickMouse(ComponentOperator oper, int x, int y, int clickCount, int mouseButton,
+ int modifiers, Timeout mouseClick) {
+
+ moveMouse(oper, x, y);
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_ENTERED,
+ 0, x, y, 0,
+ Operator.getDefaultMouseButton());
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_PRESSED,
+ modifiers, x, y, 1,
+ mouseButton);
+
+ for (int i = 1; i < clickCount; i++) {
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_RELEASED,
+ modifiers, x, y, i,
+ mouseButton);
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_CLICKED,
+ modifiers, x, y, i,
+ mouseButton);
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_PRESSED,
+ modifiers, x, y, i + 1,
+ mouseButton);
+ }
+
+ mouseClick.sleep();
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_RELEASED,
+ modifiers, x, y, clickCount,
+ mouseButton);
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_CLICKED,
+ modifiers, x, y, clickCount,
+ mouseButton);
+ exitMouse(oper);
+ }
+
+ @Override
+ public void dragMouse(ComponentOperator oper, int x, int y, int mouseButton, int modifiers) {
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_DRAGGED,
+ modifiers, x, y, 1,
+ mouseButton);
+ }
+
+ @Override
+ public void dragNDrop(ComponentOperator oper, int start_x, int start_y, int end_x, int end_y,
+ int mouseButton, int modifiers, Timeout before, Timeout after) {
+
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_ENTERED,
+ 0, start_x, start_y, 0,
+ Operator.getDefaultMouseButton());
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_PRESSED,
+ modifiers, start_x, start_y, 1,
+ mouseButton);
+ before.sleep();
+ dragMouse(oper, end_x, end_y, mouseButton, modifiers);
+ after.sleep();
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_RELEASED,
+ modifiers, end_x, end_y, 1,
+ mouseButton);
+ exitMouse(oper);
+ }
+
+ @Override
+ public void enterMouse(ComponentOperator oper) {
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_ENTERED,
+ 0, oper.getCenterX(), oper.getCenterY(), 0,
+ Operator.getDefaultMouseButton());
+ }
+
+ @Override
+ public void exitMouse(ComponentOperator oper) {
+ dispatchEvent(oper.getSource(),
+ MouseEvent.MOUSE_EXITED,
+ 0, oper.getCenterX(), oper.getCenterY(), 0,
+ Operator.getDefaultMouseButton());
+ }
+
+ /**
+ * Dispatches a mouse event to the component.
+ *
+ * @param comp Component to dispatch events to.
+ * @param id an event id.
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ * @param x relative x coordinate of event point
+ * @param y relative y coordinate of event point
+ * @param clickCount click count
+ * @param mouseButton mouse button.
+ */
+ protected void dispatchEvent(Component comp, int id, int modifiers, int x, int y, int clickCount, int mouseButton) {
+ dispatchEvent(comp,
+ new MouseEvent(comp,
+ id,
+ System.currentTimeMillis(),
+ modifiers | mouseButton, x, y, clickCount,
+ mouseButton == Operator.getPopupMouseButton()
+ && id == MouseEvent.MOUSE_PRESSED));
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/MouseRobotDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/MouseRobotDriver.java
new file mode 100644
index 00000000000..be466f8951d
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/MouseRobotDriver.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.input;
+
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.MouseDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * MouseDriver using robot operations.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class MouseRobotDriver extends RobotDriver implements MouseDriver {
+
+ /**
+ * Constructs a MouseRobotDriver object.
+ *
+ * @param autoDelay Time for {@code Robot.setAutoDelay(long)} method.
+ */
+ public MouseRobotDriver(Timeout autoDelay) {
+ super(autoDelay);
+ }
+
+ /**
+ * Constructs a MouseRobotDriver object.
+ *
+ * @param autoDelay Time for {@code Robot.setAutoDelay(long)} method.
+ * @param smooth - whether to move mouse smooth from one ppoint to another.
+ */
+ public MouseRobotDriver(Timeout autoDelay, boolean smooth) {
+ super(autoDelay, smooth);
+ }
+
+ /**
+ * Constructs a MouseRobotDriver object.
+ *
+ * @param autoDelay Time for {@code Robot.setAutoDelay(long)} method.
+ * @param supported an array of supported class names
+ */
+ public MouseRobotDriver(Timeout autoDelay, String[] supported) {
+ super(autoDelay, supported);
+ }
+
+ /**
+ * Constructs a MouseRobotDriver object.
+ *
+ * @param autoDelay Time for {@code Robot.setAutoDelay(long)} method.
+ * @param supported an array of supported class names
+ * @param smooth - whether to move mouse smooth from one ppoint to another.
+ */
+ public MouseRobotDriver(Timeout autoDelay, String[] supported, boolean smooth) {
+ super(autoDelay, supported, smooth);
+ }
+
+ @Override
+ public void pressMouse(ComponentOperator oper, int x, int y, int mouseButton, int modifiers) {
+ pressMouse(mouseButton, modifiers);
+ }
+
+ @Override
+ public void releaseMouse(ComponentOperator oper, int x, int y, int mouseButton, int modifiers) {
+ releaseMouse(mouseButton, modifiers);
+ }
+
+ @Override
+ public void moveMouse(ComponentOperator oper, int x, int y) {
+ moveMouse(getAbsoluteX(oper, x), getAbsoluteY(oper, y));
+ }
+
+ @Override
+ public void clickMouse(ComponentOperator oper, int x, int y, int clickCount, int mouseButton,
+ int modifiers, Timeout mouseClick) {
+ clickMouse(getAbsoluteX(oper, x), getAbsoluteY(oper, y), clickCount, mouseButton, modifiers, mouseClick);
+ }
+
+ @Override
+ public void dragMouse(ComponentOperator oper, int x, int y, int mouseButton, int modifiers) {
+ moveMouse(getAbsoluteX(oper, x), getAbsoluteY(oper, y));
+ }
+
+ @Override
+ public void dragNDrop(ComponentOperator oper, int start_x, int start_y, int end_x, int end_y,
+ int mouseButton, int modifiers, Timeout before, Timeout after) {
+ dragNDrop(getAbsoluteX(oper, start_x), getAbsoluteY(oper, start_y), getAbsoluteX(oper, end_x), getAbsoluteY(oper, end_y), mouseButton, modifiers, before, after);
+ }
+
+ @Override
+ public void enterMouse(ComponentOperator oper) {
+ moveMouse(oper, oper.getCenterXForClick(), oper.getCenterYForClick());
+ }
+
+ @Override
+ public void exitMouse(ComponentOperator oper) {
+ //better not go anywhere
+ //exit will be executed during the next
+ //mouse move anyway.
+ // moveMouse(oper, -1, -1);
+ }
+
+ /**
+ * Returns absolute x coordinate for relative x coordinate.
+ *
+ * @param oper an operator
+ * @param x a relative x coordinate.
+ * @return an absolute x coordinate.
+ */
+ protected int getAbsoluteX(ComponentOperator oper, int x) {
+ return oper.getSource().getLocationOnScreen().x + x;
+ }
+
+ /**
+ * Returns absolute y coordinate for relative y coordinate.
+ *
+ * @param oper an operator
+ * @param y a relative y coordinate.
+ * @return an absolute y coordinate.
+ */
+ protected int getAbsoluteY(ComponentOperator oper, int y) {
+ return oper.getSource().getLocationOnScreen().y + y;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/RobotDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/RobotDriver.java
new file mode 100644
index 00000000000..44d8638d76e
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/RobotDriver.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.input;
+
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.lang.reflect.InvocationTargetException;
+
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.JemmyException;
+import org.netbeans.jemmy.JemmyProperties;
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.TestOut;
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+
+/**
+ * Superclass for all drivers using robot.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class RobotDriver extends LightSupportiveDriver {
+
+ private boolean haveOldPos;
+ private boolean smooth = false;
+ private double oldX;
+ private double oldY;
+ private static final double CONSTANT1 = 0.75;
+ private static final double CONSTANT2 = 12.0;
+ /**
+ * A reference to the robot instance.
+ */
+ protected ClassReference robotReference = null;
+
+ /**
+ * A QueueTool instance.
+ */
+ protected QueueTool qtool;
+
+ protected Timeout autoDelay;
+
+ /**
+ * Constructs a RobotDriver object.
+ *
+ * @param autoDelay Time for {@code Robot.setAutoDelay(long)} method.
+ * @param supported an array of supported class names
+ */
+ public RobotDriver(Timeout autoDelay, String[] supported) {
+ super(supported);
+ qtool = new QueueTool();
+ qtool.setOutput(TestOut.getNullOutput());
+ this.autoDelay = autoDelay;
+ }
+
+ public RobotDriver(Timeout autoDelay, String[] supported, boolean smooth) {
+ this(autoDelay, supported);
+ this.smooth = smooth;
+ }
+
+ /**
+ * Constructs a RobotDriver object.
+ *
+ * @param autoDelay Time for {@code Robot.setAutoDelay(long)} method.
+ */
+ public RobotDriver(Timeout autoDelay) {
+ this(autoDelay, new String[]{"org.netbeans.jemmy.operators.ComponentOperator"});
+ }
+
+ public RobotDriver(Timeout autoDelay, boolean smooth) {
+ this(autoDelay);
+ this.smooth = smooth;
+ }
+
+ public void pressMouse(int mouseButton, int modifiers) {
+ pressModifiers(modifiers);
+ makeAnOperation("mousePress",
+ new Object[]{mouseButton},
+ new Class>[]{Integer.TYPE});
+ }
+
+ public void releaseMouse(int mouseButton, int modifiers) {
+ makeAnOperation("mouseRelease",
+ new Object[]{mouseButton},
+ new Class>[]{Integer.TYPE});
+ releaseModifiers(modifiers);
+ }
+
+ public void moveMouse(int x, int y) {
+ if (!smooth) {
+ makeAnOperation("mouseMove",
+ new Object[]{x, y},
+ new Class>[]{Integer.TYPE, Integer.TYPE});
+ } else {
+ double targetX = x;
+ double targetY = y;
+ if (haveOldPos) {
+ double currX = oldX;
+ double currY = oldY;
+ double vx = 0.0;
+ double vy = 0.0;
+ while (Math.round(currX) != Math.round(targetX)
+ || Math.round(currY) != Math.round(targetY)) {
+ vx = vx * CONSTANT1 + (targetX - currX) / CONSTANT2 * (1.0 - CONSTANT1);
+ vy = vy * CONSTANT1 + (targetY - currY) / CONSTANT2 * (1.0 - CONSTANT1);
+ currX += vx;
+ currY += vy;
+ makeAnOperation("mouseMove", new Object[]{
+ (int) Math.round(currX),
+ (int) Math.round(currY)},
+ new Class>[]{Integer.TYPE, Integer.TYPE});
+ }
+ } else {
+ makeAnOperation("mouseMove", new Object[]{
+ (int) Math.round(targetX),
+ (int) Math.round(targetY)},
+ new Class>[]{Integer.TYPE, Integer.TYPE});
+ }
+ haveOldPos = true;
+ oldX = targetX;
+ oldY = targetY;
+ }
+ }
+
+ public void clickMouse(int x, int y, int clickCount, int mouseButton,
+ int modifiers, Timeout mouseClick) {
+ pressModifiers(modifiers);
+ moveMouse(x, y);
+ makeAnOperation("mousePress", new Object[]{mouseButton}, new Class>[]{Integer.TYPE});
+ for (int i = 1; i < clickCount; i++) {
+ makeAnOperation("mouseRelease", new Object[]{mouseButton}, new Class>[]{Integer.TYPE});
+ makeAnOperation("mousePress", new Object[]{mouseButton}, new Class>[]{Integer.TYPE});
+ }
+ mouseClick.sleep();
+ makeAnOperation("mouseRelease", new Object[]{mouseButton}, new Class>[]{Integer.TYPE});
+ releaseModifiers(modifiers);
+ }
+
+ public void dragMouse(int x, int y, int mouseButton, int modifiers) {
+ moveMouse(x, y);
+ }
+
+ public void dragNDrop(int start_x, int start_y, int end_x, int end_y,
+ int mouseButton, int modifiers, Timeout before, Timeout after) {
+ moveMouse(start_x, start_y);
+ pressMouse(mouseButton, modifiers);
+ before.sleep();
+ moveMouse(end_x, end_y);
+ after.sleep();
+ releaseMouse(mouseButton, modifiers);
+ }
+
+ /**
+ * Presses a key.
+ *
+ * @param keyCode Key code ({@code KeyEventVK_*} field.
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ */
+ public void pressKey(int keyCode, int modifiers) {
+ pressModifiers(modifiers);
+ makeAnOperation("keyPress",
+ new Object[]{keyCode},
+ new Class>[]{Integer.TYPE});
+ }
+
+ /**
+ * Releases a key.
+ *
+ * @param keyCode Key code ({@code KeyEventVK_*} field.
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ */
+ public void releaseKey(int keyCode, int modifiers) {
+ releaseModifiers(modifiers);
+ makeAnOperation("keyRelease",
+ new Object[]{keyCode},
+ new Class>[]{Integer.TYPE});
+ }
+
+ /**
+ * Performs a single operation.
+ *
+ * @param method a name of {@code java.awt.Robot} method.
+ * @param params method parameters
+ * @param paramClasses method parameters classes
+ */
+ protected void makeAnOperation(final String method, final Object[] params, final Class>[] paramClasses) {
+ if (robotReference == null) {
+ initRobot();
+ }
+ try {
+ robotReference.invokeMethod(method, params, paramClasses);
+ synchronizeRobot();
+ } catch (InvocationTargetException
+ | IllegalStateException
+ | NoSuchMethodException
+ | IllegalAccessException e) {
+ throw (new JemmyException("Exception during java.awt.Robot accessing", e));
+ }
+ }
+
+ /**
+ * Calls {@code java.awt.Robot.waitForIdle()} method.
+ */
+ protected void synchronizeRobot() {
+ if (!QueueTool.isDispatchThread()) {
+ if ((JemmyProperties.getCurrentDispatchingModel() & JemmyProperties.QUEUE_MODEL_MASK) != 0) {
+ if (robotReference == null) {
+ initRobot();
+ }
+ try {
+ robotReference.invokeMethod("waitForIdle", null, null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ /**
+ * Presses modifiers keys by robot.
+ *
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ */
+ protected void pressModifiers(int modifiers) {
+ if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
+ pressKey(KeyEvent.VK_SHIFT, modifiers & ~InputEvent.SHIFT_MASK);
+ } else if ((modifiers & InputEvent.ALT_GRAPH_MASK) != 0) {
+ pressKey(KeyEvent.VK_ALT_GRAPH, modifiers & ~InputEvent.ALT_GRAPH_MASK);
+ } else if ((modifiers & InputEvent.ALT_MASK) != 0) {
+ pressKey(KeyEvent.VK_ALT, modifiers & ~InputEvent.ALT_MASK);
+ } else if ((modifiers & InputEvent.META_MASK) != 0) {
+ pressKey(KeyEvent.VK_META, modifiers & ~InputEvent.META_MASK);
+ } else if ((modifiers & InputEvent.CTRL_MASK) != 0) {
+ pressKey(KeyEvent.VK_CONTROL, modifiers & ~InputEvent.CTRL_MASK);
+ }
+ }
+
+ /*
+ protected void pressModifiers(ComponentOperator oper, int modifiers) {
+ if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
+ pressKey(oper, KeyEvent.VK_SHIFT, modifiers & ~InputEvent.SHIFT_MASK);
+ } else if((modifiers & InputEvent.ALT_GRAPH_MASK) != 0) {
+ pressKey(oper, KeyEvent.VK_ALT_GRAPH, modifiers & ~InputEvent.ALT_GRAPH_MASK);
+ } else if((modifiers & InputEvent.ALT_MASK) != 0) {
+ pressKey(oper, KeyEvent.VK_ALT, modifiers & ~InputEvent.ALT_MASK);
+ } else if((modifiers & InputEvent.META_MASK) != 0) {
+ pressKey(oper, KeyEvent.VK_META, modifiers & ~InputEvent.META_MASK);
+ } else if((modifiers & InputEvent.CTRL_MASK) != 0) {
+ pressKey(oper, KeyEvent.VK_CONTROL, modifiers & ~InputEvent.CTRL_MASK);
+ }
+ }
+ */
+ /**
+ * Releases modifiers keys by robot.
+ *
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ */
+ protected void releaseModifiers(int modifiers) {
+ if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
+ releaseKey(KeyEvent.VK_SHIFT, modifiers & ~InputEvent.SHIFT_MASK);
+ } else if ((modifiers & InputEvent.ALT_GRAPH_MASK) != 0) {
+ releaseKey(KeyEvent.VK_ALT_GRAPH, modifiers & ~InputEvent.ALT_GRAPH_MASK);
+ } else if ((modifiers & InputEvent.ALT_MASK) != 0) {
+ releaseKey(KeyEvent.VK_ALT, modifiers & ~InputEvent.ALT_MASK);
+ } else if ((modifiers & InputEvent.META_MASK) != 0) {
+ releaseKey(KeyEvent.VK_META, modifiers & ~InputEvent.META_MASK);
+ } else if ((modifiers & InputEvent.CTRL_MASK) != 0) {
+ releaseKey(KeyEvent.VK_CONTROL, modifiers & ~InputEvent.CTRL_MASK);
+ }
+ }
+
+ /*
+ protected void releaseModifiers(ComponentOperator oper, int modifiers) {
+ if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
+ releaseKey(oper, KeyEvent.VK_SHIFT, modifiers & ~InputEvent.SHIFT_MASK);
+ } else if((modifiers & InputEvent.ALT_GRAPH_MASK) != 0) {
+ releaseKey(oper, KeyEvent.VK_ALT_GRAPH, modifiers & ~InputEvent.ALT_GRAPH_MASK);
+ } else if((modifiers & InputEvent.ALT_MASK) != 0) {
+ releaseKey(oper, KeyEvent.VK_ALT, modifiers & ~InputEvent.ALT_MASK);
+ } else if((modifiers & InputEvent.META_MASK) != 0) {
+ releaseKey(oper, KeyEvent.VK_META, modifiers & ~InputEvent.META_MASK);
+ } else if((modifiers & InputEvent.CTRL_MASK) != 0) {
+ releaseKey(oper, KeyEvent.VK_CONTROL, modifiers & ~InputEvent.CTRL_MASK);
+ }
+ }
+ */
+ private void initRobot() {
+ // need to init Robot in dispatch thread because it hangs on Linux
+ // (see http://www.netbeans.org/issues/show_bug.cgi?id=37476)
+ if (QueueTool.isDispatchThread()) {
+ doInitRobot();
+ } else {
+ qtool.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ doInitRobot();
+ }
+ });
+ }
+ }
+
+ private void doInitRobot() {
+ try {
+ ClassReference robotClassReverence = new ClassReference("java.awt.Robot");
+ robotReference = new ClassReference(robotClassReverence.newInstance(null, null));
+ robotReference.invokeMethod("setAutoDelay",
+ new Object[]{(int) ((autoDelay != null)
+ ? autoDelay.getValue()
+ : 0)},
+ new Class>[]{Integer.TYPE});
+ } catch (InvocationTargetException
+ | IllegalStateException
+ | NoSuchMethodException
+ | IllegalAccessException
+ | ClassNotFoundException
+ | InstantiationException e) {
+ throw (new JemmyException("Exception during java.awt.Robot accessing", e));
+ }
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/package-info.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/package-info.java
new file mode 100644
index 00000000000..90d7263cdfb
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/input/package-info.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ *
Mouse and keyboard drivers
+ * Contains low-level drivers to perform user input.
+ *
+ * @since 17 Apr 2002
+ *
+ */
+package org.netbeans.jemmy.drivers.input;
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/ChoiceDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/ChoiceDriver.java
new file mode 100644
index 00000000000..a6fa8217f52
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/ChoiceDriver.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.lists;
+
+import java.awt.Point;
+import java.awt.event.KeyEvent;
+
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.KeyDriver;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.ListDriver;
+import org.netbeans.jemmy.operators.ChoiceOperator;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.Operator;
+
+/**
+ * List driver for java.awt.Choice component type.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class ChoiceDriver extends LightSupportiveDriver implements ListDriver {
+
+ private final static int RIGHT_INDENT = 10;
+
+ /**
+ * Constructs a ChoiceDriver.
+ */
+ public ChoiceDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.ChoiceOperator"});
+ }
+
+ @Override
+ public void selectItem(ComponentOperator oper, int index) {
+ ChoiceOperator coper = (ChoiceOperator) oper;
+ Point pointToClick = getClickPoint(oper);
+ DriverManager.getMouseDriver(oper).
+ clickMouse(oper, pointToClick.x, pointToClick.y,
+ 1, Operator.getDefaultMouseButton(), 0,
+ oper.getTimeouts().create("ComponentOperator.MouseClickTimeout"));
+ KeyDriver kdriver = DriverManager.getKeyDriver(oper);
+ Timeout pushTimeout = oper.getTimeouts().create("ComponentOperator.PushKeyTimeout");
+ if (System.getProperty("java.specification.version").compareTo("1.3") > 0) {
+ while (coper.getSelectedIndex() != index) {
+ kdriver.pushKey(oper, (index > coper.getSelectedIndex()) ? KeyEvent.VK_DOWN : KeyEvent.VK_UP, 0, pushTimeout);
+ }
+ } else {
+ int current = ((ChoiceOperator) oper).getSelectedIndex();
+ int diff = 0;
+ int key = 0;
+ if (index > current) {
+ diff = index - current;
+ key = KeyEvent.VK_DOWN;
+ } else {
+ diff = current - index;
+ key = KeyEvent.VK_UP;
+ }
+ for (int i = 0; i < diff; i++) {
+ kdriver.pushKey(oper, key, 0, pushTimeout);
+ }
+ }
+ kdriver.pushKey(oper, KeyEvent.VK_ENTER, 0, pushTimeout);
+ }
+
+ private Point getClickPoint(ComponentOperator oper) {
+ return new Point(oper.getWidth() - RIGHT_INDENT, oper.getHeight() / 2);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/JComboMouseDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/JComboMouseDriver.java
new file mode 100644
index 00000000000..8781721eae9
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/JComboMouseDriver.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.lists;
+
+import javax.swing.UIManager;
+
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.ListDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JComboBoxOperator;
+import org.netbeans.jemmy.operators.JListOperator;
+import org.netbeans.jemmy.util.EmptyVisualizer;
+
+/**
+ * List driver for javax.swing.JCompoBox component type.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class JComboMouseDriver extends LightSupportiveDriver implements ListDriver {
+
+ /**
+ * Constructs a JComboMouseDriver.
+ */
+ QueueTool queueTool;
+
+ public JComboMouseDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JComboBoxOperator"});
+ queueTool = new QueueTool();
+ }
+
+ @Override
+ public void selectItem(ComponentOperator oper, int index) {
+ JComboBoxOperator coper = (JComboBoxOperator) oper;
+ //1.5 workaround
+ if (System.getProperty("java.specification.version").compareTo("1.4") > 0) {
+ queueTool.setOutput(oper.getOutput().createErrorOutput());
+ queueTool.waitEmpty(10);
+ queueTool.waitEmpty(10);
+ queueTool.waitEmpty(10);
+ }
+ //end of 1.5 workaround
+ if (!coper.isPopupVisible()) {
+ if (UIManager.getLookAndFeel().getClass().getName().equals("com.sun.java.swing.plaf.motif.MotifLookAndFeel")) {
+ oper.clickMouse(oper.getWidth() - 2, oper.getHeight() / 2, 1);
+ } else {
+ DriverManager.getButtonDriver(coper.getButton()).
+ push(coper.getButton());
+ }
+ }
+ JListOperator list = new JListOperator(coper.waitList());
+ list.copyEnvironment(coper);
+ list.setVisualizer(new EmptyVisualizer());
+ coper.getTimeouts().sleep("JComboBoxOperator.BeforeSelectingTimeout");
+ DriverManager.getListDriver(list).
+ selectItem(list, index);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/JListMouseDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/JListMouseDriver.java
new file mode 100644
index 00000000000..be02eabffd6
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/JListMouseDriver.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.lists;
+
+import java.awt.Rectangle;
+import java.awt.event.InputEvent;
+
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.MultiSelListDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JListOperator;
+import org.netbeans.jemmy.operators.Operator;
+
+/**
+ * List driver for javax.swing.JList component type.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class JListMouseDriver extends LightSupportiveDriver implements MultiSelListDriver {
+
+ QueueTool queueTool;
+
+ /**
+ * Constructs a JListMouseDriver.
+ */
+ public JListMouseDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JListOperator"});
+ queueTool = new QueueTool();
+ }
+
+ @Override
+ public void selectItem(ComponentOperator oper, int index) {
+ clickOnItem((JListOperator) oper, index);
+ }
+
+ @Override
+ public void selectItems(ComponentOperator oper, int[] indices) {
+ clickOnItem((JListOperator) oper, indices[0]);
+ for (int i = 1; i < indices.length; i++) {
+ clickOnItem((JListOperator) oper, indices[i], InputEvent.CTRL_MASK);
+ }
+ }
+
+ /**
+ * Clicks on a list item.
+ *
+ * @param oper an operator to click on.
+ * @param index item index.
+ */
+ protected void clickOnItem(JListOperator oper, int index) {
+ clickOnItem(oper, index, 0);
+ }
+
+ /**
+ * Clicks on a list item.
+ *
+ * @param oper an operator to click on.
+ * @param index item index.
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ */
+ protected void clickOnItem(final JListOperator oper, final int index, final int modifiers) {
+ if (!QueueTool.isDispatchThread()) {
+ oper.scrollToItem(index);
+ }
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Path selecting") {
+ @Override
+ public Void launch() {
+ Rectangle rect = oper.getCellBounds(index, index);
+ DriverManager.getMouseDriver(oper).
+ clickMouse(oper,
+ rect.x + rect.width / 2,
+ rect.y + rect.height / 2,
+ 1, Operator.getDefaultMouseButton(), modifiers,
+ oper.getTimeouts().create("ComponentOperator.MouseClickTimeout"));
+ return null;
+ }
+ });
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/JTabAPIDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/JTabAPIDriver.java
new file mode 100644
index 00000000000..f9a9b1ba707
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/JTabAPIDriver.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.lists;
+
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.ListDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JTabbedPaneOperator;
+
+/**
+ * List driver for javax.swing.JTabbedPane component type.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class JTabAPIDriver extends LightSupportiveDriver implements ListDriver {
+
+ private QueueTool queueTool;
+
+ /**
+ * Constructs a JTabMouseDriver.
+ */
+ public JTabAPIDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JTabbedPaneOperator"});
+ queueTool = new QueueTool();
+ }
+
+ @Override
+ public void selectItem(final ComponentOperator oper, final int index) {
+ if (index != -1) {
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Selecting tab " + index + " by setting selectedIndex") {
+ @Override
+ public Void launch() {
+ ((JTabbedPaneOperator) oper).setSelectedIndex(index);
+ return null;
+ }
+ });
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/JTabMouseDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/JTabMouseDriver.java
new file mode 100644
index 00000000000..9cb1f85d596
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/JTabMouseDriver.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.lists;
+
+import java.awt.Rectangle;
+
+import javax.swing.JTabbedPane;
+
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.ListDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JTabbedPaneOperator;
+import org.netbeans.jemmy.operators.Operator;
+
+/**
+ * List driver for javax.swing.JTabbedPane component type.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class JTabMouseDriver extends LightSupportiveDriver implements ListDriver {
+
+ private QueueTool queueTool;
+
+ /**
+ * Constructs a JTabMouseDriver.
+ */
+ public JTabMouseDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JTabbedPaneOperator"});
+ queueTool = new QueueTool();
+ }
+
+ @Override
+ public void selectItem(final ComponentOperator oper, final int index) {
+ if (index != -1) {
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Selecting tab " + index + " using mouse") {
+ @Override
+ public Void launch() {
+ Rectangle rect = ((JTabbedPaneOperator) oper).
+ getUI().
+ getTabBounds((JTabbedPane) oper.getSource(),
+ index);
+ DriverManager.getMouseDriver(oper).
+ clickMouse(oper,
+ (int) (rect.getX() + rect.getWidth() / 2),
+ (int) (rect.getY() + rect.getHeight() / 2),
+ 1, Operator.getDefaultMouseButton(), 0,
+ oper.getTimeouts().create("ComponentOperator.MouseClickTimeout"));
+ return null;
+ }
+ });
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/JTableHeaderDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/JTableHeaderDriver.java
new file mode 100644
index 00000000000..e55dc8bf9c9
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/JTableHeaderDriver.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.lists;
+
+import java.awt.Point;
+import java.awt.event.InputEvent;
+
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.OrderedListDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JTableHeaderOperator;
+import org.netbeans.jemmy.operators.Operator;
+
+/**
+ * List driver for javax.swing.table.JTableHeader component type.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class JTableHeaderDriver extends LightSupportiveDriver implements OrderedListDriver {
+
+ private QueueTool queueTool;
+
+ /**
+ * Constructs a JTableHeaderDriver.
+ */
+ public JTableHeaderDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JTableHeaderOperator"});
+ queueTool = new QueueTool();
+ }
+
+ @Override
+ public void selectItem(ComponentOperator oper, int index) {
+ clickOnHeader((JTableHeaderOperator) oper, index);
+ }
+
+ @Override
+ public void selectItems(ComponentOperator oper, int[] indices) {
+ clickOnHeader((JTableHeaderOperator) oper, indices[0]);
+ for (int i = 1; i < indices.length; i++) {
+ clickOnHeader((JTableHeaderOperator) oper, indices[i], InputEvent.CTRL_MASK);
+ }
+ }
+
+ @Override
+ public void moveItem(ComponentOperator oper, int moveColumn, int moveTo) {
+ Point start = ((JTableHeaderOperator) oper).getPointToClick(moveColumn);
+ Point end = ((JTableHeaderOperator) oper).getPointToClick(moveTo);
+ oper.dragNDrop(start.x, start.y, end.x, end.y);
+ }
+
+ /**
+ * Clicks on a column header.
+ *
+ * @param oper an operator to click on.
+ * @param index column index.
+ */
+ protected void clickOnHeader(JTableHeaderOperator oper, int index) {
+ clickOnHeader(oper, index, 0);
+ }
+
+ /**
+ * Clicks on a column header.
+ *
+ * @param oper an operator to click on.
+ * @param index column index.
+ * @param modifiers a combination of {@code InputEvent.*_MASK} fields.
+ */
+ protected void clickOnHeader(final JTableHeaderOperator oper, final int index, final int modifiers) {
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Column selecting") {
+ @Override
+ public Void launch() {
+ Point toClick = oper.getPointToClick(index);
+ DriverManager.getMouseDriver(oper).
+ clickMouse(oper,
+ toClick.x,
+ toClick.y,
+ 1, Operator.getDefaultMouseButton(), modifiers,
+ oper.getTimeouts().create("ComponentOperator.MouseClickTimeout"));
+ return null;
+ }
+ });
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/ListAPIDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/ListAPIDriver.java
new file mode 100644
index 00000000000..bf464cfc67d
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/ListAPIDriver.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.lists;
+
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.MultiSelListDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.ListOperator;
+
+/**
+ * List driver for java.awt.List component type. Uses API calls.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class ListAPIDriver extends LightSupportiveDriver implements MultiSelListDriver {
+
+ /**
+ * Constructs a ListAPIDriver.
+ */
+ public ListAPIDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.ListOperator"});
+ }
+
+ @Override
+ public void selectItem(ComponentOperator oper, int index) {
+ ListOperator loper = (ListOperator) oper;
+ clearSelection(loper);
+ loper.select(index);
+ }
+
+ @Override
+ public void selectItems(ComponentOperator oper, int[] indices) {
+ ListOperator loper = (ListOperator) oper;
+ clearSelection(loper);
+ for (int indice : indices) {
+ loper.select(indice);
+ }
+ }
+
+ private void clearSelection(ListOperator loper) {
+ for (int i = 0; i < loper.getItemCount(); i++) {
+ loper.deselect(i);
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/ListKeyboardDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/ListKeyboardDriver.java
new file mode 100644
index 00000000000..927d62a570d
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/ListKeyboardDriver.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.lists;
+
+import java.awt.event.KeyEvent;
+
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.KeyDriver;
+import org.netbeans.jemmy.drivers.MultiSelListDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.ListOperator;
+
+/**
+ * List driver for java.awt.List component type. Uses keyboard and mouse.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class ListKeyboardDriver extends ListAPIDriver implements MultiSelListDriver {
+
+ /**
+ * Constructs a ListKeyboardDriver.
+ */
+ public ListKeyboardDriver() {
+ super();
+ }
+
+ @Override
+ public void selectItem(ComponentOperator oper, int index) {
+ ListOperator loper = (ListOperator) oper;
+ if (loper.isMultipleMode()) {
+ super.selectItem(loper, index);
+ }
+ DriverManager.getFocusDriver(oper).giveFocus(oper);
+ KeyDriver kDriver = DriverManager.getKeyDriver(oper);
+ int current = loper.getSelectedIndex();
+ int diff = 0;
+ int key = 0;
+ if (index > current) {
+ diff = index - current;
+ key = KeyEvent.VK_DOWN;
+ } else {
+ diff = current - index;
+ key = KeyEvent.VK_UP;
+ }
+ Timeout pushTime = oper.getTimeouts().create("ComponentOperator.PushKeyTimeout");
+ for (int i = 0; i < diff; i++) {
+ kDriver.pushKey(oper, key, 0, pushTime);
+ }
+ kDriver.pushKey(oper, KeyEvent.VK_ENTER, 0, pushTime);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/package-info.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/package-info.java
new file mode 100644
index 00000000000..0187ea93b2a
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/lists/package-info.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ *
List drivers
+ * Different drivers to perform a list operations.
+ *
+ * @since 4/17/2002
+ *
+ */
+package org.netbeans.jemmy.drivers.lists;
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/menus/APIJMenuDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/menus/APIJMenuDriver.java
new file mode 100644
index 00000000000..8df8776d61e
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/menus/APIJMenuDriver.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.menus;
+
+import java.awt.Component;
+
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+
+import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.JemmyException;
+import org.netbeans.jemmy.drivers.MenuDriver;
+import org.netbeans.jemmy.drivers.PathChooser;
+import org.netbeans.jemmy.operators.AbstractButtonOperator;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JMenuItemOperator;
+import org.netbeans.jemmy.operators.JMenuOperator;
+
+public class APIJMenuDriver extends DefaultJMenuDriver implements MenuDriver {
+
+ public APIJMenuDriver() {
+ super();
+ }
+
+ protected Object push(ComponentOperator oper, JMenuBar menuBar,
+ PathChooser chooser, int depth, boolean pressMouse) {
+ try {
+ oper.waitComponentVisible(true);
+ oper.waitComponentEnabled();
+ } catch (InterruptedException e) {
+ throw (new JemmyException("Interrupted!", e));
+ }
+ if (depth > chooser.getDepth() - 1) {
+ if (oper instanceof JMenuOperator) {
+ if (((JMenuOperator) oper).isPopupMenuVisible()) {
+ ((JMenuOperator) oper).setPopupMenuVisible(false);
+ }
+ ((JMenuOperator) oper).setPopupMenuVisible(true);
+ waitPopupMenu(oper);
+ }
+ ((AbstractButtonOperator) oper).doClick();
+ return oper.getSource();
+ } else {
+ if (((JMenuOperator) oper).isPopupMenuVisible()) {
+ ((JMenuOperator) oper).setPopupMenuVisible(false);
+ }
+ ((JMenuOperator) oper).setPopupMenuVisible(true);
+ waitPopupMenu(oper);
+ }
+ oper.getTimeouts().sleep("JMenuOperator.WaitBeforePopupTimeout");
+ JMenuItem item = waitItem(oper, waitPopupMenu(oper), chooser, depth);
+ if (item instanceof JMenu) {
+ JMenuOperator mo = new JMenuOperator((JMenu) item);
+ mo.copyEnvironment(oper);
+ Object result = push(mo, null, chooser, depth + 1, false);
+ if (result instanceof JMenu) {
+ org.netbeans.jemmy.JemmyProperties.getCurrentOutput().printLine("IN HERE" + ((JMenu) result).getText());
+ org.netbeans.jemmy.JemmyProperties.getCurrentOutput().printLine("IN HERE" + Boolean.toString(((JMenu) result).isPopupMenuVisible()));
+ if (!((JMenu) result).isPopupMenuVisible()) {
+ ((JMenuOperator) oper).setPopupMenuVisible(false);
+ }
+ } else {
+ ((JMenuOperator) oper).setPopupMenuVisible(false);
+ waitNoPopupMenu(oper);
+ }
+ return result;
+ } else {
+ JMenuItemOperator mio = new JMenuItemOperator(item);
+ mio.copyEnvironment(oper);
+ try {
+ mio.waitComponentEnabled();
+ } catch (InterruptedException e) {
+ throw (new JemmyException("Interrupted!", e));
+ }
+ mio.doClick();
+ ((JMenuOperator) oper).setPopupMenuVisible(false);
+ waitNoPopupMenu(oper);
+ return item;
+ }
+ }
+
+ protected void waitNoPopupMenu(final ComponentOperator oper) {
+ oper.waitState(new ComponentChooser() {
+ @Override
+ public boolean checkComponent(Component comp) {
+ return !((JMenuOperator) oper).isPopupMenuVisible();
+ }
+
+ @Override
+ public String getDescription() {
+ return ((JMenuOperator) oper).getText() + "'s popup";
+ }
+
+ @Override
+ public String toString() {
+ return "waitNoPopupMenu.ComponentChooser{description = " + getDescription() + '}';
+ }
+ });
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/menus/AppleMenuDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/menus/AppleMenuDriver.java
new file mode 100644
index 00000000000..1d6fcdd88a2
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/menus/AppleMenuDriver.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.menus;
+
+import java.awt.event.KeyEvent;
+
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.MenuElement;
+
+import org.netbeans.jemmy.JemmyException;
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.TimeoutExpiredException;
+import org.netbeans.jemmy.drivers.DescriptablePathChooser;
+import org.netbeans.jemmy.drivers.MenuDriver;
+import org.netbeans.jemmy.drivers.PathChooser;
+import org.netbeans.jemmy.drivers.input.RobotDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.Operator;
+
+/**
+ *
+ * @author shura
+ */
+public class AppleMenuDriver extends RobotDriver implements MenuDriver {
+
+ /**
+ * Creates a new instance of AppleMenuDriver
+ */
+ public AppleMenuDriver() {
+ super(new Timeout("apple.system.menu.delay", 100),
+ new String[]{"org.netbeans.jemmy.operators.JMenuBarOperator"});
+ }
+
+ @Override
+ public Object pushMenu(ComponentOperator oper, PathChooser chooser) {
+ Timeout maxTime = oper.getTimeouts().create("ComponentOperator.WaitComponentTimeout");
+ JMenuBar bar = (JMenuBar) (oper.getSource());
+ activateMenu(bar);
+ MenuElement menuObject;
+ maxTime.start();
+ while (!chooser.checkPathComponent(0, (menuObject = getSelectedElement(bar)))) {
+ pressKey(KeyEvent.VK_RIGHT, 0);
+ releaseKey(KeyEvent.VK_RIGHT, 0);
+ if (maxTime.expired()) {
+ throw (new TimeoutExpiredException("AppleMenuDriver: can not find an appropriate menu!"));
+ }
+ }
+ for (int depth = 1; depth < chooser.getDepth(); depth++) {
+ // TODO - wait for menu item
+ int elementIndex = getDesiredElementIndex(menuObject, chooser, depth);
+ if (elementIndex == -1) {
+ throw (new JemmyException("Unable to find menu (menuitem): " + ((DescriptablePathChooser) chooser).getDescription()));
+ }
+ for (int i = ((depth == 1) ? 0 : 1); i <= elementIndex; i++) {
+ pressKey(KeyEvent.VK_DOWN, 0);
+ releaseKey(KeyEvent.VK_DOWN, 0);
+ }
+ if (depth == chooser.getDepth() - 1) {
+ pressKey(KeyEvent.VK_ENTER, 0);
+ releaseKey(KeyEvent.VK_ENTER, 0);
+ return null;
+ } else {
+ pressKey(KeyEvent.VK_RIGHT, 0);
+ releaseKey(KeyEvent.VK_RIGHT, 0);
+ menuObject = menuObject.getSubElements()[0].getSubElements()[elementIndex];
+ }
+ }
+ return menuObject;
+ }
+
+ private void activateMenu(JMenuBar bar) {
+ if (getSelectedElement(bar) == null) {
+ tryToActivate();
+ if (getSelectedElement(bar) == null) {
+ tryToActivate();
+ }
+ }
+ }
+
+ private void tryToActivate() {
+ moveMouse(0, 0);
+ pressMouse(Operator.getDefaultMouseButton(), 0);
+ releaseMouse(Operator.getDefaultMouseButton(), 0);
+ pressKey(KeyEvent.VK_RIGHT, 0);
+ releaseKey(KeyEvent.VK_RIGHT, 0);
+ pressKey(KeyEvent.VK_RIGHT, 0);
+ releaseKey(KeyEvent.VK_RIGHT, 0);
+ }
+
+ private static MenuElement getSelectedElement(MenuElement bar) {
+ MenuElement[] subElements = bar.getSubElements();
+ for (MenuElement subElement : subElements) {
+ if (subElement instanceof JMenu
+ && ((JMenu) subElement).isSelected()) {
+ return subElement;
+ } else if (subElement instanceof JMenuItem
+ && ((JMenuItem) subElement).isSelected()) {
+ return subElement;
+ }
+ }
+ return null;
+ }
+
+ private static int getDesiredElementIndex(MenuElement bar, PathChooser chooser, int depth) {
+ MenuElement[] subElements = bar.getSubElements()[0].getSubElements();
+ int realIndex = 0;
+ for (MenuElement subElement : subElements) {
+ // do not count invisible and disabled menu items
+ if (subElement instanceof JMenuItem && ((JMenuItem) subElement).isVisible() && ((JMenuItem) subElement).isEnabled()) {
+ if (chooser.checkPathComponent(depth, subElement)) {
+ return realIndex;
+ }
+ realIndex++;
+ }
+ }
+ return -1;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/menus/DefaultJMenuDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/menus/DefaultJMenuDriver.java
new file mode 100644
index 00000000000..e4ef079ef60
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/menus/DefaultJMenuDriver.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.menus;
+
+import java.awt.Component;
+
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.MenuElement;
+
+import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.JemmyException;
+import org.netbeans.jemmy.Waitable;
+import org.netbeans.jemmy.Waiter;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.MenuDriver;
+import org.netbeans.jemmy.drivers.MouseDriver;
+import org.netbeans.jemmy.drivers.PathChooser;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JMenuBarOperator;
+import org.netbeans.jemmy.operators.JMenuItemOperator;
+import org.netbeans.jemmy.operators.JMenuOperator;
+import org.netbeans.jemmy.operators.JPopupMenuOperator;
+
+public class DefaultJMenuDriver extends LightSupportiveDriver implements MenuDriver {
+
+ public DefaultJMenuDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JMenuOperator",
+ "org.netbeans.jemmy.operators.JMenuBarOperator",
+ "org.netbeans.jemmy.operators.JPopupMenuOperator"});
+ }
+
+ @Override
+ public Object pushMenu(ComponentOperator oper, PathChooser chooser) {
+ checkSupported(oper);
+ if (oper instanceof JMenuBarOperator
+ || oper instanceof JPopupMenuOperator) {
+ JMenuItem item;
+ if (oper instanceof JMenuBarOperator) {
+ item = waitItem(oper,
+ (JMenuBar) oper.getSource(),
+ chooser, 0);
+ } else {
+ item = waitItem(oper,
+ (JPopupMenu) oper.getSource(),
+ chooser, 0);
+ }
+ JMenuItemOperator itemOper;
+ if (item instanceof JMenu) {
+ itemOper = new JMenuOperator((JMenu) item);
+ } else {
+ itemOper = new JMenuItemOperator(item);
+ }
+ itemOper.copyEnvironment(oper);
+ return (push(itemOper, null, (oper instanceof JMenuBarOperator) ? ((JMenuBar) oper.getSource()) : null,
+ chooser, 1, true));
+ } else {
+ return push(oper, null, null, chooser, 0, true);
+ }
+ }
+
+ protected Object push(ComponentOperator oper, ComponentOperator lastItem,
+ JMenuBar menuBar,
+ PathChooser chooser, int depth, boolean pressMouse) {
+ try {
+ oper.waitComponentVisible(true);
+ oper.waitComponentEnabled();
+ } catch (InterruptedException e) {
+ throw (new JemmyException("Interrupted!", e));
+ }
+ MouseDriver mDriver = DriverManager.getMouseDriver(oper);
+ //mDriver.enterMouse(oper);
+ //use enhanced algorithm instead
+ smartMove(lastItem, oper);
+ if (depth > chooser.getDepth() - 1) {
+ if (oper instanceof JMenuOperator
+ && menuBar != null && getSelectedElement(menuBar) != null) {
+ //mDriver.enterMouse(oper);
+ } else {
+ DriverManager.getButtonDriver(oper).push(oper);
+ }
+ return oper.getSource();
+ }
+ if (pressMouse && !((JMenuOperator) oper).isPopupMenuVisible()
+ && !(menuBar != null && getSelectedElement(menuBar) != null)) {
+ DriverManager.getButtonDriver(oper).push(oper);
+ }
+ oper.getTimeouts().sleep("JMenuOperator.WaitBeforePopupTimeout");
+ JMenuItem item = waitItem(oper, waitPopupMenu(oper), chooser, depth);
+ mDriver.exitMouse(oper);
+ if (item instanceof JMenu) {
+ JMenuOperator mo = new JMenuOperator((JMenu) item);
+ mo.copyEnvironment(oper);
+ return push(mo, oper, null, chooser, depth + 1, false);
+ } else {
+ JMenuItemOperator mio = new JMenuItemOperator(item);
+ mio.copyEnvironment(oper);
+ try {
+ mio.waitComponentEnabled();
+ } catch (InterruptedException e) {
+ throw (new JemmyException("Interrupted!", e));
+ }
+ //move here first
+ smartMove(oper, mio);
+ DriverManager.getButtonDriver(oper).push(mio);
+ return item;
+ }
+ }
+
+ private void smartMove(ComponentOperator last, ComponentOperator oper) {
+ if (last == null) {
+ oper.enterMouse();
+ return;
+ }
+ //get all the coordinates first
+ //previous item
+ long lastXl, lastXr, lastYl, lastYr;
+ lastXl = (long) last.getSource().getLocationOnScreen().getX();
+ lastXr = lastXl + last.getSource().getWidth();
+ lastYl = (long) last.getSource().getLocationOnScreen().getY();
+ lastYr = lastYl + last.getSource().getHeight();
+ //this item
+ long operXl, operXr, operYl, operYr;
+ operXl = (long) oper.getSource().getLocationOnScreen().getX();
+ operXr = operXl + oper.getSource().getWidth();
+ operYl = (long) oper.getSource().getLocationOnScreen().getY();
+ operYr = operYl + oper.getSource().getHeight();
+ //get the overlap borders
+ long overXl, overXr, overYl, overYr;
+ overXl = (lastXl > operXl) ? lastXl : operXl;
+ overXr = (lastXr < operXr) ? lastXr : operXr;
+ overYl = (lastYl > operYl) ? lastYl : operYl;
+ overYr = (lastYr < operYr) ? lastYr : operYr;
+ //now, let's see ...
+ //what if it overlaps by x?
+ if (overXl < overXr) {
+ //good - move mose to the center of the overlap
+ last.moveMouse((int) ((overXr - overXl) / 2 - lastXl),
+ last.getCenterY());
+ //move mouse inside
+ oper.moveMouse((int) ((overXr - overXl) / 2 - operXl),
+ oper.getCenterY());
+ //done - now move to the center
+ oper.enterMouse();
+ return;
+ }
+ //ok, what if it overlaps by y?
+ if (overYl < overYr) {
+ //good - move mose to the center of the overlap
+ last.moveMouse(last.getCenterX(),
+ (int) ((overYr - overYl) / 2 - lastYl));
+ //move mouse inside
+ oper.moveMouse(last.getCenterX(),
+ (int) ((overYr - overYl) / 2 - operYl));
+ //done - now move to the center
+ oper.enterMouse();
+ return;
+ }
+ //well - can't help it
+ oper.enterMouse();
+ }
+
+ protected JPopupMenu waitPopupMenu(final ComponentOperator oper) {
+ return ((JPopupMenu) JPopupMenuOperator.waitJPopupMenu(new ComponentChooser() {
+ @Override
+ public boolean checkComponent(Component comp) {
+ return (comp == ((JMenuOperator) oper).getPopupMenu()
+ && comp.isShowing());
+ }
+
+ @Override
+ public String getDescription() {
+ return ((JMenuOperator) oper).getText() + "'s popup";
+ }
+
+ @Override
+ public String toString() {
+ return "waitPopupMenu.ComponentChooser{description = " + getDescription() + '}';
+ }
+ }).getSource());
+ }
+
+ protected JMenuItem waitItem(ComponentOperator oper, MenuElement element, PathChooser chooser, int depth) {
+ Waiter waiter = new Waiter<>(new JMenuItemWaiter(element, chooser, depth));
+ waiter.setOutput(oper.getOutput().createErrorOutput());
+ waiter.setTimeouts(oper.getTimeouts());
+ try {
+ return (JMenuItem) waiter.waitAction(null);
+ } catch (InterruptedException e) {
+ throw (new JemmyException("Waiting has been interrupted", e));
+ }
+ }
+
+ public static Object getSelectedElement(JMenuBar bar) {
+ MenuElement[] subElements = bar.getSubElements();
+ for (MenuElement subElement : subElements) {
+ if (subElement instanceof JMenu
+ && ((JMenu) subElement).isPopupMenuVisible()) {
+ return subElement;
+ }
+ }
+ return null;
+ }
+
+ private static class JMenuItemWaiter implements Waitable {
+
+ MenuElement cont;
+ PathChooser chooser;
+ int depth;
+
+ public JMenuItemWaiter(MenuElement cont, PathChooser chooser, int depth) {
+ this.cont = cont;
+ this.chooser = chooser;
+ this.depth = depth;
+ }
+
+ @Override
+ public MenuElement actionProduced(Void obj) {
+ if (!((Component) cont).isShowing()) {
+ return null;
+ }
+ MenuElement[] subElements = cont.getSubElements();
+ for (MenuElement subElement : subElements) {
+ if (((Component) subElement).isShowing() && ((Component) subElement).isEnabled()
+ && chooser.checkPathComponent(depth, subElement)) {
+ return subElement;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String getDescription() {
+ return "";
+ }
+
+ @Override
+ public String toString() {
+ return "JMenuItemWaiter{" + "cont=" + cont + ", chooser=" + chooser + ", depth=" + depth + '}';
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/menus/QueueJMenuDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/menus/QueueJMenuDriver.java
new file mode 100644
index 00000000000..d327fb6e67b
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/menus/QueueJMenuDriver.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.menus;
+
+import java.awt.Component;
+import java.awt.Window;
+
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.MenuElement;
+
+import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.JemmyException;
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.Waitable;
+import org.netbeans.jemmy.Waiter;
+import org.netbeans.jemmy.drivers.DescriptablePathChooser;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.MenuDriver;
+import org.netbeans.jemmy.drivers.PathChooser;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JMenuBarOperator;
+import org.netbeans.jemmy.operators.JMenuItemOperator;
+import org.netbeans.jemmy.operators.JMenuOperator;
+import org.netbeans.jemmy.operators.JPopupMenuOperator;
+
+/**
+ *
+ * 100% stable menu driver. Tries to do next steps during one action executed
+ * through EventQueue:
+ * find showing window containing popup
+ * find showing popup
+ * find showing menuitem
+ * enter mouse into it
+ *
+ * Repeats this action as many times as "JMenuOperator.WaitPopupTimeout" timeout
+ * allows.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ *
+ */
+public class QueueJMenuDriver extends LightSupportiveDriver implements MenuDriver {
+
+ QueueTool queueTool;
+
+ public QueueJMenuDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JMenuOperator",
+ "org.netbeans.jemmy.operators.JMenuBarOperator",
+ "org.netbeans.jemmy.operators.JPopupMenuOperator"});
+ queueTool = new QueueTool();
+ }
+
+ @Override
+ public Object pushMenu(final ComponentOperator oper, PathChooser chooser) {
+ queueTool.setOutput(oper.getOutput().createErrorOutput());
+ checkSupported(oper);
+ JMenuItem result;
+ OneReleaseAction action;
+ if (oper instanceof JMenuBarOperator) {
+ action = new OneReleaseAction(chooser, 0, oper, false) {
+ @Override
+ protected void pushAlone(JMenuItemOperator subMenuOper) {
+ if (subMenuOper.getSource() instanceof JMenu
+ && isMenuBarSelected((JMenuBar) oper.getSource())) {
+ DriverManager.getMouseDriver(subMenuOper).enterMouse(subMenuOper);
+ } else {
+ DriverManager.getButtonDriver(subMenuOper).push(subMenuOper);
+ }
+ }
+
+ @Override
+ protected boolean inTheMiddle(JMenuOperator subMenuOper, boolean mousePressed) {
+ if (isMenuBarSelected((JMenuBar) oper.getSource())) {
+ DriverManager.getMouseDriver(subMenuOper).enterMouse(subMenuOper);
+ return false;
+ } else {
+ return super.inTheMiddle(subMenuOper, mousePressed);
+ }
+ }
+
+ @Override
+ protected void process(MenuElement element) {
+ super.process(element);
+ }
+
+ @Override
+ public MenuElement getMenuElement() {
+ return (MenuElement) oper.getSource();
+ }
+ };
+ } else if (oper instanceof JPopupMenuOperator) {
+ action = new OneReleaseAction(chooser, 0, oper, false) {
+ @Override
+ public MenuElement getMenuElement() {
+ return (MenuElement) oper.getSource();
+ }
+ };
+ } else {
+ DriverManager.getButtonDriver(oper).press(oper);
+ action = new OneReleaseAction(chooser, 0, oper, false) {
+ @Override
+ public MenuElement launch() {
+ process((MenuElement) oper.getSource());
+ return (MenuElement) oper.getSource();
+ }
+
+ @Override
+ public MenuElement getMenuElement() {
+ return null;
+ }
+ };
+ }
+ queueTool.waitEmpty(10);
+ queueTool.waitEmpty(10);
+ queueTool.waitEmpty(10);
+ result = runAction(action, oper,
+ oper.getTimeouts().getTimeout("ComponentOperator.WaitComponentTimeout"),
+ (chooser instanceof DescriptablePathChooser)
+ ? ((DescriptablePathChooser) chooser).getDescription()
+ : "Menu pushing");
+ if (result instanceof JMenu) {
+ for (int i = 1; i < chooser.getDepth(); i++) {
+ final JMenu menu = (JMenu) result;
+ final ComponentChooser popupChooser = new PopupMenuChooser(menu);
+ action = new OneReleaseAction(chooser, i, oper, action.mousePressed) {
+ @Override
+ public MenuElement getMenuElement() {
+ Window win = JPopupMenuOperator.findJPopupWindow(popupChooser);
+ if (win != null && win.isShowing()) {
+ return JPopupMenuOperator.findJPopupMenu(win, popupChooser);
+ } else {
+ return null;
+ }
+ }
+ };
+ result = runAction(action, oper,
+ oper.getTimeouts().getTimeout("JMenuOperator.WaitPopupTimeout"),
+ (chooser instanceof DescriptablePathChooser)
+ ? ((DescriptablePathChooser) chooser).getDescription()
+ : "Menu pushing");
+ }
+ }
+ return result;
+ }
+
+ private JMenuItem runAction(final OneReleaseAction action, ComponentOperator env, long waitingTime, final String description) {
+ Waiter waiter = new Waiter<>(new Waitable() {
+ @Override
+ public MenuElement actionProduced(Void param) {
+ return queueTool.invokeSmoothly(action);
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public String toString() {
+ return "runAction.Waiter{description = " + getDescription() + '}';
+ }
+ });
+ waiter.setOutput(env.getOutput().createErrorOutput());
+ waiter.setTimeouts(env.getTimeouts().cloneThis());
+ waiter.getTimeouts().setTimeout("Waiter.WaitingTime",
+ waitingTime);
+ waiter.getTimeouts().setTimeout("Waiter.TimeDelta", 100);
+ //1.5 workaround
+ if (System.getProperty("java.specification.version").compareTo("1.4") > 0) {
+ queueTool.setOutput(env.getOutput().createErrorOutput());
+ queueTool.waitEmpty(10);
+ queueTool.waitEmpty(10);
+ queueTool.waitEmpty(10);
+ }
+ //end of 1.5 workaround
+ try {
+ return (JMenuItem) waiter.waitAction(null);
+ } catch (InterruptedException e) {
+ action.stop();
+ throw (new JemmyException("Waiting has been interrupted", e));
+ }
+ }
+
+ private boolean isMenuBarSelected(JMenuBar bar) {
+ MenuElement[] subElements = bar.getSubElements();
+ for (MenuElement subElement : subElements) {
+ if (subElement instanceof JMenu
+ && ((JMenu) subElement).isPopupMenuVisible()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private abstract class OneReleaseAction extends QueueTool.QueueAction {
+
+ PathChooser chooser;
+ int depth;
+ ComponentOperator env;
+ boolean mousePressed = false;
+ private boolean stopped = false;
+
+ public OneReleaseAction(PathChooser chooser, int depth, ComponentOperator env, boolean mousePressed) {
+ super("Menu pushing");
+ this.chooser = chooser;
+ this.depth = depth;
+ this.env = env;
+ this.mousePressed = mousePressed;
+ }
+
+ protected void pushAlone(JMenuItemOperator subMenuOper) {
+ DriverManager.getButtonDriver(subMenuOper).push(subMenuOper);
+ }
+
+ protected void pushLast(JMenuItemOperator subMenuOper, boolean mousePressed) {
+ DriverManager.getMouseDriver(subMenuOper).enterMouse(subMenuOper);
+ DriverManager.getButtonDriver(subMenuOper).release(subMenuOper);
+ }
+
+ protected boolean inTheMiddle(JMenuOperator subMenuOper, boolean mousePressed) {
+ if (!subMenuOper.isPopupMenuVisible()) {
+ if (!mousePressed) {
+ DriverManager.getMouseDriver(subMenuOper).enterMouse(subMenuOper);
+ DriverManager.getButtonDriver(subMenuOper).press(subMenuOper);
+ } else {
+ DriverManager.getMouseDriver(subMenuOper).enterMouse(subMenuOper);
+ }
+ return true;
+ }
+ return mousePressed;
+ }
+
+ protected void process(MenuElement element) {
+ if (depth == chooser.getDepth() - 1) {
+ JMenuItemOperator subMenuOper = new JMenuItemOperator((JMenuItem) element);
+ subMenuOper.copyEnvironment(env);
+ if (depth == 0) {
+ pushAlone(subMenuOper);
+ } else {
+ pushLast(subMenuOper, mousePressed);
+ }
+ } else if (element instanceof JMenu) {
+ JMenuOperator subMenuOper = new JMenuOperator((JMenu) element);
+ subMenuOper.copyEnvironment(env);
+ mousePressed = inTheMiddle(subMenuOper, mousePressed);
+ } else {
+ throw (new JemmyException("Menu path too long"));
+ }
+ }
+
+ @Override
+ public MenuElement launch() {
+ MenuElement element = getMenuElement();
+ if (element != null) {
+ MenuElement[] subElements = element.getSubElements();
+ for (MenuElement subElement : subElements) {
+ if (((Component) subElement).isShowing()
+ && ((Component) subElement).isEnabled()
+ && chooser.checkPathComponent(depth, subElement)) {
+ process(subElement);
+ return subElement;
+ }
+ if (stopped) {
+ return null;
+ }
+ }
+ }
+ return null;
+ }
+
+ public abstract MenuElement getMenuElement();
+
+ private void stop() {
+ stopped = true;
+ }
+ }
+
+ private static class PopupMenuChooser implements ComponentChooser {
+
+ JMenu menu;
+
+ public PopupMenuChooser(JMenu menu) {
+ this.menu = menu;
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ return (comp == menu.getPopupMenu()
+ && comp.isShowing() && comp.isEnabled());
+ }
+
+ @Override
+ public String getDescription() {
+ return menu.getText() + "'s popup";
+ }
+
+ @Override
+ public String toString() {
+ return "PopupMenuChooser{" + "menu=" + menu + '}';
+ }
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/menus/package-info.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/menus/package-info.java
new file mode 100644
index 00000000000..071b87542c9
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/menus/package-info.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ *
Menu drivers.
+ * Different drivers to perform a menu operations.
+ *
+ */
+package org.netbeans.jemmy.drivers.menus;
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/package-info.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/package-info.java
new file mode 100644
index 00000000000..ab944add2b1
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/package-info.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ *
Drivers interfaces
+ * Contains interfaces of "drivers".
+ * Driver is a class which actually implements action reproducing. There are
+ * different types of drivers (mouse driver, keyboard driver, button drivers,
+ * ...), each of them represented by interface (button driver - by ButtonDriver
+ * interface, ...)
+ * Package also contains some classes allowing to manage driver set.
+ * Subpackages contain driver implementations.
+ * Drivers is low-level API: they are not supposed to be used directly from
+ * test.
+ *
+ * @since 04/17/2002
+ *
+ */
+package org.netbeans.jemmy.drivers;
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/AWTScrollDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/AWTScrollDriver.java
new file mode 100644
index 00000000000..3f8f254f8dd
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/AWTScrollDriver.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.scrolling;
+
+import java.awt.Point;
+
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.MouseDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.Operator;
+
+/**
+ * ScrollDriver for awt components.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public abstract class AWTScrollDriver extends AbstractScrollDriver {
+
+ private QueueTool queueTool;
+
+ /**
+ * Constructs a ChoiceDriver.
+ *
+ * @param supported an array of supported class names
+ */
+ public AWTScrollDriver(String[] supported) {
+ super(supported);
+ queueTool = new QueueTool();
+ }
+
+ @Override
+ protected void step(final ComponentOperator oper, final ScrollAdjuster adj) {
+ if (adj.getScrollDirection() != ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION) {
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Scrolling by clicking with mouse") {
+ @Override
+ public Void launch() {
+ Point clickPoint = getClickPoint(oper, adj.getScrollDirection(), adj.getScrollOrientation());
+ if (clickPoint != null) {
+ DriverManager.getMouseDriver(oper).
+ clickMouse(oper, clickPoint.x, clickPoint.y, 1,
+ Operator.getDefaultMouseButton(),
+ 0,
+ oper.getTimeouts().
+ create("ComponentOperator.MouseClickTimeout"));
+ }
+ return null;
+ }
+ });
+ }
+ }
+
+ @Override
+ protected void jump(ComponentOperator oper, ScrollAdjuster adj) {
+ }
+
+ @Override
+ protected void startPushAndWait(final ComponentOperator oper, final int direction, final int orientation) {
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Scrolling: pressing the mouse button and holding") {
+ @Override
+ public Void launch() {
+ Point clickPoint = getClickPoint(oper, direction, orientation);
+ if (clickPoint != null) {
+ MouseDriver mdriver = DriverManager.getMouseDriver(oper);
+ mdriver.moveMouse(oper, clickPoint.x, clickPoint.y);
+ mdriver.pressMouse(oper, clickPoint.x, clickPoint.y,
+ Operator.getDefaultMouseButton(),
+ 0);
+ }
+ return null;
+ }
+ });
+ }
+
+ @Override
+ protected void stopPushAndWait(final ComponentOperator oper, final int direction, final int orientation) {
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Scrolling: releasing the mouse button") {
+ @Override
+ public Void launch() {
+ Point clickPoint = getClickPoint(oper, direction, orientation);
+ if (clickPoint != null) {
+ MouseDriver mdriver = DriverManager.getMouseDriver(oper);
+ mdriver.releaseMouse(oper, clickPoint.x, clickPoint.y,
+ Operator.getDefaultMouseButton(),
+ 0);
+ }
+ return null;
+ }
+ });
+ }
+
+ @Override
+ protected Point startDragging(ComponentOperator oper) {
+ return null;
+ }
+
+ @Override
+ protected void drop(ComponentOperator oper, Point pnt) {
+ }
+
+ @Override
+ protected void drag(ComponentOperator oper, Point pnt) {
+ }
+
+ @Override
+ protected Timeout getScrollDeltaTimeout(ComponentOperator oper) {
+ return (oper.getTimeouts().
+ create("ScrollbarOperator.DragAndDropScrollingDelta"));
+ }
+
+ @Override
+ protected boolean canDragAndDrop(ComponentOperator oper) {
+ return false;
+ }
+
+ @Override
+ protected boolean canJump(ComponentOperator oper) {
+ return false;
+ }
+
+ @Override
+ protected boolean canPushAndWait(ComponentOperator oper) {
+ return true;
+ }
+
+ @Override
+ protected int getDragAndDropStepLength(ComponentOperator oper) {
+ return 1;
+ }
+
+ /**
+ * Defines a click point which needs to be used in order to
+ * increase/decrease scroller value.
+ *
+ * @param oper an operator.
+ * @param direction - one of the ScrollAdjister.INCREASE_SCROLL_DIRECTION,
+ * ScrollAdjister.DECREASE_SCROLL_DIRECTION,
+ * ScrollAdjister.DO_NOT_TOUCH_SCROLL_DIRECTION values.
+ * @param orientation one of the Adjustable.HORIZONTAL or
+ * Adjustable.VERTICAL values.
+ * @return a point to click.
+ */
+ protected abstract Point getClickPoint(ComponentOperator oper, int direction, int orientation);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/AbstractScrollDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/AbstractScrollDriver.java
new file mode 100644
index 00000000000..e029fadf283
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/AbstractScrollDriver.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.scrolling;
+
+import java.awt.Adjustable;
+import java.awt.Point;
+import org.netbeans.jemmy.JemmyException;
+import org.netbeans.jemmy.JemmyProperties;
+
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.ScrollDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Superclass for all scroll drivers. Contains all the logic of scrolling. Tries
+ * allowed operations in this order: "jump", "drag'n'drop", "push'n'wait",
+ * "step". Repeats "step" scrolling while scroller value is not equal to the
+ * necessary value, but no more than {@code ADJUST_CLICK_COUNT}.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public abstract class AbstractScrollDriver extends LightSupportiveDriver implements ScrollDriver {
+
+ /**
+ * Maximal number of attempts to reach required position by minimal
+ * scrolling operation.
+ */
+ public static final int ADJUST_CLICK_COUNT = 10;
+ public static final String SCROLL_FREEZE_TIMEOUT = AbstractScrollDriver.class.getName() + ".freeze.timeout";
+
+ static {
+ JemmyProperties.getProperties().initTimeout(SCROLL_FREEZE_TIMEOUT, 1000);
+ }
+
+ /**
+ * Constructs an AbstractScrollDriver.
+ *
+ * @param supported an array of supported class names
+ */
+ public AbstractScrollDriver(String[] supported) {
+ super(supported);
+ }
+
+ @Override
+ public void scroll(ComponentOperator oper, ScrollAdjuster adj) {
+ if (canJump(oper)) {
+ doJumps(oper, adj);
+ }
+ if (canDragAndDrop(oper)) {
+ doDragAndDrop(oper, adj);
+ }
+ if (canPushAndWait(oper)) {
+ if (!doPushAndWait(oper, adj, oper.getTimeouts().getTimeout(SCROLL_FREEZE_TIMEOUT))) {
+ throw new JemmyException("Scrolling stuck for more than "
+ + oper.getTimeouts().getTimeout(SCROLL_FREEZE_TIMEOUT)
+ + " on " + oper);
+ }
+ }
+ for (int i = 0; i < ADJUST_CLICK_COUNT; i++) {
+ doSteps(oper, adj);
+ }
+ }
+
+ /**
+ * Performs minimal scrolling step.
+ *
+ * @param oper an operator.
+ * @param adj a scroll adjuster
+ */
+ protected abstract void step(ComponentOperator oper, ScrollAdjuster adj);
+
+ /**
+ * Performs maximal scroll step.
+ *
+ * @param oper an operator.
+ * @param adj a scroll adjuster
+ */
+ protected abstract void jump(ComponentOperator oper, ScrollAdjuster adj);
+
+ /**
+ * Presses something like a scroll button.
+ *
+ * @param oper an operator.
+ * @param direction - one of the ScrollAdjister.INCREASE_SCROLL_DIRECTION,
+ * ScrollAdjister.DECREASE_SCROLL_DIRECTION,
+ * ScrollAdjister.DO_NOT_TOUCH_SCROLL_DIRECTION values.
+ * @param orientation one of the Adjustable.HORIZONTAL or
+ * Adjustable.VERTICAL values.
+ */
+ protected abstract void startPushAndWait(ComponentOperator oper, int direction, int orientation);
+
+ /**
+ * Releases something like a scroll button.
+ *
+ * @param oper an operator.
+ * @param direction - one of the ScrollAdjister.INCREASE_SCROLL_DIRECTION,
+ * ScrollAdjister.DECREASE_SCROLL_DIRECTION,
+ * ScrollAdjister.DO_NOT_TOUCH_SCROLL_DIRECTION values.
+ * @param orientation one of the Adjustable.HORIZONTAL or
+ * Adjustable.VERTICAL values.
+ */
+ protected abstract void stopPushAndWait(ComponentOperator oper, int direction, int orientation);
+
+ /**
+ * Starts drag'n'drop scrolling.
+ *
+ * @param oper an operator.
+ * @return start drugging point.
+ */
+ protected abstract Point startDragging(ComponentOperator oper);
+
+ /**
+ * Drop at a specified point.
+ *
+ * @param oper an operator.
+ * @param pnt the point to drop.
+ */
+ protected abstract void drop(ComponentOperator oper, Point pnt);
+
+ /**
+ * Drag to a specified point.
+ *
+ * @param oper an operator.
+ * @param pnt the point to drag to.
+ */
+ protected abstract void drag(ComponentOperator oper, Point pnt);
+
+ /**
+ * Returns a timeout for sleeping between verifications during "push and
+ * wait" scrolling.
+ *
+ * @param oper an operator.
+ * @return a timeout
+ */
+ protected abstract Timeout getScrollDeltaTimeout(ComponentOperator oper);
+
+ /**
+ * Tells if this driver allows to perform drag'n'drop scrolling.
+ *
+ * @param oper an operator.
+ * @return true if this driver allows to drag'n'drop.
+ */
+ protected abstract boolean canDragAndDrop(ComponentOperator oper);
+
+ /**
+ * Tells if this driver allows to perform jumps.
+ *
+ * @param oper an operator.
+ * @return true if this driver allows to jump.
+ */
+ protected abstract boolean canJump(ComponentOperator oper);
+
+ /**
+ * Tells if this driver allows to perform "push and wait" scrolling.
+ *
+ * @param oper an operator.
+ * @return true if this driver allows to "push and wait".
+ */
+ protected abstract boolean canPushAndWait(ComponentOperator oper);
+
+ /**
+ * Returns a number of pixels in one drag and drop scrolling.
+ *
+ * @param oper an operator.
+ * @return drag'n'drop step length.
+ */
+ protected abstract int getDragAndDropStepLength(ComponentOperator oper);
+
+ /**
+ * Performs drag'n'drop scrolling till scroller's value does not cross
+ * required value.
+ *
+ * @param oper an operator.
+ * @param adj a scroll adjuster
+ */
+ protected void doDragAndDrop(ComponentOperator oper, ScrollAdjuster adj) {
+ int direction = adj.getScrollDirection();
+ if (direction != ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION) {
+ Point pnt = startDragging(oper);
+ while (adj.getScrollDirection() == direction) {
+ drag(oper, pnt = increasePoint(oper, pnt, adj, direction));
+ }
+ drop(oper, pnt);
+ }
+ }
+
+ /**
+ * Performs jump scrolling till scroller's value does not cross required
+ * value.
+ *
+ * @param oper an operator.
+ * @param adj a scroll adjuster
+ */
+ protected void doJumps(ComponentOperator oper, ScrollAdjuster adj) {
+ int direction = adj.getScrollDirection();
+ if (direction != ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION) {
+ while (adj.getScrollDirection() == direction) {
+ jump(oper, adj);
+ }
+ }
+ }
+
+ protected abstract int position(ComponentOperator oper, int orientation);
+
+ /**
+ * Performs "push and wait" scrolling till scroller's value does not cross
+ * required value.
+ *
+ * @param oper an operator.
+ * @param adj a scroll adjuster
+ */
+ protected boolean doPushAndWait(ComponentOperator oper, ScrollAdjuster adj, long freezeTimeout) {
+ int direction = adj.getScrollDirection();
+ int orientation = adj.getScrollOrientation();
+ int position = position(oper, orientation);
+ long lastChanded = System.currentTimeMillis();
+ if (direction != ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION) {
+ Timeout delta = getScrollDeltaTimeout(oper);
+ startPushAndWait(oper, direction, orientation);
+ while (adj.getScrollDirection() == direction) {
+ delta.sleep();
+ int curPosition = position(oper, orientation);
+ if (curPosition != position) {
+ position = curPosition;
+ lastChanded = System.currentTimeMillis();
+ } else if ((System.currentTimeMillis() - lastChanded) > freezeTimeout) {
+ return false;
+ }
+ }
+ stopPushAndWait(oper, direction, orientation);
+ }
+ return true;
+ }
+
+ /**
+ * Performs minimal scrollings till scroller's value does not cross required
+ * value.
+ *
+ * @param oper an operator.
+ * @param adj a scroll adjuster
+ */
+ protected void doSteps(ComponentOperator oper, ScrollAdjuster adj) {
+ int direction = adj.getScrollDirection();
+ if (direction != ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION) {
+ while (adj.getScrollDirection() == direction) {
+ step(oper, adj);
+ }
+ }
+ }
+
+ private Point increasePoint(ComponentOperator oper, Point pnt, ScrollAdjuster adj, int direction) {
+ return ((adj.getScrollOrientation() == Adjustable.HORIZONTAL)
+ ? new Point(pnt.x + ((direction == 1) ? 1 : -1) * getDragAndDropStepLength(oper), pnt.y)
+ : new Point(pnt.x, pnt.y + ((direction == 1) ? 1 : -1) * getDragAndDropStepLength(oper)));
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JScrollBarAPIDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JScrollBarAPIDriver.java
new file mode 100644
index 00000000000..c50f6f5832a
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JScrollBarAPIDriver.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.scrolling;
+
+import java.awt.Point;
+
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JScrollBarOperator;
+
+/**
+ * ScrollDriver for javax.swing.JScrollBar component type.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class JScrollBarAPIDriver extends AbstractScrollDriver {
+
+ private final static int SMALL_INCREMENT = 1;
+
+ /**
+ * Constructs a JScrollBarDriver.
+ */
+ public JScrollBarAPIDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JScrollBarOperator"});
+ }
+
+ @Override
+ protected int position(ComponentOperator oper, int orientation) {
+ return ((JScrollBarOperator) oper).getValue();
+ }
+
+ @Override
+ public void scrollToMinimum(ComponentOperator oper, int orientation) {
+ JScrollBarOperator scroll = (JScrollBarOperator) oper;
+ setValue(oper, scroll.getMinimum());
+ }
+
+ @Override
+ public void scrollToMaximum(ComponentOperator oper, int orientation) {
+ JScrollBarOperator scroll = (JScrollBarOperator) oper;
+ setValue(oper, scroll.getMaximum() - scroll.getVisibleAmount());
+ }
+
+ @Override
+ protected void step(ComponentOperator oper, ScrollAdjuster adj) {
+ JScrollBarOperator scroll = (JScrollBarOperator) oper;
+ int newValue = -1;
+ if (adj.getScrollDirection() == ScrollAdjuster.DECREASE_SCROLL_DIRECTION) {
+ newValue = (scroll.getValue() > scroll.getMinimum()
+ + scroll.getUnitIncrement())
+ ? scroll.getValue() - scroll.getUnitIncrement()
+ : scroll.getMinimum();
+ } else if (adj.getScrollDirection() == ScrollAdjuster.INCREASE_SCROLL_DIRECTION) {
+ newValue = (scroll.getValue() < scroll.getMaximum()
+ - scroll.getVisibleAmount() - scroll.getUnitIncrement())
+ ? scroll.getValue() + scroll.getUnitIncrement()
+ : scroll.getMaximum();
+ }
+ setValue(oper, newValue);
+ }
+
+ private void setValue(ComponentOperator oper, int value) {
+ if (value != -1) {
+ ((JScrollBarOperator) oper).setValue(value);
+ }
+ }
+
+ @Override
+ protected Timeout getScrollDeltaTimeout(ComponentOperator oper) {
+ return (oper.getTimeouts().
+ create("JScrollBarOperator.DragAndDropScrollingDelta"));
+ }
+
+ @Override
+ protected void jump(final ComponentOperator oper, final ScrollAdjuster adj) {
+ JScrollBarOperator scroll = (JScrollBarOperator) oper;
+ int newValue = -1;
+ if (adj.getScrollDirection() == ScrollAdjuster.DECREASE_SCROLL_DIRECTION) {
+ newValue = (scroll.getValue() > scroll.getMinimum()
+ + scroll.getBlockIncrement())
+ ? scroll.getValue() - scroll.getBlockIncrement()
+ : scroll.getMinimum();
+ } else if (adj.getScrollDirection() == ScrollAdjuster.INCREASE_SCROLL_DIRECTION) {
+ newValue = (scroll.getValue() < scroll.getMaximum()
+ - scroll.getVisibleAmount() - scroll.getBlockIncrement())
+ ? scroll.getValue() + scroll.getBlockIncrement()
+ : scroll.getMaximum();
+ }
+ setValue(oper, newValue);
+ }
+
+ @Override
+ protected void startPushAndWait(ComponentOperator oper, int direction, int orientation) {
+ }
+
+ @Override
+ protected void stopPushAndWait(ComponentOperator oper, int direction, int orientation) {
+ }
+
+ @Override
+ protected Point startDragging(ComponentOperator oper) {
+ return null;
+ }
+
+ @Override
+ protected void drop(ComponentOperator oper, Point pnt) {
+ }
+
+ @Override
+ protected void drag(ComponentOperator oper, Point pnt) {
+ }
+
+ @Override
+ protected boolean canDragAndDrop(ComponentOperator oper) {
+ return false;
+ }
+
+ @Override
+ protected boolean canJump(ComponentOperator oper) {
+ return isSmallIncrement((JScrollBarOperator) oper);
+ }
+
+ @Override
+ protected boolean canPushAndWait(ComponentOperator oper) {
+ return false;
+ }
+
+ @Override
+ protected int getDragAndDropStepLength(ComponentOperator oper) {
+ return 1;
+ }
+
+ private boolean isSmallIncrement(JScrollBarOperator oper) {
+ return (oper.getUnitIncrement(-1) <= SMALL_INCREMENT
+ && oper.getUnitIncrement(1) <= SMALL_INCREMENT);
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JScrollBarDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JScrollBarDriver.java
new file mode 100644
index 00000000000..98e37595008
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JScrollBarDriver.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.scrolling;
+
+import java.awt.Point;
+
+import javax.swing.JScrollBar;
+
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.MouseDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JButtonOperator;
+import org.netbeans.jemmy.operators.JScrollBarOperator;
+import org.netbeans.jemmy.operators.Operator;
+
+/**
+ * ScrollDriver for javax.swing.JScrollBar component type.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class JScrollBarDriver extends AbstractScrollDriver {
+
+ private final static int SMALL_INCREMENT = 1;
+ private final static int MINIMAL_DRAGGER_SIZE = 5;
+ private final static int RELATIVE_DRAG_STEP_LENGTH = 20;
+
+ private QueueTool queueTool;
+
+ /**
+ * Constructs a JScrollBarDriver.
+ */
+ public JScrollBarDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JScrollBarOperator"});
+ queueTool = new QueueTool();
+ }
+
+ @Override
+ protected int position(ComponentOperator oper, int orientation) {
+ return ((JScrollBarOperator) oper).getValue();
+ }
+
+ @Override
+ public void scrollToMinimum(ComponentOperator oper, int orientation) {
+ startDragging(oper);
+ Point pnt = new Point(0, 0);
+ drag(oper, pnt);
+ Timeout sleepTime = oper.getTimeouts().create("Waiter.TimeDelta");
+ while (((JScrollBarOperator) oper).getValue()
+ > ((JScrollBarOperator) oper).getMinimum()) {
+ sleepTime.sleep();
+ }
+ drop(oper, pnt);
+ }
+
+ @Override
+ public void scrollToMaximum(ComponentOperator oper, int orientation) {
+ startDragging(oper);
+ Point pnt = new Point(oper.getWidth() - 1, oper.getHeight() - 1);
+ drag(oper, pnt);
+ Timeout sleepTime = oper.getTimeouts().create("Waiter.TimeDelta");
+ while (((JScrollBarOperator) oper).getValue()
+ > (((JScrollBarOperator) oper).getMaximum()
+ - ((JScrollBarOperator) oper).getVisibleAmount())) {
+ sleepTime.sleep();
+ }
+ drop(oper, pnt);
+ }
+
+ @Override
+ protected void step(ComponentOperator oper, ScrollAdjuster adj) {
+ JButtonOperator boper = findAButton(oper, adj.getScrollDirection());
+ DriverManager.getButtonDriver(boper).push(boper);
+ }
+
+ @Override
+ protected void jump(final ComponentOperator oper, final ScrollAdjuster adj) {
+ final JButtonOperator lessButton = findAButton(oper, ScrollAdjuster.DECREASE_SCROLL_DIRECTION);
+ final JButtonOperator moreButton = findAButton(oper, ScrollAdjuster.INCREASE_SCROLL_DIRECTION);
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Scrolling by clicking with the mouse") {
+ @Override
+ public Void launch() {
+ if (adj.getScrollDirection() != ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION) {
+ int x, y;
+ switch (((JScrollBarOperator) oper).getOrientation()) {
+ case JScrollBar.HORIZONTAL:
+ switch (adj.getScrollDirection()) {
+ case ScrollAdjuster.INCREASE_SCROLL_DIRECTION:
+ x = moreButton.getX() - 1;
+ break;
+ case ScrollAdjuster.DECREASE_SCROLL_DIRECTION:
+ x = lessButton.getX() + lessButton.getWidth();
+ break;
+ default:
+ return null;
+ }
+ y = lessButton.getHeight() / 2;
+ break;
+ case JScrollBar.VERTICAL:
+ switch (adj.getScrollDirection()) {
+ case ScrollAdjuster.INCREASE_SCROLL_DIRECTION:
+ y = moreButton.getY() - 1;
+ break;
+ case ScrollAdjuster.DECREASE_SCROLL_DIRECTION:
+ y = lessButton.getY() + lessButton.getHeight();
+ break;
+ default:
+ return null;
+ }
+ x = lessButton.getWidth() / 2;
+ break;
+ default:
+ return null;
+ }
+ DriverManager.getMouseDriver(oper).
+ clickMouse(oper, x, y, 1, Operator.getDefaultMouseButton(), 0, new Timeout("", 0));
+ }
+ return null;
+ }
+ });
+ }
+
+ @Override
+ protected void startPushAndWait(ComponentOperator oper, int direction, int orientation) {
+ JButtonOperator boper = findAButton(oper, direction);
+ DriverManager.getButtonDriver(boper).press(boper);
+ }
+
+ @Override
+ protected void stopPushAndWait(ComponentOperator oper, int direction, int orientation) {
+ JButtonOperator boper = findAButton(oper, direction);
+ DriverManager.getButtonDriver(boper).release(boper);
+ }
+
+ @Override
+ protected Point startDragging(ComponentOperator oper) {
+ JButtonOperator lessButton = findAButton(oper, ScrollAdjuster.DECREASE_SCROLL_DIRECTION);
+ JButtonOperator moreButton = findAButton(oper, ScrollAdjuster.INCREASE_SCROLL_DIRECTION);
+ Point pnt = getClickPoint((JScrollBarOperator) oper, lessButton, moreButton, ((JScrollBarOperator) oper).getValue());
+ MouseDriver mdriver = DriverManager.getMouseDriver(oper);
+ mdriver.moveMouse(oper, pnt.x, pnt.y);
+ mdriver.pressMouse(oper, pnt.x, pnt.y, Operator.getDefaultMouseButton(), 0);
+ return pnt;
+ }
+
+ @Override
+ protected void drop(ComponentOperator oper, Point pnt) {
+ DriverManager.getMouseDriver(oper).
+ releaseMouse(oper, pnt.x, pnt.y, Operator.getDefaultMouseButton(), 0);
+ }
+
+ @Override
+ protected void drag(ComponentOperator oper, Point pnt) {
+ DriverManager.getMouseDriver(oper).
+ dragMouse(oper, pnt.x, pnt.y, Operator.getDefaultMouseButton(), 0);
+ }
+
+ @Override
+ protected Timeout getScrollDeltaTimeout(ComponentOperator oper) {
+ return (oper.getTimeouts().
+ create("ScrollbarOperator.DragAndDropScrollingDelta"));
+ }
+
+ @Override
+ protected boolean canDragAndDrop(ComponentOperator oper) {
+ if (!isSmallIncrement((JScrollBarOperator) oper)) {
+ return false;
+ }
+ boolean result = false;
+ MouseDriver mdriver = DriverManager.getMouseDriver(oper);
+ JButtonOperator less = findAButton(oper, ScrollAdjuster.DECREASE_SCROLL_DIRECTION);
+ JButtonOperator more = findAButton(oper, ScrollAdjuster.INCREASE_SCROLL_DIRECTION);
+ Point pnt = getClickPoint((JScrollBarOperator) oper, less, more, ((JScrollBarOperator) oper).getValue());
+ mdriver.moveMouse(oper, pnt.x, pnt.y);
+ mdriver.pressMouse(oper, pnt.x, pnt.y, Operator.getDefaultMouseButton(), 0);
+ result = ((JScrollBarOperator) oper).getValueIsAdjusting();
+ mdriver.releaseMouse(oper, pnt.x, pnt.y, Operator.getDefaultMouseButton(), 0);
+ return result && isSmallIncrement((JScrollBarOperator) oper);
+ }
+
+ @Override
+ protected boolean canJump(ComponentOperator oper) {
+ return isSmallIncrement((JScrollBarOperator) oper);
+ }
+
+ @Override
+ protected boolean canPushAndWait(ComponentOperator oper) {
+ return isSmallIncrement((JScrollBarOperator) oper);
+ }
+
+ @Override
+ protected int getDragAndDropStepLength(ComponentOperator oper) {
+ JButtonOperator less = findAButton(oper, ScrollAdjuster.DECREASE_SCROLL_DIRECTION);
+ JButtonOperator more = findAButton(oper, ScrollAdjuster.INCREASE_SCROLL_DIRECTION);
+ int width = oper.getWidth() - less.getWidth() - more.getWidth();
+ int height = oper.getHeight() - less.getHeight() - more.getHeight();
+ int max = (width > height) ? width : height;
+ if (max >= RELATIVE_DRAG_STEP_LENGTH * 2) {
+ return max / RELATIVE_DRAG_STEP_LENGTH;
+ } else {
+ return 1;
+ }
+ }
+
+ private boolean isSmallIncrement(JScrollBarOperator oper) {
+ return (oper.getUnitIncrement(-1) <= SMALL_INCREMENT
+ && oper.getUnitIncrement(1) <= SMALL_INCREMENT);
+ }
+
+ private Point getClickPoint(JScrollBarOperator oper, JButtonOperator lessButton, JButtonOperator moreButton, int value) {
+ int lenght = (oper.getOrientation() == JScrollBar.HORIZONTAL)
+ ? oper.getWidth() - lessButton.getWidth() - moreButton.getWidth()
+ : oper.getHeight() - lessButton.getHeight() - moreButton.getHeight();
+ int subpos = (int) (((float) lenght / (oper.getMaximum() - oper.getMinimum())) * value);
+ if (oper.getOrientation() == JScrollBar.HORIZONTAL) {
+ subpos = subpos + lessButton.getWidth();
+ } else {
+ subpos = subpos + lessButton.getHeight();
+ }
+ subpos = subpos + MINIMAL_DRAGGER_SIZE / 2 + 1;
+ return ((oper.getOrientation() == JScrollBar.HORIZONTAL)
+ ? new Point(subpos, oper.getHeight() / 2)
+ : new Point(oper.getWidth() / 2, subpos));
+ }
+
+ private JButtonOperator findAButton(ComponentOperator oper, int direction) {
+ return ((direction == ScrollAdjuster.DECREASE_SCROLL_DIRECTION)
+ ? ((JScrollBarOperator) oper).getDecreaseButton()
+ : ((JScrollBarOperator) oper).getIncreaseButton());
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JSliderAPIDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JSliderAPIDriver.java
new file mode 100644
index 00000000000..290c431f6f6
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JSliderAPIDriver.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.scrolling;
+
+import java.awt.Point;
+
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JSliderOperator;
+
+/**
+ * A scroll driver serving JSlider component.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class JSliderAPIDriver extends AbstractScrollDriver {
+
+ private final static int SMALL_INCREMENT = 1;
+
+ /**
+ * Constructs a JSliderDriver object.
+ */
+ public JSliderAPIDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JSliderOperator"});
+ }
+
+ @Override
+ protected int position(ComponentOperator oper, int orientation) {
+ return ((JSliderOperator) oper).getValue();
+ }
+
+ @Override
+ public void scrollToMinimum(final ComponentOperator oper, int orientation) {
+ ((JSliderOperator) oper).setValue(((JSliderOperator) oper).getMinimum());
+ }
+
+ @Override
+ public void scrollToMaximum(final ComponentOperator oper, int orientation) {
+ ((JSliderOperator) oper).setValue(((JSliderOperator) oper).getMaximum());
+ }
+
+ @Override
+ protected void step(ComponentOperator oper, ScrollAdjuster adj) {
+ JSliderOperator scroll = (JSliderOperator) oper;
+ int newValue = -1;
+ if (adj.getScrollDirection() == ScrollAdjuster.DECREASE_SCROLL_DIRECTION) {
+ newValue = (scroll.getValue() > scroll.getMinimum()
+ + getUnitIncrement(scroll))
+ ? scroll.getValue() - getUnitIncrement(scroll)
+ : scroll.getMinimum();
+ } else if (adj.getScrollDirection() == ScrollAdjuster.INCREASE_SCROLL_DIRECTION) {
+ newValue = (scroll.getValue() < scroll.getMaximum()
+ - getUnitIncrement(scroll))
+ ? scroll.getValue() + getUnitIncrement(scroll)
+ : scroll.getMaximum();
+ }
+ setValue(oper, newValue);
+ }
+
+ private void setValue(ComponentOperator oper, int value) {
+ if (value != -1) {
+ ((JSliderOperator) oper).setValue(value);
+ }
+ }
+
+ @Override
+ protected Timeout getScrollDeltaTimeout(ComponentOperator oper) {
+ return (oper.getTimeouts().
+ create("JSliderOperator.ScrollingDelta"));
+ }
+
+ @Override
+ protected void jump(final ComponentOperator oper, final ScrollAdjuster adj) {
+ JSliderOperator scroll = (JSliderOperator) oper;
+ int newValue = -1;
+ if (adj.getScrollDirection() == ScrollAdjuster.DECREASE_SCROLL_DIRECTION) {
+ newValue = (scroll.getValue() > scroll.getMinimum()
+ + getBlockIncrement(scroll))
+ ? scroll.getValue() - getBlockIncrement(scroll)
+ : scroll.getMinimum();
+ } else if (adj.getScrollDirection() == ScrollAdjuster.INCREASE_SCROLL_DIRECTION) {
+ newValue = (scroll.getValue() < scroll.getMaximum()
+ - getBlockIncrement(scroll))
+ ? scroll.getValue() + getBlockIncrement(scroll)
+ : scroll.getMaximum();
+ }
+ setValue(oper, newValue);
+ }
+
+ @Override
+ protected void startPushAndWait(ComponentOperator oper, int direction, int orientation) {
+ }
+
+ @Override
+ protected void stopPushAndWait(ComponentOperator oper, int direction, int orientation) {
+ }
+
+ @Override
+ protected Point startDragging(ComponentOperator oper) {
+ return null;
+ }
+
+ @Override
+ protected void drop(ComponentOperator oper, Point pnt) {
+ }
+
+ @Override
+ protected void drag(ComponentOperator oper, Point pnt) {
+ }
+
+ @Override
+ protected boolean canDragAndDrop(ComponentOperator oper) {
+ return false;
+ }
+
+ @Override
+ protected boolean canJump(ComponentOperator oper) {
+ return isSmallIncrement((JSliderOperator) oper);
+ }
+
+ @Override
+ protected boolean canPushAndWait(ComponentOperator oper) {
+ return false;
+ }
+
+ @Override
+ protected int getDragAndDropStepLength(ComponentOperator oper) {
+ return 1;
+ }
+
+ private int getUnitIncrement(JSliderOperator oper) {
+ return ((oper.getMinorTickSpacing() == 0)
+ ? 1
+ : oper.getMinorTickSpacing());
+ }
+
+ private int getBlockIncrement(JSliderOperator oper) {
+ return ((oper.getMajorTickSpacing() == 0)
+ ? 1
+ : oper.getMajorTickSpacing());
+ }
+
+ private boolean isSmallIncrement(JSliderOperator oper) {
+ return (oper.getMajorTickSpacing() <= SMALL_INCREMENT
+ && oper.getMajorTickSpacing() <= SMALL_INCREMENT);
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JSliderDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JSliderDriver.java
new file mode 100644
index 00000000000..692f5fbbdd6
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JSliderDriver.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.scrolling;
+
+import java.awt.Point;
+
+import javax.swing.JSlider;
+
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.MouseDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JSliderOperator;
+import org.netbeans.jemmy.operators.Operator;
+
+/**
+ * A scroll driver serving JSlider component.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class JSliderDriver extends AbstractScrollDriver {
+
+ private QueueTool queueTool;
+
+ /**
+ * Constructs a JSliderDriver object.
+ */
+ public JSliderDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JSliderOperator"});
+ queueTool = new QueueTool();
+ }
+
+ @Override
+ protected int position(ComponentOperator oper, int orientation) {
+ return ((JSliderOperator) oper).getValue();
+ }
+
+ @Override
+ public void scrollToMinimum(final ComponentOperator oper, int orientation) {
+ checkSupported(oper);
+ scroll(oper,
+ new ScrollAdjuster() {
+ @Override
+ public int getScrollDirection() {
+ return ((((JSliderOperator) oper).getMinimum()
+ < ((JSliderOperator) oper).getValue())
+ ? DECREASE_SCROLL_DIRECTION
+ : DO_NOT_TOUCH_SCROLL_DIRECTION);
+ }
+
+ @Override
+ public int getScrollOrientation() {
+ return ((JSliderOperator) oper).getOrientation();
+ }
+
+ @Override
+ public String getDescription() {
+ return "Scroll to minimum";
+ }
+
+ @Override
+ public String toString() {
+ return "scrollToMinimum.ScrollAdjuster{description = " + getDescription() + '}';
+ }
+ });
+ }
+
+ @Override
+ public void scrollToMaximum(final ComponentOperator oper, int orientation) {
+ checkSupported(oper);
+ scroll(oper,
+ new ScrollAdjuster() {
+ @Override
+ public int getScrollDirection() {
+ return ((((JSliderOperator) oper).getMaximum()
+ > ((JSliderOperator) oper).getValue())
+ ? INCREASE_SCROLL_DIRECTION
+ : DO_NOT_TOUCH_SCROLL_DIRECTION);
+ }
+
+ @Override
+ public int getScrollOrientation() {
+ return ((JSliderOperator) oper).getOrientation();
+ }
+
+ @Override
+ public String getDescription() {
+ return "Scroll to maximum";
+ }
+
+ @Override
+ public String toString() {
+ return "scrollToMaximum.ScrollAdjuster{description = " + getDescription() + '}';
+ }
+ });
+ }
+
+ @Override
+ protected void step(final ComponentOperator oper, final ScrollAdjuster adj) {
+ if (adj.getScrollDirection() != ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION) {
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Scrolling by clicking with the mouse") {
+ @Override
+ public Void launch() {
+ Point clickPoint = getClickPoint(oper, adj.getScrollDirection(), adj.getScrollOrientation());
+ if (clickPoint != null) {
+ DriverManager.getMouseDriver(oper).
+ clickMouse(oper, clickPoint.x, clickPoint.y, 1,
+ Operator.getDefaultMouseButton(),
+ 0,
+ oper.getTimeouts().
+ create("ComponentOperator.MouseClickTimeout"));
+ }
+ return null;
+ }
+ });
+ }
+ }
+
+ @Override
+ protected void jump(ComponentOperator oper, ScrollAdjuster adj) {
+ //cannot
+ }
+
+ @Override
+ protected void startPushAndWait(final ComponentOperator oper, final int direction, final int orientation) {
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Start scrolling") {
+ @Override
+ public Void launch() {
+ Point clickPoint = getClickPoint(oper, direction, orientation);
+ if (clickPoint != null) {
+ MouseDriver mdriver = DriverManager.getMouseDriver(oper);
+ mdriver.moveMouse(oper, clickPoint.x, clickPoint.y);
+ mdriver.pressMouse(oper, clickPoint.x, clickPoint.y,
+ Operator.getDefaultMouseButton(),
+ 0);
+ }
+ return null;
+ }
+ });
+ }
+
+ @Override
+ protected void stopPushAndWait(final ComponentOperator oper, final int direction, final int orientation) {
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Stop scrolling") {
+ @Override
+ public Void launch() {
+ Point clickPoint = getClickPoint(oper, direction, orientation);
+ if (clickPoint != null) {
+ MouseDriver mdriver = DriverManager.getMouseDriver(oper);
+ mdriver.releaseMouse(oper, clickPoint.x, clickPoint.y,
+ Operator.getDefaultMouseButton(),
+ 0);
+ }
+ return null;
+ }
+ });
+ }
+
+ @Override
+ protected Point startDragging(ComponentOperator oper) {
+ //cannot
+ return null;
+ }
+
+ @Override
+ protected void drop(ComponentOperator oper, Point pnt) {
+ //cannot
+ }
+
+ @Override
+ protected void drag(ComponentOperator oper, Point pnt) {
+ //cannot
+ }
+
+ @Override
+ protected Timeout getScrollDeltaTimeout(ComponentOperator oper) {
+ return oper.getTimeouts().create("JSliderOperator.ScrollingDelta");
+ }
+
+ @Override
+ protected boolean canDragAndDrop(ComponentOperator oper) {
+ return false;
+ }
+
+ @Override
+ protected boolean canJump(ComponentOperator oper) {
+ return false;
+ }
+
+ @Override
+ protected boolean canPushAndWait(ComponentOperator oper) {
+ return true;
+ }
+
+ @Override
+ protected int getDragAndDropStepLength(ComponentOperator oper) {
+ return 0;
+ }
+
+ private Point getClickPoint(ComponentOperator oper, int direction, int orientation) {
+ int x, y;
+ boolean inverted = ((JSliderOperator) oper).getInverted();
+ int realDirection = ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION;
+ if (inverted) {
+ if (direction == ScrollAdjuster.INCREASE_SCROLL_DIRECTION) {
+ realDirection = ScrollAdjuster.DECREASE_SCROLL_DIRECTION;
+ } else if (direction == ScrollAdjuster.DECREASE_SCROLL_DIRECTION) {
+ realDirection = ScrollAdjuster.INCREASE_SCROLL_DIRECTION;
+ } else {
+ return null;
+ }
+ } else {
+ realDirection = direction;
+ }
+ if (orientation == JSlider.HORIZONTAL) {
+ if (realDirection == ScrollAdjuster.INCREASE_SCROLL_DIRECTION) {
+ x = oper.getWidth() - 1;
+ } else if (realDirection == ScrollAdjuster.DECREASE_SCROLL_DIRECTION) {
+ x = 0;
+ } else {
+ return null;
+ }
+ y = oper.getHeight() / 2;
+ } else if (orientation == JSlider.VERTICAL) {
+ if (realDirection == ScrollAdjuster.INCREASE_SCROLL_DIRECTION) {
+ y = 0;
+ } else if (realDirection == ScrollAdjuster.DECREASE_SCROLL_DIRECTION) {
+ y = oper.getHeight() - 1;
+ } else {
+ return null;
+ }
+ x = oper.getWidth() / 2;
+ } else {
+ return null;
+ }
+ return new Point(x, y);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JSpinnerDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JSpinnerDriver.java
new file mode 100644
index 00000000000..9c7389d0100
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JSpinnerDriver.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.scrolling;
+
+import javax.swing.SwingConstants;
+
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.ScrollDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JButtonOperator;
+import org.netbeans.jemmy.operators.JSpinnerOperator;
+
+/**
+ * A scroll driver serving JSpinner component.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class JSpinnerDriver extends LightSupportiveDriver implements ScrollDriver {
+
+ /**
+ * Constructs a JSpinnerDriver object.
+ */
+ public JSpinnerDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JSpinnerOperator"});
+ }
+
+ @Override
+ public void scrollToMinimum(final ComponentOperator oper, int orientation) {
+ Object minimum = ((JSpinnerOperator) oper).getMinimum();
+ if (minimum == null) {
+ throw (new JSpinnerOperator.SpinnerModelException("Impossible to get a minimum of JSpinner model.", oper.getSource()));
+ }
+ scroll(oper, new ScrollAdjuster() {
+ @Override
+ public int getScrollOrientation() {
+ return SwingConstants.VERTICAL;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Spin to minimum";
+ }
+
+ @Override
+ public int getScrollDirection() {
+ if (((JSpinnerOperator) oper).getModel().getPreviousValue() != null) {
+ return ScrollAdjuster.DECREASE_SCROLL_DIRECTION;
+ } else {
+ return ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "scrollToMinimum.ScrollAdjuster{description = " + getDescription() + '}';
+ }
+ });
+ }
+
+ @Override
+ public void scrollToMaximum(final ComponentOperator oper, int orientation) {
+ Object maximum = ((JSpinnerOperator) oper).getMaximum();
+ if (maximum == null) {
+ throw (new JSpinnerOperator.SpinnerModelException("Impossible to get a maximum of JSpinner model.", oper.getSource()));
+ }
+ scroll(oper, new ScrollAdjuster() {
+ @Override
+ public int getScrollOrientation() {
+ return SwingConstants.VERTICAL;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Spin to maximum";
+ }
+
+ @Override
+ public int getScrollDirection() {
+ if (((JSpinnerOperator) oper).getModel().getNextValue() != null) {
+ return ScrollAdjuster.INCREASE_SCROLL_DIRECTION;
+ } else {
+ return ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "scrollToMaximum.ScrollAdjuster{description = " + getDescription() + '}';
+ }
+ });
+ }
+
+ @Override
+ public void scroll(ComponentOperator oper, ScrollAdjuster adj) {
+ JButtonOperator increaseButton = ((JSpinnerOperator) oper).getIncreaseOperator();
+ JButtonOperator decreaseButton = ((JSpinnerOperator) oper).getDecreaseOperator();
+ if (adj.getScrollDirection() == ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION) {
+ return;
+ }
+ int originalDirection = adj.getScrollDirection();
+ while (adj.getScrollDirection() == originalDirection) {
+ if (originalDirection == ScrollAdjuster.INCREASE_SCROLL_DIRECTION) {
+ increaseButton.push();
+ } else {
+ decreaseButton.push();
+ }
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JSplitPaneDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JSplitPaneDriver.java
new file mode 100644
index 00000000000..cc21e09bb5d
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/JSplitPaneDriver.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.scrolling;
+
+import javax.swing.JButton;
+import javax.swing.JSplitPane;
+
+import org.netbeans.jemmy.ComponentSearcher;
+import org.netbeans.jemmy.drivers.ButtonDriver;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.ScrollDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.ContainerOperator;
+import org.netbeans.jemmy.operators.JButtonOperator;
+import org.netbeans.jemmy.operators.JSplitPaneOperator;
+import org.netbeans.jemmy.operators.Operator;
+
+/**
+ * ScrollDriver for javax.swing.JSplitPane component type.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class JSplitPaneDriver extends LightSupportiveDriver implements ScrollDriver {
+
+ /**
+ * Constructs a JSplitPaneDriver.
+ */
+ public JSplitPaneDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JSplitPaneOperator"});
+ }
+
+ @Override
+ public void scroll(ComponentOperator oper, ScrollAdjuster adj) {
+ moveDividerTo((JSplitPaneOperator) oper, adj);
+ }
+
+ @Override
+ public void scrollToMinimum(ComponentOperator oper, int orientation) {
+ expandTo((JSplitPaneOperator) oper, 0);
+ }
+
+ @Override
+ public void scrollToMaximum(ComponentOperator oper, int orientation) {
+ expandTo((JSplitPaneOperator) oper, 1);
+ }
+
+ private void moveDividerTo(JSplitPaneOperator oper, ScrollAdjuster adj) {
+ ContainerOperator> divOper = oper.getDivider();
+ /* workaround */
+ if (oper.getDividerLocation() == -1) {
+ moveTo(oper, divOper, divOper.getCenterX() - 1, divOper.getCenterY() - 1);
+ if (oper.getDividerLocation() == -1) {
+ moveTo(oper, divOper, divOper.getCenterX() + 1, divOper.getCenterY() + 1);
+ }
+ }
+ if (oper.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
+ moveOnce(oper, divOper, adj, 0, oper.getWidth());
+ } else {
+ moveOnce(oper, divOper, adj, 0, oper.getHeight());
+ }
+ }
+
+ private void moveOnce(JSplitPaneOperator oper,
+ ContainerOperator> divOper,
+ ScrollAdjuster adj,
+ int leftPosition,
+ int rightPosition) {
+ int currentPosition = 0;
+ if (oper.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
+ currentPosition = (int) (divOper.getLocationOnScreen().getX()
+ - oper.getLocationOnScreen().getX());
+ } else {
+ currentPosition = (int) (divOper.getLocationOnScreen().getY()
+ - oper.getLocationOnScreen().getY());
+ }
+ int nextPosition = 0;
+ if (adj.getScrollDirection() == ScrollAdjuster.DECREASE_SCROLL_DIRECTION) {
+ nextPosition = (currentPosition + leftPosition) / 2;
+ moveToPosition(oper, divOper, nextPosition - currentPosition);
+ if (currentPosition
+ == ((adj.getScrollOrientation() == JSplitPane.HORIZONTAL_SPLIT)
+ ? (int) (divOper.getLocationOnScreen().getX()
+ - oper.getLocationOnScreen().getX())
+ : (int) (divOper.getLocationOnScreen().getY()
+ - oper.getLocationOnScreen().getY()))) {
+ return;
+ }
+ moveOnce(oper, divOper, adj, leftPosition, currentPosition);
+ } else if (adj.getScrollDirection() == ScrollAdjuster.INCREASE_SCROLL_DIRECTION) {
+ nextPosition = (currentPosition + rightPosition) / 2;
+ moveToPosition(oper, divOper, nextPosition - currentPosition);
+ if (currentPosition
+ == ((adj.getScrollOrientation() == JSplitPane.HORIZONTAL_SPLIT)
+ ? (int) (divOper.getLocationOnScreen().getX()
+ - oper.getLocationOnScreen().getX())
+ : (int) (divOper.getLocationOnScreen().getY()
+ - oper.getLocationOnScreen().getY()))) {
+ return;
+ }
+ moveOnce(oper, divOper, adj, currentPosition, rightPosition);
+ } else { // (currentLocation == dividerLocation) - stop point
+ return;
+ }
+ }
+
+ private void moveTo(JSplitPaneOperator oper, ComponentOperator divOper, int x, int y) {
+ DriverManager.getMouseDriver(divOper).
+ dragNDrop(divOper, divOper.getCenterX(), divOper.getCenterY(), x, y,
+ Operator.getDefaultMouseButton(), 0,
+ oper.getTimeouts().create("ComponentOperator.BeforeDragTimeout"),
+ oper.getTimeouts().create("ComponentOperator.AfterDragTimeout"));
+ }
+
+ private void moveToPosition(JSplitPaneOperator oper, ComponentOperator divOper, int nextPosition) {
+ if (System.getProperty("java.version").startsWith("1.2")) {
+ oper.setDividerLocation(nextPosition);
+ }
+ if (oper.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
+ moveTo(oper, divOper, divOper.getCenterX() + nextPosition, divOper.getCenterY());
+ } else {
+ moveTo(oper, divOper, divOper.getCenterX(), divOper.getCenterY() + nextPosition);
+ }
+ }
+
+ private void expandTo(JSplitPaneOperator oper, int index) {
+ ContainerOperator> divOper = oper.getDivider();
+ JButtonOperator bo
+ = new JButtonOperator((JButton) divOper.
+ waitSubComponent(new JButtonOperator.JButtonFinder(ComponentSearcher.
+ getTrueChooser("JButton")),
+ index));
+ bo.copyEnvironment(divOper);
+ ButtonDriver bdriver = DriverManager.getButtonDriver(bo);
+ bdriver.push(bo);
+ bdriver.push(bo);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/KeyboardJSliderScrollDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/KeyboardJSliderScrollDriver.java
new file mode 100644
index 00000000000..12522ee74c0
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/KeyboardJSliderScrollDriver.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.scrolling;
+
+import java.awt.Adjustable;
+import java.awt.event.KeyEvent;
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ *
+ * @author shura
+ */
+public class KeyboardJSliderScrollDriver extends JSliderDriver {
+
+ private static int getButton(int direction, int orientation) {
+ if (direction == ScrollAdjuster.DECREASE_SCROLL_DIRECTION) {
+ return (orientation == Adjustable.HORIZONTAL) ? KeyEvent.VK_LEFT : KeyEvent.VK_DOWN;
+ } else {
+ return (orientation == Adjustable.HORIZONTAL) ? KeyEvent.VK_RIGHT : KeyEvent.VK_UP;
+ }
+ }
+
+ @Override
+ protected boolean doPushAndWait(ComponentOperator oper, ScrollAdjuster adj, long freezeTimeout) {
+ super.doPushAndWait(oper, adj, freezeTimeout);
+ return true;
+ }
+
+ @Override
+ protected void step(ComponentOperator oper, ScrollAdjuster adj) {
+ oper.pushKey(getButton(adj.getScrollDirection(), adj.getScrollOrientation()));
+ oper.getTimeouts().create("Waiter.TimeDelta").sleep();
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/ScrollAdjuster.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/ScrollAdjuster.java
new file mode 100644
index 00000000000..852b43515ef
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/ScrollAdjuster.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.scrolling;
+
+/**
+ * Specifies scrolling criteria.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public interface ScrollAdjuster {
+
+ /**
+ * Increase scroll direction.
+ */
+ public static final int INCREASE_SCROLL_DIRECTION = 1;
+
+ /**
+ * Decrease scroll direction.
+ */
+ public static final int DECREASE_SCROLL_DIRECTION = -1;
+
+ /**
+ * Specifies that necessary value has been reached..
+ */
+ public static final int DO_NOT_TOUCH_SCROLL_DIRECTION = 0;
+
+ /**
+ * Returns scroll direction to reach necessary scroller value.
+ *
+ * @return one of the values: INCREASE_SCROLL_DIRECTION,
+ * DECREASE_SCROLL_DIRECTION or DO_NOT_TOUCH_SCROLL_DIRECTION.
+ */
+ public int getScrollDirection();
+
+ /**
+ * Returns scrolling orientation.
+ *
+ * @return one of the values: Adjustable.HORIZONTAL or Adjustable.VERTICAL.
+ */
+ public int getScrollOrientation();
+
+ /**
+ * Returns a printable scrolling description.
+ *
+ * @return a description.
+ */
+ public String getDescription();
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/ScrollPaneDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/ScrollPaneDriver.java
new file mode 100644
index 00000000000..505157bf5fb
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/ScrollPaneDriver.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.scrolling;
+
+import java.awt.Adjustable;
+import java.awt.Point;
+import java.awt.Scrollbar;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.ScrollPaneOperator;
+
+/**
+ * ScrollDriver for java.awt.ScrollPane component type.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class ScrollPaneDriver extends AWTScrollDriver {
+
+ private static final int CLICK_OFFSET = 5;
+
+ /**
+ * Constructs a ScrollPaneDriver.
+ */
+ public ScrollPaneDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.ScrollPaneOperator"});
+ }
+
+ @Override
+ protected int position(ComponentOperator oper, int orientation) {
+ return (orientation == Adjustable.HORIZONTAL)
+ ? ((ScrollPaneOperator) oper).getScrollPosition().x
+ : ((ScrollPaneOperator) oper).getScrollPosition().y;
+ }
+
+ @Override
+ public void scrollToMinimum(ComponentOperator oper, final int orientation) {
+ final Adjustable adj
+ = (orientation == Scrollbar.HORIZONTAL)
+ ? ((ScrollPaneOperator) oper).getHAdjustable()
+ : ((ScrollPaneOperator) oper).getVAdjustable();
+ scroll(oper,
+ new ScrollAdjuster() {
+ @Override
+ public int getScrollDirection() {
+ return ((adj.getMinimum() < adj.getValue())
+ ? DECREASE_SCROLL_DIRECTION
+ : DO_NOT_TOUCH_SCROLL_DIRECTION);
+ }
+
+ @Override
+ public int getScrollOrientation() {
+ return orientation;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Scroll to minimum";
+ }
+
+ @Override
+ public String toString() {
+ return "scrollToMinimum.ScrollAdjuster{description = " + getDescription() + '}';
+ }
+ });
+ }
+
+ @Override
+ public void scrollToMaximum(ComponentOperator oper, final int orientation) {
+ final Adjustable adj
+ = (orientation == Scrollbar.HORIZONTAL)
+ ? ((ScrollPaneOperator) oper).getHAdjustable()
+ : ((ScrollPaneOperator) oper).getVAdjustable();
+ scroll(oper,
+ new ScrollAdjuster() {
+ @Override
+ public int getScrollDirection() {
+ return (((adj.getMaximum() - adj.getVisibleAmount()) > adj.getValue())
+ ? INCREASE_SCROLL_DIRECTION
+ : DO_NOT_TOUCH_SCROLL_DIRECTION);
+ }
+
+ @Override
+ public int getScrollOrientation() {
+ return orientation;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Scroll to maximum";
+ }
+
+ @Override
+ public String toString() {
+ return "scrollToMaximum.ScrollAdjuster{description = " + getDescription() + '}';
+ }
+ });
+ }
+
+ @Override
+ protected Point getClickPoint(ComponentOperator oper, int direction, int orientation) {
+ int x, y;
+ if (orientation == Scrollbar.HORIZONTAL) {
+ int offset = ((ScrollPaneOperator) oper).
+ isScrollbarVisible(Scrollbar.VERTICAL)
+ ? ((ScrollPaneOperator) oper).getVScrollbarWidth() : 0;
+ if (direction == ScrollAdjuster.INCREASE_SCROLL_DIRECTION) {
+ x = oper.getWidth() - 1 - CLICK_OFFSET - offset;
+ } else if (direction == ScrollAdjuster.DECREASE_SCROLL_DIRECTION) {
+ x = CLICK_OFFSET;
+ } else {
+ return null;
+ }
+ y = oper.getHeight() - ((ScrollPaneOperator) oper).getHScrollbarHeight() / 2;
+ } else if (orientation == Scrollbar.VERTICAL) {
+ int offset = ((ScrollPaneOperator) oper).
+ isScrollbarVisible(Scrollbar.HORIZONTAL)
+ ? ((ScrollPaneOperator) oper).getHScrollbarHeight() : 0;
+ if (direction == ScrollAdjuster.INCREASE_SCROLL_DIRECTION) {
+ y = oper.getHeight() - 1 - CLICK_OFFSET - offset;
+ } else if (direction == ScrollAdjuster.DECREASE_SCROLL_DIRECTION) {
+ y = CLICK_OFFSET;
+ } else {
+ return null;
+ }
+ x = oper.getWidth() - ((ScrollPaneOperator) oper).getVScrollbarWidth() / 2;
+ } else {
+ return null;
+ }
+ return new Point(x, y);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/ScrollbarDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/ScrollbarDriver.java
new file mode 100644
index 00000000000..8d831302c0b
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/ScrollbarDriver.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.scrolling;
+
+import java.awt.Point;
+import java.awt.Scrollbar;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.ScrollbarOperator;
+
+/**
+ * ScrollDriver for java.awt.Scrollbar component type.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class ScrollbarDriver extends AWTScrollDriver {
+
+ private static final int CLICK_OFFSET = 5;
+
+ /**
+ * Constructs a ScrollbarDriver.
+ */
+ public ScrollbarDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.ScrollbarOperator"});
+ }
+
+ @Override
+ protected int position(ComponentOperator oper, int orientation) {
+ return ((ScrollbarOperator) oper).getValue();
+ }
+
+ @Override
+ public void scrollToMinimum(final ComponentOperator oper, final int orientation) {
+ scroll(oper,
+ new ScrollAdjuster() {
+ @Override
+ public int getScrollDirection() {
+ return ((((ScrollbarOperator) oper).getMinimum()
+ < ((ScrollbarOperator) oper).getValue())
+ ? DECREASE_SCROLL_DIRECTION
+ : DO_NOT_TOUCH_SCROLL_DIRECTION);
+ }
+
+ @Override
+ public int getScrollOrientation() {
+ return ((ScrollbarOperator) oper).getOrientation();
+ }
+
+ @Override
+ public String getDescription() {
+ return "Scroll to minimum";
+ }
+
+ @Override
+ public String toString() {
+ return "scrollToMinimum.ScrollAdjuster{description = " + getDescription() + '}';
+ }
+ });
+ }
+
+ @Override
+ public void scrollToMaximum(final ComponentOperator oper, final int orientation) {
+ scroll(oper,
+ new ScrollAdjuster() {
+ @Override
+ public int getScrollDirection() {
+ return (((((ScrollbarOperator) oper).getMaximum()
+ - ((ScrollbarOperator) oper).getVisibleAmount())
+ > ((ScrollbarOperator) oper).getValue())
+ ? INCREASE_SCROLL_DIRECTION
+ : DO_NOT_TOUCH_SCROLL_DIRECTION);
+ }
+
+ @Override
+ public int getScrollOrientation() {
+ return ((ScrollbarOperator) oper).getOrientation();
+ }
+
+ @Override
+ public String getDescription() {
+ return "Scroll to maximum";
+ }
+
+ @Override
+ public String toString() {
+ return "scrollToMaximum.ScrollAdjuster{description = " + getDescription() + '}';
+ }
+ });
+ }
+
+ @Override
+ protected Point getClickPoint(ComponentOperator oper, int direction, int orientation) {
+ int x, y;
+ if (orientation == Scrollbar.HORIZONTAL) {
+ if (direction == ScrollAdjuster.INCREASE_SCROLL_DIRECTION) {
+ x = oper.getWidth() - 1 - CLICK_OFFSET;
+ } else if (direction == ScrollAdjuster.DECREASE_SCROLL_DIRECTION) {
+ x = CLICK_OFFSET;
+ } else {
+ return null;
+ }
+ y = oper.getHeight() / 2;
+ } else if (orientation == Scrollbar.VERTICAL) {
+ if (direction == ScrollAdjuster.INCREASE_SCROLL_DIRECTION) {
+ y = oper.getHeight() - 1 - CLICK_OFFSET;
+ } else if (direction == ScrollAdjuster.DECREASE_SCROLL_DIRECTION) {
+ y = CLICK_OFFSET;
+ } else {
+ return null;
+ }
+ x = oper.getWidth() / 2;
+ } else {
+ return null;
+ }
+ return new Point(x, y);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/package-info.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/package-info.java
new file mode 100644
index 00000000000..e3e930a658d
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/scrolling/package-info.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ *
Scrolling drivers
+ * Different drivers to perform a scrolling operations.
+ *
+ * @since 17 Apr 2002
+ *
+ */
+package org.netbeans.jemmy.drivers.scrolling;
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/tables/JTableMouseDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/tables/JTableMouseDriver.java
new file mode 100644
index 00000000000..cbf011393b1
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/tables/JTableMouseDriver.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.tables;
+
+import java.awt.Point;
+import java.awt.event.KeyEvent;
+
+import javax.swing.text.JTextComponent;
+
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.TableDriver;
+import org.netbeans.jemmy.drivers.TextDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JTableOperator;
+import org.netbeans.jemmy.operators.JTextComponentOperator;
+import org.netbeans.jemmy.operators.Operator;
+
+/**
+ * TableDriver for javax.swing.JTableDriver component type.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class JTableMouseDriver extends LightSupportiveDriver implements TableDriver {
+
+ QueueTool queueTool;
+
+ /**
+ * Constructs a JTableMouseDriver.
+ */
+ public JTableMouseDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JTableOperator"});
+ queueTool = new QueueTool();
+ }
+
+ @Override
+ public void selectCell(ComponentOperator oper, int row, int column) {
+ clickOnCell((JTableOperator) oper, row, column, 1);
+ }
+
+ @Override
+ public void editCell(ComponentOperator oper, int row, int column, Object value) {
+ JTableOperator toper = (JTableOperator) oper;
+ toper.scrollToCell(row, column);
+ if (!toper.isEditing()
+ || toper.getEditingRow() != row
+ || toper.getEditingColumn() != column) {
+ clickOnCell((JTableOperator) oper, row, column, 2);
+ }
+ JTextComponentOperator textoper
+ = new JTextComponentOperator((JTextComponent) toper.
+ waitSubComponent(new JTextComponentOperator.JTextComponentFinder()));
+ TextDriver text = DriverManager.getTextDriver(JTextComponentOperator.class);
+ text.clearText(textoper);
+ text.typeText(textoper, value.toString(), 0);
+ DriverManager.getKeyDriver(oper).
+ pushKey(textoper, KeyEvent.VK_ENTER, 0,
+ oper.getTimeouts().
+ create("ComponentOperator.PushKeyTimeout"));
+ }
+
+ /**
+ * Clicks on JTable cell.
+ *
+ * @param oper Table operator.
+ * @param row Cell row index.
+ * @param column Cell column index.
+ * @param clickCount Count to click.
+ */
+ protected void clickOnCell(final JTableOperator oper, final int row, final int column, final int clickCount) {
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Path selecting") {
+ @Override
+ public Void launch() {
+ Point point = oper.getPointToClick(row, column);
+ DriverManager.getMouseDriver(oper).
+ clickMouse(oper, point.x, point.y, clickCount,
+ Operator.getDefaultMouseButton(),
+ 0,
+ oper.getTimeouts().create("ComponentOperator.MouseClickTimeout"));
+ return null;
+ }
+ });
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/tables/package-info.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/tables/package-info.java
new file mode 100644
index 00000000000..6cbe4a1545a
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/tables/package-info.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ *
Table drivers
+ * Different drivers to perform a table operations.
+ *
+ * @since 17 Apr 2002
+ *
+ */
+package org.netbeans.jemmy.drivers.tables;
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/AWTTextAPIDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/AWTTextAPIDriver.java
new file mode 100644
index 00000000000..2d87edde851
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/AWTTextAPIDriver.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.text;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.TextComponentOperator;
+
+/**
+ * TextDriver for AWT component types. Uses API calls.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class AWTTextAPIDriver extends TextAPIDriver {
+
+ /**
+ * Constructs a AWTTextAPIDriver.
+ */
+ public AWTTextAPIDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.TextComponentOperator"});
+ }
+
+ @Override
+ public String getText(ComponentOperator oper) {
+ return ((TextComponentOperator) oper).getText();
+ }
+
+ @Override
+ public int getCaretPosition(ComponentOperator oper) {
+ return ((TextComponentOperator) oper).getCaretPosition();
+ }
+
+ @Override
+ public int getSelectionStart(ComponentOperator oper) {
+ return ((TextComponentOperator) oper).getSelectionStart();
+ }
+
+ @Override
+ public int getSelectionEnd(ComponentOperator oper) {
+ return ((TextComponentOperator) oper).getSelectionEnd();
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/AWTTextKeyboardDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/AWTTextKeyboardDriver.java
new file mode 100644
index 00000000000..b2a84dbc4ca
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/AWTTextKeyboardDriver.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.text;
+
+import java.awt.event.KeyEvent;
+
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.TextAreaOperator;
+import org.netbeans.jemmy.operators.TextComponentOperator;
+
+/**
+ * TextDriver for AWT text component types. Uses keyboard operations.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class AWTTextKeyboardDriver extends TextKeyboardDriver {
+
+ /**
+ * Constructs a AWTTextKeyboardDriver.
+ */
+ public AWTTextKeyboardDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.TextComponentOperator"});
+ }
+
+ @Override
+ public String getText(ComponentOperator oper) {
+ return ((TextComponentOperator) oper).getText();
+ }
+
+ @Override
+ public int getCaretPosition(ComponentOperator oper) {
+ return ((TextComponentOperator) oper).getCaretPosition();
+ }
+
+ @Override
+ public int getSelectionStart(ComponentOperator oper) {
+ return ((TextComponentOperator) oper).getSelectionStart();
+ }
+
+ @Override
+ public int getSelectionEnd(ComponentOperator oper) {
+ return ((TextComponentOperator) oper).getSelectionEnd();
+ }
+
+ @Override
+ public NavigationKey[] getKeys(ComponentOperator oper) {
+ boolean multiString = oper instanceof TextAreaOperator;
+ NavigationKey[] result = new NavigationKey[multiString ? 4 : 2];
+ result[0] = new UpKey(KeyEvent.VK_LEFT, 0);
+ result[1] = new DownKey(KeyEvent.VK_RIGHT, 0);
+ ((UpKey) result[0]).setDownKey((DownKey) result[1]);
+ ((DownKey) result[1]).setUpKey((UpKey) result[0]);
+ if (multiString) {
+ result[2] = new UpKey(KeyEvent.VK_UP, 0);
+ result[3] = new DownKey(KeyEvent.VK_DOWN, 0);
+ ((UpKey) result[2]).setDownKey((DownKey) result[3]);
+ ((DownKey) result[3]).setUpKey((UpKey) result[2]);
+ }
+ return result;
+ }
+
+ @Override
+ public Timeout getBetweenTimeout(ComponentOperator oper) {
+ return oper.getTimeouts().create("TextComponentOperator.BetweenKeysTimeout");
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/DownKey.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/DownKey.java
new file mode 100644
index 00000000000..cfe40cb4662
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/DownKey.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.text;
+
+class DownKey extends GoAndBackKey {
+
+ private UpKey backKey;
+
+ public DownKey(int keyCode, int mods) {
+ super(keyCode, mods);
+ }
+
+ public void setUpKey(UpKey key) {
+ backKey = key;
+ }
+
+ @Override
+ public int getDirection() {
+ return 1;
+ }
+
+ @Override
+ public GoAndBackKey getBackKey() {
+ return backKey;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/EndKey.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/EndKey.java
new file mode 100644
index 00000000000..9d7c8289cc7
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/EndKey.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.text;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+class EndKey extends OffsetKey {
+
+ TextKeyboardDriver cont;
+ ComponentOperator oper;
+
+ public EndKey(int keyCode, int mods, TextKeyboardDriver cont, ComponentOperator oper) {
+ super(keyCode, mods);
+ this.cont = cont;
+ this.oper = oper;
+ }
+
+ @Override
+ public int getDirection() {
+ return 1;
+ }
+
+ @Override
+ public int getExpectedPosition() {
+ return cont.getText(oper).length();
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/GoAndBackKey.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/GoAndBackKey.java
new file mode 100644
index 00000000000..9de2fbf8904
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/GoAndBackKey.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.text;
+
+abstract class GoAndBackKey extends NavigationKey {
+
+ public GoAndBackKey(int keyCode, int mods) {
+ super(keyCode, mods);
+ }
+
+ public abstract GoAndBackKey getBackKey();
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/HomeKey.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/HomeKey.java
new file mode 100644
index 00000000000..e34cca5c220
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/HomeKey.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.text;
+
+class HomeKey extends OffsetKey {
+
+ public HomeKey(int keyCode, int mods) {
+ super(keyCode, mods);
+ }
+
+ @Override
+ public int getDirection() {
+ return -1;
+ }
+
+ @Override
+ public int getExpectedPosition() {
+ return 0;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/NavigationKey.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/NavigationKey.java
new file mode 100644
index 00000000000..d4bd137282b
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/NavigationKey.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.text;
+
+abstract class NavigationKey {
+
+ private int keyCode;
+ private int mods;
+
+ public NavigationKey(int keyCode, int mods) {
+ this.keyCode = keyCode;
+ this.mods = mods;
+ }
+
+ public int getKeyCode() {
+ return keyCode;
+ }
+
+ public int getModifiers() {
+ return mods;
+ }
+
+ public abstract int getDirection();
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/OffsetKey.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/OffsetKey.java
new file mode 100644
index 00000000000..1c9a2ee2bc6
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/OffsetKey.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.text;
+
+abstract class OffsetKey extends NavigationKey {
+
+ public OffsetKey(int keyCode, int mods) {
+ super(keyCode, mods);
+ }
+
+ public abstract int getExpectedPosition();
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/SwingTextAPIDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/SwingTextAPIDriver.java
new file mode 100644
index 00000000000..723121d0272
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/SwingTextAPIDriver.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.text;
+
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JTextComponentOperator;
+
+/**
+ * TextDriver for swing component types. Uses API calls.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class SwingTextAPIDriver extends TextAPIDriver {
+
+ /**
+ * Constructs a SwingTextAPIDriver.
+ */
+ public SwingTextAPIDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JTextComponentOperator"});
+ }
+
+ @Override
+ public String getText(ComponentOperator oper) {
+ return ((JTextComponentOperator) oper).getDisplayedText();
+ }
+
+ @Override
+ public int getCaretPosition(ComponentOperator oper) {
+ return ((JTextComponentOperator) oper).getCaretPosition();
+ }
+
+ @Override
+ public int getSelectionStart(ComponentOperator oper) {
+ return ((JTextComponentOperator) oper).getSelectionStart();
+ }
+
+ @Override
+ public int getSelectionEnd(ComponentOperator oper) {
+ return ((JTextComponentOperator) oper).getSelectionEnd();
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/SwingTextKeyboardDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/SwingTextKeyboardDriver.java
new file mode 100644
index 00000000000..e3e71e37fcd
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/SwingTextKeyboardDriver.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.text;
+
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.KeyDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JEditorPaneOperator;
+import org.netbeans.jemmy.operators.JTextAreaOperator;
+import org.netbeans.jemmy.operators.JTextComponentOperator;
+
+/**
+ * TextDriver for swing text component types. Uses keyboard operations.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class SwingTextKeyboardDriver extends TextKeyboardDriver {
+
+ /**
+ * Constructs a SwingTextKeyboardDriver.
+ */
+ public SwingTextKeyboardDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JTextComponentOperator"});
+ }
+
+ @Override
+ public void clearText(ComponentOperator oper) {
+ if (oper instanceof JTextAreaOperator
+ || oper instanceof JEditorPaneOperator) {
+ DriverManager.getFocusDriver(oper).giveFocus(oper);
+ KeyDriver kdriver = DriverManager.getKeyDriver(oper);
+ selectText(oper, 0, getText(oper).length());
+ kdriver.pushKey(oper, KeyEvent.VK_DELETE, 0,
+ oper.getTimeouts().create("ComponentOperator.PushKeyTimeout"));
+ } else {
+ super.clearText(oper);
+ }
+ }
+
+ @Override
+ public String getText(ComponentOperator oper) {
+ return ((JTextComponentOperator) oper).getDisplayedText();
+ }
+
+ @Override
+ public int getCaretPosition(ComponentOperator oper) {
+ return ((JTextComponentOperator) oper).getCaretPosition();
+ }
+
+ @Override
+ public int getSelectionStart(ComponentOperator oper) {
+ return ((JTextComponentOperator) oper).getSelectionStart();
+ }
+
+ @Override
+ public int getSelectionEnd(ComponentOperator oper) {
+ return ((JTextComponentOperator) oper).getSelectionEnd();
+ }
+
+ @Override
+ public NavigationKey[] getKeys(ComponentOperator oper) {
+ boolean multiString
+ = oper instanceof JTextAreaOperator
+ || oper instanceof JEditorPaneOperator;
+ NavigationKey[] result = new NavigationKey[multiString ? 8 : 4];
+ result[0] = new UpKey(KeyEvent.VK_LEFT, 0);
+ result[1] = new DownKey(KeyEvent.VK_RIGHT, 0);
+ ((UpKey) result[0]).setDownKey((DownKey) result[1]);
+ ((DownKey) result[1]).setUpKey((UpKey) result[0]);
+ if (multiString) {
+ result[2] = new UpKey(KeyEvent.VK_UP, 0);
+ result[3] = new DownKey(KeyEvent.VK_DOWN, 0);
+ ((UpKey) result[2]).setDownKey((DownKey) result[3]);
+ ((DownKey) result[3]).setUpKey((UpKey) result[2]);
+ result[4] = new UpKey(KeyEvent.VK_PAGE_UP, 0);
+ result[5] = new DownKey(KeyEvent.VK_PAGE_DOWN, 0);
+ ((UpKey) result[4]).setDownKey((DownKey) result[5]);
+ ((DownKey) result[5]).setUpKey((UpKey) result[4]);
+ result[6] = new HomeKey(KeyEvent.VK_HOME, InputEvent.CTRL_MASK);
+ result[7] = new EndKey(KeyEvent.VK_END, InputEvent.CTRL_MASK, this, oper);
+ } else {
+ result[2] = new HomeKey(KeyEvent.VK_HOME, 0);
+ result[3] = new EndKey(KeyEvent.VK_END, 0, this, oper);
+ }
+ return result;
+ }
+
+ @Override
+ public Timeout getBetweenTimeout(ComponentOperator oper) {
+ return oper.getTimeouts().create("TextComponentOperator.BetweenKeysTimeout");
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/TextAPIDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/TextAPIDriver.java
new file mode 100644
index 00000000000..fdc626e45ab
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/TextAPIDriver.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.text;
+
+import java.awt.event.KeyEvent;
+
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.TextDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JTextComponentOperator;
+import org.netbeans.jemmy.operators.TextComponentOperator;
+
+/**
+ * Superclass for all TextDrivers using API calls.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public abstract class TextAPIDriver extends LightSupportiveDriver implements TextDriver {
+
+ /**
+ * Constructs a ChoiceDriver.
+ *
+ * @param supported an array of supported class names
+ */
+ public TextAPIDriver(String[] supported) {
+ super(supported);
+ }
+
+ @Override
+ public void changeCaretPosition(ComponentOperator oper, int position) {
+ checkSupported(oper);
+ if (oper instanceof TextComponentOperator) {
+ ((TextComponentOperator) oper).setCaretPosition(position);
+ } else {
+ ((JTextComponentOperator) oper).setCaretPosition(position);
+ }
+ }
+
+ @Override
+ public void selectText(ComponentOperator oper, int startPosition, int finalPosition) {
+ checkSupported(oper);
+ int start = (startPosition < finalPosition) ? startPosition : finalPosition;
+ int end = (startPosition > finalPosition) ? startPosition : finalPosition;
+ if (oper instanceof TextComponentOperator) {
+ TextComponentOperator toper = ((TextComponentOperator) oper);
+ toper.setSelectionStart(start);
+ toper.setSelectionEnd(end);
+ } else {
+ JTextComponentOperator toper = ((JTextComponentOperator) oper);
+ toper.setSelectionStart(start);
+ toper.setSelectionEnd(end);
+ }
+ }
+
+ @Override
+ public void clearText(ComponentOperator oper) {
+ if (oper instanceof TextComponentOperator) {
+ ((TextComponentOperator) oper).setText("");
+ } else {
+ ((JTextComponentOperator) oper).setText("");
+ }
+ }
+
+ @Override
+ public void typeText(ComponentOperator oper, String text, int caretPosition) {
+ checkSupported(oper);
+ String curtext = getText(oper);
+ int realPos = caretPosition;
+ if (getSelectionStart(oper) == realPos
+ || getSelectionEnd(oper) == realPos) {
+ if (getSelectionEnd(oper) == realPos) {
+ realPos = realPos - (getSelectionEnd(oper) - getSelectionStart(oper));
+ }
+ curtext
+ = curtext.substring(0, getSelectionStart(oper))
+ + curtext.substring(getSelectionEnd(oper));
+ }
+ changeText(oper,
+ curtext.substring(0, realPos) + text
+ + curtext.substring(realPos));
+ }
+
+ @Override
+ public void changeText(ComponentOperator oper, String text) {
+ checkSupported(oper);
+ if (oper instanceof TextComponentOperator) {
+ ((TextComponentOperator) oper).setText(text);
+ } else {
+ ((JTextComponentOperator) oper).setText(text);
+ }
+ }
+
+ @Override
+ public void enterText(ComponentOperator oper, String text) {
+ changeText(oper, text);
+ DriverManager.getKeyDriver(oper).
+ pushKey(oper, KeyEvent.VK_ENTER, 0,
+ new Timeout("", 0));
+ }
+
+ /**
+ * Returns operator's text.
+ *
+ * @param oper an operator.
+ * @return string representing component text.
+ */
+ public abstract String getText(ComponentOperator oper);
+
+ /**
+ * Returns current caret position.
+ *
+ * @param oper an operator.
+ * @return int represnting current operator's caret position.
+ */
+ public abstract int getCaretPosition(ComponentOperator oper);
+
+ /**
+ * Returns a caret position of selection start.
+ *
+ * @param oper an operator.
+ * @return int represnting index of operator's selection start.
+ */
+ public abstract int getSelectionStart(ComponentOperator oper);
+
+ /**
+ * Returns a caret position of selection end.
+ *
+ * @param oper an operator.
+ * @return int represnting index of operator's selection end.
+ */
+ public abstract int getSelectionEnd(ComponentOperator oper);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/TextKeyboardDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/TextKeyboardDriver.java
new file mode 100644
index 00000000000..d5121504c41
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/TextKeyboardDriver.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.text;
+
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+
+import org.netbeans.jemmy.CharBindingMap;
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.KeyDriver;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.TextDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+
+/**
+ * Superclass for all TextDrivers using keyboard.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public abstract class TextKeyboardDriver extends LightSupportiveDriver implements TextDriver {
+
+ /**
+ * Constructs a TextKeyboardDriver.
+ *
+ * @param supported an array of supported class names
+ */
+ public TextKeyboardDriver(String[] supported) {
+ super(supported);
+ }
+
+ @Override
+ public void changeCaretPosition(ComponentOperator oper, int position) {
+ DriverManager.getFocusDriver(oper).giveFocus(oper);
+ checkSupported(oper);
+ changeCaretPosition(oper, position, 0);
+ }
+
+ @Override
+ public void selectText(ComponentOperator oper, int startPosition, int finalPosition) {
+ changeCaretPosition(oper, startPosition);
+ DriverManager.getKeyDriver(oper).pressKey(oper, KeyEvent.VK_SHIFT, 0);
+ changeCaretPosition(oper, finalPosition, InputEvent.SHIFT_MASK);
+ DriverManager.getKeyDriver(oper).releaseKey(oper, KeyEvent.VK_SHIFT, 0);
+ }
+
+ @Override
+ public void clearText(ComponentOperator oper) {
+ DriverManager.getFocusDriver(oper).giveFocus(oper);
+ checkSupported(oper);
+ KeyDriver kdriver = DriverManager.getKeyDriver(oper);
+ Timeout pushTime = oper.getTimeouts().create("ComponentOperator.PushKeyTimeout");
+ Timeout betweenTime = getBetweenTimeout(oper);
+ while (getCaretPosition(oper) > 0) {
+ kdriver.typeKey(oper, KeyEvent.VK_BACK_SPACE, (char) KeyEvent.VK_BACK_SPACE, 0, pushTime);
+ betweenTime.sleep();
+ }
+ while (getText(oper).length() > 0) {
+ kdriver.pushKey(oper, KeyEvent.VK_DELETE, 0, pushTime);
+ betweenTime.sleep();
+ }
+ }
+
+ @Override
+ public void typeText(ComponentOperator oper, String text, int caretPosition) {
+ changeCaretPosition(oper, caretPosition);
+ KeyDriver kDriver = DriverManager.getKeyDriver(oper);
+ CharBindingMap map = oper.getCharBindingMap();
+ Timeout pushTime = oper.getTimeouts().create("ComponentOperator.PushKeyTimeout");
+ Timeout betweenTime = getBetweenTimeout(oper);
+ char[] crs = text.toCharArray();
+ for (char cr : crs) {
+ kDriver.typeKey(oper, map.getCharKey(cr), cr, map.getCharModifiers(cr), pushTime);
+ betweenTime.sleep();
+ }
+ }
+
+ @Override
+ public void changeText(ComponentOperator oper, String text) {
+ clearText(oper);
+ typeText(oper, text, 0);
+ }
+
+ @Override
+ public void enterText(ComponentOperator oper, String text) {
+ changeText(oper, text);
+ DriverManager.getKeyDriver(oper).pushKey(oper, KeyEvent.VK_ENTER, 0,
+ new Timeout("", 0));
+ }
+
+ /**
+ * Returns operator's text.
+ *
+ * @param oper an operator.
+ * @return string representing component text.
+ */
+ public abstract String getText(ComponentOperator oper);
+
+ /**
+ * Returns current caret position.
+ *
+ * @param oper an operator.
+ * @return int represnting current operator's caret position.
+ */
+ public abstract int getCaretPosition(ComponentOperator oper);
+
+ /**
+ * Returns a caret position of selection start.
+ *
+ * @param oper an operator.
+ * @return int represnting index of operator's selection start.
+ */
+ public abstract int getSelectionStart(ComponentOperator oper);
+
+ /**
+ * Returns a caret position of selection end.
+ *
+ * @param oper an operator.
+ * @return int represnting index of operator's selection end.
+ */
+ public abstract int getSelectionEnd(ComponentOperator oper);
+
+ /**
+ * Returns an array of navigation keys.
+ *
+ * @param oper an operator.
+ * @return an array on NavigationKey instances.
+ */
+ public abstract NavigationKey[] getKeys(ComponentOperator oper);
+
+ /**
+ * Returns a timeout to sleep between text typing and caret operations.
+ *
+ * @param oper an operator.
+ * @return a Timeout instance.
+ */
+ public abstract Timeout getBetweenTimeout(ComponentOperator oper);
+
+ /**
+ * Changes current caret position to specifyed.
+ *
+ * @param oper an operator.
+ * @param position new caret position
+ * @param preModifiers a modifiers (combination of
+ * {@code InputEvent.*_MASK} fields) pushed before caret moving (like
+ * shift during text selection).
+ */
+ protected void changeCaretPosition(ComponentOperator oper, final int position, final int preModifiers) {
+ NavigationKey[] keys = getKeys(oper);
+ for (int i = keys.length - 1; i >= 0; i--) {
+ if (keys[i] instanceof OffsetKey) {
+ moveCaret(oper, (OffsetKey) keys[i], position, preModifiers);
+ } else {
+ moveCaret(oper, (GoAndBackKey) keys[i], position, preModifiers);
+ }
+ }
+ }
+
+ private int difference(int one, int two) {
+ if (one >= two) {
+ return one - two;
+ } else {
+ return two - one;
+ }
+ }
+
+ private void push(ComponentOperator oper, NavigationKey key, int preModifiers) {
+ DriverManager.getKeyDriver(oper).
+ pushKey(oper, key.getKeyCode(), key.getModifiers() | preModifiers,
+ oper.getTimeouts().create("ComponentOperator.PushKeyTimeout"));
+ getBetweenTimeout(oper).sleep();
+ }
+
+ private final void moveCaret(ComponentOperator oper, GoAndBackKey key, int position, int preModifiers) {
+ int newDiff = difference(position, getCaretPosition(oper));
+ int oldDiff = newDiff;
+ QueueTool qTool = new QueueTool();
+ qTool.setOutput(oper.getOutput().createErrorOutput());
+ while (key.getDirection() * (position - getCaretPosition(oper)) > 0) {
+ oldDiff = newDiff;
+ push(oper, key, preModifiers);
+ qTool.waitEmpty();
+ newDiff = difference(position, getCaretPosition(oper));
+ if (newDiff == oldDiff) {
+ return;
+ }
+ }
+ if (newDiff > oldDiff) {
+ push(oper, key.getBackKey(), preModifiers);
+ }
+ }
+
+ private final void moveCaret(ComponentOperator oper, OffsetKey key, int position, int preModifiers) {
+ if (gotToGo(oper, position, key.getExpectedPosition())) {
+ push(oper, key, preModifiers);
+ }
+ }
+
+ private boolean gotToGo(ComponentOperator oper, int point, int offset) {
+ return difference(point, offset) < difference(point, getCaretPosition(oper));
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/UpKey.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/UpKey.java
new file mode 100644
index 00000000000..5bc5393bc25
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/UpKey.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.text;
+
+class UpKey extends GoAndBackKey {
+
+ private DownKey backKey;
+
+ public UpKey(int keyCode, int mods) {
+ super(keyCode, mods);
+ }
+
+ public void setDownKey(DownKey key) {
+ backKey = key;
+ }
+
+ @Override
+ public int getDirection() {
+ return -1;
+ }
+
+ @Override
+ public GoAndBackKey getBackKey() {
+ return backKey;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/package-info.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/package-info.java
new file mode 100644
index 00000000000..ecf61309846
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/text/package-info.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ *
Text drivers
+ * Different drivers to perform a text operations.
+ *
+ * @since 17 Apr 2002
+ *
+ */
+package org.netbeans.jemmy.drivers.text;
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/trees/JTreeAPIDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/trees/JTreeAPIDriver.java
new file mode 100644
index 00000000000..921d50985b0
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/trees/JTreeAPIDriver.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.trees;
+
+import javax.swing.text.JTextComponent;
+
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.TextDriver;
+import org.netbeans.jemmy.drivers.TreeDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JTextComponentOperator;
+import org.netbeans.jemmy.operators.JTreeOperator;
+
+/**
+ * TreeDriver for javax.swing.JTree component type. Uses API calls.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class JTreeAPIDriver extends LightSupportiveDriver implements TreeDriver {
+
+ /**
+ * Constructs a JTreeAPIDriver.
+ */
+ public JTreeAPIDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JTreeOperator"});
+ }
+
+ @Override
+ public void selectItem(ComponentOperator oper, int index) {
+ selectItems(oper, new int[]{index});
+ }
+
+ @Override
+ public void selectItems(ComponentOperator oper, int[] indices) {
+ checkSupported(oper);
+ ((JTreeOperator) oper).clearSelection();
+ ((JTreeOperator) oper).addSelectionRows(indices);
+ }
+
+ @Override
+ public void expandItem(ComponentOperator oper, int index) {
+ checkSupported(oper);
+ ((JTreeOperator) oper).expandRow(index);
+ }
+
+ @Override
+ public void collapseItem(ComponentOperator oper, int index) {
+ checkSupported(oper);
+ ((JTreeOperator) oper).collapseRow(index);
+ }
+
+ @Override
+ public void editItem(ComponentOperator oper, int index, Object newValue, Timeout waitEditorTime) {
+ JTextComponentOperator textoper = startEditingAndReturnEditor(oper, index, waitEditorTime);
+ TextDriver text = DriverManager.getTextDriver(JTextComponentOperator.class);
+ text.clearText(textoper);
+ text.typeText(textoper, newValue.toString(), 0);
+ ((JTreeOperator) oper).stopEditing();
+ }
+
+ @Override
+ public void startEditing(ComponentOperator oper, int index, Timeout waitEditorTime) {
+ startEditingAndReturnEditor(oper, index, waitEditorTime);
+ }
+
+ private JTextComponentOperator startEditingAndReturnEditor(ComponentOperator oper, int index, Timeout waitEditorTime) {
+ checkSupported(oper);
+ JTreeOperator toper = (JTreeOperator) oper;
+ toper.startEditingAtPath(toper.getPathForRow(index));
+ toper.getTimeouts().
+ setTimeout("ComponentOperator.WaitComponentTimeout", waitEditorTime.getValue());
+ return (new JTextComponentOperator((JTextComponent) toper.
+ waitSubComponent(new JTextComponentOperator.JTextComponentFinder())));
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/trees/JTreeMouseDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/trees/JTreeMouseDriver.java
new file mode 100644
index 00000000000..a0368477ee5
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/trees/JTreeMouseDriver.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.trees;
+
+import java.awt.Point;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+
+import javax.swing.text.JTextComponent;
+
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.Timeout;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.MouseDriver;
+import org.netbeans.jemmy.drivers.TextDriver;
+import org.netbeans.jemmy.drivers.TreeDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JTextComponentOperator;
+import org.netbeans.jemmy.operators.JTreeOperator;
+import org.netbeans.jemmy.operators.Operator;
+
+/**
+ * TreeDriver for javax.swing.JTree component type. Uses mouse operations.
+ *
+ * @author Alexandre Iline(alexandre.iline@oracle.com)
+ */
+public class JTreeMouseDriver extends LightSupportiveDriver implements TreeDriver {
+
+ QueueTool queueTool;
+
+ /**
+ * Constructs a JTreeMouseDriver.
+ */
+ public JTreeMouseDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JTreeOperator"});
+ queueTool = new QueueTool();
+ }
+
+ @Override
+ public void selectItem(ComponentOperator oper, int index) {
+ selectItems(oper, new int[]{index});
+ }
+
+ @Override
+ public void selectItems(final ComponentOperator oper, int[] indices) {
+ ((JTreeOperator) oper).clearSelection();
+ checkSupported(oper);
+ final MouseDriver mdriver = DriverManager.getMouseDriver(oper);
+ final JTreeOperator toper = (JTreeOperator) oper;
+ final Timeout clickTime = oper.getTimeouts().create("ComponentOperator.MouseClickTimeout");
+ for (int i = 0; i < indices.length; i++) {
+ final int index = i;
+ if (!QueueTool.isDispatchThread()) {
+ toper.scrollToRow(indices[i]);
+ }
+ final Point p = toper.getPointToClick(indices[index]);
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Path selecting") {
+ @Override
+ public Void launch() {
+ mdriver.clickMouse(oper, p.x, p.y, 1, Operator.getDefaultMouseButton(),
+ (index == 0) ? 0 : InputEvent.CTRL_MASK, clickTime);
+ return null;
+ }
+ });
+ }
+ //1.5 workaround
+ if (System.getProperty("java.specification.version").compareTo("1.4") > 0) {
+ if (!QueueTool.isDispatchThread()) {
+ queueTool.setOutput(oper.getOutput().createErrorOutput());
+ queueTool.waitEmpty(10);
+ queueTool.waitEmpty(10);
+ queueTool.waitEmpty(10);
+ }
+ }
+ //end of 1.5 workaround
+ }
+
+ @Override
+ public void expandItem(ComponentOperator oper, final int index) {
+ checkSupported(oper);
+ final JTreeOperator toper = (JTreeOperator) oper;
+ final MouseDriver mdriver = DriverManager.getMouseDriver(oper);
+ if (!toper.isExpanded(index)) {
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Path selecting") {
+ @Override
+ public Void launch() {
+ Point p = toper.getPointToClick(index);
+ mdriver.clickMouse(toper, p.x, p.y, 2, Operator.getDefaultMouseButton(),
+ 0, toper.getTimeouts().
+ create("ComponentOperator.MouseClickTimeout"));
+ return null;
+ }
+ });
+ }
+ }
+
+ @Override
+ public void collapseItem(ComponentOperator oper, final int index) {
+ checkSupported(oper);
+ final JTreeOperator toper = (JTreeOperator) oper;
+ final MouseDriver mdriver = DriverManager.getMouseDriver(oper);
+ if (toper.isExpanded(index)) {
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Path selecting") {
+ @Override
+ public Void launch() {
+ Point p = toper.getPointToClick(index);
+ mdriver.clickMouse(toper, p.x, p.y, 2, Operator.getDefaultMouseButton(),
+ 0, toper.getTimeouts().
+ create("ComponentOperator.MouseClickTimeout"));
+ return null;
+ }
+ });
+ }
+ }
+
+ @Override
+ public void editItem(ComponentOperator oper, int index, Object newValue, Timeout waitEditorTime) {
+ JTextComponentOperator textoper = startEditingAndReturnEditor(oper, index, waitEditorTime);
+ final TextDriver text = DriverManager.getTextDriver(JTextComponentOperator.class);
+ text.clearText(textoper);
+ text.typeText(textoper, newValue.toString(), 0);
+ DriverManager.getKeyDriver(oper).
+ pushKey(textoper, KeyEvent.VK_ENTER, 0,
+ oper.getTimeouts().
+ create("ComponentOperator.PushKeyTimeout"));
+ }
+
+ @Override
+ public void startEditing(ComponentOperator oper, int index, Timeout waitEditorTime) {
+ startEditingAndReturnEditor(oper, index, waitEditorTime);
+ }
+
+ private JTextComponentOperator startEditingAndReturnEditor(ComponentOperator oper, final int index, Timeout waitEditorTime) {
+ checkSupported(oper);
+ final JTreeOperator toper = (JTreeOperator) oper;
+ final MouseDriver mdriver = DriverManager.getMouseDriver(oper);
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Path selecting") {
+ @Override
+ public Void launch() {
+ Point p = toper.getPointToClick(index);
+ mdriver.clickMouse(toper, p.x, p.y, 1, Operator.getDefaultMouseButton(),
+ 0, toper.getTimeouts().
+ create("ComponentOperator.MouseClickTimeout"));
+ return null;
+ }
+ });
+ oper.getTimeouts().sleep("JTreeOperator.BeforeEditTimeout");
+ queueTool.invokeSmoothly(new QueueTool.QueueAction("Path selecting") {
+ @Override
+ public Void launch() {
+ Point p = toper.getPointToClick(index);
+ mdriver.clickMouse(toper, p.x, p.y, 1, Operator.getDefaultMouseButton(),
+ 0, toper.getTimeouts().
+ create("ComponentOperator.MouseClickTimeout"));
+ return null;
+ }
+ });
+ toper.getTimeouts().
+ setTimeout("ComponentOperator.WaitComponentTimeout", waitEditorTime.getValue());
+ return (new JTextComponentOperator((JTextComponent) toper.
+ waitSubComponent(new JTextComponentOperator.JTextComponentFinder())));
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/trees/package-info.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/trees/package-info.java
new file mode 100644
index 00000000000..64c6d892785
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/trees/package-info.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ *
Tree drivers
+ * Different drivers to perform a tree operations.
+ *
+ * @since 17 Apr 2002
+ *
+ */
+package org.netbeans.jemmy.drivers.trees;
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/windows/DefaultFrameDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/windows/DefaultFrameDriver.java
new file mode 100644
index 00000000000..055bc872f05
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/windows/DefaultFrameDriver.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.windows;
+
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Toolkit;
+import java.awt.Window;
+import java.awt.event.WindowEvent;
+
+import org.netbeans.jemmy.drivers.FrameDriver;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.input.EventDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.FrameOperator;
+
+public class DefaultFrameDriver extends LightSupportiveDriver implements FrameDriver {
+
+ EventDriver eDriver;
+
+ public DefaultFrameDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.FrameOperator"});
+ eDriver = new EventDriver();
+ }
+
+ @Override
+ public void iconify(ComponentOperator oper) {
+ checkSupported(oper);
+ eDriver.dispatchEvent(oper.getSource(),
+ new WindowEvent((Window) oper.getSource(),
+ WindowEvent.WINDOW_ICONIFIED));
+ ((FrameOperator) oper).setState(Frame.ICONIFIED);
+ }
+
+ @Override
+ public void deiconify(ComponentOperator oper) {
+ checkSupported(oper);
+ eDriver.dispatchEvent(oper.getSource(),
+ new WindowEvent((Window) oper.getSource(),
+ WindowEvent.WINDOW_DEICONIFIED));
+ ((FrameOperator) oper).setState(Frame.NORMAL);
+ }
+
+ @Override
+ public void maximize(ComponentOperator oper) {
+ checkSupported(oper);
+ oper.setLocation(0, 0);
+ Dimension ssize = Toolkit.getDefaultToolkit().getScreenSize();
+ oper.setSize(ssize.width, ssize.height);
+ }
+
+ @Override
+ public void demaximize(ComponentOperator oper) {
+ checkSupported(oper);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/windows/DefaultInternalFrameDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/windows/DefaultInternalFrameDriver.java
new file mode 100644
index 00000000000..27421ab9b4d
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/windows/DefaultInternalFrameDriver.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.windows;
+
+import java.awt.Component;
+import java.awt.Container;
+
+import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
+
+import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.ComponentSearcher;
+import org.netbeans.jemmy.drivers.FrameDriver;
+import org.netbeans.jemmy.drivers.InternalFrameDriver;
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.WindowDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JInternalFrameOperator;
+
+public class DefaultInternalFrameDriver extends LightSupportiveDriver
+ implements WindowDriver, FrameDriver, InternalFrameDriver {
+
+ public DefaultInternalFrameDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.JInternalFrameOperator"});
+ }
+
+ @Override
+ public void activate(ComponentOperator oper) {
+ checkSupported(oper);
+ ((JInternalFrameOperator) oper).moveToFront();
+ ((JInternalFrameOperator) oper).getTitleOperator().clickMouse();
+ }
+
+ @Override
+ public void requestClose(ComponentOperator oper) {
+ checkSupported(oper);
+ ((JInternalFrameOperator) oper).moveToFront();
+ ((JInternalFrameOperator) oper).getCloseButton().push();
+ }
+
+ @Override
+ public void requestCloseAndThenHide(ComponentOperator oper) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ @Deprecated
+ public void close(ComponentOperator oper) {
+ requestClose(oper);
+ }
+
+ @Override
+ public void move(ComponentOperator oper, int x, int y) {
+ checkSupported(oper);
+ ComponentOperator titleOperator = ((JInternalFrameOperator) oper).getTitleOperator();
+ titleOperator.dragNDrop(titleOperator.getCenterY(),
+ titleOperator.getCenterY(),
+ x - oper.getX() + titleOperator.getCenterY(),
+ y - oper.getY() + titleOperator.getCenterY());
+ }
+
+ @Override
+ public void resize(ComponentOperator oper, int width, int height) {
+ checkSupported(oper);
+ oper.
+ dragNDrop(oper.getWidth() - 1,
+ oper.getHeight() - 1,
+ width - 1,
+ height - 1);
+ }
+
+ @Override
+ public void iconify(ComponentOperator oper) {
+ checkSupported(oper);
+ ((JInternalFrameOperator) oper).getMinimizeButton().clickMouse();
+ }
+
+ @Override
+ public void deiconify(ComponentOperator oper) {
+ checkSupported(oper);
+ ((JInternalFrameOperator) oper).getIconOperator().pushButton();
+ }
+
+ @Override
+ public void maximize(ComponentOperator oper) {
+ checkSupported(oper);
+ if (!((JInternalFrameOperator) oper).isMaximum()) {
+ if (!((JInternalFrameOperator) oper).isSelected()) {
+ activate(oper);
+ }
+ ((JInternalFrameOperator) oper).getMaximizeButton().push();
+ }
+ }
+
+ @Override
+ public void demaximize(ComponentOperator oper) {
+ checkSupported(oper);
+ if (((JInternalFrameOperator) oper).isMaximum()) {
+ if (!((JInternalFrameOperator) oper).isSelected()) {
+ activate(oper);
+ }
+ ((JInternalFrameOperator) oper).getMaximizeButton().push();
+ }
+ }
+
+ @Override
+ public Component getTitlePane(ComponentOperator operator) {
+ ComponentSearcher cs = new ComponentSearcher((Container) operator.getSource());
+ cs.setOutput(operator.getOutput().createErrorOutput());
+ return (cs.findComponent(new ComponentChooser() {
+ @Override
+ public boolean checkComponent(Component comp) {
+ if (System.getProperty("java.version").startsWith("1.2")) {
+ return comp.getClass().getName().endsWith("InternalFrameTitlePane");
+ } else {
+ return comp instanceof BasicInternalFrameTitlePane;
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "Title pane";
+ }
+
+ @Override
+ public String toString() {
+ return "getTitlePane.ComponentChooser{description = " + getDescription() + '}';
+ }
+ }));
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/windows/DefaultWindowDriver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/windows/DefaultWindowDriver.java
new file mode 100644
index 00000000000..238d053ba2b
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/windows/DefaultWindowDriver.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.drivers.windows;
+
+import java.awt.Window;
+import java.awt.event.ComponentEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.WindowEvent;
+
+import org.netbeans.jemmy.drivers.LightSupportiveDriver;
+import org.netbeans.jemmy.drivers.WindowDriver;
+import org.netbeans.jemmy.drivers.input.EventDriver;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.WindowOperator;
+
+public class DefaultWindowDriver extends LightSupportiveDriver implements WindowDriver {
+
+ EventDriver eDriver;
+
+ public DefaultWindowDriver() {
+ super(new String[]{"org.netbeans.jemmy.operators.WindowOperator"});
+ eDriver = new EventDriver();
+ }
+
+ @Override
+ public void activate(ComponentOperator oper) {
+ checkSupported(oper);
+ if (((WindowOperator) oper).getFocusOwner() == null) {
+ ((WindowOperator) oper).toFront();
+ }
+ eDriver.dispatchEvent(oper.getSource(),
+ new WindowEvent((Window) oper.getSource(),
+ WindowEvent.WINDOW_ACTIVATED));
+ eDriver.dispatchEvent(oper.getSource(),
+ new FocusEvent(oper.getSource(),
+ FocusEvent.FOCUS_GAINED));
+ }
+
+ @Override
+ public void requestClose(ComponentOperator oper) {
+ checkSupported(oper);
+ eDriver.dispatchEvent(oper.getSource(),
+ new WindowEvent((Window) oper.getSource(),
+ WindowEvent.WINDOW_CLOSING));
+ }
+
+ @Override
+ public void requestCloseAndThenHide(ComponentOperator oper) {
+ requestClose(oper);
+ oper.setVisible(false);
+ }
+
+ @Override
+ @Deprecated
+ public void close(ComponentOperator oper) {
+ requestClose(oper);
+ }
+
+ @Override
+ public void move(ComponentOperator oper, int x, int y) {
+ checkSupported(oper);
+ oper.setLocation(x, y);
+ }
+
+ @Override
+ public void resize(ComponentOperator oper, int width, int height) {
+ checkSupported(oper);
+ oper.setSize(width, height);
+ eDriver.dispatchEvent(oper.getSource(),
+ new ComponentEvent(oper.getSource(),
+ ComponentEvent.COMPONENT_RESIZED));
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/windows/package-info.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/windows/package-info.java
new file mode 100644
index 00000000000..0432f2e5e0e
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/drivers/windows/package-info.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ *
Window drivers.
+ * Different drivers to perform a window operations.
+ *
+ */
+package org.netbeans.jemmy.drivers.windows;
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/explorer/GUIBrowser.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/explorer/GUIBrowser.java
new file mode 100644
index 00000000000..0166f7e97d7
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/explorer/GUIBrowser.java
@@ -0,0 +1,1619 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.explorer;
+
+import java.awt.AWTEvent;
+import java.awt.AWTException;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.Vector;
+
+import javax.swing.DefaultListModel;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.JTree;
+import javax.swing.ListCellRenderer;
+import javax.swing.border.BevelBorder;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TreeModelListener;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.filechooser.FileFilter;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.tree.TreeCellRenderer;
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreePath;
+
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.TestOut;
+import org.netbeans.jemmy.operators.Operator;
+import org.netbeans.jemmy.util.Dumper;
+
+/**
+ * An application allowing to explore a Java GUI application. Could be executed
+ * by command:
+ *
or from java code by {@code GUIBrowser.showBrowser()} method
+ * using.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class GUIBrowser extends JFrame {
+
+ private static String WINDOWS_TAB = "Subwindows";
+ private static String COMPONENTS_TAB = "Hierarchy";
+ private static String PROPERTIES_TAB = "Properties";
+ private static String REFLECTION_TAB = "Reflection";
+ private static String EVENT_TAB = "Events";
+ private static String IMAGE_TAB = "Image";
+
+ boolean exit;
+ PropertyDialog propDialog;
+ RootNode root;
+ QueueTool qt;
+ JTextField refreshDelay;
+ JTree mainTree;
+ JLabel status;
+ JButton viewButton;
+ JButton expandButton;
+ JSplitPane split;
+ ByteArrayOutputStream dumpData;
+ PrintWriter dumpWriter;
+
+ private GUIBrowser(boolean exitNecessary) {
+ super("GUI Browser");
+
+ dumpData = new ByteArrayOutputStream();
+ dumpWriter = new PrintWriter(new OutputStreamWriter(dumpData));
+
+ exit = exitNecessary;
+ propDialog = new PropertyDialog(this);
+ qt = new QueueTool();
+ qt.setOutput(TestOut.getNullOutput());
+ root = new RootNode();
+
+ mainTree = new JTree(root.getWindowModel());
+ mainTree.setCellRenderer(new WindowRenderer());
+ mainTree.setEditable(false);
+
+ refreshDelay = new JTextField(3);
+ refreshDelay.setText("0");
+
+ viewButton = new JButton("View");
+ viewButton.setEnabled(false);
+ viewButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ new ComponentBrowser(getOwnr(),
+ (ComponentNode) mainTree.getSelectionPath().
+ getLastPathComponent()).
+ setVisible(true);
+ }
+ });
+
+ expandButton = new JButton("Expand All");
+ expandButton.setEnabled(false);
+ expandButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ expandAll(mainTree,
+ mainTree.getSelectionPath());
+ }
+ });
+
+ JButton refreshButton = new JButton("Reload in ...");
+ refreshButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ reload(Integer.parseInt(refreshDelay.getText()));
+ }
+ });
+
+ JButton dumpButton = new JButton("Dump");
+ dumpButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JFileChooser chooser
+ = new JFileChooser(System.getProperty("user.home"));
+ chooser.addChoosableFileFilter(new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return f.getName().endsWith(".xml");
+ }
+
+ @Override
+ public String getDescription() {
+ return "xml files";
+ }
+
+ @Override
+ public String toString() {
+ return "dumpButton.ActionListener{description = " + getDescription() + '}';
+ }
+ });
+ chooser.showSaveDialog(GUIBrowser.this);
+ try {
+ File file = chooser.getSelectedFile();
+ try (OutputStream output = new FileOutputStream(file)) {
+ output.write(dumpData.toByteArray());
+ }
+ } catch (IOException ee) {
+ ee.printStackTrace();
+ }
+ }
+ });
+
+ JPanel refreshPane = new JPanel();
+ refreshPane.add(viewButton);
+ refreshPane.add(expandButton);
+ refreshPane.add(new JLabel(""));
+ refreshPane.add(new JLabel(""));
+ refreshPane.add(new JLabel(""));
+ refreshPane.add(new JLabel(""));
+ refreshPane.add(new JLabel(""));
+ refreshPane.add(new JLabel(""));
+ refreshPane.add(refreshButton);
+ refreshPane.add(refreshDelay);
+ refreshPane.add(new JLabel("seconds "));
+ refreshPane.add(dumpButton);
+
+ split = createUnderPane(mainTree);
+
+ JPanel nonStatusPane = new JPanel();
+ nonStatusPane.setLayout(new BorderLayout());
+ nonStatusPane.add(refreshPane, BorderLayout.SOUTH);
+ nonStatusPane.add(split, BorderLayout.CENTER);
+
+ split.setDividerLocation(0.8);
+
+ status = new JLabel("Reloaded");
+
+ JPanel statusPane = new JPanel();
+ statusPane.setLayout(new BorderLayout());
+ statusPane.add(status, BorderLayout.CENTER);
+ statusPane.setBorder(new BevelBorder(BevelBorder.LOWERED));
+
+ JPanel bottomPane = new JPanel();
+ bottomPane.setLayout(new BorderLayout());
+ bottomPane.add(statusPane, BorderLayout.NORTH);
+ bottomPane.add(statusPane, BorderLayout.CENTER);
+
+ getContentPane().setLayout(new BorderLayout());
+ getContentPane().add(bottomPane, BorderLayout.SOUTH);
+ getContentPane().add(nonStatusPane, BorderLayout.CENTER);
+
+ Component[] cpss = {viewButton, expandButton};
+ mainTree.addTreeSelectionListener(new SelectionManager(cpss));
+
+ addWindowListener(new WindowListener() {
+ @Override
+ public void windowActivated(WindowEvent e) {
+ }
+
+ @Override
+ public void windowClosed(WindowEvent e) {
+ setVisible(false);
+ if (exit) {
+ System.exit(0);
+ }
+ }
+
+ @Override
+ public void windowClosing(WindowEvent e) {
+ }
+
+ @Override
+ public void windowDeactivated(WindowEvent e) {
+ }
+
+ @Override
+ public void windowDeiconified(WindowEvent e) {
+ }
+
+ @Override
+ public void windowIconified(WindowEvent e) {
+ }
+
+ @Override
+ public void windowOpened(WindowEvent e) {
+ }
+ });
+ addComponentListener(new ComponentListener() {
+ @Override
+ public void componentHidden(ComponentEvent e) {
+ }
+
+ @Override
+ public void componentMoved(ComponentEvent e) {
+ }
+
+ @Override
+ public void componentResized(ComponentEvent e) {
+ split.setDividerLocation(0.8);
+ }
+
+ @Override
+ public void componentShown(ComponentEvent e) {
+ }
+ });
+
+ setSize(800, 400);
+ }
+
+ boolean shown = false;
+
+ @Override
+ @Deprecated
+ public void show() {
+ super.show();
+ viewButton.setEnabled(false);
+ if (!shown) {
+ split.setDividerLocation(0.8);
+ shown = true;
+ }
+ }
+
+ /**
+ * Specifies a status text.
+ *
+ * @param st a status text.
+ */
+ public void setStatus(String st) {
+ status.setText(st);
+ }
+
+ /**
+ * Method to invoke GUIBrowser from java code.
+ */
+ public static void showBrowser() {
+ showBrowser(new String[0], false);
+ }
+
+ /**
+ * Method to invoke GUIBrowser as java application.
+ *
+ * @param argv Argument array. If not empty, first element should be
+ * main class of an aplication to be browsed.
+ * Other elements are application parameters.
+ */
+ public static void main(String[] argv) {
+ showBrowser(argv, true);
+ }
+
+ private static void showBrowser(String[] argv, boolean exitNecessary) {
+ if (argv.length >= 1) {
+ String[] newArgv = new String[argv.length - 1];
+ System.arraycopy(argv, 1, newArgv, 0, argv.length - 1);
+ try {
+ new ClassReference(argv[0]).startApplication(newArgv);
+ } catch (ClassNotFoundException
+ | InvocationTargetException
+ | NoSuchMethodException e) {
+ e.printStackTrace();
+ return;
+ }
+ }
+ new GUIBrowser(exitNecessary).show();
+ }
+
+ private void reload(final int delay) {
+ viewButton.setEnabled(false);
+ expandButton.setEnabled(false);
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ for (int i = delay - 1; i >= 0; i--) {
+ setStatus("Reloading after " + Integer.toString(i) + " second");
+ Thread.sleep(1000);
+ }
+ setStatus("Reloading ...");
+ Dumper.dumpAll(dumpWriter);
+ //qt.lock();
+ root = new RootNode();
+ //qt.unlock();
+ mainTree.setModel(root.getWindowModel());
+ setStatus("Reloaded");
+ } catch (InterruptedException ignored) {
+ }
+ }
+ }).start();
+ }
+
+ private JFrame getOwnr() {
+ return this;
+ }
+
+ private class ClassNode {
+
+ Class> clzz;
+
+ protected ClassNode() {
+ clzz = null;
+ }
+
+ public ClassNode(Class> clzz) {
+ this.clzz = clzz;
+ }
+
+ public ClassNode[] getSuperClasses() {
+ int count = 0;
+ Class> parent = clzz;
+ while ((parent = parent.getSuperclass()) != null) {
+ count++;
+ }
+ Class>[] interfaces = clzz.getInterfaces();
+ ClassNode[] result = new ClassNode[count + interfaces.length + 1];
+ result[0] = new SuperClassNode(clzz);
+ count = 1;
+ parent = clzz;
+ while ((parent = parent.getSuperclass()) != null) {
+ result[count] = new SuperClassNode(parent);
+ count++;
+ }
+ for (int i = count; i < count + interfaces.length; i++) {
+ result[i] = new InterfaceNode(interfaces[i - count]);
+ }
+ return result;
+ }
+
+ public String toString() {
+ if (clzz.isArray()) {
+ return clzz.getComponentType().getName() + "[]";
+ } else {
+ return clzz.getName();
+ }
+ }
+
+ public TreeModel getMethodsModel() {
+ return new ClassModel(this);
+ }
+
+ public ClassNode[] getSubNodes() {
+ Vector res = new Vector<>();
+ Field[] fields = clzz.getFields();
+ Arrays.sort(fields, new Comparator() {
+ @Override
+ public int compare(Field f1, Field f2) {
+ return f1.getName().compareTo(f2.getName());
+ }
+ });
+ Method[] mtds = clzz.getMethods();
+ Arrays.sort(mtds, new Comparator() {
+ @Override
+ public int compare(Method m1, Method m2) {
+ return m1.getName().compareTo(m2.getName());
+ }
+ });
+ for (Field field : fields) {
+ if (field.getDeclaringClass().getName().equals(clzz.getName())) {
+ res.add(new FieldNode(field));
+ }
+ }
+ for (Method mtd : mtds) {
+ if (mtd.getDeclaringClass().getName().equals(clzz.getName())) {
+ res.add(new MethodNode(mtd));
+ }
+ }
+ ClassNode[] result = new ClassNode[res.size()];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = res.get(i);
+ }
+ return result;
+ }
+ }
+
+ private class SuperClassNode extends ClassNode {
+
+ public SuperClassNode(Class> clzz) {
+ super(clzz);
+ }
+
+ public String toString() {
+ return "Class: " + super.toString();
+ }
+ }
+
+ private class InterfaceNode extends ClassNode {
+
+ public InterfaceNode(Class> clzz) {
+ super(clzz);
+ }
+
+ public String toString() {
+ return "Interfac: " + super.toString();
+ }
+ }
+
+ private class FieldNode extends ClassNode {
+
+ Field field;
+
+ public FieldNode(Field fld) {
+ super(fld.getType());
+ field = fld;
+ }
+
+ public String toString() {
+ return ("Field: "
+ + Modifier.toString(field.getModifiers()) + " "
+ + super.toString() + " "
+ + field.getName());
+ }
+ }
+
+ private class MethodNode extends ClassNode {
+
+ Method method;
+
+ public MethodNode(Method mtd) {
+ super(mtd.getReturnType());
+ method = mtd;
+ }
+
+ public String toString() {
+ return ("Method: "
+ + Modifier.toString(method.getModifiers()) + " "
+ + super.toString() + " "
+ + method.getName());
+
+ }
+
+ public ClassNode[] getParameters() {
+ Class>[] ptps = method.getParameterTypes();
+ ClassNode[] result = new ClassNode[ptps.length];
+ for (int i = 0; i < ptps.length; i++) {
+ result[i] = new ClassNode(ptps[i]);
+ }
+ return result;
+ }
+ }
+
+ private class ComponentNode extends ClassNode {
+
+ protected Hashtable props;
+ protected String clss = "";
+ protected String compToString = "";
+ Component comp;
+ ComponentImageProvider image;
+ protected int x, y, w, h;
+
+ protected ComponentNode() {
+ props = new Hashtable<>();
+ }
+
+ public ComponentNode(Component comp) {
+ super(comp.getClass());
+ try {
+ props = Operator.createOperator(comp).getDump();
+ } catch (Exception e) {
+ props = new Hashtable<>();
+ }
+ clss = comp.getClass().getName();
+ compToString = comp.toString();
+ this.comp = comp;
+ x = comp.getLocationOnScreen().x;
+ y = comp.getLocationOnScreen().y;
+ w = comp.getWidth();
+ h = comp.getHeight();
+ }
+
+ public String toString() {
+ return clss;
+ }
+
+ public Hashtable getProperties() {
+ return props;
+ }
+
+ public String getToString() {
+ return compToString;
+ }
+
+ public void setComponentImageProvider(ComponentImageProvider provider) {
+ image = provider;
+ }
+
+ public BufferedImage getImage() {
+ if (image != null) {
+ return image.getImage(x, y, w, h);
+ } else {
+ return null;
+ }
+ }
+ }
+
+ private class ContainerNode extends ComponentNode {
+
+ protected ComponentNode[] comps;
+
+ protected ContainerNode() {
+ super();
+ comps = new ComponentNode[0];
+ }
+
+ public ContainerNode(Container comp) {
+ super(comp);
+ Component[] cmps = comp.getComponents();
+ Vector wwns = new Vector<>();
+ for (Component cmp : cmps) {
+ if (cmp != null && (propDialog.showAll || cmp.isVisible())) {
+ if (cmp instanceof Container) {
+ wwns.add(new ContainerNode((Container) cmp));
+ } else {
+ wwns.add(new ComponentNode(cmp));
+ }
+ }
+ }
+ comps = new ComponentNode[wwns.size()];
+ for (int i = 0; i < wwns.size(); i++) {
+ comps[i] = wwns.get(i);
+ }
+ }
+
+ public ComponentNode[] getComponents() {
+ return comps;
+ }
+
+ public int getComponentIndex(ComponentNode comp) {
+ for (int i = 0; i < comps.length; i++) {
+ if (comps[i].equals(comp)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ public void setComponentImageProvider(ComponentImageProvider provider) {
+ super.setComponentImageProvider(provider);
+ for (ComponentNode comp1 : comps) {
+ comp1.setComponentImageProvider(provider);
+ }
+ }
+
+ public ComponentModel getComponentModel() {
+ return new ComponentModel(this);
+ }
+ }
+
+ private class WindowNode extends ContainerNode {
+
+ protected WindowNode[] wins;
+ String title;
+
+ protected WindowNode() {
+ super();
+ wins = new WindowNode[0];
+ title = "All Frames";
+ clss = "";
+ }
+
+ public WindowNode(Window win) {
+ super(win);
+ Window[] wns = win.getOwnedWindows();
+ Vector wwns = new Vector<>();
+ for (Window wn : wns) {
+ if (propDialog.showAll || wn.isVisible()) {
+ wwns.add(new WindowNode(wn));
+ }
+ }
+ wins = new WindowNode[wwns.size()];
+ for (int i = 0; i < wwns.size(); i++) {
+ wins[i] = wwns.get(i);
+ }
+ title = win.toString();
+ clss = win.getClass().getName();
+ BufferedImage image = null;
+ try {
+ image = new Robot().
+ createScreenCapture(new Rectangle(win.getLocationOnScreen(),
+ win.getSize()));
+ } catch (AWTException e) {
+ e.printStackTrace();
+ }
+ setComponentImageProvider(new ComponentImageProvider(image, x, y));
+ }
+
+ public WindowNode[] getWindows() {
+ return wins;
+ }
+
+ public int getWindowIndex(WindowNode node) {
+ for (int i = 0; i < wins.length; i++) {
+ if (wins[i].equals(node)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public WindowModel getWindowModel() {
+ return new WindowModel(this);
+ }
+
+ public String toString() {
+ return clss + " \"" + title + "\"";
+ }
+ }
+
+ private class RootNode extends WindowNode {
+
+ public RootNode() {
+ super();
+ Window[] wns = Frame.getFrames();
+ wins = new WindowNode[wns.length];
+ int count = 0;
+ for (Window wn1 : wns) {
+ if (propDialog.showAll || wn1.isVisible()) {
+ count++;
+ }
+ }
+ wins = new WindowNode[count];
+ count = 0;
+ for (Window wn : wns) {
+ if (propDialog.showAll || wn.isVisible()) {
+ wins[count] = new WindowNode(wn);
+ count++;
+ }
+ }
+ }
+ }
+
+ private static class ClassModel implements TreeModel {
+
+ ClassNode clsn;
+
+ ClassModel(ClassNode clsn) {
+ this.clsn = clsn;
+ }
+
+ @Override
+ public void addTreeModelListener(TreeModelListener l) {
+ }
+
+ @Override
+ public Object getChild(Object parent, int index) {
+ if (parent == clsn) {
+ return clsn.getSuperClasses()[index];
+ } else if (parent instanceof SuperClassNode
+ || parent instanceof InterfaceNode) {
+ return ((ClassNode) parent).getSubNodes()[index];
+ } else if (parent instanceof MethodNode) {
+ return ((MethodNode) parent).getParameters()[index];
+ }
+ return null;
+ }
+
+ @Override
+ public int getChildCount(Object parent) {
+ if (parent == clsn) {
+ return clsn.getSuperClasses().length;
+ } else if (parent instanceof SuperClassNode
+ || parent instanceof InterfaceNode) {
+ return ((ClassNode) parent).getSubNodes().length;
+ } else if (parent instanceof MethodNode) {
+ return ((MethodNode) parent).getParameters().length;
+ }
+ return 0;
+ }
+
+ @Override
+ public int getIndexOfChild(Object parent, Object child) {
+ if (parent == clsn
+ || parent instanceof MethodNode
+ || parent instanceof SuperClassNode
+ || parent instanceof InterfaceNode) {
+ Object[] children;
+ if (parent instanceof SuperClassNode
+ || parent instanceof InterfaceNode) {
+ children = ((ClassNode) parent).getSuperClasses();
+ } else if (parent instanceof MethodNode) {
+ children = ((MethodNode) parent).getParameters();
+ } else {
+ children = clsn.getSuperClasses();
+ }
+ for (int i = 0; i < children.length; i++) {
+ if (children.equals(child)) {
+ return i;
+ }
+ }
+ }
+ return 0;
+ }
+
+ @Override
+ public Object getRoot() {
+ return clsn;
+ }
+
+ @Override
+ public boolean isLeaf(Object node) {
+ return getChildCount(node) == 0;
+ }
+
+ @Override
+ public void removeTreeModelListener(TreeModelListener l) {
+ }
+
+ @Override
+ public void valueForPathChanged(TreePath path, Object newValue) {
+ }
+ }
+
+ private static class WindowModel implements TreeModel {
+
+ WindowNode win;
+
+ WindowModel(WindowNode win) {
+ this.win = win;
+ }
+
+ @Override
+ public void addTreeModelListener(TreeModelListener l) {
+ }
+
+ @Override
+ public Object getChild(Object parent, int index) {
+ return ((WindowNode) parent).getWindows()[index];
+ }
+
+ @Override
+ public int getChildCount(Object parent) {
+ return ((WindowNode) parent).getWindows().length;
+ }
+
+ @Override
+ public int getIndexOfChild(Object parent, Object child) {
+ return ((WindowNode) parent).getWindowIndex((WindowNode) child);
+ }
+
+ @Override
+ public Object getRoot() {
+ return win;
+ }
+
+ @Override
+ public boolean isLeaf(Object node) {
+ return ((WindowNode) node).getWindows().length == 0;
+ }
+
+ @Override
+ public void removeTreeModelListener(TreeModelListener l) {
+ }
+
+ @Override
+ public void valueForPathChanged(TreePath path, Object newValue) {
+ }
+ }
+
+ private static class ComponentModel implements TreeModel {
+
+ ContainerNode cont;
+
+ ComponentModel(ContainerNode cont) {
+ this.cont = cont;
+ }
+
+ @Override
+ public void addTreeModelListener(TreeModelListener l) {
+ }
+
+ @Override
+ public Object getChild(Object parent, int index) {
+ if (parent instanceof ContainerNode) {
+ return ((ContainerNode) parent).getComponents()[index];
+ } else {
+ return "";
+ }
+ }
+
+ @Override
+ public int getChildCount(Object parent) {
+ if (parent instanceof ContainerNode) {
+ return ((ContainerNode) parent).getComponents().length;
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public int getIndexOfChild(Object parent, Object child) {
+ if (parent instanceof ContainerNode) {
+ return ((ContainerNode) parent).getComponentIndex((ComponentNode) child);
+ } else {
+ return -1;
+ }
+ }
+
+ @Override
+ public Object getRoot() {
+ return cont;
+ }
+
+ @Override
+ public boolean isLeaf(Object node) {
+ if (node instanceof ContainerNode) {
+ return ((ContainerNode) node).getComponents().length == 0;
+ } else {
+ return true;
+ }
+ }
+
+ @Override
+ public void removeTreeModelListener(TreeModelListener l) {
+ }
+
+ @Override
+ public void valueForPathChanged(TreePath path, Object newValue) {
+ }
+ }
+
+ private static class WindowRenderer implements TreeCellRenderer, ListCellRenderer {
+
+ public WindowRenderer() {
+ }
+
+ @Override
+ public Component getTreeCellRendererComponent(JTree tree,
+ Object value,
+ boolean selected,
+ boolean expanded,
+ boolean leaf,
+ int row,
+ boolean hasFocus) {
+ return get((ClassNode) value, selected);
+ }
+
+ @Override
+ public Component getListCellRendererComponent(JList extends ClassNode> list,
+ ClassNode value,
+ int index,
+ boolean isSelected,
+ boolean cellHasFocus) {
+ return get(value, isSelected);
+ }
+
+ private Component get(ClassNode value, boolean selected) {
+ Component result = new JLabel(value.toString());
+ if (selected) {
+ result.setBackground(Color.blue);
+ result.setForeground(Color.white);
+ JPanel resPane = new JPanel();
+ resPane.setLayout(new BorderLayout());
+ resPane.add(result, BorderLayout.CENTER);
+ return resPane;
+ } else {
+ return result;
+ }
+ }
+ }
+
+ private static class PropertyDialog extends JDialog {
+
+ public boolean showAll = false;
+ JComboBox visibleCombo;
+ JCheckBox showToString;
+ JCheckBox showReflection;
+ JCheckBox showEvents;
+ DefaultListModel viewTabs;
+ JList orderList;
+ JButton up;
+ JButton down;
+ Properties props;
+ File propFile;
+
+ public PropertyDialog(JFrame owner) {
+ super(owner, "Properties", true);
+
+ propFile = new File(System.getProperty("user.home")
+ + System.getProperty("file.separator")
+ + ".guibrowser");
+
+ props = new Properties();
+
+ String[] cpItems = {"Showing", "All"};
+ visibleCombo = new JComboBox<>(cpItems);
+ visibleCombo.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ showAll = (visibleCombo.getSelectedIndex() == 1);
+ }
+ });
+
+ JPanel visiblePane = new JPanel();
+ visiblePane.add(new JLabel("Show "));
+ visiblePane.add(visibleCombo);
+
+ showToString = new JCheckBox("Show toString() method result");
+ showToString.setSelected(true);
+
+ JPanel compTreePane = new JPanel();
+ compTreePane.add(visiblePane);
+
+ viewTabs = new DefaultListModel<>();
+ viewTabs.addElement(WINDOWS_TAB);
+ viewTabs.addElement(COMPONENTS_TAB);
+ viewTabs.addElement(PROPERTIES_TAB);
+ viewTabs.addElement(REFLECTION_TAB);
+ viewTabs.addElement(IMAGE_TAB);
+
+ orderList = new JList<>(viewTabs);
+ orderList.addListSelectionListener(new ListSelectionListener() {
+ @Override
+ public void valueChanged(ListSelectionEvent e) {
+ up.setEnabled(orderList.getSelectedIndex() > -1);
+ down.setEnabled(orderList.getSelectedIndex() > -1);
+ }
+ });
+
+ showReflection = new JCheckBox("Show reflection tab");
+ showReflection.setSelected(true);
+ showReflection.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (showReflection.isSelected()) {
+ viewTabs.addElement(REFLECTION_TAB);
+ } else {
+ viewTabs.remove(viewTabs.indexOf(REFLECTION_TAB));
+ }
+ up.setEnabled(orderList.getSelectedIndex() > -1);
+ down.setEnabled(orderList.getSelectedIndex() > -1);
+ }
+ });
+
+ showEvents = new JCheckBox("Show event tab");
+ showEvents.setSelected(true);
+ showEvents.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (showEvents.isSelected()) {
+ viewTabs.addElement(EVENT_TAB);
+ } else {
+ viewTabs.remove(viewTabs.indexOf(EVENT_TAB));
+ }
+ up.setEnabled(orderList.getSelectedIndex() > -1);
+ down.setEnabled(orderList.getSelectedIndex() > -1);
+ }
+ });
+
+ up = new JButton("Move Up");
+ up.setEnabled(false);
+ up.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ int index = orderList.getSelectedIndex();
+ if (index > 0) {
+ viewTabs.add(index - 1,
+ viewTabs.remove(index));
+ orderList.setSelectedIndex(index - 1);
+ }
+ }
+ });
+
+ down = new JButton("Move Down");
+ down.setEnabled(false);
+ down.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ int index = orderList.getSelectedIndex();
+ if (index < viewTabs.size() - 1) {
+ viewTabs.add(index + 1,
+ viewTabs.remove(index));
+ orderList.setSelectedIndex(index + 1);
+ }
+ }
+ });
+
+ JPanel movePane = new JPanel();
+ movePane.add(showEvents);
+ movePane.add(showReflection);
+ movePane.add(up);
+ movePane.add(down);
+
+ JPanel compViewPane = new JPanel();
+ compViewPane.setLayout(new BorderLayout());
+ compViewPane.add(new JLabel("Tab order:"), BorderLayout.NORTH);
+ compViewPane.add(movePane, BorderLayout.SOUTH);
+ compViewPane.add(orderList, BorderLayout.CENTER);
+
+ JTabbedPane tbpn = new JTabbedPane();
+ tbpn.add("Component Tree", compTreePane);
+ tbpn.add("Component View", compViewPane);
+
+ JButton okBUtton = new JButton("OK");
+ okBUtton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ save();
+ setVisible(false);
+ }
+ });
+
+ JButton cnBUtton = new JButton("Cancel");
+ cnBUtton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ setVisible(false);
+ load();
+ }
+ });
+
+ JPanel pn = new JPanel();
+ pn.add(okBUtton);
+ pn.add(cnBUtton);
+
+ getContentPane().setLayout(new BorderLayout());
+ getContentPane().add(pn, BorderLayout.SOUTH);
+ getContentPane().add(tbpn, BorderLayout.CENTER);
+
+ load();
+
+ setSize(400, 400);
+ }
+
+ private void save() {
+ try {
+ props.setProperty("guibrowser.showall",
+ showAll ? "on" : "off");
+ for (int i = 0; i < viewTabs.size(); i++) {
+ props.setProperty("guibrowser.viewpage_" + Integer.toString(i),
+ viewTabs.elementAt(i));
+ }
+ try (FileOutputStream fileOutputStream = new FileOutputStream(propFile)) {
+ props.store(fileOutputStream,
+ "Jemmy GUIBrowser");
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void load() {
+ if (propFile.exists()) {
+ try {
+ try (FileInputStream fileInputStream = new FileInputStream(propFile)) {
+ props.load(fileInputStream);
+ }
+ showAll
+ = props.getProperty("guibrowser.showall") == null
+ || props.getProperty("guibrowser.showall").equals("")
+ || props.getProperty("guibrowser.showall").equals("on");
+ visibleCombo.setSelectedIndex(showAll ? 1 : 0);
+ if (props.getProperty("guibrowser.viewpage_0") != null
+ && !props.getProperty("guibrowser.viewpage_0").equals("")) {
+ viewTabs.removeAllElements();
+ viewTabs.addElement(props.getProperty("guibrowser.viewpage_0"));
+ viewTabs.addElement(props.getProperty("guibrowser.viewpage_1"));
+ viewTabs.addElement(props.getProperty("guibrowser.viewpage_2"));
+ if (props.getProperty("guibrowser.viewpage_3") != null
+ && !props.getProperty("guibrowser.viewpage_3").equals("")) {
+ viewTabs.addElement(props.getProperty("guibrowser.viewpage_3"));
+ }
+ if (props.getProperty("guibrowser.viewpage_4") != null
+ && !props.getProperty("guibrowser.viewpage_4").equals("")) {
+ viewTabs.addElement(props.getProperty("guibrowser.viewpage_4"));
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ showReflection.setSelected(viewTabs.indexOf(REFLECTION_TAB) > -1);
+ showEvents.setSelected(viewTabs.indexOf(EVENT_TAB) > -1);
+ }
+ }
+ }
+
+ private class ComponentBrowser extends JFrame {
+
+ JTree winTree;
+ JTree componentTree;
+ JTree methodTree;
+ ClassNode compNode;
+ JTabbedPane tbd;
+ JButton viewButton;
+ JButton expandButton;
+ JSplitPane winSplit = null;
+ JSplitPane componentSplit = null;
+ WindowRenderer renderer;
+ SelectionManager selManager;
+ JList eventList;
+ ListListener listListener;
+ DefaultListModel eventModel;
+ JCheckBox mouseEvents;
+ JCheckBox mouseMotionEvents;
+ JCheckBox keyEvents;
+
+ public ComponentBrowser(JFrame owner, ClassNode componentNode) {
+ super("Component " + componentNode.toString());
+ fill(componentNode);
+ }
+
+ private void fill(ClassNode componentNode) {
+ compNode = componentNode;
+
+ viewButton = new JButton("View");
+ viewButton.setEnabled(false);
+ viewButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ new ComponentBrowser(getOwnr(),
+ getSelectedNode()).
+ setVisible(true);
+ }
+ });
+
+ expandButton = new JButton("Expand All");
+ expandButton.setEnabled(false);
+ expandButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ expandAll(getSelectedTree(),
+ getSelectionPath());
+ }
+ });
+
+ JPanel buttonPane = new JPanel();
+ buttonPane.add(viewButton);
+ buttonPane.add(expandButton);
+
+ Component[] cpss = {viewButton, expandButton};
+ selManager = new SelectionManager(cpss);
+ renderer = new WindowRenderer();
+
+ tbd = new JTabbedPane();
+
+ for (int i = 0; i < propDialog.viewTabs.size(); i++) {
+ String next = propDialog.viewTabs.elementAt(i);
+ if (next.equals(PROPERTIES_TAB)) {
+ addPropertiesTab();
+ } else if (next.equals(WINDOWS_TAB)) {
+ addWindowTab();
+ } else if (next.equals(COMPONENTS_TAB)) {
+ addComponentTab();
+ } else if (next.equals(REFLECTION_TAB)) {
+ addReflectionTab();
+ } else if (next.equals(EVENT_TAB)) {
+ addEventTab();
+ } else if (next.equals(IMAGE_TAB)) {
+ addImageTab();
+ }
+ }
+
+ tbd.addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ viewButton.setEnabled(getSelectedNode() != null);
+ }
+ });
+
+ getContentPane().setLayout(new BorderLayout());
+ getContentPane().add(buttonPane, BorderLayout.SOUTH);
+ getContentPane().add(tbd, BorderLayout.CENTER);
+
+ addComponentListener(new ComponentListener() {
+ @Override
+ public void componentHidden(ComponentEvent e) {
+ }
+
+ @Override
+ public void componentMoved(ComponentEvent e) {
+ }
+
+ @Override
+ public void componentResized(ComponentEvent e) {
+ if (winSplit != null) {
+ winSplit.setDividerLocation(0.8);
+ }
+ if (componentSplit != null) {
+ componentSplit.setDividerLocation(0.8);
+ }
+ }
+
+ @Override
+ public void componentShown(ComponentEvent e) {
+ }
+ });
+
+ setSize(800, 400);
+ }
+
+ private void addImageTab() {
+ BufferedImage image = null;
+ if (compNode instanceof ComponentNode) {
+ image = ((ComponentNode) compNode).getImage();
+ }
+ if (image != null) {
+ JPanel imagePane = new ImagePane(image);
+ imagePane.prepareImage(image, imagePane);
+ JScrollPane pane = new JScrollPane(imagePane);
+ tbd.add(IMAGE_TAB, pane);
+ }
+ }
+
+ private void addWindowTab() {
+ if (compNode instanceof WindowNode
+ && ((WindowNode) compNode).getWindows().length > 0) {
+ winTree = new JTree(((WindowNode) compNode).getWindowModel());
+ winTree.setCellRenderer(renderer);
+ winTree.setEditable(false);
+ winTree.addTreeSelectionListener(selManager);
+ winSplit = createUnderPane(winTree);
+ tbd.add(WINDOWS_TAB, winSplit);
+ }
+
+ }
+
+ private void addComponentTab() {
+ if (compNode instanceof ContainerNode
+ && ((ContainerNode) compNode).getComponents().length > 0) {
+ componentTree = new JTree(((ContainerNode) compNode).getComponentModel());
+ componentTree.setCellRenderer(renderer);
+ componentTree.setEditable(false);
+ componentTree.addTreeSelectionListener(selManager);
+ componentSplit = createUnderPane(componentTree);
+ tbd.add(COMPONENTS_TAB, componentSplit);
+ }
+
+ }
+
+ private void addReflectionTab() {
+ methodTree = new JTree(compNode.getMethodsModel());
+ methodTree.setCellRenderer(renderer);
+ methodTree.setEditable(false);
+ methodTree.addTreeSelectionListener(selManager);
+ tbd.add(REFLECTION_TAB, new JScrollPane(methodTree));
+ }
+
+ private void addPropertiesTab() {
+ if (compNode instanceof ComponentNode) {
+ Hashtable props = ((ContainerNode) compNode).getProperties();
+ if (props.size() > 0) {
+ JTable propTable = new JTable(new MyModel(props));
+ propTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
+ tbd.add(PROPERTIES_TAB, new JScrollPane(propTable));
+ /*
+ propTable.addMouseListener(new MouseListener() {
+ public void mouseClicked(MouseEvent e) {
+ new ComponentBrowser(getOwnr(),
+ getSelectedNode()).
+ show();
+ }
+ public void mouseExited(MouseEvent e) {
+ }
+ public void mouseEntered(MouseEvent e) {
+ }
+ public void mousePressed(MouseEvent e) {
+ }
+ public void mouseReleased(MouseEvent e) {
+ }
+ });
+ */
+ }
+ }
+ }
+
+ private void addEventTab() {
+ if (compNode instanceof ComponentNode) {
+ eventModel = new DefaultListModel<>();
+ eventList = new JList<>(eventModel);
+ listListener = new ListListener(eventModel, ((ComponentNode) compNode).comp);
+ mouseEvents = new JCheckBox("Mouse events");
+ mouseEvents.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (mouseEvents.isSelected()) {
+ listListener.addMouseListener();
+ } else {
+ listListener.removeMouseListener();
+ }
+ }
+ });
+ mouseMotionEvents = new JCheckBox("Mouse motion events");
+ mouseMotionEvents.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (mouseMotionEvents.isSelected()) {
+ listListener.addMouseMotionListener();
+ } else {
+ listListener.removeMouseMotionListener();
+ }
+ }
+ });
+ keyEvents = new JCheckBox("Key events");
+ keyEvents.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (keyEvents.isSelected()) {
+ listListener.addKeyListener();
+ } else {
+ listListener.removeKeyListener();
+ }
+ }
+ });
+ JButton clear = new JButton("Clear list");
+ clear.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ eventModel.removeAllElements();
+ }
+ });
+ JPanel checkPane = new JPanel();
+ checkPane.add(mouseEvents);
+ checkPane.add(mouseMotionEvents);
+ checkPane.add(keyEvents);
+ checkPane.add(clear);
+ JPanel subPane = new JPanel();
+ subPane.setLayout(new BorderLayout());
+ subPane.add(checkPane, BorderLayout.SOUTH);
+ subPane.add(new JScrollPane(eventList), BorderLayout.CENTER);
+ tbd.add(EVENT_TAB, subPane);
+ }
+ }
+
+ private JFrame getOwnr() {
+ return this;
+ }
+
+ private JTree getSelectedTree() {
+ String title = tbd.getTitleAt(tbd.getSelectedIndex());
+ if (title.equals(WINDOWS_TAB)) {
+ return winTree;
+ } else if (title.equals(COMPONENTS_TAB)) {
+ return componentTree;
+ } else if (title.equals(REFLECTION_TAB)) {
+ return methodTree;
+ }
+ return null;
+ }
+
+ private TreePath getSelectionPath() {
+ JTree tree = getSelectedTree();
+ if (tree != null) {
+ return tree.getSelectionPath();
+ } else {
+ return null;
+ }
+ }
+
+ private ClassNode getSelectedNode() {
+ TreePath path = getSelectionPath();
+ if (path != null) {
+ return (ClassNode) path.getLastPathComponent();
+ } else {
+ return null;
+ }
+ }
+
+ }
+
+ private static class SelectionManager implements TreeSelectionListener, ListSelectionListener {
+
+ Component[] comps;
+
+ public SelectionManager(Component[] comps) {
+ this.comps = comps;
+ }
+
+ @Override
+ public void valueChanged(TreeSelectionEvent e) {
+ for (Component comp : comps) {
+ comp.setEnabled(e.getPath() != null);
+ }
+ }
+
+ @Override
+ public void valueChanged(ListSelectionEvent e) {
+ for (Component comp : comps) {
+ comp.setEnabled(e.getFirstIndex() != -1);
+ }
+ }
+ }
+
+ private void expandAll(JTree tree, TreePath path) {
+ tree.expandPath(path);
+ TreeModel model = tree.getModel();
+ Object lastComponent = path.getLastPathComponent();
+ for (int i = 0; i < model.getChildCount(lastComponent); i++) {
+ expandAll(tree,
+ path.pathByAddingChild(model.getChild(lastComponent, i)));
+ }
+ }
+
+ private static class ToStringListener implements TreeSelectionListener {
+
+ JTextArea area;
+
+ public ToStringListener(JTextArea area) {
+ this.area = area;
+ }
+
+ @Override
+ public void valueChanged(TreeSelectionEvent e) {
+ if (e.getPath() != null
+ && e.getPath().getLastPathComponent() instanceof ComponentNode) {
+ area.setText("toString(): "
+ + ((ComponentNode) e.getPath().getLastPathComponent()).
+ getToString());
+ } else {
+ area.setText("");
+ }
+ }
+ }
+
+ private JSplitPane createUnderPane(JTree tree) {
+ JTextArea toStringArea = new JTextArea();
+ toStringArea.setLineWrap(true);
+ toStringArea.setEditable(false);
+ tree.addTreeSelectionListener(new ToStringListener(toStringArea));
+ JSplitPane result = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
+ new JScrollPane(tree),
+ new JScrollPane(toStringArea));
+ result.setOneTouchExpandable(true);
+ result.setDividerSize(8);
+ result.setDividerLocation(0.8);
+ return result;
+ }
+
+ private static class MyModel extends DefaultTableModel {
+
+ private static final long serialVersionUID = 42L;
+
+ @SuppressWarnings(value = "unchecked")
+ public MyModel(Hashtable props) {
+ super();
+ Object[] keys = props.keySet().toArray();
+ if (keys.length > 0) {
+ addColumn("Name");
+ addColumn("Value");
+ setNumRows(keys.length);
+ for (int i = 0; i < keys.length; i++) {
+ setValueAt(keys[i].toString(), i, 0);
+ setValueAt(props.get(keys[i]).toString(), i, 1);
+ }
+ Collections.sort((Vector>) (Vector>) getDataVector(), new Comparator>() {
+ @Override
+ public int compare(Vector> v1, Vector> v2) {
+ return v1.get(0).toString().compareTo(v2.get(0).toString());
+ }
+ });
+ }
+ }
+
+ @Override
+ public boolean isCellEditable(int x, int y) {
+ return false;
+ }
+ }
+
+ private static class ListListener extends TrialListenerManager {
+
+ DefaultListModel model;
+
+ public ListListener(DefaultListModel m, Component comp) {
+ super(comp);
+ model = m;
+ }
+
+ @Override
+ void printEvent(AWTEvent e) {
+ model.addElement(e);
+ }
+ }
+
+ private static class ImagePane extends JPanel {
+
+ private static final long serialVersionUID = 42L;
+ BufferedImage image;
+
+ public ImagePane(BufferedImage image) {
+ super();
+ this.image = image;
+ setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
+ }
+
+ @Override
+ public void paint(Graphics g) {
+ g.drawImage(image, 0, 0, null);
+ }
+ }
+
+ private static class ComponentImageProvider {
+
+ BufferedImage image;
+ int x;
+ int y;
+
+ public ComponentImageProvider(BufferedImage image, int x, int y) {
+ this.image = image;
+ this.x = x;
+ this.y = y;
+ }
+
+ public BufferedImage getImage(int x, int y, int w, int h) {
+ /*
+ BufferedImage newImage = image.getSubimage(0, 0, image.getWidth(), image.getHeight());
+ Graphics g = newImage.getGraphics();
+ g.setColor(Color.RED);
+ g.drawRect(x - this.x, y - this.y, w, h);
+ return newImage;
+ */
+ int realW = Math.min(image.getWidth() - x, w);
+ int realH = Math.min(image.getHeight() - y, h);
+ return image.getSubimage(x - this.x, y - this.y, realW, realH);
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/explorer/TrialListenerManager.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/explorer/TrialListenerManager.java
new file mode 100644
index 00000000000..3c50b405cb5
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/explorer/TrialListenerManager.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.explorer;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+
+import org.netbeans.jemmy.JemmyProperties;
+import org.netbeans.jemmy.Outputable;
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.TestOut;
+
+/**
+ * Auxiliary class to find an event sequence which should be posted to reproduce
+ * user actions.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ *
+ */
+public class TrialListenerManager implements Outputable {
+
+ Component comp;
+ TrialMouseListener mListener;
+ TrialMouseMotionListener mmListener;
+ TrialKeyListener kListener;
+ TestOut output;
+
+ /**
+ * Contructor.
+ *
+ * @param comp Component to display event sequence for.
+ */
+ public TrialListenerManager(Component comp) {
+ this.comp = comp;
+ mListener = new TrialMouseListener();
+ mmListener = new TrialMouseMotionListener();
+ kListener = new TrialKeyListener();
+ output = JemmyProperties.getCurrentOutput();
+ }
+
+ @Override
+ public void setOutput(TestOut output) {
+ this.output = output;
+ }
+
+ @Override
+ public TestOut getOutput() {
+ return output;
+ }
+
+ /**
+ * Removes mouse listener.
+ *
+ * @see #addMouseListener
+ */
+ public void removeMouseListener() {
+ comp.removeMouseListener(mListener);
+ }
+
+ /**
+ * Adds mouse listener.
+ *
+ * @see #removeMouseListener
+ */
+ public void addMouseListener() {
+ removeMouseListener();
+ comp.addMouseListener(mListener);
+ }
+
+ /**
+ * Removes mouse motion listener.
+ *
+ * @see #addMouseMotionListener
+ */
+ public void removeMouseMotionListener() {
+ comp.removeMouseMotionListener(mmListener);
+ }
+
+ /**
+ * Adds mouse motion listener.
+ *
+ * @see #removeMouseMotionListener
+ */
+ public void addMouseMotionListener() {
+ removeMouseMotionListener();
+ comp.addMouseMotionListener(mmListener);
+ }
+
+ /**
+ * Removes key listener.
+ *
+ * @see #addKeyListener
+ */
+ public void removeKeyListener() {
+ comp.removeKeyListener(kListener);
+ }
+
+ /**
+ * Adds key listener.
+ *
+ * @see #removeKeyListener
+ */
+ public void addKeyListener() {
+ removeKeyListener();
+ comp.addKeyListener(kListener);
+ }
+
+ void printEvent(final AWTEvent event) {
+ // if event != null run toString in dispatch thread
+ String eventToString = new QueueTool().invokeSmoothly(
+ new QueueTool.QueueAction("event.toString()") {
+ @Override
+ public String launch() {
+ return event.toString();
+ }
+ }
+ );
+ output.printLine(eventToString);
+ }
+
+ private class TrialMouseListener implements MouseListener {
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ printEvent(e);
+ }
+
+ @Override
+ public void mouseEntered(MouseEvent e) {
+ printEvent(e);
+ }
+
+ @Override
+ public void mouseExited(MouseEvent e) {
+ printEvent(e);
+ }
+
+ @Override
+ public void mousePressed(MouseEvent e) {
+ printEvent(e);
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ printEvent(e);
+ }
+ }
+
+ private class TrialMouseMotionListener implements MouseMotionListener {
+
+ @Override
+ public void mouseDragged(MouseEvent e) {
+ printEvent(e);
+ }
+
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ printEvent(e);
+ }
+ }
+
+ private class TrialKeyListener implements KeyListener {
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ printEvent(e);
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ printEvent(e);
+ }
+
+ @Override
+ public void keyTyped(KeyEvent e) {
+ printEvent(e);
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/explorer/package-info.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/explorer/package-info.java
new file mode 100644
index 00000000000..aa05f9aff1d
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/explorer/package-info.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ *
Package org.netbeans.jemmy.explorer
+ * Contains auxiliary classes to explore tested application.
+ *
+ * @since 23 Feb 2002
+ *
+ */
+package org.netbeans.jemmy.explorer;
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ColorImageComparator.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ColorImageComparator.java
new file mode 100644
index 00000000000..1f4472cda4e
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ColorImageComparator.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.image;
+
+import java.awt.image.BufferedImage;
+
+/**
+ * Compares two images with color mapping defined by {@code ColorModel}
+ * implementation.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class ColorImageComparator extends StrictImageComparator {
+
+ ColorMap leftMap, rightMap;
+ ImageComparator comparator = null;
+
+ /**
+ * Creates a comparator with a color maps. Object created by this
+ * constructor behaves like {@code StrictImageComparator}. Object
+ * created works faster because it does not create intermediate images for
+ * another comparator.
+ *
+ * @param map Map applied to both left and right images during comparision.
+ */
+ public ColorImageComparator(ColorMap map) {
+ leftMap = map;
+ rightMap = map;
+ }
+
+ /**
+ * Creates a comparator with {@code map} color mapping. Actual
+ * comparision perfomed by {@code comparator} parameter.
+ *
+ * @param map Map applied to both left and right images during comparision.
+ * @param subComparator comporator to perform a comparision of to images
+ * with mapped colors.
+ */
+ public ColorImageComparator(ColorMap map, ImageComparator subComparator) {
+ this(map);
+ this.comparator = subComparator;
+ }
+
+ /**
+ * Creates a comparator with two color maps. Object created by this
+ * constructor behaves like {@code StrictImageComparator}. Object
+ * created works faster because it does not create intermediate images for
+ * another comparator.
+ *
+ * @param leftMap Map applied to the left image during comparision.
+ * @param rightMap Map applied to the right image during comparision.
+ */
+ public ColorImageComparator(ColorMap leftMap, ColorMap rightMap) {
+ this.leftMap = leftMap;
+ this.rightMap = rightMap;
+ }
+
+ /**
+ * Creates a comparator with two color maps. Actual comparision perfomed by
+ * {@code comparator} parameter.
+ *
+ * @param leftMap Map applied to the left image during comparision.
+ * @param rightMap Map applied to the right image during comparision.
+ * @param subComparator comporator to perform a comparision of to images
+ * with mapped colors.
+ */
+ public ColorImageComparator(ColorMap leftMap, ColorMap rightMap, ImageComparator subComparator) {
+ this(leftMap, rightMap);
+ this.comparator = subComparator;
+ }
+
+ /**
+ * Compares images by {@code ImageComparator} passed into constructor,
+ * or itself if no {@code ImageComparator} was passed, processing both
+ * images by {@code ColorMap} instance before comparision.
+ */
+ @Override
+ public boolean compare(BufferedImage image1, BufferedImage image2) {
+ if (comparator != null) {
+ return comparator.compare(recolor(image1, leftMap), recolor(image2, rightMap));
+ } else {
+ return super.compare(image1, image2);
+ }
+ }
+
+ private BufferedImage recolor(BufferedImage src, ColorMap map) {
+ BufferedImage result = new BufferedImage(src.getWidth(), src.getHeight(), src.getType());
+ for (int x = 0; x < src.getWidth(); x++) {
+ for (int y = 0; y < src.getWidth(); y++) {
+ result.setRGB(x, y, map.mapColor(src.getRGB(x, y)));
+ }
+ }
+ return result;
+ }
+
+ @Override
+ protected final boolean compareColors(int rgb1, int rgb2) {
+ return leftMap.mapColor(rgb1) == rightMap.mapColor(rgb2);
+ }
+
+ /**
+ * Interface to map colors during the comparision.
+ */
+ public static interface ColorMap {
+
+ /**
+ * Maps one color into another.
+ *
+ * @param rgb an original color.
+ * @return a converted color.
+ */
+ public int mapColor(int rgb);
+ }
+
+ /**
+ * Turns {@code foreground} color to white, other - to black.
+ */
+ public static class ForegroundColorMap implements ColorMap {
+
+ int foreground;
+
+ /**
+ * Constructs a ColorImageComparator$ForegroundColorMap object.
+ *
+ * @param foreground Foreground color.
+ */
+ public ForegroundColorMap(int foreground) {
+ this.foreground = foreground;
+ }
+
+ @Override
+ public int mapColor(int rgb) {
+ return (rgb == foreground) ? 0xffffff : 0;
+ }
+ }
+
+ /**
+ * Turns {@code background} color to black, left others unchanged.
+ */
+ public static class BackgroundColorMap implements ColorMap {
+
+ int background;
+
+ /**
+ * Constructs a ColorImageComparator$BackgroundColorMap object.
+ *
+ * @param background Background color.
+ */
+ public BackgroundColorMap(int background) {
+ this.background = background;
+ }
+
+ @Override
+ public int mapColor(int rgb) {
+ return (rgb == background) ? 0 : rgb;
+ }
+ }
+
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/FileImageComparator.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/FileImageComparator.java
new file mode 100644
index 00000000000..9898a875d56
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/FileImageComparator.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.image;
+
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+import org.netbeans.jemmy.JemmyException;
+
+/**
+ * Allowes compares images in memory to ones stored in files and compare such
+ * images one with another.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class FileImageComparator {
+
+ ImageLoader loader;
+ ImageComparator comparator;
+
+ /**
+ * Constructs a FileImageComparator object.
+ *
+ * @param comparator - ImageComparator to be used for image comparision.
+ * @param loader - ImageLoader to be used for image loading.
+ */
+ public FileImageComparator(ImageComparator comparator, ImageLoader loader) {
+ this.loader = loader;
+ this.comparator = comparator;
+ }
+
+ /**
+ * Compares an image with one stored in file. Comparision is performed by
+ * ImageComparator passed into constructor. Image is loaded by ImageLoader
+ * passed into constructor.
+ *
+ * @param image an image to compare.
+ * @param fileName a file containing an image to compare.
+ * @return true if images match each other.
+ */
+ public boolean compare(BufferedImage image, String fileName) {
+ try {
+ return comparator.compare(image, loader.load(fileName));
+ } catch (IOException e) {
+ throw (new JemmyException("IOException during image loading", e));
+ }
+ }
+
+ /**
+ * Compares two image stored in files.. Comparision is performed by
+ * ImageComparator passed into constructor. Images are loaded by ImageLoader
+ * passed into constructor.
+ *
+ * @param fileName1 a file containing an image to compare.
+ * @param fileName2 a file containing an image to compare.
+ * @return true if images match each other.
+ */
+ public boolean compare(String fileName1, String fileName2) {
+ try {
+ return (comparator.compare(loader.load(fileName1),
+ loader.load(fileName2)));
+ } catch (IOException e) {
+ throw (new JemmyException("IOException during image loading", e));
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ImageComparator.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ImageComparator.java
new file mode 100644
index 00000000000..f3fbde9eaab
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ImageComparator.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.image;
+
+import java.awt.image.BufferedImage;
+
+/**
+ * Interface for all classes performing image comparison.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface ImageComparator {
+
+ /**
+ * Should return true if images matches, false otherwise.
+ *
+ * @param image1 an image to compare.
+ * @param image2 an image to compare.
+ * @return true if images match each other.
+ */
+ public boolean compare(BufferedImage image1, BufferedImage image2);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ImageFinder.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ImageFinder.java
new file mode 100644
index 00000000000..9a218994526
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ImageFinder.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.image;
+
+import java.awt.Point;
+import java.awt.image.BufferedImage;
+
+/**
+ * Interface for all classes performing image lookup.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface ImageFinder {
+
+ /**
+ * Should return location if image lays inside an image represented by this
+ * object.
+ *
+ * @param image an image to search.
+ * @param index an ordinal image location index. If equal to 1, for example,
+ * second appropriate location will be found.
+ * @return Image location coordinates if image was found, null otherwise.
+ */
+ public Point findImage(BufferedImage image, int index);
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ImageLoader.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ImageLoader.java
new file mode 100644
index 00000000000..b3e4bab9408
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ImageLoader.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.image;
+
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+/**
+ * Interface for all classes performing image loading.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface ImageLoader {
+
+ /**
+ * Loads an image from file.
+ *
+ * @param fileName a file to load image from.
+ * @return a loaded image.
+ * @throws IOException
+ */
+ public BufferedImage load(String fileName) throws IOException;
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ImageSaver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ImageSaver.java
new file mode 100644
index 00000000000..07f45d4d9d1
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ImageSaver.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.image;
+
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+/**
+ * Interface for classes performing image saving.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public interface ImageSaver {
+
+ /**
+ * Should save image into file.
+ *
+ * @param image an image to be saved.
+ * @param fileName a file to load image from.
+ * @throws IOException
+ */
+ public void save(BufferedImage image, String fileName) throws IOException;
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ImageTool.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ImageTool.java
new file mode 100644
index 00000000000..cca418332b4
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/ImageTool.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.image;
+
+import java.awt.AWTException;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.awt.image.BufferedImage;
+
+import org.netbeans.jemmy.JemmyException;
+
+/**
+ * Contains util methods to work with images.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class ImageTool {
+
+ /**
+ * Gets an image from a rectange on screen.
+ *
+ * @param rect a rectangle on screen in absolute screen coordinates.
+ * @return a captured image.
+ */
+ public static BufferedImage getImage(Rectangle rect) {
+ try {
+ return new Robot().createScreenCapture(rect);
+ } catch (AWTException e) {
+ throw (new JemmyException("Exception during screen capturing", e));
+ }
+ }
+
+ /**
+ * Gets an image from a component.
+ *
+ * @param comp a visible component.
+ * @return a captured image.
+ */
+ public static BufferedImage getImage(Component comp) {
+ return (getImage(new Rectangle(comp.getLocationOnScreen(),
+ comp.getSize())));
+ }
+
+ /**
+ * Gets the whole screen image.
+ *
+ * @return a captured image.
+ */
+ public static BufferedImage getImage() {
+ return getImage(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
+ }
+
+ /**
+ * Increases image.
+ *
+ * @param image an image to enlarge.
+ * @param zoom A scale.
+ * @return a result image.
+ */
+ public static BufferedImage enlargeImage(BufferedImage image, int zoom) {
+ int wight = image.getWidth();
+ int height = image.getHeight();
+ BufferedImage result = new BufferedImage(wight * zoom,
+ height * zoom,
+ image.getType());
+ int rgb;
+ for (int x = 0; x < wight; x++) {
+ for (int y = 0; y < height; y++) {
+ rgb = image.getRGB(x, y);
+ for (int i = 0; i < zoom; i++) {
+ for (int j = 0; j < zoom; j++) {
+ result.setRGB(x * zoom + i,
+ y * zoom + j,
+ rgb);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @deprecated Use subtractImage(BufferedImage, BufferedImage) instead.
+ * @param minuend an image to subtract from.
+ * @param deduction an image to subtract.
+ * @return a result image.
+ */
+ @Deprecated
+ public static BufferedImage substractImage(BufferedImage minuend, BufferedImage deduction) {
+ return subtractImage(minuend, deduction);
+ }
+
+ /**
+ * Subtracts second image from first one. Could be used to save file
+ * difference for future analysis.
+ *
+ * @param minuend an image to subtract from.
+ * @param deduction an image to subtract.
+ * @return a result image.
+ */
+ public static BufferedImage subtractImage(BufferedImage minuend, BufferedImage deduction) {
+ return subtractImage(minuend, deduction, 0, 0);
+ }
+
+ /**
+ * @deprecated Use subtractImage(BufferedImage, BufferedImage, int, int)
+ * instead.
+ * @param minuend an image to subtract from.
+ * @param deduction an image to subtract.
+ * @return a result image.
+ */
+ @Deprecated
+ public static BufferedImage substractImage(BufferedImage minuend, BufferedImage deduction, int relativeX, int relativeY) {
+ return subtractImage(minuend, deduction, relativeX, relativeY);
+ }
+
+ /**
+ * Subtracts subimage from image. Could be used to save file difference for
+ * future analysis.
+ *
+ * @param minuend an image to subtract from.
+ * @param deduction an image to subtract.
+ * @param relativeX - deduction-in-minuend X coordinate
+ * @param relativeY - deduction-in-minuend Y coordinate
+ * @return a result image.
+ */
+ public static BufferedImage subtractImage(BufferedImage minuend, BufferedImage deduction, int relativeX, int relativeY) {
+ int mWidth = minuend.getWidth();
+ int mHeight = minuend.getHeight();
+ int dWidth = deduction.getWidth();
+ int dHeight = deduction.getHeight();
+
+ int maxWidth = (mWidth > relativeX + dWidth) ? mWidth : (relativeX + dWidth);
+ int maxHeight = (mHeight > relativeY + dHeight) ? mHeight : (relativeY + dHeight);
+
+ BufferedImage result = new BufferedImage(maxWidth, maxHeight, BufferedImage.TYPE_INT_RGB);
+ int mColor, dColor;
+ for (int x = 0; x < maxWidth; x++) {
+ for (int y = 0; y < maxHeight; y++) {
+ if (x >= mWidth
+ || y >= mHeight) {
+ mColor = 0;
+ } else {
+ mColor = minuend.getRGB(x, y);
+ }
+ if (x >= dWidth + relativeX
+ || y >= dHeight + relativeY
+ || x < relativeX
+ || y < relativeY) {
+ dColor = 0;
+ } else {
+ dColor = deduction.getRGB(x - relativeX, y - relativeY);
+ }
+ result.setRGB(x, y, subtractColors(mColor, dColor));
+ }
+ }
+ return result;
+ }
+
+ private static int subtractColors(int mRGB, int dRGB) {
+ Color mColor = new Color(mRGB);
+ Color dColor = new Color(dRGB);
+ int red = subtractColor(mColor.getRed(), dColor.getRed());
+ int green = subtractColor(mColor.getGreen(), dColor.getGreen());
+ int blue = subtractColor(mColor.getBlue(), dColor.getBlue());
+ return new Color(red, green, blue).getRGB();
+ }
+
+ private static int subtractColor(int mColor, int dColor) {
+ if (mColor >= dColor) {
+ return mColor - dColor;
+ } else {
+ return mColor - dColor + 0Xff;
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/PNGImageLoader.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/PNGImageLoader.java
new file mode 100644
index 00000000000..935f90df8b3
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/PNGImageLoader.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.image;
+
+import java.awt.image.BufferedImage;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import org.netbeans.jemmy.util.PNGDecoder;
+
+/**
+ * Allowes to process PNF image format.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class PNGImageLoader implements ImageLoader {
+
+ /**
+ * Loads an image from a PNG image file.
+ */
+ @Override
+ public BufferedImage load(String fileName) throws IOException {
+ return new PNGDecoder(new FileInputStream(fileName)).decode();
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/PNGImageSaver.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/PNGImageSaver.java
new file mode 100644
index 00000000000..d2fae52470d
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/PNGImageSaver.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.image;
+
+import java.awt.image.BufferedImage;
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.netbeans.jemmy.util.PNGEncoder;
+
+/**
+ * Allowes to process PNF image format.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class PNGImageSaver implements ImageSaver {
+
+ /**
+ * Saves an image into a PNG image file.
+ */
+ @Override
+ public void save(BufferedImage image, String fileName) throws IOException {
+ new PNGEncoder(new BufferedOutputStream(new FileOutputStream(fileName)),
+ PNGEncoder.COLOR_MODE).
+ encode(image);
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/RoughImageComparator.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/RoughImageComparator.java
new file mode 100644
index 00000000000..cdf8ddd9ae5
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/RoughImageComparator.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.image;
+
+import java.awt.image.BufferedImage;
+
+/**
+ * Compares two images roughly (i.e. not all of the pixel colors should match).
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class RoughImageComparator implements ImageComparator {
+
+ double roughness = .0;
+
+ /**
+ * Creates a comparator with {@code roughness} allowed roughness.
+ *
+ * @param roughness Allowed comparision roughness.
+ */
+ public RoughImageComparator(double roughness) {
+ this.roughness = roughness;
+ }
+
+ /**
+ * Compares two images with allowed roughness.
+ *
+ * @param image1 an image to compare.
+ * @param image2 an image to compare.
+ * @return true if images have the same sizes and number of unmatching
+ * pixels less or equal to image1.getWidth() * image1.getHeight() * roughness
+ */
+ @Override
+ public boolean compare(BufferedImage image1, BufferedImage image2) {
+ if (image1.getWidth() != image2.getWidth()
+ || image1.getHeight() != image2.getHeight()) {
+ return false;
+ }
+ double maxRoughPixels = (double) (image1.getWidth() * image1.getHeight()) * roughness;
+ int errorCount = 0;
+ for (int x = 0; x < image1.getWidth(); x++) {
+ for (int y = 0; y < image1.getHeight(); y++) {
+ if (image1.getRGB(x, y) != image2.getRGB(x, y)) {
+ errorCount++;
+ if (errorCount > maxRoughPixels) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/RoughImageFinder.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/RoughImageFinder.java
new file mode 100644
index 00000000000..6848fc825c3
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/RoughImageFinder.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.image;
+
+import java.awt.Point;
+import java.awt.image.BufferedImage;
+
+/**
+ * Performs "rough" image search.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class RoughImageFinder implements ImageFinder {
+
+ double roughness = .0;
+ int bigWidth, bigHeight;
+ int[][] bigPixels;
+
+ /**
+ * Creates an instance allowing to find an image inside the one passed as
+ * parameter with some "roughness".
+ *
+ * @param area - Image to search in.
+ * @param roughness - Allowed
+ */
+ public RoughImageFinder(BufferedImage area, double roughness) {
+ this.roughness = roughness;
+ bigWidth = area.getWidth();
+ bigHeight = area.getHeight();
+ bigPixels = new int[bigWidth][bigHeight];
+ for (int x = 0; x < bigWidth; x++) {
+ for (int y = 0; y < bigHeight; y++) {
+ bigPixels[x][y] = area.getRGB(x, y);
+ }
+ }
+ }
+
+ /**
+ * Performs "rough" search.
+ *
+ * @param image an image to search.
+ * @param index an ordinal image location index.
+ * @return Point where number of unmatching pixels less or equal to image1.getWidth() * image1.getHeight() * roughness
+ */
+ @Override
+ public Point findImage(BufferedImage image, int index) {
+ int smallWidth = image.getWidth();
+ int smallHeight = image.getHeight();
+ int[][] smallPixels = new int[smallWidth][smallHeight];
+ for (int x = 0; x < smallWidth; x++) {
+ for (int y = 0; y < smallHeight; y++) {
+ smallPixels[x][y] = image.getRGB(x, y);
+ }
+ }
+ double maxRoughPixels = (double) (smallWidth * smallHeight) * roughness;
+ int count = 0;
+ for (int X = 0; X <= bigWidth - smallWidth; X++) {
+ for (int Y = 0; Y <= bigHeight - smallHeight; Y++) {
+ int roughPixels = 0;
+ for (int x = 0; x < smallWidth; x++) {
+ for (int y = 0; y < smallHeight; y++) {
+ if (smallPixels[x][y] != bigPixels[X + x][Y + y]) {
+ roughPixels++;
+ if (roughPixels > maxRoughPixels) {
+ break;
+ }
+ }
+ }
+ if (roughPixels > maxRoughPixels) {
+ break;
+ }
+ }
+ if (roughPixels <= maxRoughPixels) {
+ if (count == index) {
+ return new Point(X, Y);
+ }
+ count++;
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/StrictImageComparator.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/StrictImageComparator.java
new file mode 100644
index 00000000000..dce51c568f7
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/StrictImageComparator.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.image;
+
+import java.awt.image.BufferedImage;
+
+/**
+ * Compares two images strictly (i.e. all the pixel colors should match).
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class StrictImageComparator implements ImageComparator {
+
+ /**
+ * Checks images sizes and pixels. Compares one pixel after another untill
+ * one will be different.
+ *
+ * @param image1 an image to compare.
+ * @param image2 an image to compare.
+ * @return True if all the pixels match, false otherwise.
+ */
+ @Override
+ public boolean compare(BufferedImage image1, BufferedImage image2) {
+ if (image1.getWidth() != image2.getWidth()
+ || image1.getHeight() != image2.getHeight()) {
+ return false;
+ }
+ for (int x = 0; x < image1.getWidth(); x++) {
+ for (int y = 0; y < image1.getHeight(); y++) {
+ if (!compareColors(image1.getRGB(x, y), image2.getRGB(x, y))) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Could be used to override the way of comparing colors.
+ *
+ * @param rgb1 a color to compare.
+ * @param rgb2 a color to compare.
+ * @return true if colors are equal.
+ */
+ protected boolean compareColors(int rgb1, int rgb2) {
+ return rgb1 == rgb2;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/StrictImageFinder.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/StrictImageFinder.java
new file mode 100644
index 00000000000..674e550c122
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/StrictImageFinder.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.image;
+
+import java.awt.Point;
+import java.awt.image.BufferedImage;
+
+/**
+ * Performs "strict" (i.e. based on all pixels matching) image search.
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class StrictImageFinder implements ImageFinder {
+
+ int bigWidth, bigHeight;
+ int[][] bigPixels;
+
+ /**
+ * Creates an instance searching subimages insige a parameter image.
+ *
+ * @param area - Image to search in.
+ */
+ public StrictImageFinder(BufferedImage area) {
+ bigWidth = area.getWidth();
+ bigHeight = area.getHeight();
+ bigPixels = new int[bigWidth][bigHeight];
+ for (int x = 0; x < bigWidth; x++) {
+ for (int y = 0; y < bigHeight; y++) {
+ bigPixels[x][y] = area.getRGB(x, y);
+ }
+ }
+ }
+
+ /**
+ * Searchs for an image inside image passed into constructor.
+ *
+ * @param image an image to search.
+ * @param index an ordinal image location index. If equal to 1, for example,
+ * second appropriate location will be found.
+ * @return Left-up corner coordinates of image location.
+ */
+ @Override
+ public Point findImage(BufferedImage image, int index) {
+ int smallWidth = image.getWidth();
+ int smallHeight = image.getHeight();
+ int[][] smallPixels = new int[smallWidth][smallHeight];
+ for (int x = 0; x < smallWidth; x++) {
+ for (int y = 0; y < smallHeight; y++) {
+ smallPixels[x][y] = image.getRGB(x, y);
+ }
+ }
+ boolean good;
+ int count = 0;
+ for (int X = 0; X <= bigWidth - smallWidth; X++) {
+ for (int Y = 0; Y <= bigHeight - smallHeight; Y++) {
+ good = true;
+ for (int x = 0; x < smallWidth; x++) {
+ for (int y = 0; y < smallHeight; y++) {
+ if (smallPixels[x][y] != bigPixels[X + x][Y + y]) {
+ good = false;
+ break;
+ }
+ }
+ if (!good) {
+ break;
+ }
+ }
+ if (good) {
+ if (count == index) {
+ return new Point(X, Y);
+ }
+ count++;
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/package-info.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/package-info.java
new file mode 100644
index 00000000000..f1987a4caf4
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/image/package-info.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ *
Image library
+ * Contains classes allowing to compare two images and to find one image inside
+ * another.
+ *
+ * @since 9 Nov 2002
+ *
+ */
+package org.netbeans.jemmy.image;
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/AbstractButtonOperator.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/AbstractButtonOperator.java
new file mode 100644
index 00000000000..577ce4fb95d
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/AbstractButtonOperator.java
@@ -0,0 +1,1213 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.operators;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Insets;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemListener;
+import java.util.Hashtable;
+
+import javax.swing.AbstractButton;
+import javax.swing.ButtonModel;
+import javax.swing.Icon;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.ButtonUI;
+
+import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.JemmyException;
+import org.netbeans.jemmy.Outputable;
+import org.netbeans.jemmy.TestOut;
+import org.netbeans.jemmy.TimeoutExpiredException;
+import org.netbeans.jemmy.Timeoutable;
+import org.netbeans.jemmy.Timeouts;
+import org.netbeans.jemmy.drivers.ButtonDriver;
+import org.netbeans.jemmy.drivers.DriverManager;
+
+/**
+ *
+ *
Timeouts used:
+ * AbstractButtonOperator.PushButtonTimeout - time between button pressing and
+ * releasing
+ * ComponentOperator.WaitComponentTimeout - time to wait button displayed
+ * ComponentOperator.WaitComponentEnabledTimeout - time to wait button enabled
+ *
+ * ComponentOperator.WaitStateTimeout - time to wait for text .
+ *
+ * @see org.netbeans.jemmy.Timeouts
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ *
+ */
+public class AbstractButtonOperator extends JComponentOperator
+ implements Timeoutable, Outputable {
+
+ /**
+ * Identifier for a text property.
+ *
+ * @see #getDump
+ */
+ public static final String TEXT_DPROP = "Text";
+
+ /**
+ * Identifier for a selected text property.
+ *
+ * @see #getDump
+ */
+ public static final String IS_SELECTED_DPROP = "Selected";
+
+ /**
+ * Default value for AbstractButtonOperator.PushButtonTimeout timeout.
+ */
+ private final static long PUSH_BUTTON_TIMEOUT = 0;
+
+ private Timeouts timeouts;
+ private TestOut output;
+
+ ButtonDriver driver;
+
+ /**
+ * Constructor.
+ *
+ * @param b The {@code java.awt.AbstractButton} managed by this
+ * instance.
+ */
+ public AbstractButtonOperator(AbstractButton b) {
+ super(b);
+ driver = DriverManager.getButtonDriver(getClass());
+ }
+
+ /**
+ * Constructs an AbstractButtonOperator object.
+ *
+ * @param cont container
+ * @param chooser a component chooser specifying searching criteria.
+ * @param index an index between appropriate ones.
+ */
+ public AbstractButtonOperator(ContainerOperator> cont, ComponentChooser chooser, int index) {
+ this((AbstractButton) cont.
+ waitSubComponent(new AbstractButtonFinder(chooser),
+ index));
+ copyEnvironment(cont);
+ }
+
+ /**
+ * Constructs an AbstractButtonOperator object.
+ *
+ * @param cont container
+ * @param chooser a component chooser specifying searching criteria.
+ */
+ public AbstractButtonOperator(ContainerOperator> cont, ComponentChooser chooser) {
+ this(cont, chooser, 0);
+ }
+
+ /**
+ * Constructor. Waits for a component in a container to show. The component
+ * is identified as the {@code index+1}'th
+ * {@code javax.swing.AbstractButton} that shows, lies below the
+ * container in the display containment hierarchy, and that has the desired
+ * text. Uses cont's timeout and output for waiting and to init this
+ * operator.
+ *
+ * @param cont The operator for a container containing the sought for
+ * button.
+ * @param text Button text.
+ * @param index Ordinal component index. The first component has
+ * {@code index} 0.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public AbstractButtonOperator(ContainerOperator> cont, String text, int index) {
+ this((AbstractButton) waitComponent(cont,
+ new AbstractButtonByLabelFinder(text,
+ cont.getComparator()),
+ index));
+ copyEnvironment(cont);
+ }
+
+ /**
+ * Constructor. Waits for a component in a container to show. The component
+ * is identified as the first {@code javax.swing.AbstractButton} that
+ * shows, lies below the container in the display containment hierarchy, and
+ * that has the desired text. Uses cont's timeout and output for waiting and
+ * to init this operator.
+ *
+ * @param cont The operator for a container containing the sought for
+ * button.
+ * @param text Button text.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public AbstractButtonOperator(ContainerOperator> cont, String text) {
+ this(cont, text, 0);
+ }
+
+ /**
+ * Constructor. Waits component in container first. Uses cont's timeout and
+ * output for waiting and to init operator.
+ *
+ * @param cont The operator for a container containing the sought for
+ * button.
+ * @param index Ordinal component index.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public AbstractButtonOperator(ContainerOperator> cont, int index) {
+ this((AbstractButton) waitComponent(cont,
+ new AbstractButtonFinder(),
+ index));
+ copyEnvironment(cont);
+ }
+
+ /**
+ * Constructor. Waits component in container first. Uses cont's timeout and
+ * output for waiting and to init operator.
+ *
+ * @param cont The operator for a container containing the sought for
+ * button.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public AbstractButtonOperator(ContainerOperator> cont) {
+ this(cont, 0);
+ }
+
+ /**
+ * Searches AbstractButton in a container.
+ *
+ * @param cont Container in which to search for the component. The container
+ * lies above the component in the display containment hierarchy. The
+ * containment need not be direct.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation,
+ * defining and applying search criteria.
+ * @param index Ordinal component index. The first {@code index} is 0.
+ * @return AbstractButton instance or null if component was not found.
+ */
+ public static AbstractButton findAbstractButton(Container cont, ComponentChooser chooser, int index) {
+ return (AbstractButton) findComponent(cont, new AbstractButtonFinder(chooser), index);
+ }
+
+ /**
+ * Searches for the first AbstractButton in a container.
+ *
+ * @param cont Container in which to search for the component. The container
+ * lies above the component in the display containment hierarchy. The
+ * containment need not be direct.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation,
+ * defining and applying search criteria.
+ * @return AbstractButton instance or null if component was not found.
+ */
+ public static AbstractButton findAbstractButton(Container cont, ComponentChooser chooser) {
+ return findAbstractButton(cont, chooser, 0);
+ }
+
+ /**
+ * Searches AbstractButton by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Button text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @param index Ordinal component index.
+ * @return AbstractButton instance or null if component was not found.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ */
+ public static AbstractButton findAbstractButton(Container cont, String text, boolean ce, boolean ccs, int index) {
+ return findAbstractButton(cont, new AbstractButtonByLabelFinder(text, new DefaultStringComparator(ce, ccs)), index);
+ }
+
+ /**
+ * Searches AbstractButton by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Button text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @return AbstractButton instance or null if component was not found.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ */
+ public static AbstractButton findAbstractButton(Container cont, String text, boolean ce, boolean ccs) {
+ return findAbstractButton(cont, text, ce, ccs, 0);
+ }
+
+ /**
+ * Waits AbstractButton in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @param index Ordinal component index.
+ * @return AbstractButton instance.
+ * @throws TimeoutExpiredException
+ */
+ public static AbstractButton waitAbstractButton(Container cont, ComponentChooser chooser, int index) {
+ return (AbstractButton) waitComponent(cont, new AbstractButtonFinder(chooser), index);
+ }
+
+ /**
+ * Waits 0'th AbstractButton in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @return AbstractButton instance.
+ * @throws TimeoutExpiredException
+ */
+ public static AbstractButton waitAbstractButton(Container cont, ComponentChooser chooser) {
+ return waitAbstractButton(cont, chooser, 0);
+ }
+
+ /**
+ * Waits AbstractButton by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Button text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @param index Ordinal component index.
+ * @return AbstractButton instance.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public static AbstractButton waitAbstractButton(Container cont, String text, boolean ce, boolean ccs, int index) {
+ return waitAbstractButton(cont, new AbstractButtonByLabelFinder(text, new DefaultStringComparator(ce, ccs)), index);
+ }
+
+ /**
+ * Waits AbstractButton by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Button text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @return AbstractButton instance.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public static AbstractButton waitAbstractButton(Container cont, String text, boolean ce, boolean ccs) {
+ return waitAbstractButton(cont, text, ce, ccs, 0);
+ }
+
+ static {
+ Timeouts.initDefault("AbstractButtonOperator.PushButtonTimeout", PUSH_BUTTON_TIMEOUT);
+ }
+
+ @Override
+ public void setTimeouts(Timeouts timeouts) {
+ super.setTimeouts(timeouts);
+ this.timeouts = timeouts;
+ }
+
+ @Override
+ public Timeouts getTimeouts() {
+ return timeouts;
+ }
+
+ @Override
+ public void setOutput(TestOut out) {
+ output = out;
+ super.setOutput(output.createErrorOutput());
+ }
+
+ @Override
+ public TestOut getOutput() {
+ return output;
+ }
+
+ @Override
+ public void copyEnvironment(Operator anotherOperator) {
+ super.copyEnvironment(anotherOperator);
+ driver = DriverManager.getButtonDriver(this);
+ }
+
+ /**
+ * Pushs the button using a ButtonDriver registered for this operator.
+ */
+ public void push() {
+ output.printLine("Push button\n :" + toStringSource());
+ output.printGolden("Push button");
+ makeComponentVisible();
+ try {
+ waitComponentEnabled();
+ } catch (InterruptedException e) {
+ throw (new JemmyException("Interrupted", e));
+ }
+ driver.push(this);
+ }
+
+ /**
+ * Runs {@code push()} method in a separate thread.
+ */
+ public void pushNoBlock() {
+ produceNoBlocking(new NoBlockingAction("Button pushing") {
+ @Override
+ public Void doAction(Void param) {
+ push();
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Changes selection if necessary. Uses {@code push()} method in order
+ * to do so.
+ *
+ * @param selected a button selection.
+ */
+ public void changeSelection(boolean selected) {
+ if (isSelected() != selected) {
+ push();
+ }
+ if (getVerification()) {
+ waitSelected(selected);
+ }
+ }
+
+ /**
+ * Runs {@code changeSelection(boolean)} method in a separate thread.
+ *
+ * @param selected a button selection.
+ */
+ public void changeSelectionNoBlock(boolean selected) {
+ produceNoBlocking(new NoBlockingAction("Button selection changing") {
+ @Override
+ public Void doAction(Boolean param) {
+ changeSelection(param);
+ return null;
+ }
+ }, selected ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Press the button by mouse.
+ *
+ * @throws TimeoutExpiredException
+ */
+ public void press() {
+ output.printLine("Press button\n :" + toStringSource());
+ output.printGolden("Press button");
+ makeComponentVisible();
+ try {
+ waitComponentEnabled();
+ } catch (InterruptedException e) {
+ throw (new JemmyException("Interrupted", e));
+ }
+ driver.press(this);
+ }
+
+ /**
+ * Releases the button by mouse.
+ *
+ * @throws TimeoutExpiredException
+ */
+ public void release() {
+ output.printLine("Release button\n :" + toStringSource());
+ output.printGolden("Release button");
+ try {
+ waitComponentEnabled();
+ } catch (InterruptedException e) {
+ throw (new JemmyException("Interrupted", e));
+ }
+ driver.release(this);
+ }
+
+ /**
+ * Waits for button to be selected.
+ *
+ * @param selected a button selection.
+ */
+ public void waitSelected(final boolean selected) {
+ getOutput().printLine("Wait button to be selected \n : "
+ + toStringSource());
+ getOutput().printGolden("Wait button to be selected");
+ waitState(new ComponentChooser() {
+ @Override
+ public boolean checkComponent(Component comp) {
+ return isSelected() == selected;
+ }
+
+ @Override
+ public String getDescription() {
+ return ("Items has been "
+ + (selected ? "" : "un") + "selected");
+ }
+
+ @Override
+ public String toString() {
+ return "waitSelected.ComponentChooser{description = " + getDescription() + '}';
+ }
+ });
+ }
+
+ /**
+ * Waits for text. Uses getComparator() comparator.
+ *
+ * @param text Text to wait for.
+ */
+ public void waitText(String text) {
+ getOutput().printLine("Wait \"" + text + "\" text in component \n : "
+ + toStringSource());
+ getOutput().printGolden("Wait \"" + text + "\" text");
+ waitState(new AbstractButtonByLabelFinder(text, getComparator()));
+ }
+
+ /**
+ * Returns information about component.
+ */
+ @Override
+ public Hashtable getDump() {
+ Hashtable result = super.getDump();
+ if (((AbstractButton) getSource()).getText() != null) {
+ result.put(TEXT_DPROP, ((AbstractButton) getSource()).getText());
+ }
+ result.put(IS_SELECTED_DPROP, ((AbstractButton) getSource()).isSelected() ? "true" : "false");
+ return result;
+ }
+
+ ////////////////////////////////////////////////////////
+ //Mapping //
+ /**
+ * Maps {@code AbstractButton.addActionListener(ActionListener)}
+ * through queue
+ */
+ public void addActionListener(final ActionListener actionListener) {
+ runMapping(new MapVoidAction("addActionListener") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).addActionListener(actionListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.addChangeListener(ChangeListener)}
+ * through queue
+ */
+ public void addChangeListener(final ChangeListener changeListener) {
+ runMapping(new MapVoidAction("addChangeListener") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).addChangeListener(changeListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.addItemListener(ItemListener)} through queue
+ */
+ public void addItemListener(final ItemListener itemListener) {
+ runMapping(new MapVoidAction("addItemListener") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).addItemListener(itemListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.doClick()} through queue
+ */
+ public void doClick() {
+ runMapping(new MapVoidAction("doClick") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).doClick();
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.doClick(int)} through queue
+ */
+ public void doClick(final int i) {
+ runMapping(new MapVoidAction("doClick") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).doClick(i);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.getActionCommand()} through queue
+ */
+ public String getActionCommand() {
+ return (runMapping(new MapAction("getActionCommand") {
+ @Override
+ public String map() {
+ return ((AbstractButton) getSource()).getActionCommand();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getDisabledIcon()} through queue
+ */
+ public Icon getDisabledIcon() {
+ return (runMapping(new MapAction("getDisabledIcon") {
+ @Override
+ public Icon map() {
+ return ((AbstractButton) getSource()).getDisabledIcon();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getDisabledSelectedIcon()} through queue
+ */
+ public Icon getDisabledSelectedIcon() {
+ return (runMapping(new MapAction("getDisabledSelectedIcon") {
+ @Override
+ public Icon map() {
+ return ((AbstractButton) getSource()).getDisabledSelectedIcon();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getHorizontalAlignment()} through queue
+ */
+ public int getHorizontalAlignment() {
+ return (runMapping(new MapIntegerAction("getHorizontalAlignment") {
+ @Override
+ public int map() {
+ return ((AbstractButton) getSource()).getHorizontalAlignment();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getHorizontalTextPosition()} through queue
+ */
+ public int getHorizontalTextPosition() {
+ return (runMapping(new MapIntegerAction("getHorizontalTextPosition") {
+ @Override
+ public int map() {
+ return ((AbstractButton) getSource()).getHorizontalTextPosition();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getIcon()} through queue
+ */
+ public Icon getIcon() {
+ return (runMapping(new MapAction("getIcon") {
+ @Override
+ public Icon map() {
+ return ((AbstractButton) getSource()).getIcon();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getMargin()} through queue
+ */
+ public Insets getMargin() {
+ return (runMapping(new MapAction("getMargin") {
+ @Override
+ public Insets map() {
+ return ((AbstractButton) getSource()).getMargin();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getMnemonic()} through queue
+ */
+ public int getMnemonic() {
+ return (runMapping(new MapIntegerAction("getMnemonic") {
+ @Override
+ public int map() {
+ return ((AbstractButton) getSource()).getMnemonic();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getModel()} through queue
+ */
+ public ButtonModel getModel() {
+ return (runMapping(new MapAction("getModel") {
+ @Override
+ public ButtonModel map() {
+ return ((AbstractButton) getSource()).getModel();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getPressedIcon()} through queue
+ */
+ public Icon getPressedIcon() {
+ return (runMapping(new MapAction("getPressedIcon") {
+ @Override
+ public Icon map() {
+ return ((AbstractButton) getSource()).getPressedIcon();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getRolloverIcon()} through queue
+ */
+ public Icon getRolloverIcon() {
+ return (runMapping(new MapAction("getRolloverIcon") {
+ @Override
+ public Icon map() {
+ return ((AbstractButton) getSource()).getRolloverIcon();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getRolloverSelectedIcon()} through queue
+ */
+ public Icon getRolloverSelectedIcon() {
+ return (runMapping(new MapAction("getRolloverSelectedIcon") {
+ @Override
+ public Icon map() {
+ return ((AbstractButton) getSource()).getRolloverSelectedIcon();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getSelectedIcon()} through queue
+ */
+ public Icon getSelectedIcon() {
+ return (runMapping(new MapAction("getSelectedIcon") {
+ @Override
+ public Icon map() {
+ return ((AbstractButton) getSource()).getSelectedIcon();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getSelectedObjects()} through queue
+ */
+ public Object[] getSelectedObjects() {
+ return ((Object[]) runMapping(new MapAction("getSelectedObjects") {
+ @Override
+ public Object map() {
+ return ((AbstractButton) getSource()).getSelectedObjects();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getText()} through queue
+ */
+ public String getText() {
+ return (runMapping(new MapAction("getText") {
+ @Override
+ public String map() {
+ return ((AbstractButton) getSource()).getText();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getUI()} through queue
+ */
+ public ButtonUI getUI() {
+ return (runMapping(new MapAction("getUI") {
+ @Override
+ public ButtonUI map() {
+ return ((AbstractButton) getSource()).getUI();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getVerticalAlignment()} through queue
+ */
+ public int getVerticalAlignment() {
+ return (runMapping(new MapIntegerAction("getVerticalAlignment") {
+ @Override
+ public int map() {
+ return ((AbstractButton) getSource()).getVerticalAlignment();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.getVerticalTextPosition()} through queue
+ */
+ public int getVerticalTextPosition() {
+ return (runMapping(new MapIntegerAction("getVerticalTextPosition") {
+ @Override
+ public int map() {
+ return ((AbstractButton) getSource()).getVerticalTextPosition();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.isBorderPainted()} through queue
+ */
+ public boolean isBorderPainted() {
+ return (runMapping(new MapBooleanAction("isBorderPainted") {
+ @Override
+ public boolean map() {
+ return ((AbstractButton) getSource()).isBorderPainted();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.isContentAreaFilled()} through queue
+ */
+ public boolean isContentAreaFilled() {
+ return (runMapping(new MapBooleanAction("isContentAreaFilled") {
+ @Override
+ public boolean map() {
+ return ((AbstractButton) getSource()).isContentAreaFilled();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.isFocusPainted()} through queue
+ */
+ public boolean isFocusPainted() {
+ return (runMapping(new MapBooleanAction("isFocusPainted") {
+ @Override
+ public boolean map() {
+ return ((AbstractButton) getSource()).isFocusPainted();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.isRolloverEnabled()} through queue
+ */
+ public boolean isRolloverEnabled() {
+ return (runMapping(new MapBooleanAction("isRolloverEnabled") {
+ @Override
+ public boolean map() {
+ return ((AbstractButton) getSource()).isRolloverEnabled();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.isSelected()} through queue
+ */
+ public boolean isSelected() {
+ return (runMapping(new MapBooleanAction("isSelected") {
+ @Override
+ public boolean map() {
+ return ((AbstractButton) getSource()).isSelected();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code AbstractButton.removeActionListener(ActionListener)}
+ * through queue
+ */
+ public void removeActionListener(final ActionListener actionListener) {
+ runMapping(new MapVoidAction("removeActionListener") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).removeActionListener(actionListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.removeChangeListener(ChangeListener)}
+ * through queue
+ */
+ public void removeChangeListener(final ChangeListener changeListener) {
+ runMapping(new MapVoidAction("removeChangeListener") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).removeChangeListener(changeListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.removeItemListener(ItemListener)} through queue
+ */
+ public void removeItemListener(final ItemListener itemListener) {
+ runMapping(new MapVoidAction("removeItemListener") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).removeItemListener(itemListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setActionCommand(String)} through queue
+ */
+ public void setActionCommand(final String string) {
+ runMapping(new MapVoidAction("setActionCommand") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setActionCommand(string);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setBorderPainted(boolean)} through queue
+ */
+ public void setBorderPainted(final boolean b) {
+ runMapping(new MapVoidAction("setBorderPainted") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setBorderPainted(b);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setContentAreaFilled(boolean)} through queue
+ */
+ public void setContentAreaFilled(final boolean b) {
+ runMapping(new MapVoidAction("setContentAreaFilled") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setContentAreaFilled(b);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setDisabledIcon(Icon)} through queue
+ */
+ public void setDisabledIcon(final Icon icon) {
+ runMapping(new MapVoidAction("setDisabledIcon") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setDisabledIcon(icon);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setDisabledSelectedIcon(Icon)} through queue
+ */
+ public void setDisabledSelectedIcon(final Icon icon) {
+ runMapping(new MapVoidAction("setDisabledSelectedIcon") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setDisabledSelectedIcon(icon);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setFocusPainted(boolean)} through queue
+ */
+ public void setFocusPainted(final boolean b) {
+ runMapping(new MapVoidAction("setFocusPainted") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setFocusPainted(b);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setHorizontalAlignment(int)} through queue
+ */
+ public void setHorizontalAlignment(final int i) {
+ runMapping(new MapVoidAction("setHorizontalAlignment") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setHorizontalAlignment(i);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setHorizontalTextPosition(int)} through queue
+ */
+ public void setHorizontalTextPosition(final int i) {
+ runMapping(new MapVoidAction("setHorizontalTextPosition") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setHorizontalTextPosition(i);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setIcon(Icon)} through queue
+ */
+ public void setIcon(final Icon icon) {
+ runMapping(new MapVoidAction("setIcon") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setIcon(icon);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setMargin(Insets)} through queue
+ */
+ public void setMargin(final Insets insets) {
+ runMapping(new MapVoidAction("setMargin") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setMargin(insets);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setMnemonic(char)} through queue
+ */
+ public void setMnemonic(final char c) {
+ runMapping(new MapVoidAction("setMnemonic") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setMnemonic(c);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setMnemonic(int)} through queue
+ */
+ public void setMnemonic(final int i) {
+ runMapping(new MapVoidAction("setMnemonic") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setMnemonic(i);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setModel(ButtonModel)} through queue
+ */
+ public void setModel(final ButtonModel buttonModel) {
+ runMapping(new MapVoidAction("setModel") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setModel(buttonModel);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setPressedIcon(Icon)} through queue
+ */
+ public void setPressedIcon(final Icon icon) {
+ runMapping(new MapVoidAction("setPressedIcon") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setPressedIcon(icon);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setRolloverEnabled(boolean)} through queue
+ */
+ public void setRolloverEnabled(final boolean b) {
+ runMapping(new MapVoidAction("setRolloverEnabled") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setRolloverEnabled(b);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setRolloverIcon(Icon)} through queue
+ */
+ public void setRolloverIcon(final Icon icon) {
+ runMapping(new MapVoidAction("setRolloverIcon") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setRolloverIcon(icon);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setRolloverSelectedIcon(Icon)} through queue
+ */
+ public void setRolloverSelectedIcon(final Icon icon) {
+ runMapping(new MapVoidAction("setRolloverSelectedIcon") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setRolloverSelectedIcon(icon);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setSelected(boolean)} through queue
+ */
+ public void setSelected(final boolean b) {
+ runMapping(new MapVoidAction("setSelected") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setSelected(b);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setSelectedIcon(Icon)} through queue
+ */
+ public void setSelectedIcon(final Icon icon) {
+ runMapping(new MapVoidAction("setSelectedIcon") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setSelectedIcon(icon);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setText(String)} through queue
+ */
+ public void setText(final String string) {
+ runMapping(new MapVoidAction("setText") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setText(string);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setUI(ButtonUI)} through queue
+ */
+ public void setUI(final ButtonUI buttonUI) {
+ runMapping(new MapVoidAction("setUI") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setUI(buttonUI);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setVerticalAlignment(int)} through queue
+ */
+ public void setVerticalAlignment(final int i) {
+ runMapping(new MapVoidAction("setVerticalAlignment") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setVerticalAlignment(i);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code AbstractButton.setVerticalTextPosition(int)} through queue
+ */
+ public void setVerticalTextPosition(final int i) {
+ runMapping(new MapVoidAction("setVerticalTextPosition") {
+ @Override
+ public void map() {
+ ((AbstractButton) getSource()).setVerticalTextPosition(i);
+ }
+ });
+ }
+
+ //End of mapping //
+ ////////////////////////////////////////////////////////
+ /**
+ * Allows to find component by text.
+ */
+ public static class AbstractButtonByLabelFinder implements ComponentChooser {
+
+ String label;
+ StringComparator comparator;
+
+ /**
+ * Constructs AbstractButtonByLabelFinder.
+ *
+ * @param lb a text pattern
+ * @param comparator specifies string comparision algorithm.
+ */
+ public AbstractButtonByLabelFinder(String lb, StringComparator comparator) {
+ label = lb;
+ this.comparator = comparator;
+ }
+
+ /**
+ * Constructs AbstractButtonByLabelFinder.
+ *
+ * @param lb a text pattern
+ */
+ public AbstractButtonByLabelFinder(String lb) {
+ this(lb, Operator.getDefaultStringComparator());
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ if (comp instanceof AbstractButton) {
+ if (((AbstractButton) comp).getText() != null) {
+ return (comparator.equals(((AbstractButton) comp).getText(),
+ label));
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getDescription() {
+ return "AbstractButton with text \"" + label + "\"";
+ }
+
+ @Override
+ public String toString() {
+ return "AbstractButtonByLabelFinder{" + "label=" + label + ", comparator=" + comparator + '}';
+ }
+ }
+
+ /**
+ * Checks component type.
+ */
+ public static class AbstractButtonFinder extends Finder {
+
+ /**
+ * Constructs AbstractButtonFinder.
+ *
+ * @param sf other searching criteria.
+ */
+ public AbstractButtonFinder(ComponentChooser sf) {
+ super(AbstractButton.class, sf);
+ }
+
+ /**
+ * Constructs AbstractButtonFinder.
+ */
+ public AbstractButtonFinder() {
+ super(AbstractButton.class);
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/ButtonOperator.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/ButtonOperator.java
new file mode 100644
index 00000000000..e1af1f252a0
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/ButtonOperator.java
@@ -0,0 +1,530 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.operators;
+
+import java.awt.Button;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.event.ActionListener;
+import java.util.Hashtable;
+
+import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.Outputable;
+import org.netbeans.jemmy.TestOut;
+import org.netbeans.jemmy.TimeoutExpiredException;
+import org.netbeans.jemmy.Timeoutable;
+import org.netbeans.jemmy.Timeouts;
+import org.netbeans.jemmy.drivers.ButtonDriver;
+import org.netbeans.jemmy.drivers.DriverManager;
+
+/**
+ *
+ *
Timeouts used:
+ * ButtonOperator.PushButtonTimeout - time between button pressing and
+ * releasing
+ * ComponentOperator.WaitComponentTimeout - time to wait button displayed
+ * ComponentOperator.WaitComponentEnabledTimeout - time to wait button enabled
+ * .
+ *
+ * @see org.netbeans.jemmy.Timeouts
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ *
+ */
+public class ButtonOperator extends ComponentOperator
+ implements Timeoutable, Outputable {
+
+ /**
+ * Identifier for a label property.
+ *
+ * @see #getDump
+ */
+ public static final String TEXT_DPROP = "Label";
+
+ private final static long PUSH_BUTTON_TIMEOUT = 0;
+
+ private Timeouts timeouts;
+ private TestOut output;
+
+ ButtonDriver driver;
+
+ /**
+ * Constructor.
+ *
+ * @param b The {@code java.awt.Button} managed by this instance.
+ */
+ public ButtonOperator(Button b) {
+ super(b);
+ driver = DriverManager.getButtonDriver(getClass());
+ }
+
+ /**
+ * Constructs a ButtonOperator object.
+ *
+ * @param cont container
+ * @param chooser a component chooser specifying searching criteria.
+ * @param index an index between appropriate ones.
+ */
+ public ButtonOperator(ContainerOperator> cont, ComponentChooser chooser, int index) {
+ this((Button) cont.
+ waitSubComponent(new ButtonFinder(chooser),
+ index));
+ copyEnvironment(cont);
+ }
+
+ /**
+ * Constructs a ButtonOperator object.
+ *
+ * @param cont container
+ * @param chooser a component chooser specifying searching criteria.
+ */
+ public ButtonOperator(ContainerOperator> cont, ComponentChooser chooser) {
+ this(cont, chooser, 0);
+ }
+
+ /**
+ * Constructor. Waits for a component in a container to show. The component
+ * is identified as the {@code index+1}'th {@code java.awt.Button}
+ * that shows, lies below the container in the display containment
+ * hierarchy, and that has the desired text. Uses cont's timeout and output
+ * for waiting and to init this operator.
+ *
+ * @param cont The operator for a container containing the sought for
+ * button.
+ * @param text Button text.
+ * @param index Ordinal component index. The first component has
+ * {@code index} 0.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public ButtonOperator(ContainerOperator> cont, String text, int index) {
+ this((Button) waitComponent(cont,
+ new ButtonByLabelFinder(text,
+ cont.getComparator()),
+ index));
+ copyEnvironment(cont);
+ }
+
+ /**
+ * Constructor. Waits for a component in a container to show. The component
+ * is identified as the first {@code java.awt.Button} that shows, lies
+ * below the container in the display containment hierarchy, and that has
+ * the desired text. Uses cont's timeout and output for waiting and to init
+ * this operator.
+ *
+ * @param cont The operator for a container containing the sought for
+ * button.
+ * @param text Button text.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public ButtonOperator(ContainerOperator> cont, String text) {
+ this(cont, text, 0);
+ }
+
+ /**
+ * Constructor. Waits component in container first. Uses cont's timeout and
+ * output for waiting and to init operator.
+ *
+ * @param cont The operator for a container containing the sought for
+ * button.
+ * @param index Ordinal component index.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public ButtonOperator(ContainerOperator> cont, int index) {
+ this((Button) waitComponent(cont,
+ new ButtonFinder(),
+ index));
+ copyEnvironment(cont);
+ }
+
+ /**
+ * Constructor. Waits component in container first. Uses cont's timeout and
+ * output for waiting and to init operator.
+ *
+ * @param cont The operator for a container containing the sought for
+ * button.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public ButtonOperator(ContainerOperator> cont) {
+ this(cont, 0);
+ }
+
+ /**
+ * Searches Button in a container.
+ *
+ * @param cont Container in which to search for the component. The container
+ * lies above the component in the display containment hierarchy. The
+ * containment need not be direct.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation,
+ * defining and applying search criteria.
+ * @param index Ordinal component index. The first {@code index} is 0.
+ * @return Button instance or null if component was not found.
+ */
+ public static Button findButton(Container cont, ComponentChooser chooser, int index) {
+ return (Button) findComponent(cont, new ButtonFinder(chooser), index);
+ }
+
+ /**
+ * Searches for the first Button in a container.
+ *
+ * @param cont Container in which to search for the component. The container
+ * lies above the component in the display containment hierarchy. The
+ * containment need not be direct.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation,
+ * defining and applying search criteria.
+ * @return Button instance or null if component was not found.
+ */
+ public static Button findButton(Container cont, ComponentChooser chooser) {
+ return findButton(cont, chooser, 0);
+ }
+
+ /**
+ * Searches Button by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Button text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @param index Ordinal component index.
+ * @return Button instance or null if component was not found.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ */
+ public static Button findButton(Container cont, String text, boolean ce, boolean ccs, int index) {
+ return findButton(cont, new ButtonByLabelFinder(text, new DefaultStringComparator(ce, ccs)), index);
+ }
+
+ /**
+ * Searches Button by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Button text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @return Button instance or null if component was not found.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ */
+ public static Button findButton(Container cont, String text, boolean ce, boolean ccs) {
+ return findButton(cont, text, ce, ccs, 0);
+ }
+
+ /**
+ * Waits Button in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @param index Ordinal component index.
+ * @return Button instance.
+ * @throws TimeoutExpiredException
+ */
+ public static Button waitButton(Container cont, ComponentChooser chooser, int index) {
+ return (Button) waitComponent(cont, new ButtonFinder(chooser), index);
+ }
+
+ /**
+ * Waits 0'th Button in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @return Button instance.
+ * @throws TimeoutExpiredException
+ */
+ public static Button waitButton(Container cont, ComponentChooser chooser) {
+ return waitButton(cont, chooser, 0);
+ }
+
+ /**
+ * Waits Button by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Button text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @param index Ordinal component index.
+ * @return Button instance.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public static Button waitButton(Container cont, String text, boolean ce, boolean ccs, int index) {
+ return waitButton(cont, new ButtonByLabelFinder(text, new DefaultStringComparator(ce, ccs)), index);
+ }
+
+ /**
+ * Waits Button by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Button text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @return Button instance.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public static Button waitButton(Container cont, String text, boolean ce, boolean ccs) {
+ return waitButton(cont, text, ce, ccs, 0);
+ }
+
+ static {
+ Timeouts.initDefault("ButtonOperator.PushButtonTimeout", PUSH_BUTTON_TIMEOUT);
+ }
+
+ @Override
+ public void setTimeouts(Timeouts timeouts) {
+ super.setTimeouts(timeouts);
+ this.timeouts = timeouts;
+ }
+
+ @Override
+ public Timeouts getTimeouts() {
+ return timeouts;
+ }
+
+ @Override
+ public void setOutput(TestOut out) {
+ output = out;
+ super.setOutput(output.createErrorOutput());
+ }
+
+ @Override
+ public TestOut getOutput() {
+ return output;
+ }
+
+ @Override
+ public void copyEnvironment(Operator anotherOperator) {
+ super.copyEnvironment(anotherOperator);
+ driver
+ = (ButtonDriver) DriverManager.
+ getDriver(DriverManager.BUTTON_DRIVER_ID,
+ getClass(),
+ anotherOperator.getProperties());
+ }
+
+ /**
+ * Pushes the button by mouse click.
+ *
+ * @throws TimeoutExpiredException
+ */
+ public void push() {
+ output.printLine("Push button\n :" + toStringSource());
+ output.printGolden("Push button");
+ driver.push(this);
+ }
+
+ /**
+ * Runs {@code push()} method in a separate thread.
+ */
+ public void pushNoBlock() {
+ produceNoBlocking(new NoBlockingAction("Button pushing") {
+ @Override
+ public Void doAction(Void param) {
+ push();
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Press the button by mouse.
+ *
+ * @throws TimeoutExpiredException
+ */
+ public void press() {
+ output.printLine("Press button\n :" + toStringSource());
+ output.printGolden("Press button");
+ driver.press(this);
+ }
+
+ /**
+ * Releases the button by mouse.
+ *
+ * @throws TimeoutExpiredException
+ */
+ public void release() {
+ output.printLine("Release button\n :" + toStringSource());
+ output.printGolden("Release button");
+ driver.press(this);
+ }
+
+ /**
+ * Returns information about component.
+ */
+ @Override
+ public Hashtable getDump() {
+ Hashtable result = super.getDump();
+ if (((Button) getSource()).getLabel() != null) {
+ result.put(TEXT_DPROP, ((Button) getSource()).getLabel());
+ }
+ return result;
+ }
+
+ ////////////////////////////////////////////////////////
+ //Mapping //
+ /**
+ * Maps {@code Button.addActionListener(ActionListener)} through queue
+ */
+ public void addActionListener(final ActionListener actionListener) {
+ runMapping(new MapVoidAction("addActionListener") {
+ @Override
+ public void map() {
+ ((Button) getSource()).addActionListener(actionListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Button.getActionCommand()} through queue
+ */
+ public String getActionCommand() {
+ return (runMapping(new MapAction("getActionCommand") {
+ @Override
+ public String map() {
+ return ((Button) getSource()).getActionCommand();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Button.getLabel()} through queue
+ */
+ public String getLabel() {
+ return (runMapping(new MapAction("getLabel") {
+ @Override
+ public String map() {
+ return ((Button) getSource()).getLabel();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Button.removeActionListener(ActionListener)} through queue
+ */
+ public void removeActionListener(final ActionListener actionListener) {
+ runMapping(new MapVoidAction("removeActionListener") {
+ @Override
+ public void map() {
+ ((Button) getSource()).removeActionListener(actionListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Button.setActionCommand(String)} through queue
+ */
+ public void setActionCommand(final String string) {
+ runMapping(new MapVoidAction("setActionCommand") {
+ @Override
+ public void map() {
+ ((Button) getSource()).setActionCommand(string);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Button.setLabel(String)} through queue
+ */
+ public void setLabel(final String string) {
+ runMapping(new MapVoidAction("setLabel") {
+ @Override
+ public void map() {
+ ((Button) getSource()).setLabel(string);
+ }
+ });
+ }
+
+ //End of mapping //
+ ////////////////////////////////////////////////////////
+ /**
+ * Allows to find component by label.
+ */
+ public static class ButtonByLabelFinder implements ComponentChooser {
+
+ String label;
+ StringComparator comparator;
+
+ /**
+ * Constructs ButtonByLabelFinder.
+ *
+ * @param lb a text pattern
+ * @param comparator specifies string comparision algorithm.
+ */
+ public ButtonByLabelFinder(String lb, StringComparator comparator) {
+ label = lb;
+ this.comparator = comparator;
+ }
+
+ /**
+ * Constructs ButtonByLabelFinder.
+ *
+ * @param lb a text pattern
+ */
+ public ButtonByLabelFinder(String lb) {
+ this(lb, Operator.getDefaultStringComparator());
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ if (comp instanceof Button) {
+ if (((Button) comp).getLabel() != null) {
+ return (comparator.equals(((Button) comp).getLabel(),
+ label));
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Button with label \"" + label + "\"";
+ }
+
+ @Override
+ public String toString() {
+ return "ButtonByLabelFinder{" + "label=" + label + ", comparator=" + comparator + '}';
+ }
+ }
+
+ /**
+ * Checks component type.
+ */
+ public static class ButtonFinder extends Finder {
+
+ /**
+ * Constructs AbstractButtonFinder.
+ *
+ * @param sf other searching criteria.
+ */
+ public ButtonFinder(ComponentChooser sf) {
+ super(Button.class, sf);
+ }
+
+ /**
+ * Constructs AbstractButtonFinder.
+ */
+ public ButtonFinder() {
+ super(Button.class);
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/CheckboxOperator.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/CheckboxOperator.java
new file mode 100644
index 00000000000..bdda5e63683
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/CheckboxOperator.java
@@ -0,0 +1,540 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.operators;
+
+import java.awt.Checkbox;
+import java.awt.CheckboxGroup;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.event.ItemListener;
+import java.util.Hashtable;
+
+import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.JemmyException;
+import org.netbeans.jemmy.Outputable;
+import org.netbeans.jemmy.TestOut;
+import org.netbeans.jemmy.TimeoutExpiredException;
+import org.netbeans.jemmy.drivers.ButtonDriver;
+import org.netbeans.jemmy.drivers.DriverManager;
+
+/**
+ *
+ *
Timeouts used:
+ * ButtonOperator.PushButtonTimeout - time between checkbox pressing and
+ * releasing
+ * ComponentOperator.WaitComponentTimeout - time to wait checkbox displayed
+ * ComponentOperator.WaitComponentEnabledTimeout - time to wait checkbox enabled
+ * .
+ *
+ * @see org.netbeans.jemmy.Timeouts
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ *
+ */
+public class CheckboxOperator extends ComponentOperator implements Outputable {
+
+ /**
+ * Identifier for a label property.
+ *
+ * @see #getDump
+ */
+ public static final String TEXT_DPROP = "Label";
+
+ private TestOut output;
+ ButtonDriver driver;
+
+ /**
+ * Constructor.
+ *
+ * @param b a component
+ */
+ public CheckboxOperator(Checkbox b) {
+ super(b);
+ driver = DriverManager.getButtonDriver(getClass());
+ }
+
+ /**
+ * Constructs an CheckboxOperator object.
+ *
+ * @param cont container
+ * @param chooser a component chooser specifying searching criteria.
+ * @param index an index between appropriate ones.
+ */
+ public CheckboxOperator(ContainerOperator> cont, ComponentChooser chooser, int index) {
+ this((Checkbox) cont.
+ waitSubComponent(new CheckboxFinder(chooser),
+ index));
+ copyEnvironment(cont);
+ }
+
+ /**
+ * Constructs an CheckboxOperator object.
+ *
+ * @param cont container
+ * @param chooser a component chooser specifying searching criteria.
+ */
+ public CheckboxOperator(ContainerOperator> cont, ComponentChooser chooser) {
+ this(cont, chooser, 0);
+ }
+
+ /**
+ * Constructor. Waits component in container first. Uses cont's timeout and
+ * output for waiting and to init operator.
+ *
+ * @param cont container
+ * @param text Checkbox text.
+ * @param index Ordinal component index.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public CheckboxOperator(ContainerOperator> cont, String text, int index) {
+ this((Checkbox) waitComponent(cont,
+ new CheckboxByLabelFinder(text,
+ cont.getComparator()),
+ index));
+ copyEnvironment(cont);
+ }
+
+ /**
+ * Constructor. Waits component in container first. Uses cont's timeout and
+ * output for waiting and to init operator.
+ *
+ * @param cont container
+ * @param text Checkbox text.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public CheckboxOperator(ContainerOperator> cont, String text) {
+ this(cont, text, 0);
+ }
+
+ /**
+ * Constructor. Waits component in container first. Uses cont's timeout and
+ * output for waiting and to init operator.
+ *
+ * @param cont container
+ * @param index Ordinal component index.
+ * @throws TimeoutExpiredException
+ */
+ public CheckboxOperator(ContainerOperator> cont, int index) {
+ this((Checkbox) waitComponent(cont,
+ new CheckboxFinder(),
+ index));
+ copyEnvironment(cont);
+ }
+
+ /**
+ * Constructor. Waits component in container first. Uses cont's timeout and
+ * output for waiting and to init operator.
+ *
+ * @param cont container
+ * @throws TimeoutExpiredException
+ */
+ public CheckboxOperator(ContainerOperator> cont) {
+ this(cont, 0);
+ }
+
+ /**
+ * Searches Checkbox in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @param index Ordinal component index.
+ * @return Checkbox instance or null if component was not found.
+ */
+ public static Checkbox findCheckbox(Container cont, ComponentChooser chooser, int index) {
+ return (Checkbox) findComponent(cont, new CheckboxFinder(chooser), index);
+ }
+
+ /**
+ * Searches 0'th Checkbox in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @return Checkbox instance or null if component was not found.
+ */
+ public static Checkbox findCheckbox(Container cont, ComponentChooser chooser) {
+ return findCheckbox(cont, chooser, 0);
+ }
+
+ /**
+ * Searches Checkbox by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Checkbox text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @param index Ordinal component index.
+ * @return Checkbox instance or null if component was not found.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ */
+ public static Checkbox findCheckbox(Container cont, String text, boolean ce, boolean ccs, int index) {
+ return (findCheckbox(cont,
+ new CheckboxByLabelFinder(text,
+ new DefaultStringComparator(ce, ccs)),
+ index));
+ }
+
+ /**
+ * Searches Checkbox by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Checkbox text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @return Checkbox instance or null if component was not found.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ */
+ public static Checkbox findCheckbox(Container cont, String text, boolean ce, boolean ccs) {
+ return findCheckbox(cont, text, ce, ccs, 0);
+ }
+
+ /**
+ * Waits Checkbox in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @param index Ordinal component index.
+ * @return Checkbox instance.
+ * @throws TimeoutExpiredException
+ */
+ public static Checkbox waitCheckbox(Container cont, ComponentChooser chooser, int index) {
+ return (Checkbox) waitComponent(cont, new CheckboxFinder(chooser), index);
+ }
+
+ /**
+ * Waits 0'th Checkbox in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @return Checkbox instance.
+ * @throws TimeoutExpiredException
+ */
+ public static Checkbox waitCheckbox(Container cont, ComponentChooser chooser) {
+ return waitCheckbox(cont, chooser, 0);
+ }
+
+ /**
+ * Waits Checkbox by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Checkbox text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @param index Ordinal component index.
+ * @return Checkbox instance.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public static Checkbox waitCheckbox(Container cont, String text, boolean ce, boolean ccs, int index) {
+ return (waitCheckbox(cont,
+ new CheckboxByLabelFinder(text,
+ new DefaultStringComparator(ce, ccs)),
+ index));
+ }
+
+ /**
+ * Waits Checkbox by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Checkbox text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @return Checkbox instance.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public static Checkbox waitCheckbox(Container cont, String text, boolean ce, boolean ccs) {
+ return waitCheckbox(cont, text, ce, ccs, 0);
+ }
+
+ @Override
+ public void setOutput(TestOut out) {
+ output = out;
+ super.setOutput(output.createErrorOutput());
+ }
+
+ @Override
+ public TestOut getOutput() {
+ return output;
+ }
+
+ @Override
+ public void copyEnvironment(Operator anotherOperator) {
+ super.copyEnvironment(anotherOperator);
+ driver
+ = (ButtonDriver) DriverManager.
+ getDriver(DriverManager.BUTTON_DRIVER_ID,
+ getClass(),
+ anotherOperator.getProperties());
+ }
+
+ /**
+ * Changes selection if necessary. Uses a ButtonDriver registered for this
+ * operator.
+ *
+ * @param newValue a button selection.
+ */
+ public void changeSelection(boolean newValue) {
+ makeComponentVisible();
+ if (getState() != newValue) {
+ try {
+ waitComponentEnabled();
+ } catch (InterruptedException e) {
+ throw (new JemmyException("Interrupted!", e));
+ }
+ output.printLine("Change checkbox selection to " + (newValue ? "true" : "false")
+ + "\n :" + toStringSource());
+ output.printGolden("Change checkbox selection to " + (newValue ? "true" : "false"));
+ driver.push(this);
+ if (getVerification()) {
+ waitSelected(newValue);
+ }
+ }
+ }
+
+ /**
+ * Runs {@code changeSelection(boolean)} method in a separate thread.
+ *
+ * @param selected a button selection.
+ */
+ public void changeSelectionNoBlock(boolean selected) {
+ produceNoBlocking(new NoBlockingAction("Button selection changing") {
+ @Override
+ public Void doAction(Boolean param) {
+ changeSelection(param);
+ return null;
+ }
+ }, selected ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Waits for button to be selected.
+ *
+ * @param selected selection.
+ */
+ public void waitSelected(final boolean selected) {
+ getOutput().printLine("Wait button to be selected \n : "
+ + toStringSource());
+ getOutput().printGolden("Wait button to be selected");
+ waitState(new ComponentChooser() {
+ @Override
+ public boolean checkComponent(Component comp) {
+ return getState() == selected;
+ }
+
+ @Override
+ public String getDescription() {
+ return ("Items has been "
+ + (selected ? "" : "un") + "selected");
+ }
+
+ @Override
+ public String toString() {
+ return "CheckboxOperator.waitSelected.ComponentChooser{description = " + getDescription() + '}';
+ }
+ });
+ }
+
+ /**
+ * Returns information about component.
+ */
+ @Override
+ public Hashtable getDump() {
+ Hashtable result = super.getDump();
+ result.put(TEXT_DPROP, ((Checkbox) getSource()).getLabel());
+ return result;
+ }
+
+ ////////////////////////////////////////////////////////
+ //Mapping //
+ /**
+ * Maps {@code Checkbox.addItemListener(ItemListener)} through queue
+ */
+ public void addItemListener(final ItemListener itemListener) {
+ runMapping(new MapVoidAction("addItemListener") {
+ @Override
+ public void map() {
+ ((Checkbox) getSource()).addItemListener(itemListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Checkbox.getCheckboxGroup()} through queue
+ */
+ public CheckboxGroup getCheckboxGroup() {
+ return (runMapping(new MapAction("getCheckboxGroup") {
+ @Override
+ public CheckboxGroup map() {
+ return ((Checkbox) getSource()).getCheckboxGroup();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Checkbox.getLabel()} through queue
+ */
+ public String getLabel() {
+ return (runMapping(new MapAction("getLabel") {
+ @Override
+ public String map() {
+ return ((Checkbox) getSource()).getLabel();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Checkbox.getState()} through queue
+ */
+ public boolean getState() {
+ return (runMapping(new MapBooleanAction("getState") {
+ @Override
+ public boolean map() {
+ return ((Checkbox) getSource()).getState();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Checkbox.removeItemListener(ItemListener)} through queue
+ */
+ public void removeItemListener(final ItemListener itemListener) {
+ runMapping(new MapVoidAction("removeItemListener") {
+ @Override
+ public void map() {
+ ((Checkbox) getSource()).removeItemListener(itemListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Checkbox.setCheckboxGroup(CheckboxGroup)} through queue
+ */
+ public void setCheckboxGroup(final CheckboxGroup grp) {
+ runMapping(new MapVoidAction("setCheckboxGroup") {
+ @Override
+ public void map() {
+ ((Checkbox) getSource()).setCheckboxGroup(grp);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Checkbox.setLabel(String)} through queue
+ */
+ public void setLabel(final String string) {
+ runMapping(new MapVoidAction("setLabel") {
+ @Override
+ public void map() {
+ ((Checkbox) getSource()).setLabel(string);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Checkbox.setState(boolean)} through queue
+ */
+ public void setState(final boolean state) {
+ runMapping(new MapVoidAction("setState") {
+ @Override
+ public void map() {
+ ((Checkbox) getSource()).setState(state);
+ }
+ });
+ }
+
+ //End of mapping //
+ ////////////////////////////////////////////////////////
+ /**
+ * Allows to find component by label.
+ */
+ public static class CheckboxByLabelFinder implements ComponentChooser {
+
+ String label;
+ StringComparator comparator;
+
+ /**
+ * Constructs CheckboxByLabelFinder.
+ *
+ * @param lb a label pattern
+ * @param comparator specifies string comparision algorithm.
+ */
+ public CheckboxByLabelFinder(String lb, StringComparator comparator) {
+ label = lb;
+ this.comparator = comparator;
+ }
+
+ /**
+ * Constructs CheckboxByLabelFinder.
+ *
+ * @param lb a label pattern
+ */
+ public CheckboxByLabelFinder(String lb) {
+ this(lb, Operator.getDefaultStringComparator());
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ if (comp instanceof Checkbox) {
+ if (((Checkbox) comp).getLabel() != null) {
+ return (comparator.equals(((Checkbox) comp).getLabel(),
+ label));
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Checkbox with label \"" + label + "\"";
+ }
+
+ @Override
+ public String toString() {
+ return "CheckboxByLabelFinder{" + "label=" + label + ", comparator=" + comparator + '}';
+ }
+ }
+
+ /**
+ * Checks component type.
+ */
+ public static class CheckboxFinder extends Finder {
+
+ /**
+ * Constructs CheckboxFinder.
+ *
+ * @param sf other searching criteria.
+ */
+ public CheckboxFinder(ComponentChooser sf) {
+ super(Checkbox.class, sf);
+ }
+
+ /**
+ * Constructs CheckboxFinder.
+ */
+ public CheckboxFinder() {
+ super(Checkbox.class);
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/ChoiceOperator.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/ChoiceOperator.java
new file mode 100644
index 00000000000..0f22ac00441
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/ChoiceOperator.java
@@ -0,0 +1,667 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.operators;
+
+import java.awt.Choice;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.event.ItemListener;
+import java.util.Hashtable;
+
+import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.JemmyException;
+import org.netbeans.jemmy.Outputable;
+import org.netbeans.jemmy.TestOut;
+import org.netbeans.jemmy.TimeoutExpiredException;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.ListDriver;
+
+/**
+ *
+ *
Timeouts used:
+ * ButtonOperator.PushButtonTimeout - time between choice pressing and
+ * releasing
+ * ComponentOperator.WaitComponentTimeout - time to wait choice displayed
+ * ComponentOperator.WaitComponentEnabledTimeout - time to wait choice enabled
+ * .
+ *
+ * @see org.netbeans.jemmy.Timeouts
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ *
+ */
+public class ChoiceOperator extends ComponentOperator implements Outputable {
+
+ /**
+ * Identifier for a selected item property.
+ *
+ * @see #getDump
+ */
+ public static final String SELECTED_ITEM_DPROP = "Selected item";
+
+ /**
+ * Identifier for a items properties.
+ *
+ * @see #getDump
+ */
+ public static final String ITEM_PREFIX_DPROP = "Item";
+
+ private TestOut output;
+ private ListDriver driver;
+
+ /**
+ * Constructor.
+ *
+ * @param b a component
+ */
+ public ChoiceOperator(Choice b) {
+ super(b);
+ driver = DriverManager.getListDriver(getClass());
+ }
+
+ /**
+ * Constructs a ChoiceOperator object.
+ *
+ * @param cont container
+ * @param chooser a component chooser specifying searching criteria.
+ * @param index an index between appropriate ones.
+ */
+ public ChoiceOperator(ContainerOperator> cont, ComponentChooser chooser, int index) {
+ this((Choice) cont.
+ waitSubComponent(new ChoiceFinder(chooser),
+ index));
+ copyEnvironment(cont);
+ }
+
+ /**
+ * Constructs a ChoiceOperator object.
+ *
+ * @param cont container
+ * @param chooser a component chooser specifying searching criteria.
+ */
+ public ChoiceOperator(ContainerOperator> cont, ComponentChooser chooser) {
+ this(cont, chooser, 0);
+ }
+
+ /**
+ * Constructor. Waits component in container first. Uses cont's timeout and
+ * output for waiting and to init operator.
+ *
+ * @param cont container
+ * @param text Choice text.
+ * @param index Ordinal component index.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public ChoiceOperator(ContainerOperator> cont, String text, int index) {
+ this((Choice) waitComponent(cont,
+ new ChoiceBySelectedItemFinder(text,
+ cont.getComparator()),
+ index));
+ copyEnvironment(cont);
+ }
+
+ /**
+ * Constructor. Waits component in container first. Uses cont's timeout and
+ * output for waiting and to init operator.
+ *
+ * @param cont container
+ * @param text Choice text.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public ChoiceOperator(ContainerOperator> cont, String text) {
+ this(cont, text, 0);
+ }
+
+ /**
+ * Constructor. Waits component in container first. Uses cont's timeout and
+ * output for waiting and to init operator.
+ *
+ * @param cont container
+ * @param index Ordinal component index.
+ * @throws TimeoutExpiredException
+ */
+ public ChoiceOperator(ContainerOperator> cont, int index) {
+ this((Choice) waitComponent(cont,
+ new ChoiceFinder(),
+ index));
+ copyEnvironment(cont);
+ }
+
+ /**
+ * Constructor. Waits component in container first. Uses cont's timeout and
+ * output for waiting and to init operator.
+ *
+ * @param cont container
+ * @throws TimeoutExpiredException
+ */
+ public ChoiceOperator(ContainerOperator> cont) {
+ this(cont, 0);
+ }
+
+ /**
+ * Searches Choice in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @param index Ordinal component index.
+ * @return Choice instance or null if component was not found.
+ */
+ public static Choice findChoice(Container cont, ComponentChooser chooser, int index) {
+ return (Choice) findComponent(cont, new ChoiceFinder(chooser), index);
+ }
+
+ /**
+ * Searches 0'th Choice in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @return Choice instance or null if component was not found.
+ */
+ public static Choice findChoice(Container cont, ComponentChooser chooser) {
+ return findChoice(cont, chooser, 0);
+ }
+
+ /**
+ * Searches Choice by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Choice text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @param index Ordinal component index.
+ * @return Choice instance or null if component was not found.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ */
+ public static Choice findChoice(Container cont, String text, boolean ce, boolean ccs, int index) {
+ return (findChoice(cont,
+ new ChoiceBySelectedItemFinder(text,
+ new DefaultStringComparator(ce, ccs)),
+ index));
+ }
+
+ /**
+ * Searches Choice by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Choice text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @return Choice instance or null if component was not found.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ */
+ public static Choice findChoice(Container cont, String text, boolean ce, boolean ccs) {
+ return findChoice(cont, text, ce, ccs, 0);
+ }
+
+ /**
+ * Waits Choice in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @param index Ordinal component index.
+ * @return Choice instance.
+ * @throws TimeoutExpiredException
+ */
+ public static Choice waitChoice(Container cont, ComponentChooser chooser, int index) {
+ return (Choice) waitComponent(cont, new ChoiceFinder(chooser), index);
+ }
+
+ /**
+ * Waits 0'th Choice in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @return Choice instance.
+ * @throws TimeoutExpiredException
+ */
+ public static Choice waitChoice(Container cont, ComponentChooser chooser) {
+ return waitChoice(cont, chooser, 0);
+ }
+
+ /**
+ * Waits Choice by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Choice text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @param index Ordinal component index.
+ * @return Choice instance.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public static Choice waitChoice(Container cont, String text, boolean ce, boolean ccs, int index) {
+ return (waitChoice(cont,
+ new ChoiceBySelectedItemFinder(text,
+ new DefaultStringComparator(ce, ccs)),
+ index));
+ }
+
+ /**
+ * Waits Choice by text.
+ *
+ * @param cont Container to search component in.
+ * @param text Choice text. If null, contents is not checked.
+ * @param ce Compare text exactly.
+ * @param ccs Compare text case sensitively.
+ * @return Choice instance.
+ * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
+ * @throws TimeoutExpiredException
+ */
+ public static Choice waitChoice(Container cont, String text, boolean ce, boolean ccs) {
+ return waitChoice(cont, text, ce, ccs, 0);
+ }
+
+ @Override
+ public void setOutput(TestOut out) {
+ output = out;
+ super.setOutput(output.createErrorOutput());
+ }
+
+ @Override
+ public TestOut getOutput() {
+ return output;
+ }
+
+ @Override
+ public void copyEnvironment(Operator anotherOperator) {
+ super.copyEnvironment(anotherOperator);
+ driver
+ = (ListDriver) DriverManager.
+ getDriver(DriverManager.LIST_DRIVER_ID,
+ getClass(),
+ anotherOperator.getProperties());
+ }
+
+ /**
+ * Finds an item between choice items.
+ *
+ * @param item a text pattern.
+ * @param index an ordinal index between appropriate items.
+ * @return an item index.
+ */
+ public int findItemIndex(String item, int index) {
+ return findItemIndex(item, getComparator(), index);
+ }
+
+ /**
+ * Finds an item between choice items.
+ *
+ * @param item a text pattern.
+ * @return an item index.
+ */
+ public int findItemIndex(String item) {
+ return findItemIndex(item, 0);
+ }
+
+ /**
+ * Selects an item by text.
+ *
+ * @param item a text pattern.
+ * @param index an ordinal index between appropriate items.
+ */
+ public void selectItem(String item, int index) {
+ selectItem(item, getComparator(), index);
+ }
+
+ /**
+ * Selects an item by text.
+ *
+ * @param item a text pattern.
+ */
+ public void selectItem(String item) {
+ selectItem(item, 0);
+ }
+
+ /**
+ * Selects an item by index.
+ *
+ * @param index an item index.
+ */
+ public void selectItem(int index) {
+ output.printLine("Select " + Integer.toString(index) + "`th item in combobox\n : "
+ + toStringSource());
+ output.printGolden("Select " + Integer.toString(index) + "`th item in combobox");
+ makeComponentVisible();
+ try {
+ waitComponentEnabled();
+ } catch (InterruptedException e) {
+ throw (new JemmyException("Interrupted!", e));
+ }
+ driver.selectItem(this, index);
+ if (getVerification()) {
+ waitItemSelected(index);
+ }
+ }
+
+ /**
+ * Waits for item to be selected.
+ *
+ * @param index Item index.
+ */
+ public void waitItemSelected(final int index) {
+ getOutput().printLine("Wait " + Integer.toString(index)
+ + "'th item to be selected in component \n : "
+ + toStringSource());
+ getOutput().printGolden("Wait " + Integer.toString(index)
+ + "'th item to be selected");
+ waitState(new ComponentChooser() {
+ @Override
+ public boolean checkComponent(Component comp) {
+ return getSelectedIndex() == index;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Has " + Integer.toString(index) + "'th item selected";
+ }
+
+ @Override
+ public String toString() {
+ return "ChoiceOperator.waitItemSelected.ComponentChooser{description = " + getDescription() + '}';
+ }
+ });
+ }
+
+ /**
+ * Returns information about component.
+ */
+ @Override
+ public Hashtable getDump() {
+ Hashtable result = super.getDump();
+ if (((Choice) getSource()).getSelectedItem() != null) {
+ result.put(SELECTED_ITEM_DPROP, ((Choice) getSource()).getSelectedItem());
+ }
+ String[] items = new String[((Choice) getSource()).getItemCount()];
+ for (int i = 0; i < ((Choice) getSource()).getItemCount(); i++) {
+ items[i] = ((Choice) getSource()).getItem(i);
+ }
+ addToDump(result, ITEM_PREFIX_DPROP, items);
+ return result;
+ }
+
+ ////////////////////////////////////////////////////////
+ //Mapping //
+ /**
+ * Maps {@code Choice.add(String)} through queue
+ */
+ public void add(final String item) {
+ runMapping(new MapVoidAction("add") {
+ @Override
+ public void map() {
+ ((Choice) getSource()).add(item);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Choice.addItemListener(ItemListener)} through queue
+ */
+ public void addItemListener(final ItemListener itemListener) {
+ runMapping(new MapVoidAction("addItemListener") {
+ @Override
+ public void map() {
+ ((Choice) getSource()).addItemListener(itemListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Choice.addNotify()} through queue
+ */
+ @Override
+ public void addNotify() {
+ runMapping(new MapVoidAction("addNotify") {
+ @Override
+ public void map() {
+ getSource().addNotify();
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Choice.getItem(int)} through queue
+ */
+ public String getItem(final int index) {
+ return (runMapping(new MapAction("getItem") {
+ @Override
+ public String map() {
+ return ((Choice) getSource()).getItem(index);
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Choice.getItemCount()} through queue
+ */
+ public int getItemCount() {
+ return (runMapping(new MapIntegerAction("getItemCount") {
+ @Override
+ public int map() {
+ return ((Choice) getSource()).getItemCount();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Choice.getSelectedIndex()} through queue
+ */
+ public int getSelectedIndex() {
+ return (runMapping(new MapIntegerAction("getSelectedIndex") {
+ @Override
+ public int map() {
+ return ((Choice) getSource()).getSelectedIndex();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Choice.getSelectedItem()} through queue
+ */
+ public String getSelectedItem() {
+ return (runMapping(new MapAction("getSelectedItem") {
+ @Override
+ public String map() {
+ return ((Choice) getSource()).getSelectedItem();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Choice.insert(String)} through queue
+ */
+ public void insert(final String item, final int index) {
+ runMapping(new MapVoidAction("insert") {
+ @Override
+ public void map() {
+ ((Choice) getSource()).insert(item, index);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Choice.remove(int)} through queue
+ */
+ public void remove(final int position) {
+ runMapping(new MapVoidAction("remove") {
+ @Override
+ public void map() {
+ ((Choice) getSource()).remove(position);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Choice.remove(String)} through queue
+ */
+ public void remove(final String item) {
+ runMapping(new MapVoidAction("remove") {
+ @Override
+ public void map() {
+ ((Choice) getSource()).remove(item);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Choice.removeAll()} through queue
+ */
+ public void removeAll() {
+ runMapping(new MapVoidAction("removeAll") {
+ @Override
+ public void map() {
+ ((Choice) getSource()).removeAll();
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Choice.removeItemListener(ItemListener)} through queue
+ */
+ public void removeItemListener(final ItemListener itemListener) {
+ runMapping(new MapVoidAction("removeItemListener") {
+ @Override
+ public void map() {
+ ((Choice) getSource()).removeItemListener(itemListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Choice.select(int)} through queue
+ */
+ public void select(final int pos) {
+ runMapping(new MapVoidAction("select") {
+ @Override
+ public void map() {
+ ((Choice) getSource()).select(pos);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Choice.select(String)} through queue
+ */
+ public void setState(final String str) {
+ runMapping(new MapVoidAction("select") {
+ @Override
+ public void map() {
+ ((Choice) getSource()).select(str);
+ }
+ });
+ }
+
+ //End of mapping //
+ ////////////////////////////////////////////////////////
+ private int findItemIndex(String item, StringComparator comparator, int index) {
+ int count = 0;
+ for (int i = 0; i < getItemCount(); i++) {
+ if (comparator.equals(getItem(i), item)) {
+ if (count == index) {
+ return i;
+ } else {
+ count++;
+ }
+ }
+ }
+ return -1;
+ }
+
+ private void selectItem(String item, StringComparator comparator, int index) {
+ selectItem(findItemIndex(item, comparator, index));
+ }
+
+ /**
+ * Allows to find component by label.
+ */
+ public static class ChoiceBySelectedItemFinder implements ComponentChooser {
+
+ String label;
+ StringComparator comparator;
+
+ /**
+ * Constructs ChoiceBySelectedItemFinder.
+ *
+ * @param lb a text pattern
+ * @param comparator specifies string comparision algorithm.
+ */
+ public ChoiceBySelectedItemFinder(String lb, StringComparator comparator) {
+ label = lb;
+ this.comparator = comparator;
+ }
+
+ /**
+ * Constructs ChoiceBySelectedItemFinder.
+ *
+ * @param lb a text pattern
+ */
+ public ChoiceBySelectedItemFinder(String lb) {
+ this(lb, Operator.getDefaultStringComparator());
+ }
+
+ @Override
+ public boolean checkComponent(Component comp) {
+ if (comp instanceof Choice) {
+ if (((Choice) comp).getSelectedItem() != null) {
+ return (comparator.equals(((Choice) comp).getSelectedItem(),
+ label));
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Choice with label \"" + label + "\"";
+ }
+
+ @Override
+ public String toString() {
+ return "ChoiceBySelectedItemFinder{" + "label=" + label + ", comparator=" + comparator + '}';
+ }
+ }
+
+ /**
+ * Checks component type.
+ */
+ public static class ChoiceFinder extends Finder {
+
+ /**
+ * Constructs ChoiceFinder.
+ *
+ * @param sf other searching criteria.
+ */
+ public ChoiceFinder(ComponentChooser sf) {
+ super(Choice.class, sf);
+ }
+
+ /**
+ * Constructs ChoiceFinder.
+ */
+ public ChoiceFinder() {
+ super(Choice.class);
+ }
+ }
+}
diff --git a/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/ComponentOperator.java b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/ComponentOperator.java
new file mode 100644
index 00000000000..804ad6e4449
--- /dev/null
+++ b/jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/ComponentOperator.java
@@ -0,0 +1,2535 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.netbeans.jemmy.operators;
+
+import java.awt.AWTEvent;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.ComponentOrientation;
+import java.awt.Container;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.MenuComponent;
+import java.awt.Point;
+import java.awt.PopupMenu;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.Window;
+import java.awt.dnd.DropTarget;
+import java.awt.event.ComponentListener;
+import java.awt.event.FocusListener;
+import java.awt.event.InputMethodListener;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.im.InputContext;
+import java.awt.im.InputMethodRequests;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.beans.PropertyChangeListener;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.Hashtable;
+import java.util.Locale;
+
+import org.netbeans.jemmy.CharBindingMap;
+import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.ComponentSearcher;
+import org.netbeans.jemmy.EventDispatcher;
+import org.netbeans.jemmy.JemmyException;
+import org.netbeans.jemmy.JemmyProperties;
+import org.netbeans.jemmy.Outputable;
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.TestOut;
+import org.netbeans.jemmy.TimeoutExpiredException;
+import org.netbeans.jemmy.Timeoutable;
+import org.netbeans.jemmy.Timeouts;
+import org.netbeans.jemmy.Waitable;
+import org.netbeans.jemmy.Waiter;
+import org.netbeans.jemmy.drivers.DriverManager;
+import org.netbeans.jemmy.drivers.FocusDriver;
+import org.netbeans.jemmy.drivers.KeyDriver;
+import org.netbeans.jemmy.drivers.MouseDriver;
+
+/**
+ * Root class for all component operators.
+ *
+ * Provides basic methods to operate with mouse and keyboard.
+ *
+ * Almost all input methods can throw JemmyInputException or its subclass.
+ *
+ * ComponentOperator and its subclasses has a lot of methods which name and
+ * parameters just like consistent component has. In this case operator class
+ * just invokes consistent component method through AWT Event Queue
+ * (invokeAndWait method).
+ *
+ *
Timeouts used:
+ * ComponentOperator.PushKeyTimeout - time between key pressing and releasing
+ *
+ * ComponentOperator.MouseClickTimeout - time between mouse pressing and
+ * releasing
+ * ComponentOperator.WaitComponentTimeout - time to wait component displayed
+ *
+ * ComponentOperator.WaitComponentEnabledTimeout - time to wait component
+ * enabled
+ * ComponentOperator.BeforeDragTimeout - time to sleep before grag'n'drop
+ * operations
+ * ComponentOperator.AfterDragTimeout - time to sleep after grag'n'drop
+ * operations
+ * ComponentOperator.WaitFocusTimeout - time to wait component focus
+ * ComponentOperator.WaitStateTimeout- time to wait component to be in some
+ * state. Typically used from methods like
+ * {@code Operator.wait"something happened"(*)} .
+ *
+ * @see org.netbeans.jemmy.Timeouts
+ *
+ * @author Alexandre Iline (alexandre.iline@oracle.com)
+ */
+public class ComponentOperator extends Operator
+ implements Timeoutable, Outputable {
+
+ /**
+ * Identifier for a name property.
+ *
+ * @see #getDump
+ */
+ public static final String NAME_DPROP = "Name:";
+
+ /**
+ * Identifier for a visible property.
+ *
+ * @see #getDump
+ */
+ public static final String IS_VISIBLE_DPROP = "Visible";
+
+ /**
+ * Identifier for a showing property.
+ *
+ * @see #getDump
+ */
+ public static final String IS_SHOWING_DPROP = "Showing";
+
+ /**
+ * Identifier for a x coordinate property.
+ *
+ * @see #getDump
+ */
+ public static final String X_DPROP = "X";
+
+ /**
+ * Identifier for a y coordinate property.
+ *
+ * @see #getDump
+ */
+ public static final String Y_DPROP = "Y";
+
+ /**
+ * Identifier for a width property.
+ *
+ * @see #getDump
+ */
+ public static final String WIDTH_DPROP = "Width";
+
+ /**
+ * Identifier for a height property.
+ *
+ * @see #getDump
+ */
+ public static final String HEIGHT_DPROP = "Height";
+
+ private static final long PUSH_KEY_TIMEOUT = 0;
+ private static final long MOUSE_CLICK_TIMEOUT = 0;
+ private static final long BEFORE_DRAG_TIMEOUT = 0;
+ private static final long AFTER_DRAG_TIMEOUT = 0;
+ private static final long WAIT_COMPONENT_TIMEOUT = 60000;
+ private static final long WAIT_COMPONENT_ENABLED_TIMEOUT = 60000;
+ private static final long WAIT_FOCUS_TIMEOUT = 60000;
+ private static final long WAIT_STATE_TIMEOUT = 60000;
+
+ private final Component source;
+ private volatile Timeouts timeouts; // used in invokeSmoothly in clickMouse
+ private volatile TestOut output; // used in QueueTool.Locker
+ private volatile EventDispatcher dispatcher; // used in JInternalFrameByTitleFinder.checkComponent
+ private KeyDriver kDriver;
+ private MouseDriver mDriver;
+ private FocusDriver fDriver;
+
+ /**
+ * Constructor.
+ *
+ * @param comp a component
+ */
+ public ComponentOperator(Component comp) {
+ super();
+ source = comp;
+ kDriver = DriverManager.getKeyDriver(getClass());
+ mDriver = DriverManager.getMouseDriver(getClass());
+ fDriver = DriverManager.getFocusDriver(getClass());
+ setEventDispatcher(new EventDispatcher(comp));
+ }
+
+ /**
+ * Constructs a ComponentOperator object.
+ *
+ * @param cont container
+ * @param chooser a component chooser specifying searching criteria.
+ * @param index an index between appropriate ones.
+ */
+ public ComponentOperator(ContainerOperator> cont, ComponentChooser chooser, int index) {
+ this(waitComponent((Container) cont.getSource(),
+ chooser,
+ index, cont.getTimeouts(), cont.getOutput()));
+ copyEnvironment(cont);
+ }
+
+ /**
+ * Constructs a ComponentOperator object.
+ *
+ * @param cont container
+ * @param chooser a component chooser specifying searching criteria.
+ */
+ public ComponentOperator(ContainerOperator> cont, ComponentChooser chooser) {
+ this(cont, chooser, 0);
+ }
+
+ /**
+ * Constructor. Waits for a component in a container to show. The component
+ * is iis the {@code index+1}'th {@code java.awt.Component} that
+ * shows and that lies below the container in the display containment
+ * hierarchy. Uses cont's timeout and output for waiting and to init
+ * operator.
+ *
+ * @param cont Operator for a java.awt.Container.
+ * @param index an index between appropriate ones.
+ * @throws TimeoutExpiredException
+ */
+ public ComponentOperator(ContainerOperator> cont, int index) {
+ this(cont, ComponentSearcher.getTrueChooser("Any component"), index);
+ }
+
+ /**
+ * Constructor. Waits for a component in a container to show. The component
+ * is is the first {@code java.awt.Component} that shows and that lies
+ * below the container in the display containment hierarchy. Uses cont's
+ * timeout and output for waiting and to init operator.
+ *
+ * @param cont Operator for a java.awt.Container.
+ * @throws TimeoutExpiredException
+ */
+ public ComponentOperator(ContainerOperator> cont) {
+ this(cont, 0);
+ }
+
+ /**
+ * Searches Component in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @param index Ordinal component index.
+ * @return Component instance or null if component was not found.
+ */
+ public static Component findComponent(Container cont, ComponentChooser chooser, int index) {
+ return findComponent(cont, chooser, index, false);
+ }
+
+ /**
+ * Searches Component in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @return Component instance or null if component was not found.
+ */
+ public static Component findComponent(Container cont, ComponentChooser chooser) {
+ return findComponent(cont, chooser, 0);
+ }
+
+ /**
+ * Waits Component in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @param index Ordinal component index.
+ * @return Component instance or null if component was not found.
+ * @throws TimeoutExpiredException
+ */
+ public static Component waitComponent(Container cont, ComponentChooser chooser, int index) {
+ return (waitComponent(cont, chooser, index,
+ JemmyProperties.getCurrentTimeouts(),
+ JemmyProperties.getCurrentOutput()));
+ }
+
+ /**
+ * Waits Component in container.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @return Component instance or null if component was not found.
+ * @throws TimeoutExpiredException
+ */
+ public static Component waitComponent(Container cont, ComponentChooser chooser) {
+ return waitComponent(cont, chooser, 0);
+ }
+
+ /**
+ * A method to be used from subclasses. Uses {@code contOper}'s
+ * timeouts and output during the waiting.
+ *
+ * @param contOper Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @param index Ordinal component index.
+ * @return Component instance or null if component was not found.
+ * @throws TimeoutExpiredException
+ */
+ protected static Component waitComponent(ContainerOperator> contOper,
+ ComponentChooser chooser, int index) {
+ return (waitComponent((Container) contOper.getSource(),
+ chooser, index,
+ contOper.getTimeouts(),
+ contOper.getOutput()));
+ }
+
+ /**
+ * A method to be used from subclasses. Uses timeouts and output passed as
+ * parameters during the waiting.
+ *
+ * @param cont Container to search component in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @param index Ordinal component index.
+ * @param timeouts timeouts to be used during the waiting.
+ * @param output an output to be used during the waiting.
+ * @return Component instance or null if component was not found.
+ * @throws TimeoutExpiredException
+ */
+ protected static Component waitComponent(final Container cont,
+ final ComponentChooser chooser,
+ final int index,
+ Timeouts timeouts, final TestOut output) {
+ try {
+ Waiter waiter = new Waiter<>(new Waitable() {
+ @Override
+ public Component actionProduced(Void obj) {
+ return findComponent(cont, new VisibleComponentFinder(chooser), index,
+ output.createErrorOutput());
+ }
+
+ @Override
+ public String getDescription() {
+ return "Wait " + chooser.getDescription() + " loaded";
+ }
+
+ @Override
+ public String toString() {
+ return "ComponentOperator.waitComponent.Waitable{description = " + getDescription() + '}';
+ }
+ });
+ waiter.setTimeoutsToCloneOf(timeouts, "ComponentOperator.WaitComponentTimeout");
+ waiter.setOutput(output);
+ return waiter.waitAction(null);
+ } catch (InterruptedException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Searches Components in container.
+ *
+ * @param cont Container to search components in.
+ * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
+ * @return Component array or empty array if component was not found.
+ */
+ public static Component[] findComponents(Container cont, ComponentChooser chooser) {
+ ComponentSearcher searcher = new ComponentSearcher(cont);
+ return searcher.findComponents(new VisibleComponentFinder(chooser));
+ }
+
+ private static Component findComponent(Container cont, ComponentChooser chooser, int index, TestOut output) {
+ ComponentSearcher searcher = new ComponentSearcher(cont);
+ searcher.setOutput(output);
+ return searcher.findComponent(new VisibleComponentFinder(chooser), index);
+ }
+
+ private static Component findComponent(Container cont, ComponentChooser chooser, int index, boolean supressOutout) {
+ return findComponent(cont, chooser, index, JemmyProperties.getCurrentOutput().createErrorOutput());
+ }
+
+ static {
+ Timeouts.initDefault("ComponentOperator.PushKeyTimeout", PUSH_KEY_TIMEOUT);
+ Timeouts.initDefault("ComponentOperator.MouseClickTimeout", MOUSE_CLICK_TIMEOUT);
+ Timeouts.initDefault("ComponentOperator.BeforeDragTimeout", BEFORE_DRAG_TIMEOUT);
+ Timeouts.initDefault("ComponentOperator.AfterDragTimeout", AFTER_DRAG_TIMEOUT);
+ Timeouts.initDefault("ComponentOperator.WaitComponentTimeout", WAIT_COMPONENT_TIMEOUT);
+ Timeouts.initDefault("ComponentOperator.WaitComponentEnabledTimeout", WAIT_COMPONENT_ENABLED_TIMEOUT);
+ Timeouts.initDefault("ComponentOperator.WaitStateTimeout", WAIT_STATE_TIMEOUT);
+ Timeouts.initDefault("ComponentOperator.WaitFocusTimeout", WAIT_FOCUS_TIMEOUT);
+ }
+
+ /**
+ * Returns component.
+ */
+ @Override
+ public Component getSource() {
+ return source;
+ }
+
+ /**
+ * Returns org.netbeans.jemmy.EventDispatcher instance which is used to
+ * dispatch events.
+ *
+ * @return the dispatcher.
+ * @see org.netbeans.jemmy.EventDispatcher
+ */
+ public EventDispatcher getEventDispatcher() {
+ return dispatcher;
+ }
+
+ ////////////////////////////////////////////////////////
+ //Environment //
+ ////////////////////////////////////////////////////////
+ @Override
+ public void setOutput(TestOut out) {
+ super.setOutput(out);
+ this.output = out;
+ if (dispatcher != null) {
+ dispatcher.setOutput(output.createErrorOutput());
+ }
+ }
+
+ @Override
+ public TestOut getOutput() {
+ return output;
+ }
+
+ @Override
+ public void setTimeouts(Timeouts timeouts) {
+ super.setTimeouts(timeouts);
+ this.timeouts = timeouts;
+ if (dispatcher != null) {
+ dispatcher.setTimeouts(getTimeouts());
+ }
+ }
+
+ @Override
+ public Timeouts getTimeouts() {
+ return timeouts;
+ }
+
+ @Override
+ public void copyEnvironment(Operator anotherOperator) {
+ super.copyEnvironment(anotherOperator);
+ kDriver = (KeyDriver) DriverManager.
+ getDriver(DriverManager.KEY_DRIVER_ID,
+ getClass(),
+ anotherOperator.getProperties());
+ mDriver = (MouseDriver) DriverManager.
+ getDriver(DriverManager.MOUSE_DRIVER_ID,
+ getClass(),
+ anotherOperator.getProperties());
+ fDriver = (FocusDriver) DriverManager.
+ getDriver(DriverManager.FOCUS_DRIVER_ID,
+ getClass(),
+ anotherOperator.getProperties());
+ }
+
+ ////////////////////////////////////////////////////////
+ //Mouse operations
+ ////////////////////////////////////////////////////////
+ /**
+ * Makes mouse click.
+ *
+ * @param x Horizontal click coordinate
+ * @param y Vertical click coordinate
+ * @param clickCount Click count
+ * @param mouseButton Mouse button (InputEvent.BUTTON1/2/3_MASK value)
+ * @param modifiers Modifiers (combination of InputEvent.*_MASK values)
+ * @param forPopup signals that click is intended to call popup.
+ */
+ public void clickMouse(final int x, final int y, final int clickCount, final int mouseButton,
+ final int modifiers, final boolean forPopup) {
+ getQueueTool().invokeSmoothly(new QueueTool.QueueAction("Path selecting") {
+ @Override
+ public Void launch() {
+ mDriver.clickMouse(ComponentOperator.this, x, y, clickCount, mouseButton, modifiers,
+ timeouts.create("ComponentOperator.MouseClickTimeout"));
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Makes mouse click.
+ *
+ * @param x Horizontal click coordinate
+ * @param y Vertical click coordinate
+ * @param clickCount Click count
+ * @param mouseButton Mouse button (InputEvent.BUTTON1/2/3_MASK value)
+ * @param modifiers Modifiers (combination of InputEvent.*_MASK values)
+ * @see #clickMouse(int, int, int, int, int, boolean)
+ */
+ public void clickMouse(int x, int y, int clickCount, int mouseButton, int modifiers) {
+ clickMouse(x, y, clickCount, mouseButton, modifiers, false);
+ }
+
+ /**
+ * Makes mouse click with 0 modifiers.
+ *
+ * @param x Horizontal click coordinate
+ * @param y Vertical click coordinate
+ * @param clickCount Click count
+ * @param mouseButton Mouse button (InputEvent.BUTTON1/2/3_MASK value)
+ * @see #clickMouse(int, int, int, int, int)
+ */
+ public void clickMouse(int x, int y, int clickCount, int mouseButton) {
+ clickMouse(x, y, clickCount, mouseButton, 0);
+ }
+
+ /**
+ * Makes mouse click by default mouse button with 0 modifiers.
+ *
+ * @param x Horizontal click coordinate
+ * @param y Vertical click coordinate
+ * @param clickCount Click count
+ * @see #clickMouse(int, int, int, int)
+ * @see #getDefaultMouseButton()
+ */
+ public void clickMouse(int x, int y, int clickCount) {
+ clickMouse(x, y, clickCount, getDefaultMouseButton());
+ }
+
+ /**
+ * Press mouse.
+ *
+ * @param x Horizontal click coordinate
+ * @param y Vertical click coordinate
+ */
+ public void pressMouse(int x, int y) {
+ mDriver.pressMouse(this, x, y, getDefaultMouseButton(), 0);
+ }
+
+ /**
+ * Releases mouse.
+ *
+ * @param x Horizontal click coordinate
+ * @param y Vertical click coordinate
+ */
+ public void releaseMouse(int x, int y) {
+ mDriver.releaseMouse(this, x, y, getDefaultMouseButton(), 0);
+ }
+
+ /**
+ * Move mouse over the component.
+ *
+ * @param x Horisontal destination coordinate.
+ * @param y Vertical destination coordinate.
+ */
+ public void moveMouse(int x, int y) {
+ mDriver.moveMouse(this, x, y);
+ }
+
+ /**
+ * Drag mouse over the component.
+ *
+ * @param x Horisontal destination coordinate.
+ * @param y Vertical destination coordinate.
+ * @param mouseButton Mouse button
+ * @param modifiers Modifiers
+ */
+ public void dragMouse(int x, int y, int mouseButton, int modifiers) {
+ mDriver.dragMouse(this, x, y, getDefaultMouseButton(), 0);
+ }
+
+ /**
+ * Drag mouse over the component with 0 modifiers.
+ *
+ * @param x Horisontal destination coordinate.
+ * @param y Vertical destination coordinate.
+ * @param mouseButton Mouse button
+ * @see #dragMouse(int, int, int, int)
+ */
+ public void dragMouse(int x, int y, int mouseButton) {
+ dragMouse(x, y, mouseButton, 0);
+ }
+
+ /**
+ * Drag mouse over the component with 0 modifiers and default mose button
+ * pressed.
+ *
+ * @param x Horisontal destination coordinate.
+ * @param y Vertical destination coordinate.
+ * @see #dragMouse(int, int, int)
+ * @see #getDefaultMouseButton()
+ */
+ public void dragMouse(int x, int y) {
+ dragMouse(x, y, getDefaultMouseButton());
+ }
+
+ /**
+ * Makes drag'n'drop operation.
+ *
+ * @param start_x Start horizontal coordinate
+ * @param start_y Start vertical coordinate
+ * @param end_x End horizontal coordinate
+ * @param end_y End vertical coordinate
+ * @param mouseButton Mouse button
+ * @param modifiers Modifiers
+ */
+ public void dragNDrop(int start_x, int start_y, int end_x, int end_y, int mouseButton, int modifiers) {
+ mDriver.dragNDrop(this, start_x, start_y, end_x, end_y, mouseButton, modifiers,
+ timeouts.create("ComponentOperator.BeforeDragTimeout"),
+ timeouts.create("ComponentOperator.AfterDragTimeout"));
+ }
+
+ /**
+ * Makes drag'n'drop operation with 0 modifiers.
+ *
+ * @param start_x Start horizontal coordinate
+ * @param start_y Start vertical coordinate
+ * @param end_x End horizontal coordinate
+ * @param end_y End vertical coordinate
+ * @param mouseButton Mouse button
+ * @see #dragNDrop(int, int, int, int, int, int)
+ */
+ public void dragNDrop(int start_x, int start_y, int end_x, int end_y, int mouseButton) {
+ dragNDrop(start_x, start_y, end_x, end_y, mouseButton, 0);
+ }
+
+ /**
+ * Makes drag'n'drop operation by default mouse buttons with 0 modifiers.
+ *
+ * @param start_x Start horizontal coordinate
+ * @param start_y Start vertical coordinate
+ * @param end_x End horizontal coordinate
+ * @param end_y End vertical coordinate
+ * @see #dragNDrop(int, int, int, int, int)
+ * @see #getDefaultMouseButton()
+ */
+ public void dragNDrop(int start_x, int start_y, int end_x, int end_y) {
+ dragNDrop(start_x, start_y, end_x, end_y, getDefaultMouseButton(), 0);
+ }
+
+ /**
+ * Clicks for popup.
+ *
+ * @param x Horizontal click coordinate.
+ * @param y Vertical click coordinate.
+ * @param mouseButton Mouse button.
+ * @see #clickMouse(int, int, int, int, int, boolean)
+ */
+ public void clickForPopup(int x, int y, int mouseButton) {
+ makeComponentVisible();
+ clickMouse(x, y, 1, mouseButton, 0, true);
+ }
+
+ /**
+ * Clicks for popup by popup mouse button.
+ *
+ * @param x Horizontal click coordinate.
+ * @param y Vertical click coordinate.
+ * @see #clickForPopup(int, int, int)
+ * @see #getPopupMouseButton()
+ */
+ public void clickForPopup(int x, int y) {
+ clickForPopup(x, y, getPopupMouseButton());
+ }
+
+ /**
+ * Makes mouse click on the component center with 0 modifiers.
+ *
+ * @param clickCount Click count
+ * @param mouseButton Mouse button (InputEvent.BUTTON1/2/3_MASK value)
+ * @see #clickMouse(int, int, int, int)
+ */
+ public void clickMouse(final int clickCount, final int mouseButton) {
+ getQueueTool().invokeSmoothly(new QueueTool.QueueAction("Clicking the mouse button") {
+ @Override
+ public Void launch() {
+ clickMouse(getCenterXForClick(), getCenterYForClick(), clickCount, mouseButton);
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Makes mouse click on the component center by default mouse button with 0
+ * modifiers.
+ *
+ * @param clickCount Click count
+ * @see #clickMouse(int, int)
+ * @see #getDefaultMouseButton()
+ */
+ public void clickMouse(int clickCount) {
+ clickMouse(clickCount, getDefaultMouseButton());
+ }
+
+ /**
+ * Makes siple mouse click on the component center by default mouse button
+ * with 0 modifiers.
+ *
+ * @see #clickMouse(int)
+ * @see #getDefaultMouseButton()
+ */
+ public void clickMouse() {
+ clickMouse(1);
+ }
+
+ /**
+ * Move mouse inside the component.
+ */
+ public void enterMouse() {
+ mDriver.enterMouse(this);
+ }
+
+ /**
+ * Move mouse outside the component.
+ */
+ public void exitMouse() {
+ mDriver.exitMouse(this);
+ }
+
+ /**
+ * Press mouse.
+ */
+ public void pressMouse() {
+ getQueueTool().invokeSmoothly(new QueueTool.QueueAction("Pressing the mouse button") {
+ @Override
+ public Void launch() {
+ pressMouse(getCenterXForClick(), getCenterYForClick());
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Releases mouse.
+ */
+ public void releaseMouse() {
+ getQueueTool().invokeSmoothly(new QueueTool.QueueAction("Releasing the mouse button") {
+ @Override
+ public Void launch() {
+ releaseMouse(getCenterXForClick(), getCenterYForClick());
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Clicks for popup at the component center.
+ *
+ * @param mouseButton Mouse button.
+ * @see #clickForPopup(int, int)
+ */
+ public void clickForPopup(int mouseButton) {
+ clickForPopup(getCenterXForClick(), getCenterYForClick(), mouseButton);
+ }
+
+ /**
+ * Clicks for popup by popup mouse button at the component center.
+ *
+ * @see #clickForPopup(int)
+ * @see #getPopupMouseButton()
+ */
+ public void clickForPopup() {
+ clickForPopup(getPopupMouseButton());
+ }
+
+ ////////////////////////////////////////////////////////
+ //Keyboard operations
+ ////////////////////////////////////////////////////////
+ /**
+ * Press key.
+ *
+ * @param keyCode Key code (KeyEvent.VK_* value)
+ * @param modifiers Modifiers (combination of InputEvent.*_MASK fields)
+ */
+ public void pressKey(int keyCode, int modifiers) {
+ kDriver.pressKey(this, keyCode, modifiers);
+ }
+
+ /**
+ * Press key with no modifiers.
+ *
+ * @param keyCode Key code (KeyEvent.VK_* value)
+ */
+ public void pressKey(int keyCode) {
+ pressKey(keyCode, 0);
+ }
+
+ /**
+ * Typed key.
+ *
+ * @param keyChar Char to be typed.
+ * @param modifiers Modifiers (combination of InputEvent.*_MASK fields)
+ */
+ public void typedKey(char keyChar, int modifiers) {
+ kDriver.typedKey(this, getCharBindingMap().getCharKey(keyChar), keyChar, modifiers);
+ }
+
+ /**
+ * Releases key.
+ *
+ * @param keyCode Key code (KeyEvent.VK_* value)
+ * @param modifiers Modifiers (combination of InputEvent.*_MASK fields)
+ */
+ public void releaseKey(int keyCode, int modifiers) {
+ kDriver.releaseKey(this, keyCode, modifiers);
+ }
+
+ /**
+ * Releases key with no modifiers.
+ *
+ * @param keyCode Key code (KeyEvent.VK_* value)
+ */
+ public void releaseKey(int keyCode) {
+ releaseKey(keyCode, 0);
+ }
+
+ /**
+ * Pushs key.
+ *
+ * @param keyCode Key code (KeyEvent.VK_* value)
+ * @param modifiers Modifiers (combination of InputEvent.*_MASK fields)
+ */
+ public void pushKey(int keyCode, int modifiers) {
+ kDriver.pushKey(this, keyCode, modifiers, timeouts.create("ComponentOperator.PushKeyTimeout"));
+ }
+
+ /**
+ * Pushs key.
+ *
+ * @param keyCode Key code (KeyEvent.VK_* value)
+ */
+ public void pushKey(int keyCode) {
+ pushKey(keyCode, 0);
+ }
+
+ /**
+ * Types one char.
+ *
+ * @param keyCode Key code (KeyEvent.VK_* value)
+ * @param keyChar Char to be typed.
+ * @param modifiers Modifiers (combination of InputEvent.*_MASK fields)
+ */
+ public void typeKey(int keyCode, char keyChar, int modifiers) {
+ kDriver.typeKey(this, keyCode, keyChar, modifiers, timeouts.create("ComponentOperator.PushKeyTimeout"));
+ }
+
+ /**
+ * Types one char. Uses map defined by setCharBindingMap(CharBindingMap)
+ * method to find a key should be pressed.
+ *
+ * @param keyChar Char to be typed.
+ * @param modifiers Modifiers (combination of InputEvent.*_MASK fields)
+ * @see org.netbeans.jemmy.CharBindingMap
+ * @see #setCharBindingMap(CharBindingMap)
+ * @see #typeKey(int, char, int)
+ */
+ public void typeKey(char keyChar, int modifiers) {
+ typeKey(getCharKey(keyChar), keyChar, modifiers | getCharModifiers(keyChar));
+ }
+
+ /**
+ * Types one char. Uses map defined by setCharBindingMap(CharBindingMap)
+ * method to find a key and modifiers should be pressed.
+ *
+ * @param keyChar Char to be typed.
+ * @see #setCharBindingMap(CharBindingMap)
+ * @see #typeKey(char, int)
+ */
+ public void typeKey(char keyChar) {
+ typeKey(keyChar, 0);
+ }
+
+ ////////////////////////////////////////////////////////
+ //Util
+ ////////////////////////////////////////////////////////
+ /**
+ * Activates component's window.
+ *
+ * @deprecated Use makeComponentVisible() instead.
+ * @see #makeComponentVisible()
+ */
+ @Deprecated
+ public void activateWindow() {
+ getVisualizer().makeVisible(this);
+ }
+
+ /**
+ * Prepares component for user input. Uses visualizer defined by
+ * setVisualiser() method.
+ */
+ public void makeComponentVisible() {
+ getVisualizer().makeVisible(this);
+ /*
+ final ComponentOperator compOper = (ComponentOperator)this;
+ runMapping(new MapVoidAction("add") {
+ public void map() {
+ getVisualizer().makeVisible(compOper);
+ }
+ });
+ */
+ }
+
+ /**
+ * Gives input focus to the component.
+ */
+ public void getFocus() {
+ fDriver.giveFocus(this);
+ }
+
+ /**
+ * Return the center x coordinate.
+ *
+ * @return the center x coordinate.
+ */
+ public int getCenterX() {
+ return getWidth() / 2;
+ }
+
+ /**
+ * Return the center y coordinate.
+ *
+ * @return the center y coordinate.
+ */
+ public int getCenterY() {
+ return getHeight() / 2;
+ }
+
+ /**
+ * Return the x coordinate which should be used for mouse operations by
+ * default.
+ *
+ * @return the center x coordinate of the visible component part.
+ */
+ public int getCenterXForClick() {
+ return getCenterX();
+ }
+
+ /**
+ * Return the y coordinate which should be used for mouse operations by
+ * default.
+ *
+ * @return the center y coordinate of the visible component part.
+ */
+ public int getCenterYForClick() {
+ return getCenterY();
+ }
+
+ /**
+ * Waits for the component to be enabled.
+ *
+ * @throws TimeoutExpiredException
+ * @throws InterruptedException
+ */
+ public void waitComponentEnabled() throws InterruptedException {
+ Waiter waiter = new Waiter<>(new Waitable() {
+ @Override
+ public Component actionProduced(Component obj) {
+ if (obj.isEnabled()) {
+ return obj;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return ("Component enabled: "
+ + getSource().getClass().toString());
+ }
+
+ @Override
+ public String toString() {
+ return "ComponentOperator.waitComponentEnabled.Waitable{description = " + getDescription() + '}';
+ }
+ });
+ waiter.setOutput(output);
+ waiter.setTimeoutsToCloneOf(timeouts, "ComponentOperator.WaitComponentEnabledTimeout");
+ waiter.waitAction(getSource());
+ }
+
+ /**
+ * Waits for the component to be enabled. per request: 37831
+ *
+ * @throws TimeoutExpiredException
+ */
+ public void wtComponentEnabled() {
+ try {
+ waitComponentEnabled();
+ } catch (InterruptedException e) {
+ throw (new JemmyException("Interrupted!", e));
+ }
+ }
+
+ /**
+ * Returns an array of containers for this component.
+ *
+ * @return an array of containers
+ */
+ public Container[] getContainers() {
+ int counter = 0;
+ Container cont = getSource().getParent();
+ if (cont == null) {
+ return new Container[0];
+ }
+ do {
+ counter++;
+ } while ((cont = cont.getParent()) != null);
+ Container[] res = new Container[counter];
+ cont = getSource().getParent();
+ counter = 0;
+ do {
+ counter++;
+ res[counter - 1] = cont;
+ } while ((cont = cont.getParent()) != null);
+ return res;
+ }
+
+ /**
+ * Searches a container.
+ *
+ * @param chooser a chooser specifying the searching criteria.
+ * @return a containers specified by searching criteria.
+ */
+ public Container getContainer(ComponentChooser chooser) {
+ int counter = 0;
+ Container cont = getSource().getParent();
+ if (cont == null) {
+ return null;
+ }
+ do {
+ if (chooser.checkComponent(cont)) {
+ return cont;
+ }
+ counter++;
+ } while ((cont = cont.getParent()) != null);
+ return null;
+ }
+
+ /**
+ * Searches the window under component.
+ *
+ * @return the component window.
+ */
+ public Window getWindow() {
+ if (getSource() instanceof Window) {
+ return (Window) getSource();
+ }
+ Window window = (Window) getContainer(new ComponentChooser() {
+ @Override
+ public boolean checkComponent(Component comp) {
+ return comp instanceof Window;
+ }
+
+ @Override
+ public String getDescription() {
+ return "";
+ }
+
+ @Override
+ public String toString() {
+ return "ComponentOperator.getWindow.ComponentChooser{description = " + getDescription() + '}';
+ }
+ });
+ if (window == null && getSource() instanceof Window) {
+ return (Window) getSource();
+ } else {
+ return window;
+ }
+ }
+
+ /**
+ * Waits for this Component has the keyboard focus.
+ *
+ * @throws TimeoutExpiredException
+ */
+ public void waitHasFocus() {
+ Waiter focusWaiter = new Waiter<>(new Waitable() {
+ @Override
+ public String actionProduced(Void obj) {
+ return hasFocus() ? "" : null;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Wait component has focus";
+ }
+
+ @Override
+ public String toString() {
+ return "ComponentOperator.waitHasFocus.Waitable{description = " + getDescription() + '}';
+ }
+ });
+ focusWaiter.setTimeoutsToCloneOf(timeouts, "ComponentOperator.WaitFocusTimeout");
+ focusWaiter.setOutput(output.createErrorOutput());
+ try {
+ focusWaiter.waitAction(null);
+ } catch (InterruptedException e) {
+ output.printStackTrace(e);
+ }
+ }
+
+ /**
+ * Waits for the component to be visible or unvisible.
+ *
+ * @param visibility required visiblity.
+ * @throws TimeoutExpiredException
+ */
+ public void waitComponentVisible(final boolean visibility) {
+ waitState(new ComponentChooser() {
+ @Override
+ public boolean checkComponent(Component comp) {
+ return isVisible() == visibility;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Component is " + (visibility ? "" : " not ") + "visible";
+ }
+
+ @Override
+ public String toString() {
+ return "ComponentOperator.waitComponentVisible.ComponentChooser{description = " + getDescription() + '}';
+ }
+ });
+ }
+
+ public void waitComponentShowing(final boolean visibility) {
+ waitState(new ComponentChooser() {
+ @Override
+ public boolean checkComponent(Component comp) {
+ return isShowing() == visibility;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Component is " + (visibility ? "" : " not ") + "showing";
+ }
+
+ @Override
+ public String toString() {
+ return "ComponentOperator.waitComponentShowing.ComponentChooser{description = " + getDescription() + '}';
+ }
+ });
+ }
+
+ /**
+ * Returns information about component.
+ */
+ @Override
+ public Hashtable getDump() {
+ Hashtable result = super.getDump();
+ if (getSource().getName() != null) {
+ result.put(NAME_DPROP, getSource().getName());
+ }
+ result.put(IS_VISIBLE_DPROP, getSource().isVisible() ? "true" : "false");
+ result.put(IS_SHOWING_DPROP, getSource().isShowing() ? "true" : "false");
+ result.put(X_DPROP, Integer.toString(getSource().getX()));
+ result.put(Y_DPROP, Integer.toString(getSource().getY()));
+ result.put(WIDTH_DPROP, Integer.toString(getSource().getWidth()));
+ result.put(HEIGHT_DPROP, Integer.toString(getSource().getHeight()));
+ return result;
+ }
+
+ ////////////////////////////////////////////////////////
+ //Mapping //
+ /**
+ * Maps {@code Component.add(PopupMenu)} through queue
+ */
+ public void add(final PopupMenu popupMenu) {
+ runMapping(new MapVoidAction("add") {
+ @Override
+ public void map() {
+ getSource().add(popupMenu);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Component.addComponentListener(ComponentListener)}
+ * through queue
+ */
+ public void addComponentListener(final ComponentListener componentListener) {
+ runMapping(new MapVoidAction("addComponentListener") {
+ @Override
+ public void map() {
+ getSource().addComponentListener(componentListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Component.addFocusListener(FocusListener)} through queue
+ */
+ public void addFocusListener(final FocusListener focusListener) {
+ runMapping(new MapVoidAction("addFocusListener") {
+ @Override
+ public void map() {
+ getSource().addFocusListener(focusListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Component.addInputMethodListener(InputMethodListener)}
+ * through queue
+ */
+ public void addInputMethodListener(final InputMethodListener inputMethodListener) {
+ runMapping(new MapVoidAction("addInputMethodListener") {
+ @Override
+ public void map() {
+ getSource().addInputMethodListener(inputMethodListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Component.addKeyListener(KeyListener)} through queue
+ */
+ public void addKeyListener(final KeyListener keyListener) {
+ runMapping(new MapVoidAction("addKeyListener") {
+ @Override
+ public void map() {
+ getSource().addKeyListener(keyListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Component.addMouseListener(MouseListener)} through queue
+ */
+ public void addMouseListener(final MouseListener mouseListener) {
+ runMapping(new MapVoidAction("addMouseListener") {
+ @Override
+ public void map() {
+ getSource().addMouseListener(mouseListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Component.addMouseMotionListener(MouseMotionListener)}
+ * through queue
+ */
+ public void addMouseMotionListener(final MouseMotionListener mouseMotionListener) {
+ runMapping(new MapVoidAction("addMouseMotionListener") {
+ @Override
+ public void map() {
+ getSource().addMouseMotionListener(mouseMotionListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Component.addNotify()} through queue
+ */
+ public void addNotify() {
+ runMapping(new MapVoidAction("addNotify") {
+ @Override
+ public void map() {
+ getSource().addNotify();
+ }
+ });
+ }
+
+ /**
+ * Maps
+ * {@code Component.addPropertyChangeListener(PropertyChangeListener)}
+ * through queue
+ */
+ public void addPropertyChangeListener(final PropertyChangeListener propertyChangeListener) {
+ runMapping(new MapVoidAction("addPropertyChangeListener") {
+ @Override
+ public void map() {
+ getSource().addPropertyChangeListener(propertyChangeListener);
+ }
+ });
+ }
+
+ /**
+ * Maps
+ * {@code Component.addPropertyChangeListener(String, PropertyChangeListener)}
+ * through queue
+ */
+ public void addPropertyChangeListener(final String string, final PropertyChangeListener propertyChangeListener) {
+ runMapping(new MapVoidAction("addPropertyChangeListener") {
+ @Override
+ public void map() {
+ getSource().addPropertyChangeListener(string, propertyChangeListener);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Component.checkImage(Image, int, int, ImageObserver)}
+ * through queue
+ */
+ public int checkImage(final Image image, final int i, final int i1, final ImageObserver imageObserver) {
+ return (runMapping(new MapIntegerAction("checkImage") {
+ @Override
+ public int map() {
+ return getSource().checkImage(image, i, i1, imageObserver);
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.checkImage(Image, ImageObserver)} through queue
+ */
+ public int checkImage(final Image image, final ImageObserver imageObserver) {
+ return (runMapping(new MapIntegerAction("checkImage") {
+ @Override
+ public int map() {
+ return getSource().checkImage(image, imageObserver);
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.contains(int, int)} through queue
+ */
+ public boolean contains(final int i, final int i1) {
+ return (runMapping(new MapBooleanAction("contains") {
+ @Override
+ public boolean map() {
+ return getSource().contains(i, i1);
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.contains(Point)} through queue
+ */
+ public boolean contains(final Point point) {
+ return (runMapping(new MapBooleanAction("contains") {
+ @Override
+ public boolean map() {
+ return getSource().contains(point);
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.createImage(int, int)} through queue
+ */
+ public Image createImage(final int i, final int i1) {
+ return (runMapping(new MapAction("createImage") {
+ @Override
+ public Image map() {
+ return getSource().createImage(i, i1);
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.createImage(ImageProducer)} through queue
+ */
+ public Image createImage(final ImageProducer imageProducer) {
+ return (runMapping(new MapAction("createImage") {
+ @Override
+ public Image map() {
+ return getSource().createImage(imageProducer);
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.dispatchEvent(AWTEvent)} through queue
+ */
+ public void dispatchEvent(final AWTEvent aWTEvent) {
+ runMapping(new MapVoidAction("dispatchEvent") {
+ @Override
+ public void map() {
+ getSource().dispatchEvent(aWTEvent);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Component.doLayout()} through queue
+ */
+ public void doLayout() {
+ runMapping(new MapVoidAction("doLayout") {
+ @Override
+ public void map() {
+ getSource().doLayout();
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Component.enableInputMethods(boolean)} through queue
+ */
+ public void enableInputMethods(final boolean b) {
+ runMapping(new MapVoidAction("enableInputMethods") {
+ @Override
+ public void map() {
+ getSource().enableInputMethods(b);
+ }
+ });
+ }
+
+ /**
+ * Maps {@code Component.getAlignmentX()} through queue
+ */
+ public float getAlignmentX() {
+ return (runMapping(new MapFloatAction("getAlignmentX") {
+ @Override
+ public float map() {
+ return getSource().getAlignmentX();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getAlignmentY()} through queue
+ */
+ public float getAlignmentY() {
+ return (runMapping(new MapFloatAction("getAlignmentY") {
+ @Override
+ public float map() {
+ return getSource().getAlignmentY();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getBackground()} through queue
+ */
+ public Color getBackground() {
+ return (runMapping(new MapAction("getBackground") {
+ @Override
+ public Color map() {
+ return getSource().getBackground();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getBounds()} through queue
+ */
+ public Rectangle getBounds() {
+ return (runMapping(new MapAction("getBounds") {
+ @Override
+ public Rectangle map() {
+ return getSource().getBounds();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getBounds(Rectangle)} through queue
+ */
+ public Rectangle getBounds(final Rectangle rectangle) {
+ return (runMapping(new MapAction("getBounds") {
+ @Override
+ public Rectangle map() {
+ return getSource().getBounds(rectangle);
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getColorModel()} through queue
+ */
+ public ColorModel getColorModel() {
+ return (runMapping(new MapAction("getColorModel") {
+ @Override
+ public ColorModel map() {
+ return getSource().getColorModel();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getComponentAt(int, int)} through queue
+ */
+ public Component getComponentAt(final int i, final int i1) {
+ return (runMapping(new MapAction("getComponentAt") {
+ @Override
+ public Component map() {
+ return getSource().getComponentAt(i, i1);
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getComponentAt(Point)} through queue
+ */
+ public Component getComponentAt(final Point point) {
+ return (runMapping(new MapAction("getComponentAt") {
+ @Override
+ public Component map() {
+ return getSource().getComponentAt(point);
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getComponentOrientation()} through queue
+ */
+ public ComponentOrientation getComponentOrientation() {
+ return (runMapping(new MapAction("getComponentOrientation") {
+ @Override
+ public ComponentOrientation map() {
+ return getSource().getComponentOrientation();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getCursor()} through queue
+ */
+ public Cursor getCursor() {
+ return (runMapping(new MapAction("getCursor") {
+ @Override
+ public Cursor map() {
+ return getSource().getCursor();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getDropTarget()} through queue
+ */
+ public DropTarget getDropTarget() {
+ return (runMapping(new MapAction("getDropTarget") {
+ @Override
+ public DropTarget map() {
+ return getSource().getDropTarget();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getFont()} through queue
+ */
+ public Font getFont() {
+ return (runMapping(new MapAction("getFont") {
+ @Override
+ public Font map() {
+ return getSource().getFont();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getFontMetrics(Font)} through queue
+ */
+ public FontMetrics getFontMetrics(final Font font) {
+ return (runMapping(new MapAction("getFontMetrics") {
+ @Override
+ public FontMetrics map() {
+ return getSource().getFontMetrics(font);
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getForeground()} through queue
+ */
+ public Color getForeground() {
+ return (runMapping(new MapAction("getForeground") {
+ @Override
+ public Color map() {
+ return getSource().getForeground();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getGraphics()} through queue
+ */
+ public Graphics getGraphics() {
+ return (runMapping(new MapAction("getGraphics") {
+ @Override
+ public Graphics map() {
+ return getSource().getGraphics();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getHeight()} through queue
+ */
+ public int getHeight() {
+ return (runMapping(new MapIntegerAction("getHeight") {
+ @Override
+ public int map() {
+ return getSource().getHeight();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getInputContext()} through queue
+ */
+ public InputContext getInputContext() {
+ return (runMapping(new MapAction("getInputContext") {
+ @Override
+ public InputContext map() {
+ return getSource().getInputContext();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getInputMethodRequests()} through queue
+ */
+ public InputMethodRequests getInputMethodRequests() {
+ return (runMapping(new MapAction("getInputMethodRequests") {
+ @Override
+ public InputMethodRequests map() {
+ return getSource().getInputMethodRequests();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getLocale()} through queue
+ */
+ public Locale getLocale() {
+ return (runMapping(new MapAction("getLocale") {
+ @Override
+ public Locale map() {
+ return getSource().getLocale();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getLocation()} through queue
+ */
+ public Point getLocation() {
+ return (runMapping(new MapAction("getLocation") {
+ @Override
+ public Point map() {
+ return getSource().getLocation();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getLocation(Point)} through queue
+ */
+ public Point getLocation(final Point point) {
+ return (runMapping(new MapAction("getLocation") {
+ @Override
+ public Point map() {
+ return getSource().getLocation(point);
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getLocationOnScreen()} through queue
+ */
+ public Point getLocationOnScreen() {
+ return (runMapping(new MapAction("getLocationOnScreen") {
+ @Override
+ public Point map() {
+ return getSource().getLocationOnScreen();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getMaximumSize()} through queue
+ */
+ public Dimension getMaximumSize() {
+ return (runMapping(new MapAction("getMaximumSize") {
+ @Override
+ public Dimension map() {
+ return getSource().getMaximumSize();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getMinimumSize()} through queue
+ */
+ public Dimension getMinimumSize() {
+ return (runMapping(new MapAction("getMinimumSize") {
+ @Override
+ public Dimension map() {
+ return getSource().getMinimumSize();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getName()} through queue
+ */
+ public String getName() {
+ return (runMapping(new MapAction("getName") {
+ @Override
+ public String map() {
+ return getSource().getName();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getParent()} through queue
+ */
+ public Container getParent() {
+ return (runMapping(new MapAction("getParent") {
+ @Override
+ public Container map() {
+ return getSource().getParent();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getPreferredSize()} through queue
+ */
+ public Dimension getPreferredSize() {
+ return (runMapping(new MapAction("getPreferredSize") {
+ @Override
+ public Dimension map() {
+ return getSource().getPreferredSize();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getSize()} through queue
+ */
+ public Dimension getSize() {
+ return (runMapping(new MapAction("getSize") {
+ @Override
+ public Dimension map() {
+ return getSource().getSize();
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getSize(Dimension)} through queue
+ */
+ public Dimension getSize(final Dimension dimension) {
+ return (runMapping(new MapAction("getSize") {
+ @Override
+ public Dimension map() {
+ return getSource().getSize(dimension);
+ }
+ }));
+ }
+
+ /**
+ * Maps {@code Component.getToolkit()} through queue
+ */
+ public Toolkit getToolkit() {
+ return (runMapping(new MapAction