Proposal For Inclusion of Robot and ParametersImpl in the Public API

Michael Ennen mike.ennen at gmail.com
Wed Dec 20 21:08:37 UTC 2017


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
> 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
>
> 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> 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>
>> 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> 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> <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> <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
>>>>
>>>> All suggested changes can be found by using Github Compare View:
>>>> 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
>>>> /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/
>>>> 10-dev/rt/file/tip/modules/javafx.graphics/src/main/java/com
>>>> /sun/glass/ui/Robot.java)
>>>> [com.sun.javafx.application.ParametersImpl](http://hg.openjdk.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
>>>> 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
>>>> x.graphics/src/main/java/javafx/scene/robot/Robot.java
>>>>
>>>>
>>>> --
>>>> Michael Ennen
>>>>
>>>>
>>>>
>>>> --
>>>> Michael Ennen
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>> --
>>> Michael Ennen
>>>
>>
>>
>>
>> --
>> Michael Ennen
>>
>>
>
>
> --
> Michael Ennen
>
>


-- 
Michael Ennen


More information about the openjfx-dev mailing list