为何部分JDK 17/JavaFX 17发行版中Background.fill方法报缺失错误?
我编写的代码在捆绑FX的Azul Zulu SDK(17.0.8+7)中可正常运行,但使用无捆绑的Azul Zulu SDK(17.0.8+7)+ Gluon JavaFX SDK时,抛出如下错误:
Exception in thread "JavaFX Application Thread" java.lang.NoSuchMethodError: 'javafx.scene.layout.Background javafx.scene.layout.Background.fill(javafx.scene.paint.Paint)'
该问题在捆绑FX的Liberica JDK 17.0.8+7中同样存在。看起来Background.fill()方法仅在捆绑FX的Zulu JDK中可用,在独立Gluon JavaFX库或捆绑FX的Liberica JDK中不可用。
原代码如下:
void setgradient(Pane bpane, boolean b, String color) { if (b) { bpane.setBackground(Background.fill(new LinearGradient( 0, 0, 1, 1, true, //sizing CycleMethod.NO_CYCLE, //cycling new Stop(0, Color.web("#5e89b1")), //colors new Stop(1, Color.web("#68a5de"))))); } else { bpane.setBackground(Background.fill(new LinearGradient( 0, 0, 1, 1, true, //sizing CycleMethod.NO_CYCLE, //cycling new Stop(0, Color.web("#7d7b75")), //colors new Stop(1, Color.web("#dedbd3"))))); } }
Background.fill()并不是OpenJFX官方标准API中的方法,它是Azul Zulu针对自身捆绑的JavaFX版本额外添加的私有扩展方法。其他发行版(比如Gluon提供的标准OpenJFX、Liberica捆绑的JavaFX)严格遵循OpenJFX官方规范,没有实现这个非标准的扩展方法,因此调用时会抛出NoSuchMethodError。
要实现相同的背景填充效果,只需使用OpenJFX官方标准API即可——通过Background的构造方法,结合BackgroundFill来创建背景:
修改后的代码如下:
void setgradient(Pane bpane, boolean b, String color) { LinearGradient gradient; if (b) { gradient = new LinearGradient( 0, 0, 1, 1, true, CycleMethod.NO_CYCLE, new Stop(0, Color.web("#5e89b1")), new Stop(1, Color.web("#68a5de"))); } else { gradient = new LinearGradient( 0, 0, 1, 1, true, CycleMethod.NO_CYCLE, new Stop(0, Color.web("#7d7b75")), new Stop(1, Color.web("#dedbd3"))); } // 使用标准API创建背景 BackgroundFill backgroundFill = new BackgroundFill(gradient, CornerRadii.EMPTY, Insets.EMPTY); bpane.setBackground(new Background(backgroundFill)); }
关键说明:
BackgroundFill是官方标准类,用于定义背景填充样式,参数依次为:填充画刷(此处为渐变)、圆角半径、内边距- 传入
CornerRadii.EMPTY和Insets.EMPTY可以模拟原fill()方法默认的无圆角、无内边距效果 - 这种写法在所有遵循OpenJFX标准的发行版中都能正常运行,包括Gluon JavaFX、Liberica捆绑FX等
内容的提问来源于stack exchange,提问作者blm99

