如果关键帧动画可以在FML中指定,那么许多包含动画的文件格式就可以移植到FML,而不会丢失信息.我知道RotateTransition等更简单的变体.

将KeyValue目标声明为$text.translateX(或我能想到的其他变体)的最简单方法会导致类型判断运行时错误. 经过一番摆弄,我设法想出了不会出错的代码,但目标绑定似乎也没有发生.我为此在控制器中添加了一行,以便可以轻松测试想要的行为.如何才能摆脱这一行并使其仅与FML一起工作?它不应该也适用于$text.translateX吗?

animated.fxml

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

<?import javafx.animation.*?>
<?import javafx.beans.property.SimpleDoubleProperty?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.Group?>
<?import javafx.scene.Scene?>
<?import javafx.scene.text.Text?>
<?import javafx.util.Duration?>
<?import java.lang.Double?>
<Scene xmlns:fx="http://javafx.com/fxml" fx:controller="org.example.demo.AnimatedController">
    <height>240.0</height>
    <width>320.0</width>
    <fx:define>
        <SimpleDoubleProperty fx:id="count"/>
        <Timeline fx:id="timeline">
            <keyFrames>
                <fx:define>
                    <Double fx:id="endValue0" fx:value="0.0"/>
                    <Double fx:id="endValue1" fx:value="100.0"/>
                </fx:define>
                <KeyFrame fx:id="keyFrame0">
                    <values>
                        <KeyValue fx:id="keyValue0" endValue="$endValue0">
                            <target>
                                <fx:reference source="count"/>
                            </target>
                        </KeyValue>
                    </values>
                    <time>
                        <Duration fx:constant="ZERO"/>
                    </time>
                </KeyFrame>
                <KeyFrame fx:id="keyFrame1">
                    <values>
                        <KeyValue fx:id="keyValue1" endValue="$endValue1">
                            <target>
                                <fx:reference source="count"/>
                            </target>
                        </KeyValue>
                    </values>
                    <time>
                        <Duration millis="1000"/>
                    </time>
                </KeyFrame>
            </keyFrames>
        </Timeline>
    </fx:define>
    <Group>
        <Text fx:id="text" y="60" x="${count.value}">Hello, World!</Text>
        <Button onAction="#play">Play</Button>
    </Group>
</Scene>

AnimatedController.java

package org.example.demo;

import javafx.animation.Timeline;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.text.Text;

public class AnimatedController {

    @FXML
    private Text text;

    @FXML
    private Timeline timeline;

    @FXML
    private SimpleDoubleProperty count = new SimpleDoubleProperty(0);

    public void play(ActionEvent ignoredActionEvent) {
        text.xProperty().bind(count); // without this line, text.getX() doesn't get updated
        count.addListener((_, oldVal, newVal) -> System.out.printf("%s, %s, %s\n", text.getX(), oldVal, newVal));
        timeline.play();
    }
}

HelloApplication.java

package org.example.demo;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class HelloApplication extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("animated.fxml"));
        Scene scene = fxmlLoader.load();
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}

推荐答案

通过一些实验,以下方法有效:

<KeyValue target="$someNode.translateXProperty" endValue="..."/>

为什么这有效?不确定.我在Introduction to FXML文件中找不到任何解释这种行为的信息,但也许其他人知道它是否被记录在哪里.也就是说,显然使用xxxProperty会给您提供与xxx相关的实际property,而不仅仅是属性的value.

请注意,此解决方案使得中间属性变得不必要.


Example

使用RDX 22进行测试(但不使用其他RDX版本).

Main.java

package com.example;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;

public class Main extends Application {

  @Override
  public void start(javafx.stage.Stage primaryStage) throws Exception {
    var loader = new FXMLLoader();
    loader.setLocation(Main.class.getResource("/Main.fxml"));

    var root = loader.<Parent>load();
    var controller = loader.<Controller>getController();

    primaryStage.setScene(new Scene(root, 600, 400));
    primaryStage.show();

    controller.playAnimation();
  }
}

Controller.java

package com.example;

import javafx.animation.Timeline;
import javafx.fxml.FXML;

public class Controller {

  @FXML private Timeline timeline;

  public void playAnimation() {
    timeline.play();
  }
}

Main.fxml

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

<?import java.lang.Double?>
<?import javafx.animation.Animation?>
<?import javafx.animation.KeyFrame?>
<?import javafx.animation.KeyValue?>
<?import javafx.animation.Timeline?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.util.Duration?>

<StackPane xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml"
    fx:controller="com.example.Controller">

    <Label fx:id="label" text="Hello, World!" />

    <fx:define>
        <Double fx:id="fromValue" fx:value="-100.0" />
        <Double fx:id="toValue" fx:value="100.0" />

        <Duration fx:id="startTime" fx:constant="ZERO" />
        <Duration fx:id="endTime" millis="1000.0" />

        <Timeline fx:id="timeline" autoReverse="true">
            <cycleCount>
                <Animation fx:constant="INDEFINITE" />
            </cycleCount>
            <keyFrames>
                <KeyFrame time="$startTime">
                    <values>
                        <KeyValue target="$label.translateXProperty" endValue="$fromValue" />
                    </values>
                </KeyFrame>
                <KeyFrame time="$endTime">
                    <values>
                        <KeyValue target="$label.translateXProperty" endValue="$toValue" />
                    </values>
                </KeyFrame>
            </keyFrames>
        </Timeline>
    </fx:define>

</StackPane>

Java相关问答推荐

如何跟踪我在数组中的位置

有没有方法可以修复错误错误:无法初始化主类code_editor?

int Array Stream System. out. print方法在打印Java8时在末尾添加% sign

Javascript在边界中心调整ImageView大小

名称冲突具有相同的擦除

Java LocalTime.parse在本地PC上的Spring Boot中工作,但在Docker容器中不工作

相同的Java SerializedLambda为implMethodKind返回不同的结果

更新GWT 2.5.1到2.11.0和sencha GXT 3.1.1到4.1时出现错误

返回响应时,CamelCase命名约定不起作用

将java.util.Date转换为OffsetDateTime

Javadoc在方法摘要中省略方法

使用多个RemoteDatabase对象的一个线程

在Spring Boot应用程序中,server.port=0的默认端口范围是多少?

我的代码是线程安全的吗?[Java、CAS、转账]

Java Flux中的延迟增加

";home/runner/work/中没有文件...匹配到[**/pom.xml];Maven项目的构建过程中出现错误

获取401未经授权,即使在标头中设置了浏览器名称和cookie

始终使用Spring Boot连接mongodb上的测试数据库

放置在变量中的Java成员引用不相等

";重复键的值提示唯一约束«;livre_genre_pkey»";例外