Proposal For Inclusion of Robot and ParametersImpl in the Public API

Kevin Rushforth kevin.rushforth at oracle.com
Tue Mar 20 12:28:23 UTC 2018


I will do an initial review of the API today and suggest next steps.

-- Kevin


Michael Ennen wrote:
> Ping :)
>
> On Mon, Jan 8, 2018 at 4:28 PM, Kevin Rushforth 
> <kevin.rushforth at oracle.com <mailto:kevin.rushforth at oracle.com>> wrote:
>
>     I'll take a look some time after RDP2 of JDK 10.
>
>
>     -- Kevin
>
>
>     Michael Ennen wrote:
>>     Hey Kevin,
>>
>>     Hope you had a good holiday. Hopefully you will get some time in
>>     the coming weeks
>>     to review my work.
>>
>>     Thanks!
>>
>>     On Wed, Dec 20, 2017 at 3:05 PM, Kevin Rushforth
>>     <kevin.rushforth at oracle.com <mailto:kevin.rushforth at oracle.com>>
>>     wrote:
>>
>>         Sure, no problem. One quick comment is that a common way to
>>         solve this is by delegating to an implementation class, which
>>         would then be sub-classes.
>>
>>
>>         -- Kevin
>>
>>
>>         Michael Ennen wrote:
>>>         I am not trying to be a burden here. I understand that you
>>>         may not have time to hand-hold
>>>         to this degree. I will try and make progress, sorry for the
>>>         follow up question.
>>>
>>>         On Wed, Dec 20, 2017 at 2:08 PM, Michael Ennen
>>>         <mike.ennen at gmail.com <mailto:mike.ennen at gmail.com>> wrote:
>>>
>>>             How can Robot call into the implementation when it is a
>>>             super class of the implementations?
>>>
>>>             On Wed, Dec 20, 2017 at 2:04 PM, Kevin Rushforth
>>>             <kevin.rushforth at oracle.com
>>>             <mailto:kevin.rushforth at oracle.com>> wrote:
>>>
>>>
>>>
>>>                 Michael Ennen wrote:
>>>>                 I have a question about how to proceed with the
>>>>                 Robot code.
>>>>
>>>>                 The base abstract Robot class
>>>>                 is: https://github.com/brcolow/openjfx/blob/master/modules/javafx.graphics/src/main/java/javafx/scene/robot/Robot.java
>>>>                 <https://github.com/brcolow/openjfx/blob/master/modules/javafx.graphics/src/main/java/javafx/scene/robot/Robot.java>
>>>>
>>>>                 As you can see for each method, such as
>>>>                 "getMouseX()" there is a "_" prefixed method
>>>>                 which is abstract and a non-prefixed method:
>>>>
>>>>                 protected abstract int _getMouseX();
>>>>
>>>>                 public int getMouseX() {
>>>>                     Application.checkEventThread();
>>>>                     return _getMouseX();
>>>>                 }
>>>>
>>>>                 I have copied this from the private Robot API.
>>>>
>>>>                 Is there a better way to do this? Would this pass
>>>>                 review?
>>>
>>>                 Yes there are better ways to do this. No it would
>>>                 not pass review, since this would be leaking
>>>                 implementation into the public API.
>>>
>>>                 Rather than copying the public / protected methods
>>>                 from the internal package, it probably makes more
>>>                 sense to start with what a Robot API should look
>>>                 like and then have that call into the implementation
>>>                 (suitably modified so it better matches the public
>>>                 API). For one thing you will then leave the
>>>                 implementation, including the per-platform code,
>>>                 where it belongs -- in glass. The Robot API can be
>>>                 informed by the current implementation, but should
>>>                 not be defined by it.
>>>
>>>                 -- Kevin
>>>
>>>
>>>>
>>>>                 Thanks very much.
>>>>
>>>>
>>>>                 On Tue, Dec 5, 2017 at 5:29 PM, Kevin Rushforth
>>>>                 <kevin.rushforth at oracle.com
>>>>                 <mailto:kevin.rushforth at oracle.com>> wrote:
>>>>
>>>>                     Glad you got the build working. You can post
>>>>                     back on this thread when you are ready.
>>>>
>>>>
>>>>                     -- Kevin
>>>>
>>>>
>>>>                     Michael Ennen wrote:
>>>>>                     Correction:
>>>>>
>>>>>                     Adding ""--add-exports
>>>>>                     javafx.graphics/javafx.scene.robot=ALL-UNNAMED"
>>>>>                     to buildSrc/addExports.
>>>>>
>>>>>                     For posterity :)
>>>>>
>>>>>                     On Mon, Dec 4, 2017 at 6:08 PM, Michael Ennen
>>>>>                     <mike.ennen at gmail.com
>>>>>                     <mailto:mike.ennen at gmail.com>> wrote:
>>>>>
>>>>>                         Ah, indeed, missed adding "--add-opens
>>>>>                         javafx.graphics/javafx.scene.robot=ALL-UNNAMED"
>>>>>                         to buildSrc/addExports.
>>>>>                         Thanks for the guidance on that.
>>>>>
>>>>>                         I will continue to work on this in the
>>>>>                         GitHub repo and polish it up (add
>>>>>                         javadocs, better method signatures, etc.)
>>>>>                         and 
>>>>>                         even plan on maybe improving the
>>>>>                         underlying native Robot implementations
>>>>>                         (for example fixing/improving the
>>>>>                         way color profiles are handled for MacRobot).
>>>>>
>>>>>                         I will also take a look at "fixing"
>>>>>                         JemmyFX to use the new public API (as well
>>>>>                         as any other place in the JavaFX code
>>>>>                         base that does).
>>>>>
>>>>>                         I was expecting that JDK 11 would be the
>>>>>                         appropriate time frame, especially because
>>>>>                         it will be the release where
>>>>>                         private APIs will be totally inaccessible,
>>>>>                         correct?
>>>>>
>>>>>                         After I get it in a reasonable state
>>>>>                         should I post back on this mailing list
>>>>>                         thread or what would be the appropriate
>>>>>                         way?
>>>>>
>>>>>                         Thanks Kevin.
>>>>>
>>>>>                         On Mon, Dec 4, 2017 at 5:12 PM, Kevin
>>>>>                         Rushforth <kevin.rushforth at oracle.com
>>>>>                         <mailto:kevin.rushforth at oracle.com>> wrote:
>>>>>
>>>>>                             This is a limitation of the the way
>>>>>                             --patch-modules works. You will need
>>>>>                             to add an entry in:
>>>>>
>>>>>                             buildSrc/addExports
>>>>>
>>>>>                             Btw, as for the proposal itself, this
>>>>>                             might need to be a JEP depending on
>>>>>                             the scope. In any case, it could be
>>>>>                             considered in the JDK 11 time frame,
>>>>>                             but there are several things that need
>>>>>                             to be worked out before making Robot a
>>>>>                             public API, including the fact that
>>>>>                             the JemmyFX framework in the
>>>>>                             openjfx/jfx/tests directory uses
>>>>>                             Robot. Once you get a working
>>>>>                             prototype, it would be interesting to
>>>>>                             discuss it in more detail.
>>>>>
>>>>>                             -- Kevin
>>>>>
>>>>>
>>>>>
>>>>>                             Michael Ennen wrote:
>>>>>>                             Currently I am stuck with tests not being able to see the new
>>>>>>                             "javafx.scene.robot" module:
>>>>>>
>>>>>>                               
>>>>>>>                             Task :systemTests:compileTestJava
>>>>>>>                                 
>>>>>>                             C:\Users\brcolow\dev\openjfx\tests\system\src\test\java\test\robot\com\sun\glass\ui\monocle\ModalDialogTest.java:34:
>>>>>>                             error: package javafx.scene.robot is not visible
>>>>>>                             import javafx.scene.robot.Robot;
>>>>>>                                                ^
>>>>>>                               (package javafx.scene.robot is declared in module javafx.graphics, which
>>>>>>                             does not export it)
>>>>>>                             C:\Users\brcolow\dev\openjfx\tests\system\src\test\java\test\robot\com\sun\glass\ui\monocle\RobotTest.java:33:
>>>>>>                             error: package javafx.scene.robot is not visible
>>>>>>                             import javafx.scene.robot.Robot;
>>>>>>
>>>>>>                             I have added:
>>>>>>
>>>>>>                                 exports javafx.scene.robot;
>>>>>>
>>>>>>                             to: modules/javafx.graphics/src/main/java/module-info.java
>>>>>>
>>>>>>                             But this does not seem to be enough.
>>>>>>
>>>>>>                             On Sun, Dec 3, 2017 at 4:48 PM, Michael Ennen <mike.ennen at gmail.com> <mailto:mike.ennen at gmail.com> wrote:
>>>>>>
>>>>>>                               
>>>>>>>                             I am still working on all the necessary changes to actually allow openjfx
>>>>>>>                             to compile.
>>>>>>>                             Tons to learn in that arena and I know the code as it is written won't
>>>>>>>                             totally work.
>>>>>>>                             For example one can no longer:
>>>>>>>
>>>>>>>                             #include "com_sun_glass_ui_Robot.h"
>>>>>>>
>>>>>>>                             as in openjfx\modules\javafx.graphics\src\main\native-glass\win\Robot.cpp
>>>>>>>
>>>>>>>                             But I am not sure how those headers are generated and if I can just simply
>>>>>>>                             change
>>>>>>>                             it to "#include javafx_scene_robot_Robot.h" (which I very much doubt).
>>>>>>>
>>>>>>>                             On Sun, Dec 3, 2017 at 2:29 PM, Michael Ennen <mike.ennen at gmail.com> <mailto:mike.ennen at gmail.com>
>>>>>>>                             wrote:
>>>>>>>
>>>>>>>                                 
>>>>>>>>                             I have created a (small) proposal (building on the work of Benjamin
>>>>>>>>                             Gudehaus) about moving some classes in to the public API so that TestFX (a
>>>>>>>>                             JavaFX UI testing framework) can continue to work with future JDK releases.
>>>>>>>>                             The somewhat nicely formatted proposal can be found as a Github gist:
>>>>>>>>
>>>>>>>>                             https://gist.github.com/brcolow/26370db6cab0355186d4a1d13b30fc19 <https://gist.github.com/brcolow/26370db6cab0355186d4a1d13b30fc19>
>>>>>>>>
>>>>>>>>                             All suggested changes can be found by using Github Compare View:
>>>>>>>>
>>>>>>>>                             https://github.com/brcolow/openjfx/compare/4ccdbbbce5234e2c5 <https://github.com/brcolow/openjfx/compare/4ccdbbbce5234e2c5>
>>>>>>>>                             e1f4f1cb8f20430feaa53b6...master
>>>>>>>>
>>>>>>>>                             But I have copied it to this email for convenience:
>>>>>>>>
>>>>>>>>                             ----------------------- PROPOSAL -----------------------
>>>>>>>>
>>>>>>>>                             TestFX, the JavaFX GUI testing framework currently requires 4 (four)
>>>>>>>>                             classes that are part of the JDK's private API. They are:
>>>>>>>>
>>>>>>>>                             [com.sun.glass.ui.Application](http://hg.openjdk.java.net/op
>>>>>>>>                             enjfx/10-dev/rt/file/tip/modules/javafx.graphics/src/main/
>>>>>>>>                             java/com/sun/glass/ui/Application.java)
>>>>>>>>                             [com.sun.glass.ui.Pixels](http://hg.openjdk.java.net/openjfx <http://hg.openjdk.java.net/openjfx>
>>>>>>>>                             /10-dev/rt/file/tip/modules/javafx.graphics/src/main/java/
>>>>>>>>                             com/sun/glass/ui/Pixels.java)
>>>>>>>>                             [com.sun.glass.ui.Robot](http://hg.openjdk.java.net/openjfx/ <http://hg.openjdk.java.net/openjfx/>
>>>>>>>>                             10-dev/rt/file/tip/modules/javafx.graphics/src/main/java/com
>>>>>>>>                             /sun/glass/ui/Robot.java)
>>>>>>>>                             [com.sun.javafx.application.Pa <http://com.sun.javafx.application.Pa>rametersImpl](http://hg.openjd
>>>>>>>>                             k.java.net/openjfx/10-dev/rt/file/tip/modules/javafx.
>>>>>>>>                             graphics/src/main/java/com/sun/javafx/application/ParametersImpl.java <http://k.java.net/openjfx/10-dev/rt/file/tip/modules/javafx.graphics/src/main/java/com/sun/javafx/application/ParametersImpl.java>)
>>>>>>>>
>>>>>>>>                             In order to compile the project with Java 9, we use the following flags:
>>>>>>>>
>>>>>>>>                             ```sh
>>>>>>>>                             --add-exports javafx.graphics/com.sun.glass.ui=org.testfx
>>>>>>>>                             --add-exports javafx.graphics/com.sun.javafx.application=org.testfx
>>>>>>>>                             ```
>>>>>>>>
>>>>>>>>                             If the --add-exports flags are disabled in a future Java release TestFX
>>>>>>>>                             will require these four classes to be moved into the public API to
>>>>>>>>                             continue working.
>>>>>>>>
>>>>>>>>                             While these classes are probably not very useful for applications to use
>>>>>>>>                             directly, any JavaFX application wanting to write UI tests will most
>>>>>>>>                             likely
>>>>>>>>                             use TestFX and thus they will indirectly be using these classes.
>>>>>>>>
>>>>>>>>                             JavaFX internal tests also use these classes for essentially the same
>>>>>>>>                             purpose (UI tests).
>>>>>>>>
>>>>>>>>                             ### Details of Usage For Each Private API Class
>>>>>>>>
>>>>>>>>                             #### com.sun.javafx.application.ParametersImpl
>>>>>>>>
>>>>>>>>                             ##### TestFX Usage
>>>>>>>>
>>>>>>>>                             ```java
>>>>>>>>                             ParametersImpl parameters = new ParametersImpl(applicationArgs);
>>>>>>>>                             ParametersImpl.registerParameters(application, parameters);
>>>>>>>>                             ```
>>>>>>>>
>>>>>>>>                             The parameters are set on a constructed Application.
>>>>>>>>
>>>>>>>>                             ##### Suggested Public API Replacement
>>>>>>>>
>>>>>>>>                             `javafx.application.Application`:
>>>>>>>>
>>>>>>>>                             ```java
>>>>>>>>                             /**
>>>>>>>>                              * Sets the parameters for this Application.
>>>>>>>>                              *
>>>>>>>>                              * <p>
>>>>>>>>                              * NOTE: this method should not be called from the Application
>>>>>>>>                             constructor,
>>>>>>>>                              * as it will return null. It may be called in the init() method or any
>>>>>>>>                              * time after that.
>>>>>>>>                              * </p>
>>>>>>>>                              *
>>>>>>>>                              * @param parameters the parameters to set for this Application
>>>>>>>>                              */
>>>>>>>>                             public final Parameters setParameters(String... parameters) {
>>>>>>>>                                 ParametersImpl parameters = new ParametersImpl(parameters);
>>>>>>>>                                 ParametersImpl.registerParameters(this, parameters);
>>>>>>>>                             }
>>>>>>>>                             ```
>>>>>>>>
>>>>>>>>                             #### com.sun.glass.ui.Application
>>>>>>>>
>>>>>>>>                             ##### TestFX Usage
>>>>>>>>
>>>>>>>>                             ```java
>>>>>>>>                             return Application.GetApplication().createRobot();
>>>>>>>>                             ```
>>>>>>>>
>>>>>>>>                             The Application class is used to instantiate a Robot.
>>>>>>>>
>>>>>>>>                             ##### Suggested Public API Replacement
>>>>>>>>
>>>>>>>>                             `javafx.application.Application`:
>>>>>>>>
>>>>>>>>                             https://github.com/brcolow/openjfx/blob/master/modules/javaf <https://github.com/brcolow/openjfx/blob/master/modules/javaf>
>>>>>>>>                             x.graphics/src/main/java/javafx/application/Application.java#L527
>>>>>>>>
>>>>>>>>                             #### com.sun.glass.ui.Pixels
>>>>>>>>
>>>>>>>>                             ##### TestFX Usage
>>>>>>>>
>>>>>>>>                             ```java
>>>>>>>>                             @Override
>>>>>>>>                             public Image getCaptureRegion(Rectangle2D region) {
>>>>>>>>                                 return waitForAsyncFx(RETRIEVAL_TIMEOUT_IN_MILLIS, () -> {
>>>>>>>>                                     Pixels glassPixels = useRobot().getScreenCapture(
>>>>>>>>                                         (int) region.getMinX(), (int) region.getMinY(),
>>>>>>>>                                         (int) region.getWidth(), (int) region.getHeight()
>>>>>>>>                                     );
>>>>>>>>                                     return convertFromGlassPixels(glassPixels);
>>>>>>>>                                 });
>>>>>>>>                             }
>>>>>>>>
>>>>>>>>                             private Image convertFromGlassPixels(Pixels glassPixels) {
>>>>>>>>                                 int width = glassPixels.getWidth();
>>>>>>>>                                 int height = glassPixels.getHeight();
>>>>>>>>                                 WritableImage image = new WritableImage(width, height);
>>>>>>>>
>>>>>>>>                                 int bytesPerComponent = glassPixels.getBytesPerComponent();
>>>>>>>>                                 if (bytesPerComponent == INT_BUFFER_BYTES_PER_COMPONENT) {
>>>>>>>>                                     IntBuffer intBuffer = (IntBuffer) glassPixels.getPixels();
>>>>>>>>                                     writeIntBufferToImage(intBuffer, image);
>>>>>>>>                                 }
>>>>>>>>
>>>>>>>>                                 return image;
>>>>>>>>                             }
>>>>>>>>
>>>>>>>>                             private void writeIntBufferToImage(IntBuffer intBuffer,
>>>>>>>>                                                                WritableImage image) {
>>>>>>>>                                 PixelWriter pixelWriter = image.getPixelWriter();
>>>>>>>>                                 double width = image.getWidth();
>>>>>>>>                                 double height = image.getHeight();
>>>>>>>>
>>>>>>>>                                 for (int y = 0; y < height; y++) {
>>>>>>>>                                     for (int x = 0; x < width; x++) {
>>>>>>>>                                         int argb = intBuffer.get();
>>>>>>>>                                         pixelWriter.setArgb(x, y, argb);
>>>>>>>>                                     }
>>>>>>>>                                 }
>>>>>>>>                             }
>>>>>>>>                             ```
>>>>>>>>
>>>>>>>>                             Pixels is used to create a screen capture.
>>>>>>>>
>>>>>>>>                             ##### Suggested Public API Replacement
>>>>>>>>
>>>>>>>>                             Bypass needing to expose the Pixels class to the public API by
>>>>>>>>                             changing the getScreenCapture method of Robot - that is, changing:
>>>>>>>>
>>>>>>>>                             `public Pixels getScreenCapture(int x, int y, int width, int height)`
>>>>>>>>
>>>>>>>>                             to:
>>>>>>>>
>>>>>>>>                             `public Image getScreenCapture(int x, int y, int width, int height)`
>>>>>>>>
>>>>>>>>                             #### com.sun.glass.ui.Robot
>>>>>>>>
>>>>>>>>                             ##### TestFX Usage
>>>>>>>>
>>>>>>>>                             Essentially every method of Robot is used:
>>>>>>>>
>>>>>>>>                             ```
>>>>>>>>                             public void keyPress(int code)
>>>>>>>>                             public void keyRelease(int code)
>>>>>>>>                             public int getMouseX()
>>>>>>>>                             public int getMouseY()
>>>>>>>>                             public void mouseMove(int x, int y)
>>>>>>>>                             public void mousePress(int buttons)
>>>>>>>>                             public void mouseRelease(int buttons)
>>>>>>>>                             public void mouseWheel(int wheelAmt)
>>>>>>>>                             public int getPixelColor(int x, int y)
>>>>>>>>                             public Pixels getScreenCapture(int x, int y, int width, int height)
>>>>>>>>                             ```
>>>>>>>>
>>>>>>>>                             ##### Suggested Public API Replacement
>>>>>>>>
>>>>>>>>                             https://github.com/brcolow/openjfx/blob/master/modules/javaf <https://github.com/brcolow/openjfx/blob/master/modules/javaf>
>>>>>>>>                             x.graphics/src/main/java/javafx/scene/robot/Robot.java
>>>>>>>>
>>>>>>>>
>>>>>>>>                             --
>>>>>>>>                             Michael Ennen
>>>>>>>>
>>>>>>>>                                   
>>>>>>>                             --
>>>>>>>                             Michael Ennen
>>>>>>>
>>>>>>>                                 
>>>>>>                               
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>                         -- 
>>>>>                         Michael Ennen
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>                     -- 
>>>>>                     Michael Ennen
>>>>
>>>>
>>>>
>>>>
>>>>                 -- 
>>>>                 Michael Ennen
>>>
>>>
>>>
>>>
>>>             -- 
>>>             Michael Ennen
>>>
>>>
>>>
>>>
>>>         -- 
>>>         Michael Ennen
>>
>>
>>
>>
>>     -- 
>>     Michael Ennen
>
>
>
>
> -- 
> Michael Ennen


More information about the openjfx-dev mailing list