JavaFX: Не удается показать переходы непрозрачности на прозрачных этапах?
То, что я пытаюсь сделать, это показать эффект перехода постепенного появления / исчезновения на прозрачной сцене (всплывающее уведомление) с эффектом тени.
Я создал прозрачную сцену с помощью 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
(когда пользователь нажимает на "х"), Stage
едва показан. Что-то вроде эффекта перехода останавливается в середине его выполнения (я установил непрозрачность преобразования с 0,0 до 1,0).
Вы можете увидеть это на панели задач ниже, так как есть второе окно Java, которое является той стадией.
Если я наведу курсор на кнопку "х", он просто появится. Это означает (я полагаю), что переходы воспроизводятся, но сцена (как-то) не показана или не прозрачна, пока что-то не захватит ее фокус.
Я старался
setting stage.toFront();
stage.requestFocus();
stage.setAlwaysOnTop(true);
без успеха.
Когда я меняюсь StageStyle.UNDECORATED
на Stage
, затем сцена показана с ее переходами, но вокруг нее есть тот раздражающий белый фон, что и ожидается.
Не могли бы вы оказать помощь? Я не могу понять, почему это происходит или как найти возможное решение.
Моя настройка:
Windows 7 x64 Pro
Java (TM) SE Runtime Environment (сборка 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 ответ
У другого парня возникла та же проблема, и он назвал ее ошибкой 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();