Java sdk 12的JFXTextField的IllegalAccessException

时间:2019-04-28 11:10:22

标签: java javafx jfoenix

我在javafx应用程序中添加了JFXTextField,但出现此错误却不知道如何解决

  

com.jfoenix.skins.JFXTextFieldSkin类(在com.jfoenix模块中)无法访问带有修饰符“私有”的javafx.scene.control.skin.TextFieldSkin类(在javafx.controls模块中)的成员

控制器:

package sample;

import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXTextField;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;

import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable {

@FXML
private Button clickMe;


@FXML
private JFXButton materialButton;

@FXML
private JFXTextField textField;


@Override
public void initialize(URL url, ResourceBundle resourceBundle) {

    materialButton.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent actionEvent)
        {
            String text = textField.getText().trim();
            System.out.println(text);
        }
    });

}
}

Sample.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXTextField?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: #fcda;" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <children>
      <Button fx:id="clickMe" layoutX="198.0" layoutY="188.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="225.0" style="-fx-background-color: #fffe;" text="Click Me" textFill="#722929" />
      <JFXButton fx:id="materialButton" layoutX="231.0" layoutY="82.0" prefHeight="54.0" prefWidth="139.0" style="-fx-background-color: #ffff;" textFill="#280c0c">
         <font>
            <Font size="25.0" />
         </font></JFXButton>
      <JFXTextField fx:id="textField" layoutX="233.0" layoutY="24.0" promptText="Enter UserName" />
   </children>
</AnchorPane>

1 个答案:

答案 0 :(得分:6)

JFoenix的问题跟踪器已经报告了此问题:

对于初学者来说,JFoenix尚未真正为Java 11+做好准备。该发行版本适用于Java 9,但仍可以与Java 11和JavaFX 11一起使用,只要您添加JavaFX依赖项即可。

但是,在JDK 12下它无法运行,并且该问题与JavaFX无关:即使使用JavaFX 11.0.2,它仍然会失败。

问题与使用reflection访问Text的{​​{1}}节点有关:

TextFieldSkin
textNode = ReflectionHelper.getFieldContent(TextFieldSkin.class, this, "textNode");

尽管此方法在Java 11.0.2之前都可以正常使用,而Java 12 a regression java.lang.IllegalAccessException: class com.jfoenix.adapters.ReflectionHelper (in module com.jfoenix) cannot access a member of class javafx.scene.control.skin.TextFieldSkin (in module javafx.controls) with modifiers "private" at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:355) at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:639) at java.base/java.lang.reflect.Field.checkAccess(Field.java:1075) at java.base/java.lang.reflect.Field.get(Field.java:416) at com.jfoenix/com.jfoenix.adapters.ReflectionHelper.getFieldContent(ReflectionHelper.java:98) at com.jfoenix/com.jfoenix.skins.JFXTextFieldSkin.<init>(JFXTextFieldSkin.java:59) 中的最新更改阻止了此操作,并导致unsafe

@AlanBateman在下面的评论中提到:

  

[JFoenix维护者]应该替换其textNode = null方法来调用setAccessible,以便在库尝试破解无法访问的内部结构时,用户获得正确的异常。如果这样做,则用户可以使用obj.setAccessible(true)--add-exports选项解决这些问题,直到库的维护者解决他们的问题为止。

目前,这意味着要坚持使用JDK 11。

或者,您可以尝试构建自己的JFoenix版本,克隆存储库(分支9.0.0),并进行必要的更改以使其与JavaFX 11+兼容(超出此答案的范围...),并且尽可能避免使用反射。

例如,--add-opens可以直接通过以下方式检索:

textNode

或者,仍然依靠反射,但是提到了适当的更改:

textNode = textPane.getChildren().get(1);

结合:

try {
    Field field = cls.getDeclaredField(fieldName);
    field.setAccessible(true); // <-- Use this.
    return (T) field.get(obj);
} catch (Throwable ex) { }