【问题标题】:Slide in/out JavaFX stage from/to right side of the screen从屏幕右侧滑入/滑出 JavaFX 舞台
【发布时间】:2015-07-27 13:04:56
【问题描述】:

我的任务是制作 JavaFX 应用程序。当我启动它时,窗口应该从屏幕右侧平滑滑动,当我点击“x”按钮时,它应该滑到右侧然后结束。

我发现可以为此使用简单的时间轴动画。当我运行应用程序时,我让窗口滑入,但不知道如何滑出窗口。

我尝试通过阶段的 setOnCloseRequest() 方法来处理这个定义处理程序,但遇到了两个问题:

  1. 无法实现动画
  2. 点击“x”后应用程序立即关闭,即使我使用 Window 事件的 consume() 方法

代码:

public class Main extends Application {

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

    @Override
    public void start(Stage stage) {
        stage.setTitle("Main");
        Group root = new Group();
        Scene scene = new Scene(root, 300, 250);
        stage.setScene(scene);


        Rectangle2D primScreenBounds = Screen.getPrimary().getVisualBounds();
        stage.setX(primScreenBounds.getMinX() + primScreenBounds.getWidth());
        System.out.println(primScreenBounds.getWidth());
        stage.setY(primScreenBounds.getMinY());
        stage.setWidth(0);
        stage.setHeight(primScreenBounds.getHeight());

        Timeline timeline = new Timeline();
        timeline.setAutoReverse(true);

        WritableValue<Double> writableWidth = new WritableValue<Double>() {
            @Override
            public Double getValue() {
                return stage.getWidth();
            }

            @Override
            public void setValue(Double value) {
                stage.setWidth(value);
            }
        };

        KeyValue kv = new KeyValue(writableWidth, 600d);
        KeyFrame kf = new KeyFrame(Duration.millis(3000), kv);
        timeline.getKeyFrames().addAll(kf);
        timeline.play();
        stage.show();
        stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent event) {
                event.consume();

            }
        });

    }
}

【问题讨论】:

    标签: animation javafx-8


    【解决方案1】:

    这对我有用(有点,不是很顺利):

    import javafx.animation.KeyFrame;
    import javafx.animation.KeyValue;
    import javafx.animation.Timeline;
    import javafx.application.Application;
    import javafx.application.Platform;
    import javafx.beans.value.WritableValue;
    import javafx.event.EventHandler;
    import javafx.geometry.Rectangle2D;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.stage.Screen;
    import javafx.stage.Stage;
    import javafx.stage.WindowEvent;
    import javafx.util.Duration;
    
    public class SlidingWindow extends Application {
    
        public static void main(String[] args) {
            Application.launch(args);
        }
    
        @Override
        public void start(Stage stage) {
    
            stage.setTitle("Main");
            Group root = new Group();
            Scene scene = new Scene(root);
            stage.setScene(scene);
    
    
            Rectangle2D primScreenBounds = Screen.getPrimary().getVisualBounds();
            double screenRightEdge = primScreenBounds.getMaxX() ;
            stage.setX(screenRightEdge);
            System.out.println(primScreenBounds.getWidth());
            stage.setY(primScreenBounds.getMinY());
            stage.setWidth(0);
            stage.setHeight(primScreenBounds.getHeight());
    
            Timeline timeline = new Timeline();
    
    
            WritableValue<Double> writableWidth = new WritableValue<Double>() {
                @Override
                public Double getValue() {
                    return stage.getWidth();
                }
    
                @Override
                public void setValue(Double value) {
                    stage.setX(screenRightEdge - value);
                    stage.setWidth(value);
                }
            };
    
    
            KeyValue kv = new KeyValue(writableWidth, 600d);
            KeyFrame kf = new KeyFrame(Duration.millis(3000), kv);
            timeline.getKeyFrames().addAll(kf);
            timeline.play();
            stage.show();
            stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
                @Override
                public void handle(WindowEvent event) {
                    Timeline timeline = new Timeline();
                    KeyFrame endFrame = new KeyFrame(Duration.millis(3000), new KeyValue(writableWidth, 0.0));
                    timeline.getKeyFrames().add(endFrame);
                    timeline.setOnFinished(e -> Platform.runLater(() -> stage.hide()));
                    timeline.play();
                    event.consume();
                }
            });
    
        }
    }
    

    Platform.runLater(...) 似乎有必要在窗口隐藏时防止出现大量 NullPointerExceptions,可能是因为动画导致某些系统尝试访问不再存在的阶段。

    【讨论】:

    • 谢谢!它有效,但不是我期望的方式。我做了一些将宽度设置为 0 的实验,但我需要在关闭窗口后向它出现的方向移动。现在它向左移动。我不知道是否可以这样做。
    • 请解释一下。它从左到右出现,然后向左关闭(即它出现的方向)。什么意思?
    • 我的意思是当我点击关闭窗口应该向右移动然后消失。
    • 我认为这是向与它来的方向相反的方向收缩。当width 更改时,您可以更新窗口的x 属性,但它会(甚至更多)闪烁......请参阅更新。
    • 谢谢!是的。这正是我所需要的。是否可以减少闪烁?
    猜你喜欢
    • 1970-01-01
    • 2012-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多