【发布时间】:2015-10-13 01:41:54
【问题描述】:
我要做的是在带有阴影效果的透明舞台(弹出通知)上显示淡入/淡出过渡效果。
我创建了一个透明场景,将 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);
没有成功。
当我在Stage 上更改StageStyle.UNDECORATED 时,会显示带有过渡的舞台,但它周围有令人讨厌的白色背景,这是意料之中的。
您能提供一些帮助吗?我不明白为什么会发生这种情况或如何找到可能的解决方案。
我的设置是:
Windows 7 x64 专业版
Java(TM) SE 运行时环境(内部版本 1.8.0_45-b15)
--- 更新 ---
经过一些测试,我得出结论,StageStyle.TRANSPARENT 阶段和 transition opacity 效果之间可能存在“不兼容”?
我的转换代码是:
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();
}
... ... ...
}
【问题讨论】:
-
虽然我不太清楚为什么新版本的外观会发生这种变化,但您可以通过从 hbox 的样式中删除
-fx-background-insets和-fx-border-insets来解决此问题。 -
@ItachiUchiha 我更改了整个代码。请看一下。感谢您的回复。
-
一个问题:这是来自 ControlsFX 的控件吗?
-
@PeterPenzov 不,不是。这是我的自定义阶段。
-
如果这是一个开源应用程序,您可以分享代码吗?我对这个解决方案是如何实现的很感兴趣。