我有一个创建JavaFX应用程序的任务。当我启动它时,窗口应该从屏幕的右侧平滑滑动,当我点击“x”按钮时,它应该滑到右侧,然后完成。
我发现可以使用简单的时间轴动画。当我运行应用程序时,我让窗口滑入,但无法弄清楚如何滑出窗口。
我尝试通过stage的setOnCloseRequest()方法来处理这个定义处理程序,但是遇到了两个问题:
代码:
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();
}
});
}
}
答案 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
,这可能是因为动画导致某些系统尝试访问不再存在的阶段。