1

我在 JavaFX 中使用一个按钮构建了一个自定义复合 UI 控件,如果将鼠标悬停在控件上的某个位置,它应该从 0 淡入到 0.1 不透明度。如果将鼠标悬停在按钮本身上,不透明度应更改为 1.0,这可以通过 CSS 轻松实现。

这里是 FadeTransition:

// unfortunately, animations cannot be defined in CSS yet
FadeTransition fadeInButton =
    new FadeTransition(Duration.millis(300), settingsButton);
fadeInButton.setFromValue(0);
fadeInButton.setToValue(0.1);

这里是按钮的 CSS:

.settings-button {
    -fx-background-image: url("settings_32_inactive.png");
    -fx-background-repeat: no-repeat;   
    -fx-background-position: center center;
    -fx-opacity: 0; /* button shall be initially invisible, will be faded in */
}

.settings-button:hover {
    -fx-background-image: url("settings_32.png");
    -fx-opacity: 1.0; /* why is this ignored if used together with animations? */
}

动画和 CSS 属性分别很好地工作。不幸的是,结合起来,动画似乎覆盖了 CSS 文件中的 -fx-opacity 属性。任何想法如何使动画和 CSS 属性一起工作?

4

1 回答 1

0

没有办法让 css over API 调用,请参阅下一个主题:JavaFX:无法在 CSS 设置字体后以编程方式设置字体大小

但是你可以做下一个技巧:

  • 不透明度为 0.1 的按钮未悬停,悬停时为 1
  • 将按钮放入窗格并将此窗格从 0 设置为 1

请参阅下一个 css:

/*Button*/
.b1 { -fx-opacity: 0.1; }
.b1:hover { -fx-opacity: 1.0; }
/*Pane*/
.p1 {
    -fx-border-color: red;
    -fx-opacity: 0;
}

和代码:

public class OpacityCss extends Application {

    private static final Duration DURATION = Duration.millis(300);

    @Override
    public void start(Stage primaryStage) {
        Pane pane = new Pane();
        pane.getStyleClass().add("p1");
        pane.setMinSize(100, 100);
        pane.setMaxSize(100, 100);

        final Button btn = new Button("Fading Button");
        btn.getStyleClass().add("b1");
        pane.getChildren().add(btn);

        final FadeTransition fade = new FadeTransition(DURATION, pane);
        fade.setAutoReverse(true);
        fade.setFromValue(0);
        fade.setToValue(1);

        pane.setOnMouseEntered(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent t) {
                fade.setCycleCount(1); // this way autoreverse wouldn't kick
                fade.playFromStart();
            }
        });

        pane.setOnMouseExited(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent t) {
                fade.setCycleCount(2); // starting from autoreverse
                fade.playFrom(DURATION);
            }
        });

        StackPane root = new StackPane();
        root.getChildren().addAll(pane);
        Scene scene = new Scene(root, 300, 250);
        scene.getStylesheets().add(getClass().getResource("/css/btn.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) { launch(); }
}
于 2013-03-01T13:18:13.320 回答