【问题标题】:JavaFX animation on button hover按钮悬停时的 JavaFX 动画
【发布时间】:2018-04-14 23:43:56
【问题描述】:

我想在悬停按钮时制作动画,但如果我使用 CSS,则没有过渡,属性会立即更改。我尝试扩展按钮类并设置 onMouseEntered 属性,但如果这样做,我将无法再使用 SceneBuilder 打开 FXML 文件,因为它不知道我的子类扩展了 Button 类。那么我该怎么做才能让所有按钮在悬停或单击时都有过渡?

【问题讨论】:

  • 为什么不使用场景构建器添加鼠标点击或鼠标悬停监听器

标签: javafx


【解决方案1】:

您可以通过多种方式完成此操作,甚至可以让它在 Scene Builder 上运行。

我首先将按钮皮肤子类化,您可以在其中添加带有动画的事件处理程序。在这种情况下,让我们有一个淡入/淡出动画:

MyButtonSkin.java

public class MyButtonSkin extends ButtonSkin {

    public MyButtonSkin(Button control) {
        super(control);

        final FadeTransition fadeIn = new FadeTransition(Duration.millis(100));
        fadeIn.setNode(control);
        fadeIn.setToValue(1);
        control.setOnMouseEntered(e -> fadeIn.playFromStart());

        final FadeTransition fadeOut = new FadeTransition(Duration.millis(100));
        fadeOut.setNode(control);
        fadeOut.setToValue(0.5);
        control.setOnMouseExited(e -> fadeOut.playFromStart());

        control.setOpacity(0.5);
    }

}

现在您可以将此自定义皮肤应用到常规 JavaFX Button

一种方式,通过代码:

MyApplication.java

@Override
public void start(Stage primaryStage) throws IOException {
    Button btn = new Button("Button");
    btn.setSkin(new MyButtonSkin(btn));
    StackPane root = new StackPane(btn);
    Scene scene = new Scene(root, 300, 250);
    primaryStage.setScene(scene);
    primaryStage.show();
}

另一种选择是通过 css,让我们添加一个style.css 文件:

style.css

.button {
    -fx-skin: 'your.package.name.MyButtonSkin';
}

现在:

MyApplication.java

@Override
public void start(Stage primaryStage) throws IOException {
    Button btn = new Button("Button");
    StackPane root = new StackPane(btn);
    Scene scene = new Scene(root, 300, 250);
    scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());        
    primaryStage.setScene(scene);
    primaryStage.show();
}

在这两种情况下,当您运行应用程序时,按钮动画都会正常工作:

场景构建器

如果您现在将常规 JavaFX Button 添加到 FXML 文件:

FXML.fxml

<AnchorPane id="AnchorPane" prefWidth="300" prefHeight="250" stylesheets="@style.css" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="your.package.name.FXMLController">
   <children>
      <Button layoutX="100" layoutY="100" text="Button" />
   </children>
</AnchorPane> 

Scene Builder 不知道自定义皮肤(无论是通过代码还是通过 css 应用),也不会显示或预览。

在这种情况下,这个解决方案已经足够好了,因为毕竟 Scene Builder 只是一个设计工具,当你运行你的应用程序时,动画就会起作用。

但如果你真的想从 Scene Builder 中预览动画,你仍然可以这样做,但为此你需要:

  • 子类Button,和
  • 将此类(jar)导入 Scene Builder

那么让我们创建MyButton 类:

MyButton.java

public class MyButton extends Button {

    public MyButton() {
        super();
    }

    public MyButton(String text) {
        super(text);
    }

    @Override
    protected Skin<?> createDefaultSkin() {
        return new MyButtonSkin(this);
    }

}

现在构建您的项目。至少应该包含MyButtonMyButtonSkin),但它可以包含一个演示应用程序类来测试它:

@Override
public void start(Stage primaryStage) throws IOException {
    MyButton btn = new MyButton("Button");
    StackPane root = new StackPane(btn);
    Scene scene = new Scene(root, 300, 250);
    primaryStage.setScene(scene);
    primaryStage.show();
}

将项目导入Scene Builder:

打开 Scene Builder,然后选择 JAR/FXML Manager -> Add Library/FXML from file system。找到你的 jar,然后点击 Import Component:

现在您可以将MyButton 控件从“自定义”面板拖到左上角。

FXML.fxml

<?import javafx.scene.layout.AnchorPane?>
<?import your.package.name.MyButton?>

<AnchorPane prefHeight="250.0" prefWidth="300.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <MyButton layoutX="100" layoutY="100" text="Button" />
   </children>
</AnchorPane>

最后,点击Preview -&gt; Show Preview in Window,就能看到动画了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-20
    • 2023-02-03
    • 2015-07-04
    • 1970-01-01
    • 1970-01-01
    • 2015-08-21
    • 2020-09-23
    • 1970-01-01
    相关资源
    最近更新 更多