From be39f64c368d13f3572e65903137c0dd045cd07f Mon Sep 17 00:00:00 2001 From: Timofeev_V_S Date: Sun, 22 Mar 2026 17:25:38 +0300 Subject: [PATCH 1/2] commander: test --- .../java/commander/CommanderApplication.java | 19 +- .../hse/java/commander/MainController.java | 190 ++++++++++++++++-- .../hse/java/commander/commander-ui.fxml | 12 +- 3 files changed, 186 insertions(+), 35 deletions(-) diff --git a/commander/src/main/java/hse/java/commander/CommanderApplication.java b/commander/src/main/java/hse/java/commander/CommanderApplication.java index 471f6fd5..fab31f01 100644 --- a/commander/src/main/java/hse/java/commander/CommanderApplication.java +++ b/commander/src/main/java/hse/java/commander/CommanderApplication.java @@ -5,22 +5,13 @@ import javafx.scene.Scene; import javafx.stage.Stage; -import java.io.IOException; -import java.nio.file.Paths; - public class CommanderApplication extends Application { @Override - public void start(Stage stage) throws IOException { - FXMLLoader fxmlLoader = new FXMLLoader(CommanderApplication.class.getResource("commander-ui.fxml")); - Scene scene = new Scene(fxmlLoader.load(), 400, 400); - MainController ctrl = fxmlLoader.getController(); - String home = System.getProperty("user.home"); - if (ctrl != null && home != null) { - ctrl.setInitialDirs(Paths.get(home), Paths.get(home)); - } - stage.setTitle("Commander"); + public void start(Stage stage) throws Exception { + FXMLLoader loader = new FXMLLoader(getClass().getResource("commander-ui.fxml")); + Scene scene = new Scene(loader.load()); + stage.setTitle("Two-Panel File Commander"); stage.setScene(scene); stage.show(); - System.out.println("Hello world"); } -} +} \ No newline at end of file diff --git a/commander/src/main/java/hse/java/commander/MainController.java b/commander/src/main/java/hse/java/commander/MainController.java index 5de3b66d..53d4c5f5 100644 --- a/commander/src/main/java/hse/java/commander/MainController.java +++ b/commander/src/main/java/hse/java/commander/MainController.java @@ -1,45 +1,205 @@ package hse.java.commander; +import javafx.application.Platform; import javafx.fxml.FXML; +import javafx.scene.control.Alert; import javafx.scene.control.Button; import javafx.scene.control.ListView; +import javafx.scene.input.MouseButton; -import java.nio.file.Path; +import java.io.IOException; +import java.nio.file.*; +import java.util.stream.Collectors; public class MainController { @FXML public ListView left; - @FXML public ListView right; - + @FXML + public Button copy; @FXML public Button move; + @FXML + public Button delete; private Path leftDir; private Path rightDir; + private ListView activePanel; - // for testing public void setInitialDirs(Path leftStart, Path rightStart) { this.leftDir = leftStart; this.rightDir = rightStart; } + @FXML public void initialize() { - move.setOnMouseClicked(event -> { - - }); - System.out.println(System.getProperty("user.home")); - left.getItems().add("Kek"); + if (leftDir == null) leftDir = Paths.get(System.getProperty("user.home")); + if (rightDir == null) rightDir = Paths.get(System.getProperty("user.home")); left.setOnMouseClicked(event -> { - if (event.getClickCount() == 2) { - int index = left.getSelectionModel().getSelectedIndex(); - if (index >= 0) { - left.getItems().set(index, "clicked"); - } + if (event.getClickCount() == 2 && event.getButton() == MouseButton.PRIMARY) { + navigate(left); } + activePanel = left; }); + right.setOnMouseClicked(event -> { + if (event.getClickCount() == 2 && event.getButton() == MouseButton.PRIMARY) { + navigate(right); + } + activePanel = right; + }); + + activePanel = left; + + copy.setOnAction(e -> performCopy()); + move.setOnAction(e -> performMove()); + delete.setOnAction(e -> performDelete()); + + refresh(left, leftDir); + refresh(right, rightDir); + } + + private void navigate(ListView panel) { + String selected = panel.getSelectionModel().getSelectedItem(); + if (selected == null) return; + + Path currentDir = panel == left ? leftDir : rightDir; + Path newDir; + if (selected.equals("..")) { + newDir = currentDir.getParent(); + if (newDir == null) return; + } else { + newDir = currentDir.resolve(selected); + if (!Files.isDirectory(newDir)) return; + } + + if (panel == left) { + leftDir = newDir; + refresh(left, leftDir); + } else { + rightDir = newDir; + refresh(right, rightDir); + } + } + + private void refresh(ListView panel, Path dir) { + try { + var items = Files.list(dir) + .filter(p -> !p.getFileName().toString().startsWith(".")) + .map(p -> p.getFileName().toString()) + .sorted() + .collect(Collectors.toList()); + items.add(0, ".."); + Platform.runLater(() -> panel.getItems().setAll(items)); + } catch (IOException e) { + showError("Cannot read directory", e.getMessage()); + } + } + + private void performCopy() { + if (activePanel == null) return; + Path sourceDir = activePanel == left ? leftDir : rightDir; + Path targetDir = activePanel == left ? rightDir : leftDir; + String selected = activePanel.getSelectionModel().getSelectedItem(); + if (selected == null || selected.equals("..")) return; + + Path source = sourceDir.resolve(selected); + Path target = targetDir.resolve(selected); + + try { + if (Files.isDirectory(source)) { + copyDirectory(source, target); + } else { + Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); + } + refreshBoth(); + } catch (IOException e) { + showError("Copy failed", e.getMessage()); + refreshBoth(); + } + } + + private void performMove() { + if (activePanel == null) return; + Path sourceDir = activePanel == left ? leftDir : rightDir; + Path targetDir = activePanel == left ? rightDir : leftDir; + String selected = activePanel.getSelectionModel().getSelectedItem(); + if (selected == null || selected.equals("..")) return; + + Path source = sourceDir.resolve(selected); + Path target = targetDir.resolve(selected); + + try { + Files.move(source, target, StandardCopyOption.REPLACE_EXISTING); + refreshBoth(); + } catch (IOException e) { + showError("Move failed", e.getMessage()); + refreshBoth(); + } + } + + private void performDelete() { + if (activePanel == null) return; + Path dir = activePanel == left ? leftDir : rightDir; + String selected = activePanel.getSelectionModel().getSelectedItem(); + if (selected == null || selected.equals("..")) return; + + Path target = dir.resolve(selected); + try { + if (Files.isDirectory(target)) { + deleteDirectory(target); + } else { + Files.delete(target); + } + refreshBoth(); + } catch (IOException e) { + showError("Delete failed", e.getMessage()); + refreshBoth(); + } + } + + private void copyDirectory(Path source, Path target) throws IOException { + try (var stream = Files.walk(source)) { + stream.forEach(sourcePath -> { + Path targetPath = target.resolve(source.relativize(sourcePath)); + try { + if (Files.isDirectory(sourcePath)) { + Files.createDirectories(targetPath); + } else { + Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING); + } + } catch (IOException e) { + System.err.println("Failed to copy " + sourcePath + ": " + e.getMessage()); + } + }); + } + } + + private void deleteDirectory(Path dir) throws IOException { + try (var stream = Files.walk(dir)) { + stream.sorted((a, b) -> b.compareTo(a)) + .forEach(path -> { + try { + Files.deleteIfExists(path); + } catch (IOException e) { + System.err.println("Failed to delete " + path + ": " + e.getMessage()); + } + }); + } + } + + private void refreshBoth() { + refresh(left, leftDir); + refresh(right, rightDir); + } + + private void showError(String title, String message) { + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle(title); + alert.setHeaderText(null); + alert.setContentText(message); + alert.showAndWait(); } -} +} \ No newline at end of file diff --git a/commander/src/main/resources/hse/java/commander/commander-ui.fxml b/commander/src/main/resources/hse/java/commander/commander-ui.fxml index 724bbc8a..b824ae31 100644 --- a/commander/src/main/resources/hse/java/commander/commander-ui.fxml +++ b/commander/src/main/resources/hse/java/commander/commander-ui.fxml @@ -5,12 +5,12 @@ - - + + -