当前位置: 首页 > 知识库问答 >
问题:

JavaFX FXML:无法绑定到静态属性

公冶森
2023-03-14

我正在尝试创建一个用于多屏幕分辨率(也是高分辨率)的JavaFX应用程序。

-- exec-maven-plugin:1.2.1:exec (default-cli) @ SecureChat ---
dec 04, 2014 10:13:50 AM securechat.helpers.CustomStage initialize
SEVERE: null
javafx.fxml.LoadException: Cannot bind to static property.
file:/D:/private_java/SecureChat/target/SecureChat-1.0-SNAPSHOT.jar!/fxml/main.fxml:24

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2591)
    at javafx.fxml.FXMLLoader.access$100(FXMLLoader.java:104)
    at javafx.fxml.FXMLLoader$Element.processPropertyAttribute(FXMLLoader.java:291)
    at javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:771)
    at javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2817)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2526)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2435)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2403)
    at securechat.helpers.CustomStage.initialize(CustomStage.java:111)
    at securechat.helpers.CustomStage.<init>(CustomStage.java:104)
    at securechat.MainApp.start(MainApp.java:40)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821)
    at com.sun.javafx.application.LauncherImpl$$Lambda$51/967161415.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323)
    at com.sun.javafx.application.PlatformImpl$$Lambda$45/584634336.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292)
    at com.sun.javafx.application.PlatformImpl$$Lambda$47/1040960283.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291)
    at com.sun.javafx.application.PlatformImpl$$Lambda$46/501263526.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$141(WinApplication.java:102)
    at com.sun.glass.ui.win.WinApplication$$Lambda$37/96639997.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)

Exception in Application start method
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:363)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:303)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:875)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$147(LauncherImpl.java:157)
    at com.sun.javafx.application.LauncherImpl$$Lambda$48/815033865.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException: Root cannot be null
    at javafx.scene.Scene.<init>(Scene.java:313)
    at javafx.scene.Scene.<init>(Scene.java:181)
    at securechat.helpers.CustomStage.initialize(CustomStage.java:120)
    at securechat.helpers.CustomStage.<init>(CustomStage.java:104)
    at securechat.MainApp.start(MainApp.java:40)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821)
    at com.sun.javafx.application.LauncherImpl$$Lambda$51/967161415.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323)
    at com.sun.javafx.application.PlatformImpl$$Lambda$45/584634336.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292)
    at com.sun.javafx.application.PlatformImpl$$Lambda$47/1040960283.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291)
    at com.sun.javafx.application.PlatformImpl$$Lambda$46/501263526.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$141(WinApplication.java:102)
    at com.sun.glass.ui.win.WinApplication$$Lambda$37/96639997.run(Unknown Source)
    ... 1 more
Exception running application securechat.MainApp
------------------------------------------------------------------------
BUILD FAILURE
------------------------------------------------------------------------
Total time: 9.363s
Finished at: Thu Dec 04 10:13:51 CET 2014
Final Memory: 19M/265M
------------------------------------------------------------------------
Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.2.1:exec (default-cli) on project SecureChat: Command execution failed. Process exited with an error: 1 (Exit value: 1) -> [Help 1]

To see the full stack trace of the errors, re-run Maven with the -e switch.
Re-run Maven using the -X switch to enable full debug logging.

For more information about the errors and possible solutions, please read the following articles:
[Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

我正在使用以下代码段。

main.fxml

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

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import securechat.helpers.Scaling?>

<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="securechat.controllers.MainController">
    <children>
        <fx:define>
            <Scaling fx:id="dpi"></Scaling>
        </fx:define>
        <AnchorPane fx:id="chatsAnchorPane" maxWidth="${dpi.value*200}" minWidth="${dpi.value*200}" prefWidth="${dpi.value*200}" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0">
            <children>
                <Button fx:id="openNewChatWindowButton" onAction="#openNewChatDialog" text="%button.openNewChatDialog" prefHeight="${dpi.value*40}" maxHeight="${dpi.value*40}" minHeight="${dpi.value*40}" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
                <ListView fx:id="chatsListView" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="40.0" />
            </children>
        </AnchorPane>
        <AnchorPane fx:id="chatAnchorPane" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="${dpi.value*200}" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
            <children>
                <ListView fx:id="chatMessagesListView" AnchorPane.bottomAnchor="40.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
                <TextField fx:id="chatMessageTextField" onAction="#sendChatMessage" promptText="%textfield.chatMessagePrompt" maxHeight="${dpi.value*40}" minHeight="${dpi.value*40}" prefHeight="${dpi.value*40}"  AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" />
            </children>
        </AnchorPane>
    </children>
</AnchorPane>

Scaling.java

package securechat.helpers;

import java.awt.GraphicsEnvironment;

/**
 *
 */
public final class Scaling {

    public double value;

    public Scaling() {
        value = getDefaultScaling();
    }

    private double getDefaultScaling() {
        int width = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().width;
        return width / 1920;
    }

    public double getValue() {
        return value;
    }

}

共有1个答案

葛鸿熙
2023-03-14

经过html" target="_blank">调试,我发现在FXMLLoader类中有几个LinkedList 列表。一个if例如属性属性,如PrefHeight=“400.0”,另一个用于静态属性属性,如AnchorPane.bottomanchor=“0.0”

如果使用常规值,如PrefHeight=“400.0”或绑定表达式,如PrefWidth=“${DPI.value*200}”,则这些情况将在此方法ProcessPropertyAttribute()中处理。

对于绑定,有三个初步检查:

    @SuppressWarnings("unchecked")
    public void processPropertyAttribute(Attribute attribute) throws IOException {
        String value = attribute.value;
        if (isBindingExpression(value)) {
            // Resolve the expression
            Expression expression;

            if (attribute.sourceType != null) {
                throw constructLoadException("Cannot bind to static property.");
            }

            if (!isTyped()) {
                throw constructLoadException("Cannot bind to untyped object.");
            }

            if (this.value instanceof Builder) {
                throw constructLoadException("Cannot bind to builder property.");
            }
            // Evaluate the expression
            ...
       } else {
            processValue(attribute.sourceType, attribute.name, value);
       }

虽然prefwidth=“${dpi.value*200}”通过了这些检查,但相反,在AnchorPane.leftanchor=“${dpi.value*200}”上,您将发现它具有一个源类型:

attribute.sourceType = (java.lang.Class) class javafx.scene.layout.AnchorPane

因此,按照设计,这将发生:

if (attribute.sourceType != null) {
     throw constructLoadException("Cannot bind to static property.");
}

双向绑定也是不可能的:

if (isBidirectionalBindingExpression(value)) {
    throw constructLoadException(new UnsupportedOperationException("This feature is not currently enabled."));
}

表示静态属性的属性的处理方式与静态属性元素类似,并使用类似的语法。除了更简洁之外,静态属性属性(如实例属性属性)支持位置、资源和变量解析运算符,唯一的限制是不可能创建与静态属性绑定的表达式。

你得另想办法...

编辑

基于所提供的FXML,我建议避免静态属性的方法是使用hboxvbox,通过绑定使用所需的min/pref/max大小,包装控件。

类似这样的事情:

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

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import securechat.helpers.Scaling?>

<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="securechat.controllers.MainController">
    <children>
        <fx:define>
            <Scaling fx:id="dpi"></Scaling>
        </fx:define>
        <HBox AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"  AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
         <children>
            <VBox fx:id="chatsVBox" maxWidth="${dpi.value*200}" minWidth="${dpi.value*200}" prefWidth="${dpi.value*200}" HBox.hgrow="NEVER">
               <children>
                      <Button fx:id="openNewChatWindowButton" onAction="#openNewChatDialog" text="%button.openNewChatDialog" maxHeight="${dpi.value*40}" minHeight="${dpi.value*40}" prefHeight="${dpi.value*40}" prefWidth="${dpi.value*200}" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" VBox.vgrow="NEVER" />
                      <ListView fx:id="chatsListView" VBox.vgrow="ALWAYS" />
               </children>
            </VBox>
            <VBox fx:id="chatVBox" HBox.hgrow="ALWAYS">
               <children>
                      <ListView fx:id="chatMessagesListView"  VBox.vgrow="ALWAYS" />
                      <TextField fx:id="chatMessageTextField" onAction="#sendChatMessage" maxHeight="${dpi.value*40}" minHeight="${dpi.value*40}"  prefHeight="${dpi.value*40}" promptText="%textfield.chatMessagePrompt" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" VBox.vgrow="NEVER" />
               </children>
            </VBox>
         </children>
      </HBox>
    </children>
</AnchorPane>
 类似资料:
  • 问题内容: 我对动态绑定和静态绑定感到非常困惑。我已经读过,在编译时确定对象的类型称为静态绑定,而在运行时确定它的称为动态绑定。 下面的代码会发生什么: 静态绑定还是动态绑定? 这表明什么样的多态性? 问题答案: 您的示例是 动态绑定 ,因为在运行时确定类型是什么,并调用适当的方法。 现在假设您也具有以下两种方法: 即使您更改为 这将打印出来,因为对的调用使用 静态绑定 ,并且编译器仅知道其类型。

  • 静态绑定还是动态绑定? 这显示了什么样的多态性?

  • 我们知道静态绑定发生在私有、静态、最终和重载的方法上,而动态绑定发生在被覆盖的方法上。但是如果我的方法只是公共的,它既不是静态的,也不是覆盖和重载的怎么办? 有人能给我解释一下print()的绑定会怎样,因为它既没有重载也没有被覆盖。

  • 起初我是一个初学者 我看过很多教程,读过很多例子,甚至试图从JLS来理解这个主题,但我仍然有一些困惑或误解。 让我给你看我看不懂的问题。

  • 我们可以把一个方法赋值给类的函数本身,而不是赋给它的 "prototype"。这样的方法被称为 静态的(static)。 在一个类中,它们以 static 关键字开头,如下所示: class User { static staticMethod() { alert(this === User); } } User.staticMethod(); // true 这实际上跟直接将其

  • 本文向大家介绍java动态绑定和静态绑定用法实例详解,包括了java动态绑定和静态绑定用法实例详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了java动态绑定和静态绑定用法。分享给大家供大家参考,具体如下: 背景 1.当子类和父类存在同一个方法,子类重写了父类的方法,程序在运行时调用的是父类的方法还是子类的重写方法呢(尤其是存在向上类型转换的情况)? 2.当一个类中存在方法名相同但参数