JavaFX 8更改舞台的不透明度不适用于StageStyle.TRANSPARENT(错误或我的错误?) [英] JavaFX 8 Changing the opacity of the stage does not work with StageStyle.TRANSPARENT (bug or my fault?)

查看:1131
本文介绍了JavaFX 8更改舞台的不透明度不适用于StageStyle.TRANSPARENT(错误或我的错误?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在窗口(舞台)上构建FadeIn / Out动画。如果鼠标进入舞台,它应该淡入,如果鼠标离开它应该淡出。

I'm trying to build a FadeIn/Out animation on a window (stage). If the mouse moves into the stage it should fade in and if the mouse leaves it should fade out.

我创建了一个修改阶段的时间轴.opacityProperty()来实现这一目标。当我将舞台样式设置为透明时,我遇到了问题,例如 stage.initStyle(StageStyle.TRANSPARENT); 。如果我这样做,褪色将不可见。时间轴播放动画,但JavaFX不会呈现不透明度更改。将stageStyle设置为默认值时,一切正常,窗口及其装饰将淡入和淡出。

I created a Timeline that modifies the stage.opacityProperty() to achieve this. I ran into problems when I set the stage style transparent like this stage.initStyle(StageStyle.TRANSPARENT);. If I do so, the fading will not be visible. The Timeline plays the animation, but the opacity change will not be rendered by JavaFX. When setting the stageStyle to default, everything works fine and the window plus its decoration will fade in and out.

我希望此效果在TRANSPARENT舞台风格中工作,所以我试过以下内容:
我在场景中放置了一个标签,并在另一个时间轴中更改了其textproperty。我现在每400毫秒更新标签文本。如果我这样做,不透明度的变化将在每次标签更改时呈现。

I want this effect to work in TRANSPARENT stage style so i tried the following: I put a label onto the scene and change its textproperty in another Timeline. I now update the label text every 400msecs. If i do so, the opacity change will be rendered on every label-change.

这让我得出结论,修改TRANSPARENT舞台风格的不透明度,不会导致舞台重画。
修改标签文本将导致重新绘制。这是否意味着,如果内容没有改变,我无法淡化TRANSPARENT舞台风格的舞台?

This brings me to the conclusion, that modifying the opacity in TRANSPARENT stage style, will not result in a repaint of the stage. Modifying the label text will result in repaint. Does this mean, that i cannot fade a stage in TRANSPARENT stage style, if the content does not change?

这是一个错误还是我做错了什么?

Is this a bug or am I doing something wrong?

我已经制作了一个可以重现问题的SSCCE。如果你删除行 stage.initStyle(StageStyle.TRANSPARENT); fadeIn / out动画将顺利运行。

I've made an SSCCE that reproduces the problem. If you remove the line stage.initStyle(StageStyle.TRANSPARENT); the fadeIn/out animation will run smoothly.

package de.schuette.jfx.stage_opacity_bug;

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.KeyCode;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;

public class FadeApp extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }

    private Label label;

    @Override
    public void start(Stage stage) {
        if (stage == null)
            throw new IllegalArgumentException("No stage was set.");

        this.label = new Label("HALLO WELT");

        Scene scene = new Scene(label, 300, 300);

        scene.setOnKeyPressed(e -> {
            if (e.getCode() == KeyCode.ESCAPE) {
                stage.close();
            }
        });

        stage.setScene(scene);
        stage.setOpacity(1);
        stage.initStyle(StageStyle.TRANSPARENT);
        stage.setTitle("Opacity change does result in repaint when stage style is transparent.");
        stage.setAlwaysOnTop(true);
        stage.show();

        Platform.runLater(() -> {

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

            t.playFromStart();
        });

        Platform.runLater(() -> {

            Timeline t = new Timeline(new KeyFrame(Duration.millis(400), e -> {
                label.textProperty().set(String.valueOf(Math.random()));
            }));
            t.setCycleCount(Timeline.INDEFINITE);
            t.playFromStart();
        });
    }

}

我正在坚持使用


  • Java(TM)SE运行时环境(版本1.8.0_20-b26)

  • Windows 7 x64专业

推荐答案

在JavaFX开发团队的帮助下,我找到了一个解决方法这个问题。使用自定义线性插值器更改场景的填充属性并立即将其更改回原始值将导致在舞台上重新绘制。这是通过以下代码中的bugFixInterpolator完成的:

With the help of the JavaFX developer team I was able to find a workaround for this problem. Using a custom linear interpolator that changes the scene's fill property and immediately change it back to its original value will cause a repaint on the stage. This is done by the "bugFixInterpolator" in the code below:

package de.schuette.jfx.stage_opacity_bug;

import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.KeyCode;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;

public class FadeApp extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }

    private Label label;

    /*
     * (non-Javadoc)
     * 
     * @see javafx.application.Application#start(javafx.stage.Stage)
     */
    @Override
    public void start(Stage stage) {
        if (stage == null)
            throw new IllegalArgumentException("No stage was set.");

        this.label = new Label("HELLO WORLD");

        Scene scene = new Scene(label, 300, 300);

        scene.setOnKeyPressed(e -> {
            if (e.getCode() == KeyCode.ESCAPE) {
                stage.close();
            }
        });

        stage.setScene(scene);
        stage.setOpacity(1);
        stage.initStyle(StageStyle.TRANSPARENT);
        stage.setTitle("Opacity change does result in repaint when stage style is transparent.");
        stage.setAlwaysOnTop(true);
        stage.show();

        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();

        t = new Timeline(new KeyFrame(Duration.millis(400), e -> {
            label.textProperty().set(String.valueOf(Math.random()));
        }));
        t.setCycleCount(Timeline.INDEFINITE);
        t.playFromStart();
    }

}

这篇关于JavaFX 8更改舞台的不透明度不适用于StageStyle.TRANSPARENT(错误或我的错误?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆