从/向右侧滑入/滑出JavaFX阶段

时间:2015-07-27 13:04:57

标签: animation javafx-8

我有一个创建JavaFX应用程序的任务。当我启动它时,窗口应该从屏幕的右侧平滑滑动,当我点击“x”按钮时,它应该滑到右侧,然后完成。

我发现可以使用简单的时间轴动画。当我运行应用程序时,我让窗口滑入,但无法弄清楚如何滑出窗口。

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

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

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

1 个答案:

答案 0 :(得分:2)

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

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(...)似乎有必要防止大量NullPointerException,这可能是因为动画导致某些系统尝试访问不再存在的阶段。