JavaFX:无法在透明舞台上显示不透明度过渡?

时间:2015-07-22 23:26:24

标签: javafx shadow stage

我尝试做的是在带阴影效果的透明舞台(弹出通知)上显示淡入/淡出过渡效果。

我创建了一个透明场景,StackPane fx:id="rootNode"设置为-fx-background-color: transparent,在StackPane内部,我用一个阴影效果包装一个AnchorPane。接下来,我用那个场景设置我的透明舞台。

@FXML private StackPane rootNode;

Parent rootNode = FXMLLoader.load(getClass().getResource("notification.fxml"));
Scene scene = new Scene(rootNode, Color.TRANSPARENT);

Stage stage = new Stage();
stage.initStyle(StageStyle.TRANSPARENT);
stage.setScene(scene);

到目前为止一切顺利。我设法让这个透明的舞台有一个很好的阴影效果。

注意:下图显示了我的桌面上具有阴影效果的透明舞台,其具有青色。

transparent stage with shadow effect

但是现在,因为我已经添加了一些过渡效果以逐渐淡入淡出Stage(当用户点击" x"时),Stage几乎没有显示出来。过渡效果在执行过程中会停止(我设置将不透明度从0.0变为1.0)。

barely shown

你可以在下面的任务栏中看到它,因为还有第二个java窗口就是那个阶段。

taskbar

如果我将光标放在" x"按钮然后它只是出现。这意味着(我想)转换被播放,但是舞台是(某种程度上)没有显示或透明,直到某些东西抓住它的焦点。

我试过

setting stage.toFront(); 
stage.requestFocus(); 
stage.setAlwaysOnTop(true);

没有成功。

当我在StageStyle.UNDECORATED上更改Stage时,会显示舞台上的过渡但是周围有令人讨厌的白色背景,这是预期的。

not transparent stage with shadow effect

你能提供一些帮助吗?我无法理解为什么会这样,或者如何找到可能的解决方案。

我的设置是:

  • Windows 7 x64 Pro

  • Java(TM)SE运行时环境(版本1.8.0_45-b15)

---更新---

经过一些测试后,我得出结论,可能存在错误的兼容性"在 StageStyle.TRANSPARENT 阶段和过渡不透明度效果之间?

我的转换代码是:

public class FadeTransition {

    private final Timeline showTransition, dismissTransition;
    private final NotificationStage stage;

    public FadeTransition(NotificationStage customStage) {
        this.stage = customStage;

        showTransition = setupShowTransition();
        dismissTransition = setupDismissTransition();
    }

    private Timeline setupShowTransition() {
        Timeline tl = new Timeline();

        // Set opacity to 0.0 instantly
        KeyValue kvOpacity = new KeyValue(stage.opacityProperty(), 0.0);
        KeyFrame frame1 = new KeyFrame(Duration.ZERO, kvOpacity);

        // Sets opacity to 1.0 gradually over 500 milliseconds.
        KeyValue kvOpacity2 = new KeyValue(stage.opacityProperty(), 1.0);
        KeyFrame frame2 = new KeyFrame(Duration.millis(500), kvOpacity2);

        tl.getKeyFrames().addAll(frame1, frame2);

        //Action to be performed when the transition has finished
        tl.setOnFinished(e -> notificationIsShowing = true);

        return tl;
    }

    private Timeline setupDismissTransition() {
        Timeline tl = new Timeline();

        // At this stage the opacity is already at 1.0

        // Lower the opacity to 0.0 within 1000 milliseconds
        KeyValue kv1 = new KeyValue(stage.opacityProperty(), 0.0);
        KeyFrame kf1 = new KeyFrame(Duration.millis(1000), kv1);

        tl.getKeyFrames().addAll(kf1);

        //Action to be performed when the transition has finished
        tl.setOnFinished(e -> {
            notificationIsShowing = false;
            stage.close();
            stage.setLocation(stage.getAnchorLocation());
        });

        return tl;
    }

    public void playShowTransition() {
        showTransition.play();
    }

    public void playDismissAnimation() {
        dismissTransition.play();
    }

    ... ... ...
}

1 个答案:

答案 0 :(得分:0)

另一个人here有完全相同的问题,并将其声明为JavaFX错误。

解决方法是构建自定义Interpolator(bugFixInterpolator)以重新绘制场景。

以下是代码的一部分,发布在上面的链接中:

Interpolator bugFixInterpolator = new Interpolator() {
            @Override
            protected double curve(double t) {
                Paint fill = scene.getFill();
                scene.setFill(Color.RED);
                scene.setFill(fill);
                return t;
            }

            @Override
            public String toString() {
                return "Interpolator.LINEAR";
            }
        };

        Timeline t = new Timeline(new KeyFrame(Duration.millis(0),
                new KeyValue(stage.opacityProperty(), 1, bugFixInterpolator)),
                new KeyFrame(Duration.millis(500), new KeyValue(stage
                        .opacityProperty(), 0, bugFixInterpolator)));
        t.setAutoReverse(true);
        t.setCycleCount(Timeline.INDEFINITE);
        t.playFromStart();