JavaFX 警报不会在新 window 中打开,而是在新选项卡中打开
JavaFX Alert doesn't open in new window but in a new tab
我正在将 JavaFX 8 与场景生成器一起使用,我正在尝试创建一个警报弹出窗口 window。请参阅下面的代码:
更新:包括我所有的代码(不包括一些个人标识符)。
public class MainViewController {
@FXML
private void handleQuitButtonAction(ActionEvent event) {
System.exit(0);
}
@FXML
private void handleImportButtonAction(ActionEvent event) {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Select the file to import");
File file = fileChooser.showOpenDialog(new Stage());
Alert alert;
if (FileAccess.importFile(file)) {
alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Success!");
alert.setHeaderText("Congrats!");
alert.setContentText("Successfully imported data from the chosen file!");
} else {
alert = new Alert(AlertType.ERROR);
alert.setTitle("Error!");
alert.setHeaderText("Sorry...");
alert.setContentText("Something wrong with the import, please try again.");
}
alert.showAndWait();
// Refresh Scroll List
}
@FXML
private void handleExportButtonAction(ActionEvent event) {
}
}
public class MainApp extends Application {
private Stage primaryStage;
private BorderPane mainView;
@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Main System");
showMainView();
}
private void showMainView() {
try {
// Load Main View from FXML file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("view/MainView.fxml"));
mainView = (BorderPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(mainView);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public Stage getPrimaryStage() {
return primaryStage;
}
public static void main(String[] args) {
launch(args);
}
}
public class FileAccess {
public static boolean importFile(File file) {
return false;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.effect.DropShadow?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="view.MainViewController">
<center>
<ScrollPane prefWidth="800.0" BorderPane.alignment="CENTER" />
</center>
<top>
<ButtonBar prefHeight="40.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<buttons>
<Button focusTraversable="false" mnemonicParsing="false" onAction="#handleImportButtonAction" text="Import" ButtonBar.buttonData="LEFT" />
<Button focusTraversable="false" mnemonicParsing="false" onAction="#handleExportButtonAction" text="Export" ButtonBar.buttonData="LEFT" />
<Button focusTraversable="false" mnemonicParsing="false" onAction="#handleQuitButtonAction" text="Quit Program" ButtonBar.buttonData="RIGHT" />
</buttons>
<effect>
<DropShadow />
</effect>
<BorderPane.margin>
<Insets left="10.0" right="10.0" />
</BorderPane.margin>
</ButtonBar>
</top>
</BorderPane>
但是,它并没有打开一个新的 window,而是在一个新的选项卡中打开警报(我没有任何与选项卡设置相关的内容),请参见下面的屏幕截图:
它的尺寸甚至都不正确...
我正在使用 macOS Mojave。
谢谢!
我认为您不应该创建新的舞台对象。这可能是问题所在。
Stage stage = (Stage)((Node)(event).getSource()).getScene().getWindow();
以上代码将为您提供当前阶段。这可能会解决您的问题。
祝你好运
已解决:
这是一个 OS 设置问题。在 Dock 的 系统偏好设置 中,我已将 打开文档时首选选项卡 设置为 始终,设置为手动后,正常工作。
感谢大家的帮助。
@Jing 解决方案工作正常,但如果您不想强制用户修改他们的 OS 设置,您需要为 JavaFX 警报或任何对话框组件分配父级。警报扩展对话框。
private void setDefaultOwnerIfNotExisting(Dialog<?> dialog, Window parent) {
if (dialog.getOwner() == null) {
dialog.initOwner(parent);
}
}
这已经在 Mac 上进行了测试OS Monterey,现在我的提醒不会作为新标签出现。
我正在将 JavaFX 8 与场景生成器一起使用,我正在尝试创建一个警报弹出窗口 window。请参阅下面的代码:
更新:包括我所有的代码(不包括一些个人标识符)。
public class MainViewController {
@FXML
private void handleQuitButtonAction(ActionEvent event) {
System.exit(0);
}
@FXML
private void handleImportButtonAction(ActionEvent event) {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Select the file to import");
File file = fileChooser.showOpenDialog(new Stage());
Alert alert;
if (FileAccess.importFile(file)) {
alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Success!");
alert.setHeaderText("Congrats!");
alert.setContentText("Successfully imported data from the chosen file!");
} else {
alert = new Alert(AlertType.ERROR);
alert.setTitle("Error!");
alert.setHeaderText("Sorry...");
alert.setContentText("Something wrong with the import, please try again.");
}
alert.showAndWait();
// Refresh Scroll List
}
@FXML
private void handleExportButtonAction(ActionEvent event) {
}
}
public class MainApp extends Application {
private Stage primaryStage;
private BorderPane mainView;
@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Main System");
showMainView();
}
private void showMainView() {
try {
// Load Main View from FXML file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("view/MainView.fxml"));
mainView = (BorderPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(mainView);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public Stage getPrimaryStage() {
return primaryStage;
}
public static void main(String[] args) {
launch(args);
}
}
public class FileAccess {
public static boolean importFile(File file) {
return false;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.effect.DropShadow?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="view.MainViewController">
<center>
<ScrollPane prefWidth="800.0" BorderPane.alignment="CENTER" />
</center>
<top>
<ButtonBar prefHeight="40.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<buttons>
<Button focusTraversable="false" mnemonicParsing="false" onAction="#handleImportButtonAction" text="Import" ButtonBar.buttonData="LEFT" />
<Button focusTraversable="false" mnemonicParsing="false" onAction="#handleExportButtonAction" text="Export" ButtonBar.buttonData="LEFT" />
<Button focusTraversable="false" mnemonicParsing="false" onAction="#handleQuitButtonAction" text="Quit Program" ButtonBar.buttonData="RIGHT" />
</buttons>
<effect>
<DropShadow />
</effect>
<BorderPane.margin>
<Insets left="10.0" right="10.0" />
</BorderPane.margin>
</ButtonBar>
</top>
</BorderPane>
但是,它并没有打开一个新的 window,而是在一个新的选项卡中打开警报(我没有任何与选项卡设置相关的内容),请参见下面的屏幕截图:
它的尺寸甚至都不正确...
我正在使用 macOS Mojave。
谢谢!
我认为您不应该创建新的舞台对象。这可能是问题所在。
Stage stage = (Stage)((Node)(event).getSource()).getScene().getWindow();
以上代码将为您提供当前阶段。这可能会解决您的问题。
祝你好运
已解决:
这是一个 OS 设置问题。在 Dock 的 系统偏好设置 中,我已将 打开文档时首选选项卡 设置为 始终,设置为手动后,正常工作。
感谢大家的帮助。
@Jing 解决方案工作正常,但如果您不想强制用户修改他们的 OS 设置,您需要为 JavaFX 警报或任何对话框组件分配父级。警报扩展对话框。
private void setDefaultOwnerIfNotExisting(Dialog<?> dialog, Window parent) {
if (dialog.getOwner() == null) {
dialog.initOwner(parent);
}
}
这已经在 Mac 上进行了测试OS Monterey,现在我的提醒不会作为新标签出现。