在屏幕右侧滑动 in/out JavaFX 舞台 from/to
Slide in/out JavaFX stage from/to right side of the screen
我的任务是制作 JavaFX 应用程序。当我启动它时,window 应该从屏幕右侧平滑地滑动,当我点击 "x" 按钮时,它应该滑出到右侧然后完成。
我发现可以为此使用简单的时间轴动画。当我 运行 应用程序时,我让 window 滑入,但不知道如何滑出 window。
我尝试通过阶段的 setOnCloseRequest() 方法来处理这个定义处理程序,但遇到了两个问题:
- 无法实现动画
- 即使我使用 Window 事件
的 consume() 方法,单击 "x" 应用程序也会立即关闭
代码:
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();
}
});
}
}
这对我有用(有点,不是很流畅):
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();
}
});
}
}
当 window 被隐藏时,Platform.runLater(...)
似乎是防止大量 NullPointerException
的必要条件,可能是因为动画导致某些系统尝试访问一个没有的阶段不再存在。
我的任务是制作 JavaFX 应用程序。当我启动它时,window 应该从屏幕右侧平滑地滑动,当我点击 "x" 按钮时,它应该滑出到右侧然后完成。
我发现可以为此使用简单的时间轴动画。当我 运行 应用程序时,我让 window 滑入,但不知道如何滑出 window。
我尝试通过阶段的 setOnCloseRequest() 方法来处理这个定义处理程序,但遇到了两个问题:
- 无法实现动画
- 即使我使用 Window 事件 的 consume() 方法,单击 "x" 应用程序也会立即关闭
代码:
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();
}
});
}
}
这对我有用(有点,不是很流畅):
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();
}
});
}
}
当 window 被隐藏时,Platform.runLater(...)
似乎是防止大量 NullPointerException
的必要条件,可能是因为动画导致某些系统尝试访问一个没有的阶段不再存在。