JavaFX 等待 FileChooser showSaveDialog 获取选择的文件路径
JavaFX wait FileChooser showSaveDialog to get selected file path
我想从 JavaFX 中的 FileChooser showSaveDialog() 对话框中获取选定的文件路径,以便将表视图导出到文件。
代码在 Runnable 中 运行ning,所以我必须 运行 JavaFX 主线程中的 showSaveDialog (Platform.runLater)
public class ExportUtils {
...
private File file = null;
private String outputPath = null;
public void Export(){
...
ChooseDirectory(stage);
if (outputPath != null{
... //export to the selected path
}
}
public void ChooseDirectory(Stage stage) {
...
FileChooser newFileChooser = new FileChooser();
...
Platform.runLater(new Runnable() {
public void run() {
file = newFileChooser.showSaveDialog(stage);
if (file != null) {
outputPath = file.getPath();
}
}
});
}
我想知道这种情况的最佳解决方案,在这种情况下,我必须等待用户选择路径和文件名,然后才能在 Export() 方法中评估 outputPath 变量的值。
不要这样拆分方法。 Platform.runLater()
.
之后,您的 export()
无法继续
选项 1
把所有的东西合二为一。
public void export() {
...
Platform.runLater(new Runnable() {
public void run() {
file = new FileChooser().showSaveDialog(stage);
if (file != null) {
outputPath = file.getPath();
// Export to the path
}
}
});
}
选项 2
您可以将 Platform.runLater()
移动到 export()
的开头。
public void export() {
...
Platform.runLater(() -> {
String outputPath = chooseDirectory(stage);
if (outputPath != null) {
// Export to the path
}
});
}
private String chooseDirectory(Stage stage) {
...
file = new FileChooser().showSaveDialog(stage);
if (file != null) {
return file.getPath();
}
else return null;
}
除非您需要保留线程 运行 我建议通过启动新线程而不是在 ExecutorService
.
上发布任务来处理文件选择
如果您确实需要这样做,您可以使用 CompletableFuture
来检索结果:
private static void open(Stage stage, CompletableFuture<File> future) {
Platform.runLater(() -> {
FileChooser fileChooser = new FileChooser();
future.complete(fileChooser.showSaveDialog(stage)); // fill future with result
});
}
@Override
public void start(Stage primaryStage) throws Exception {
Button button = new Button("start");
button.setOnAction(evt -> {
new Thread(() -> {
for (int i = 0; i < 5; i++) {
CompletableFuture<File> future = new CompletableFuture<>();
open(primaryStage, future);
try {
File file = future.get(); // wait for future to be assigned a result and retrieve it
System.out.println(file == null ? "no file chosen" : file.toString());
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
}
}).start();
});
primaryStage.setScene(new Scene(new StackPane(button)));
primaryStage.show();
}
注意:如果您在单独的线程中访问来自ui的数据,如果同时修改数据,您可能会遇到麻烦。
我想从 JavaFX 中的 FileChooser showSaveDialog() 对话框中获取选定的文件路径,以便将表视图导出到文件。 代码在 Runnable 中 运行ning,所以我必须 运行 JavaFX 主线程中的 showSaveDialog (Platform.runLater)
public class ExportUtils {
...
private File file = null;
private String outputPath = null;
public void Export(){
...
ChooseDirectory(stage);
if (outputPath != null{
... //export to the selected path
}
}
public void ChooseDirectory(Stage stage) {
...
FileChooser newFileChooser = new FileChooser();
...
Platform.runLater(new Runnable() {
public void run() {
file = newFileChooser.showSaveDialog(stage);
if (file != null) {
outputPath = file.getPath();
}
}
});
}
我想知道这种情况的最佳解决方案,在这种情况下,我必须等待用户选择路径和文件名,然后才能在 Export() 方法中评估 outputPath 变量的值。
不要这样拆分方法。 Platform.runLater()
.
export()
无法继续
选项 1
把所有的东西合二为一。
public void export() {
...
Platform.runLater(new Runnable() {
public void run() {
file = new FileChooser().showSaveDialog(stage);
if (file != null) {
outputPath = file.getPath();
// Export to the path
}
}
});
}
选项 2
您可以将 Platform.runLater()
移动到 export()
的开头。
public void export() {
...
Platform.runLater(() -> {
String outputPath = chooseDirectory(stage);
if (outputPath != null) {
// Export to the path
}
});
}
private String chooseDirectory(Stage stage) {
...
file = new FileChooser().showSaveDialog(stage);
if (file != null) {
return file.getPath();
}
else return null;
}
除非您需要保留线程 运行 我建议通过启动新线程而不是在 ExecutorService
.
如果您确实需要这样做,您可以使用 CompletableFuture
来检索结果:
private static void open(Stage stage, CompletableFuture<File> future) {
Platform.runLater(() -> {
FileChooser fileChooser = new FileChooser();
future.complete(fileChooser.showSaveDialog(stage)); // fill future with result
});
}
@Override
public void start(Stage primaryStage) throws Exception {
Button button = new Button("start");
button.setOnAction(evt -> {
new Thread(() -> {
for (int i = 0; i < 5; i++) {
CompletableFuture<File> future = new CompletableFuture<>();
open(primaryStage, future);
try {
File file = future.get(); // wait for future to be assigned a result and retrieve it
System.out.println(file == null ? "no file chosen" : file.toString());
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
}
}).start();
});
primaryStage.setScene(new Scene(new StackPane(button)));
primaryStage.show();
}
注意:如果您在单独的线程中访问来自ui的数据,如果同时修改数据,您可能会遇到麻烦。