如何在当前primaryStage上设置警报框位置?(JavaFX)

IRG*_*uce 2 alert javafx java-8

编辑:如果用户单击“删除”以删除 ListView 中的项目,我会弹出一个警告框。它有效,但我希望它弹出原始阶段。它出现在我的第一台显示器上。有没有办法在显示时设置警报的位置?

请注意,“所有者”在不同的类中,我使用 Scenebuilder/FXML 创建了所有内容。我不知道如何让 initOwner() 工作。这是“主要”类:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Assignment_5 extends Application {
    public Stage primaryStage;

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("Assignment_5.fxml"));
    primaryStage.setTitle("Plant Pack");
    primaryStage.setScene(new Scene(root, 1200, 500));
    primaryStage.show();
}

public static void main(String[] args) {
    launch(args);
}
}
Run Code Online (Sandbox Code Playgroud)

这是 Controller 类中的工作代码。没有必要实现此警报的模式,但它会是一个很好的补充,使其更方便。我只是不知道如何将主 Window 从 Main 类传递给这个:

    protected void handleDeleteButtonClick(ActionEvent event) {
    Alert alertBox = new Alert(Alert.AlertType.CONFIRMATION, "Confirm Delete", ButtonType.OK, ButtonType.CANCEL);
    alertBox.setContentText("Are you sure you want to delete this " + plantType.getValue().toString().toLowerCase() + "?");
    alertBox.showAndWait();
    if(alertBox.getResult() == ButtonType.OK) {
        int selectedPlant = plantList.getSelectionModel().getSelectedIndex();
        observablePlantList.remove(selectedPlant);
    }
    else {
        alertBox.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道这是相当新的,所以很难找到很多资源。如果有人知道我可能遗漏的任何信息,请告诉我。感谢您提供的任何帮助。我在 IntelliJ 14.1.5 中使用 Java 8。

cla*_*taq 6

正如@jewelsea 所建议的,设置警报框的模式和所有者将确保警报会出现在舞台上,即使舞台被移动。

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ListView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class DeleteAlertDemo extends Application {

    Stage owner;
    ObservableList<String> observablePlantList;
    ListView<String> plantList;

    protected void handleDeleteButtonClick(ActionEvent event) {
        String item = plantList.getSelectionModel().getSelectedItem();
        Alert alertBox = new Alert(Alert.AlertType.CONFIRMATION, "Confirm Delete", 
                ButtonType.OK, ButtonType.CANCEL);
        alertBox.setContentText("Are you sure you want to delete this " 
                + item.toLowerCase() + "?");
        alertBox.initModality(Modality.APPLICATION_MODAL); /* *** */
        alertBox.initOwner(owner);                         /* *** */
        alertBox.showAndWait();
        if (alertBox.getResult() == ButtonType.OK) {
            int selectedPlant = plantList.getSelectionModel().getSelectedIndex();
            observablePlantList.remove(selectedPlant);
        } else {
            alertBox.close();
        }
    }

    @Override
    public void start(Stage primaryStage) {
        owner = primaryStage;                /* *** */
        Button deleteBtn = new Button();
        deleteBtn.setText("Delete");
        deleteBtn.setOnAction(this::handleDeleteButtonClick);

        observablePlantList = FXCollections.observableArrayList("Begonia", 
                "Peony", "Rose", "Lilly", "Chrysanthemum", "Hosta");
        plantList = new ListView<>(observablePlantList);
        plantList.getSelectionModel().select(0);
        BorderPane root = new BorderPane();
        root.setCenter(plantList);
        root.setRight(deleteBtn);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Delete Alert Demo");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 啊。解决方案很简单,但很难看。请参阅 http://stackoverflow.com/questions/11994366/how-to-reference-primarystage 的第二个答案和评论。您只需在控制器类中包含一个方法即可让您设置主要阶段。 (2认同)
  • 或者,如果您不喜欢传递变量,在事件处理程序中您可以执行以下操作:`Window Owner = ((Node)event.getTarget()).getScene().getWindow();` 这假设当然,按钮(事件目标)与舞台属于同一类。 (2认同)