JavaFx如何使用Timeline移动窗口位置

时间:2015-09-22 03:47:07

标签: java javafx javafx-2 javafx-8

我有这个舞台,当我展示它。我希望它显示在屏幕底部,然后上到中心屏幕。 就像通知一样。

我的代码

try {          
        Stage window = new Stage();
        window.initModality(Modality.APPLICATION_MODAL);
        window.setTitle(Message);
        AnchorPane layout = (AnchorPane) FXMLLoader.load(Notification.class.getResource("window.fxml"));
        Scene scene = new Scene(layout);
        window.setScene(scene);
        window.showAndWait();
} catch (Exception e) {
        System.out.println(e);
}

2 个答案:

答案 0 :(得分:0)

您需要在移动窗口的位置添加一个Timer。这是因为Window / Stage仅具有X和Y值的ReadOnlyProperties,因此您无法使用关键帧进行简单的时间轴动画。

您需要使用primaryScreenBounds的高度和宽度,以便它符合您的需求。

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Screen;
import javafx.stage.Stage;

public class TimelineEvents extends Application {

    private AnimationTimer timer;
    Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
    double x = primaryScreenBounds.getMaxX() - 180;
    double y = primaryScreenBounds.getMaxY() - 180;
    double centerX = primaryScreenBounds.getWidth() / 2;
    double centerY = primaryScreenBounds.getHeight() / 2;
    double tickX = (x - centerX) / primaryScreenBounds.getWidth() * 10;
    double tickY = (y - centerY) / primaryScreenBounds.getHeight() * 10;

    @Override
    public void start(Stage stage) {
        Button btn = new Button();
        btn.setText("Show Message");
        btn.setOnAction((ActionEvent event) -> {
            Label l = new Label("Message");
            BorderPane root = new BorderPane(l);
            Scene s = new Scene(root, 100, 100);
            Stage window = new Stage();
            window.setX(x);
            window.setY(y);

            timer = new AnimationTimer() {

                @Override
                public void handle(long l) {
                    x = x - tickX;
                    y = y - tickY;
                    if (x >= centerX) {
                        window.setX(x);
                        window.setY(y);
                    } else {
                       stop();
                    }
                }
            };

            timer.start();
            window.setScene(s);
            window.showAndWait();
        });

        BorderPane pane = new BorderPane(btn);
        Scene scene = new Scene(pane, 200, 200);
        stage.setScene(scene);
        stage.show();

    }

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

答案 1 :(得分:0)

专门为Timeline创建一个属性,然后为其添加一个监听器:

double startPos = ... ;
double endPos = ... ;
DoubleProperty y = new SimpleDoubleProperty(startPos);
Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(1), new KeyValue(y, endPos)));
y.addListener((obs, oldValue, newValue) ->
    window.setY(newValue.doubleValue()));
timeline.play();

SSCCE:

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Popup;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.util.Duration;

public class SlidingNotificationWindow extends Application {

    @Override
    public void start(Stage primaryStage) {
        Button button = new Button("Show notification");
        button.setOnAction(e -> {
            Popup window = new Popup();
            StackPane content = new StackPane(new Label("Notification"));
            content.setStyle("-fx-background-color: aquamarine; -fx-padding: 40;");
            content.setOnMouseClicked(evt -> window.hide());
            window.getContent().add(content);
            window.setWidth(120);
            window.setHeight(75);

            Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();

            double startPos = primaryScreenBounds.getMaxY();
            double endPos = 2*primaryScreenBounds.getMinY()/3 + primaryScreenBounds.getMaxY() / 3 ;
            DoubleProperty y = new SimpleDoubleProperty(startPos);
            Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(1), new KeyValue(y, endPos)));
            y.addListener((obs, oldValue, newValue) ->
                window.setY(newValue.doubleValue()));
            timeline.play();
            window.setX(primaryScreenBounds.getMaxX() - 120);
            window.show(primaryStage);
        });

        StackPane root = new StackPane(button);
        primaryStage.setScene(new Scene(root, 350, 120));
        primaryStage.show();
    }

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