feat: окно статуса сохранения папок
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
package ru.di9.ss14.extractor.gui;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.stage.Stage;
|
||||
import lombok.Setter;
|
||||
import ru.di9.ss14.extractor.ContentDbManager;
|
||||
import ru.di9.ss14.extractor.ContentRec;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class ExportInfoController implements Initializable {
|
||||
private static final Path EMPTY_PATH = Paths.get("");
|
||||
|
||||
@FXML
|
||||
public Label labelCurrentExport;
|
||||
|
||||
@FXML
|
||||
public Button btnCancel;
|
||||
|
||||
@Setter
|
||||
private Stage stage;
|
||||
|
||||
@Setter
|
||||
private ContentDbManager manager;
|
||||
|
||||
private volatile boolean running = false;
|
||||
private Task<Void> task;
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
btnCancel.setDisable(false);
|
||||
btnCancel.setText("Отменить");
|
||||
|
||||
btnCancel.setOnAction(e -> {
|
||||
btnCancel.setDisable(true);
|
||||
btnCancel.setText("Отменяется...");
|
||||
stopExport();
|
||||
});
|
||||
}
|
||||
|
||||
public void startExport(ContentRec contentRec, Path currentDir) {
|
||||
running = true;
|
||||
|
||||
task = new Task<>() {
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
exportRecursiveFolder(contentRec, currentDir, new AtomicReference<>(EMPTY_PATH));
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
task.setOnSucceeded(e -> {
|
||||
stage.close();
|
||||
task = null;
|
||||
});
|
||||
task.setOnCancelled(e -> {
|
||||
running = false;
|
||||
stage.close();
|
||||
task = null;
|
||||
});
|
||||
|
||||
var thread = new Thread(task);
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public void stopExport() {
|
||||
task.cancel();
|
||||
}
|
||||
|
||||
private void exportRecursiveFolder(ContentRec contentRec, Path currentDir, AtomicReference<Path> refExportedPath) throws IOException {
|
||||
if (!running) {
|
||||
return;
|
||||
}
|
||||
|
||||
var subDir = currentDir.resolve(contentRec.getName());
|
||||
if (Files.notExists(subDir)) {
|
||||
Files.createDirectory(subDir);
|
||||
}
|
||||
|
||||
for (ContentRec rec : contentRec.getChildren()) {
|
||||
if (!running) {
|
||||
break;
|
||||
}
|
||||
|
||||
refExportedPath.updateAndGet(p -> p.resolve(rec.getName()));
|
||||
|
||||
if (rec.isFolder()) {
|
||||
exportRecursiveFolder(rec, subDir, refExportedPath);
|
||||
} else {
|
||||
var path = subDir.resolve(rec.getName());
|
||||
try (var out = new FileOutputStream(path.toFile())) {
|
||||
var exportedPath = refExportedPath.get();
|
||||
System.out.printf("export %s...\n", exportedPath);
|
||||
final var ref = new AtomicReference<>(exportedPath);
|
||||
Platform.runLater(() -> labelCurrentExport.setText(ref.get().toString()));
|
||||
manager.readContent(rec.getId(), out);
|
||||
}
|
||||
refExportedPath.updateAndGet(p -> p.getParent() == null ? EMPTY_PATH : p.getParent());
|
||||
}
|
||||
}
|
||||
refExportedPath.updateAndGet(p -> p.getParent() == null ? EMPTY_PATH : p.getParent());
|
||||
}
|
||||
}
|
||||
@@ -2,14 +2,15 @@ package ru.di9.ss14.extractor.gui;
|
||||
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.TreeItem;
|
||||
import javafx.scene.control.TreeView;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.*;
|
||||
import lombok.Setter;
|
||||
import ru.di9.ss14.extractor.ContentDbManager;
|
||||
import ru.di9.ss14.extractor.ContentRec;
|
||||
@@ -18,12 +19,8 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.SortedSet;
|
||||
import java.util.*;
|
||||
|
||||
public class MainController implements Initializable {
|
||||
private static final int STATE_NOT_LOADED = 0;
|
||||
@@ -168,7 +165,7 @@ public class MainController implements Initializable {
|
||||
}
|
||||
|
||||
try {
|
||||
exportRecursiveFolder(contentRec, dir.toPath());
|
||||
showExportWindow(contentRec, dir.toPath());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -181,20 +178,28 @@ public class MainController implements Initializable {
|
||||
return contextMenu;
|
||||
}
|
||||
|
||||
private void exportRecursiveFolder(ContentRec contentRec, Path currentDir) throws IOException {
|
||||
var subDir = currentDir.resolve(contentRec.getName());
|
||||
if (Files.notExists(subDir)) {
|
||||
Files.createDirectory(subDir);
|
||||
}
|
||||
private void showExportWindow(ContentRec contentRec, Path currentDir) throws IOException {
|
||||
var loader = new FXMLLoader(Objects.requireNonNull(getClass().getResource("/view/export-dialog.fxml")));
|
||||
Parent root = loader.load();
|
||||
|
||||
for (ContentRec rec : contentRec.getChildren()) {
|
||||
if (rec.isFolder()) {
|
||||
exportRecursiveFolder(rec, subDir);
|
||||
} else {
|
||||
try (var out = new FileOutputStream(subDir.resolve(rec.getName()).toFile())) {
|
||||
manager.readContent(rec.getId(), out);
|
||||
}
|
||||
}
|
||||
}
|
||||
var exportStage = new Stage();
|
||||
exportStage.setScene(new Scene(root));
|
||||
exportStage.setTitle("Статус сохранения");
|
||||
exportStage.initModality(Modality.APPLICATION_MODAL);
|
||||
exportStage.initOwner(stage);
|
||||
|
||||
var controller = (ExportInfoController)loader.getController();
|
||||
controller.setStage(exportStage);
|
||||
controller.setManager(manager);
|
||||
|
||||
exportStage.setOnShowing(event -> {
|
||||
stage.getScene().getRoot().setDisable(true);
|
||||
controller.startExport(contentRec, currentDir);
|
||||
});
|
||||
exportStage.setOnHiding(event -> {
|
||||
controller.stopExport();
|
||||
stage.getScene().getRoot().setDisable(false);
|
||||
});
|
||||
exportStage.showAndWait();
|
||||
}
|
||||
}
|
||||
|
||||
29
src/main/resources/view/export-dialog.fxml
Normal file
29
src/main/resources/view/export-dialog.fxml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?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.Label?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<VBox fx:controller="ru.di9.ss14.extractor.gui.ExportInfoController"
|
||||
prefHeight="70.0" prefWidth="409.0"
|
||||
xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
|
||||
</padding>
|
||||
<Label text="Сохранение..."/>
|
||||
<Label fx:id="labelCurrentExport" text="Texture/Alert/some.rsi/meta.json">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<ButtonBar prefHeight="40.0" prefWidth="200.0">
|
||||
<buttons>
|
||||
<Button fx:id="btnCancel" mnemonicParsing="false" text="Отмена"/>
|
||||
</buttons>
|
||||
<VBox.margin>
|
||||
<Insets top="10.0"/>
|
||||
</VBox.margin>
|
||||
</ButtonBar>
|
||||
</VBox>
|
||||
Reference in New Issue
Block a user