ControlsFX should support Java 9

Issue #780 new
Abhinay Agarwal
created an issue

This issue will be used for all discussions while we try to migrate ControlsFX to Java 9.

Background:

ControlsFX already has a branch "9.0.0" for all the Java 9 related changes with few controls that are already Java 9 compliant.

Current Status:

The following controls are broken and needs to be fixed:

  • BreadCrumbBar
  • FilterPanel
  • GlyphFont
  • GridView
  • NotificationPane
  • SegmentBar
  • SpreadSheetView
  • SVGLoader
  • TableRowExpanderColumn

Also, we need to change the way "VersionChecker" works since in Java 9 we have a new way to check version and we may want to use the public API Runtime#version.

Approach

Since few controls mentioned above uses internal APIs, we would have to export the respective packages (mostly behavior and traversal) from their respective modules so that the code can compile.

To be able to use few restricted methods and fields, we will fall back to reflection. This may again need opening up few modules and exporting packages.

Update

23 Sep, 2017

  • Remove SpreadSheetView until someone fix them for good.
  • Added a fix for GridView

Comments (26)

  1. Florian Brunner

    The crumbFactory of BreadCrumbBar seems to expect that an instance of the internal BreadCrumbButton gets returned.

    Solution 1: move BreadCrumbButton to the org.controlsfx.control package (how could custom skins override this? how can the API be fixed to make this more clear?).

    Solution 2: Adopt a cell-subclass approach (see ListCell/ TreeCell; though BreadCrumbBar does not manage a huge amount of data, I guess).

    Solution 3: provide crumbTextFactory and crumbGraphicFactory, which provide the text and graphic for the TreeItems. The skin could create the BreadCrumbButton itself.

  2. Thomas Andres

    I have a JavaFx application that uses webstart. When I use webstart, I need to add the vm option: java-vm-args="--add-opens=javafx.base/com.sun.javafx.event=ALL-UNNAMED" otherwise I get runtime errors:

    java.lang.IllegalAccessError: class org.controlsfx.control.textfield.AutoCompletionBinding (in unnamed module @0x2954d3b6) cannot access class com.sun.javafx.event.EventHandlerManager (in module javafx.base) because module javafx.base does not export com.sun.javafx.event to unnamed module @0x2954d3b6
            at org.controlsfx.control.textfield.AutoCompletionBinding.<init>(AutoCompletionBinding.java:521)
    
  3. Thomas Andres

    Without webstart the issue doesn't occur.

    It's possible though, that it's also related to my build for webstart. I package my app and all libs in a fat jar and sign that jar. But when I run that jar with java -jar, the error also doesn't occur.

  4. Jens Deters

    I have issues when using the GridView with Java 9:

    Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private final javafx.scene.control.skin.VirtualFlow javafx.scene.control.skin.VirtualContainerBase.flow accessible: module javafx.controls does not "opens javafx.scene.control.skin" to unnamed module @1b1871b2
    
  5. SamirH

    @Abdullah Asendar I am one of the developer working and using the SpreadsheetView. Like Abhinay said, JDK 9 brings lots of changes. The SpreadsheetView was using quite a lot of internal API because it provides lots of features that were difficult to do without.

    Right now, I do not have the bandwidth to work on the SpreadsheetView. In JDK9, the access to VirtualFlow was cut thus depriving the SpreadsheetView from its core mechanism. Without this access, the SpreadsheetView won't work. So if anyone has time to work on that issue, I'll gladly help, but right now, the SpreadsheetView won't be compatible with JDK 9.

  6. SamirH

    Any contribution to ControlsFX is welcomed. I just want to warn you that a lot of the SpreadsheetView internal API have been removed and it will be tough to migrate the SpreadsheetView towards JDK9. But you can give it a try. Maybe a solution will be to deliver a functional SpreadsheetView with limited features. Don't hesitate to ping me if you need some help.

  7. acuriousbison NA

    @Abhinay Agarwal With PR#700 there is a similar error now when using a GridView:

    Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make void javafx.scene.control.skin.VirtualFlow.rebuildCells() accessible: module javafx.controls does not "opens javafx.scene.control.skin" to unnamed module @5e4c75bf
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337)
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:281)
        at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:198)
        at java.base/java.lang.reflect.Method.setAccessible(Method.java:192)
        at impl.org.controlsfx.ReflectionUtils.rebuildCells(ReflectionUtils.java:83)
        at impl.org.controlsfx.skin.GridViewSkin.updateItemCount(GridViewSkin.java:131)
        at impl.org.controlsfx.skin.GridViewSkin.updateGridViewItems(GridViewSkin.java:95)
        at impl.org.controlsfx.skin.GridViewSkin.<init>(GridViewSkin.java:53)
        at org.controlsfx.control.GridView.createDefaultSkin(GridView.java:142)
    
  8. acuriousbison NA

    @Abhinay Agarwal The following sample produces the error:

    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    import org.controlsfx.control.GridView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Main extends Application {
        public static void main(String[] args) {
            launch(args);
        }
    
        @Override
        public void start(Stage primaryStage) throws Exception {
            List<String> items = new ArrayList<>();
            for (int i = 0; i < 100; i++) {
                items.add("item" + i);
            }
    
            GridView<String> gridView = new GridView<>();
            gridView.setPrefSize(200, 200);
            gridView.getItems().setAll(items);
    
            Scene scene = new Scene(gridView);
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    }
    
  9. Log in to comment