有,你可以通過它的yProperty()
的方式移動的警告對話框中,一種方式。我們將使用時間軸來設置此屬性,而不是路徑轉換。但由於這是隻讀屬性,我們不必在轉換中使用DoubleProperty
,而應使用Alert.setY()
。
問題的第一部分在對話框中滑動很容易。其次,滑出更復雜,因爲一旦單擊按鈕,對話框立即關閉。
解決方案1.在
只需滑動我們需要對話的尺寸和位置,爲此,我們需要展示出來。這意味着它會顯示,並立即移動到屏幕的頂部。
所以我會更換alert.showAndWait()
爲alert.show()
。
@Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Show Sliding In Alert Dialog");
btn.setOnAction(event -> {
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirmation Dialog");
alert.setHeaderText("Look, a Confirmation Dialog");
alert.setContentText("Are you ok with this?");
ButtonBar buttonBar=(ButtonBar)alert.getDialogPane().lookup(".button-bar");
buttonBar.setDisable(true);
alert.initModality(Modality.APPLICATION_MODAL);
alert.show();
// now we can retrive alert bounds:
double yIni=-alert.getHeight();
double yEnd=alert.getY();
// and move alert to the top of the screen
alert.setY(yIni);
final DoubleProperty yProperty = new SimpleDoubleProperty();
yProperty.addListener((ob,n,n1)->alert.setY(n1.doubleValue()));
Timeline timeIn = new Timeline();
timeIn.getKeyFrames().add(
new KeyFrame(Duration.seconds(1.5),
e->buttonBar.setDisable(false),
new KeyValue(yProperty, yEnd,Interpolator.EASE_BOTH)));
timeIn.play();
alert.resultProperty().addListener((ob,r,r1)->{
if (r1 == ButtonType.OK){
// alert is closed and hidden in its final position
}
else{
primaryStage.close();
}
});
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
在yProperty()
監聽器允許我們設置在過渡期間內插所有的不同的位置中的位置的對話框。
溶液2滑入和滑出
這有點髒溶液,因爲使用第二Alert
對話框包括,給予一次的按鈕被點擊原來的關閉。我們將在第一個對話框後面添加第二個對話框,並在第一個對話框關閉後使用它創建滑出效果。
您會注意到的唯一副作用是在顯示第二個並將第一個放在第一個之上的快速閃爍。
@Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Show Sliding In Alert Dialog");
btn.setOnAction(event -> {
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirmation Dialog");
alert.setHeaderText("Look, a Confirmation Dialog");
alert.setContentText("Are you ok with this?");
Alert alertOut = new Alert(AlertType.CONFIRMATION);
alertOut.setTitle("Confirmation Dialog");
alertOut.setHeaderText("Look, a Confirmation Dialog");
alertOut.setContentText("Are you ok with this?");
alertOut.initModality(Modality.NONE);
((Stage)alertOut.getDialogPane().getScene().getWindow()).setOpacity(0);
ButtonBar buttonBar=(ButtonBar)alert.getDialogPane().lookup(".button-bar");
buttonBar.setDisable(true);
alert.initModality(Modality.APPLICATION_MODAL);
alert.show();
// now we can retrive alert bounds:
double yIni=-alert.getHeight();
double yEnd=alert.getY();
// and move alert to the top of the screen
alert.setY(yIni);
final DoubleProperty yProperty = new SimpleDoubleProperty();
yProperty.addListener((ob,n,n1)->alert.setY(n1.doubleValue()));
Timeline timeIn = new Timeline();
timeIn.getKeyFrames().add(
new KeyFrame(Duration.seconds(1.5),
e->{
buttonBar.setDisable(false);
// show second dialog
alertOut.show();
// move to front the first one
((Stage)alert.getDialogPane().getScene().
getWindow()).toFront();
}, new KeyValue(yProperty, yEnd,Interpolator.EASE_BOTH)));
timeIn.play();
alert.resultProperty().addListener((ob,r,r1)->{
if (r1 == ButtonType.OK){
// show second dialog
((Stage)alertOut.getDialogPane().getScene().getWindow()).setOpacity(1);
ButtonBar buttonBarOut=(ButtonBar)alertOut.getDialogPane().lookup(".button-bar");
buttonBarOut.setDisable(true);
final DoubleProperty yPropertyOut = new SimpleDoubleProperty(yEnd);
yPropertyOut.addListener((ov,n,n1)->alertOut.setY(n1.doubleValue()));
// Create slide out transition
Timeline timeOut = new Timeline();
timeOut.getKeyFrames().add(
new KeyFrame(Duration.seconds(1.5),
e->alertOut.close(),
new KeyValue(yPropertyOut, yIni,Interpolator.EASE_BOTH)));
timeOut.play();
}
else{
alertOut.close();
primaryStage.close();
}
});
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
編輯
解決方案2.改進和拉出
我發現使用一個單一的對話框,並提供了在滑動過的方式。
它只需將點擊動作置於所選按鈕上,消耗事件,在此處添加滑出過渡,並隱藏完成對話框。
@Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Show Sliding In Alert Dialog");
btn.setOnAction(event -> {
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirmation Dialog");
alert.setHeaderText("Look, a Confirmation Dialog");
alert.setContentText("Are you ok with this?");
ButtonBar buttonBar=(ButtonBar)alert.getDialogPane().lookup(".button-bar");
buttonBar.setDisable(true);
alert.initModality(Modality.APPLICATION_MODAL);
alert.show();
// now we can retrive alert bounds:
double yIni=-alert.getHeight();
double yEnd=alert.getY();
// and move alert to the top of the screen
alert.setY(yIni);
buttonBar.getButtons().stream().filter(b->((Button)b).isDefaultButton()).findFirst()
.ifPresent(b->((Button)b).addEventFilter(EventType.ROOT,
e->{
if(e.getEventType().equals(ActionEvent.ACTION)){
e.consume();
final DoubleProperty yPropertyOut = new SimpleDoubleProperty(yEnd);
yPropertyOut.addListener((ov,n,n1)->alert.setY(n1.doubleValue()));
Timeline timeOut = new Timeline();
timeOut.getKeyFrames().add(new KeyFrame(Duration.seconds(1.5), t->alert.close(),
new KeyValue(yPropertyOut, yIni,Interpolator.EASE_BOTH)));
timeOut.play();
}
}));
final DoubleProperty yProperty = new SimpleDoubleProperty();
yProperty.addListener((ob,n,n1)->alert.setY(n1.doubleValue()));
Timeline timeIn = new Timeline();
timeIn.getKeyFrames().add(new KeyFrame(Duration.seconds(1.5), e->{
buttonBar.setDisable(false);
},new KeyValue(yProperty, yEnd,Interpolator.EASE_BOTH)));
timeIn.play();
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
酷,我可能會使用第一個解決方案,並嘗試調整,使該按鈕只是來和自動退出。 –
謝謝,我也會選擇第一個... –
你能簡單介紹一下Interpolator.EASE_BOTH的功能嗎? –