我尝试做的是在带阴影效果的透明舞台(弹出通知)上显示淡入/淡出过渡效果。
我创建了一个透明场景,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);
到目前为止一切顺利。我设法让这个透明的舞台有一个很好的阴影效果。
注意:下图显示了我的桌面上具有阴影效果的透明舞台,其具有青色。
但是现在,因为我已经添加了一些过渡效果以逐渐淡入淡出Stage
(当用户点击" x"时),Stage
几乎没有显示出来。过渡效果在执行过程中会停止(我设置将不透明度从0.0变为1.0)。
你可以在下面的任务栏中看到它,因为还有第二个java窗口就是那个阶段。
如果我将光标放在" x"按钮然后它只是出现。这意味着(我想)转换被播放,但是舞台是(某种程度上)没有显示或透明,直到某些东西抓住它的焦点。
我试过
setting stage.toFront();
stage.requestFocus();
stage.setAlwaysOnTop(true);
没有成功。
当我在StageStyle.UNDECORATED
上更改Stage
时,会显示舞台上的过渡但是周围有令人讨厌的白色背景,这是预期的。
我的设置是:
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();
}
... ... ...
}
答案 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();