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.rushfo...@oracle.com <mailto:kevin.rushfo...@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.en...@gmail.com <mailto:mike.en...@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.rushfo...@oracle.com
        <mailto:kevin.rushfo...@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.en...@gmail.com> 
<mailto:mike.en...@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.en...@gmail.com> 
<mailto:mike.en...@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

Reply via email to