使用Java SDK 12的JFXTextField的IllegalAccessException [英] IllegalAccessException for JFXTextField with java sdk 12
问题描述
我在javafx应用程序中添加了JFXTextField,但出现此错误却不知道如何解决
I added JFXTextField in my javafx application but I got this error with no clue how to solve it
com.jfoenix.skins.JFXTextFieldSkin类(在com.jfoenix模块中)无法访问带有修饰符私有"的javafx.scene.control.skin.TextFieldSkin类(在javafx.controls模块中)的成员
class com.jfoenix.skins.JFXTextFieldSkin (in module com.jfoenix) cannot access a member of class javafx.scene.control.skin.TextFieldSkin (in module javafx.controls) with modifiers "private"
控制器:
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
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>
推荐答案
JFoenix的问题跟踪器已经报告了此问题:
This issue has already been reported at the JFoenix's issue tracker:
- JDK 12 incompatible
- IllegalAccessException for JFXTextField / JFXPasswordField with JDK12
对于初学者来说,JFoenix尚未真正为Java 11+做好准备.该发行版本适用于Java 9,但仍可以与Java 11和JavaFX 11一起使用,只要您添加JavaFX依赖项即可.
For starters, JFoenix is not really ready for Java 11+. The released version is intended for Java 9, but it still works with Java 11 and JavaFX 11, providing you add the JavaFX dependencies.
但是,在JDK 12下它无法运行,并且该问题与JavaFX无关:即使使用JavaFX 11.0.2,它仍然会失败.
However, under JDK 12 it fails to run, and the issue is not JavaFX related: even with JavaFX 11.0.2 it still fails.
The issue is related to the use of reflection to access the Text
node of TextFieldSkin
:
textNode = ReflectionHelper.getFieldContent(TextFieldSkin.class, this, "textNode");
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)
尽管在Java 11.0.2之前,它在Java 12中仍然可以正常运行 a 回归 unsafe
中的最新更改阻止了此操作,并导致textNode = null
.
While this worked fine up until Java 11.0.2, with Java 12 a regression recent changes in unsafe
prevents this from working, and causes textNode = null
.
@AlanBateman在下面的评论中提到:
As @AlanBateman mentions in his comments below:
[JFoenix维护者]应该替换其
setAccessible
方法来调用obj.setAccessible(true)
,以便在库尝试破解无法访问的内部结构时,用户获得正确的异常.如果这样做,那么用户可以使用--add-exports
或--add-opens
选项解决这些问题,直到库的维护者修复其问题为止.
[The JFoenix maintainers] should replace their
setAccessible
method to callobj.setAccessible(true)
so that the user gets the right exceptions when the library tries to hack internals that are not accessible to it. If you do that then the user can workaround those issues with--add-exports
or--add-opens
options until the maintainers of the library fix their issues.
目前,这意味着要坚持使用JDK 11.
For now this will mean sticking to JDK 11.
或者,您可以尝试构建自己的JFoenix版本,克隆存储库(分支9.0.0),并进行必要的更改以使其与JavaFX 11+兼容(超出此答案的范围...),并且尽可能取消使用反射.
Alternatively, you could try to build your own JFoenix version, cloning the repo (branch 9.0.0) and making the necessary changes to make it work with JavaFX 11+ (out of scope of this answer...), and removing the use of reflection where possible.
例如,textNode
可以直接通过以下方式检索:
For instance, the textNode
can be directly retrieved with:
textNode = textPane.getChildren().get(1);
或者,仍然依靠反射,但是提到了适当的更改:
or, still rely on reflection, but with the proper changes mentioned:
try {
Field field = cls.getDeclaredField(fieldName);
field.setAccessible(true); // <-- Use this.
return (T) field.get(obj);
} catch (Throwable ex) { }
结合:
--add-exports=javafx.controls/javafx.scene.control.skin=$moduleName
这篇关于使用Java SDK 12的JFXTextField的IllegalAccessException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!