diff --git a/.gitignore b/.gitignore index 9356e88..f4ad437 100644 --- a/.gitignore +++ b/.gitignore @@ -111,3 +111,4 @@ buildNumber.properties .idea/ clusters/ +output/ diff --git a/package.bat b/package.bat new file mode 100644 index 0000000..d52f333 --- /dev/null +++ b/package.bat @@ -0,0 +1,11 @@ +call mvn clean package +call jpackage ^ + --type app-image ^ + --verbose ^ + --dest target\image ^ + --name CrystalKeep ^ + --icon src/main/resources/nl/andrewlalis/crystalkeep/ui/images/cluster_node_icon.png ^ + --module crystalkeep/nl.andrewlalis.crystalkeep.CrystalKeep ^ + --module-path target\modules ^ + --module-path target\classes ^ + --win-console ^ \ No newline at end of file diff --git a/pom.xml b/pom.xml index 3cab3d1..9ba79bd 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ nl.andrewlalis crystalkeep - 1.0-SNAPSHOT + 0.0.1 11 @@ -14,23 +14,11 @@ UTF-8 UTF-8 16 + nl.andrewlalis.crystalkeep.CrystalKeep - - org.openjfx - javafx-maven-plugin - 0.0.4 - - nl.andrewlalis.crystalkeep.CrystalKeep - true - true - 2 - true - crystalkeep - - org.apache.maven.plugins maven-compiler-plugin @@ -42,27 +30,36 @@ 2.22.2 - org.apache.maven.plugins - maven-assembly-plugin - 3.3.0 + org.openjfx + javafx-maven-plugin + 0.0.4 - - - nl.andrewlalis.crystalkeep.CrystalKeep - - - - jar-with-dependencies - - true + ${java.version} + ${java.version} + ${java.version} + ${project.mainClass} + true + ${project.build.directory}/modules + ${main.class} + true + test + + + + org.apache.maven.plugins + maven-dependency-plugin - make-assembly - package + copy-dependencies + prepare-package - single + copy-dependencies + + runtime + ${project.build.directory}/modules + diff --git a/src/main/java/nl/andrewlalis/crystalkeep/control/MainViewController.java b/src/main/java/nl/andrewlalis/crystalkeep/control/MainViewController.java index 48c7eea..b79f9eb 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/control/MainViewController.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/control/MainViewController.java @@ -6,11 +6,13 @@ import javafx.geometry.Pos; import javafx.scene.control.*; import javafx.scene.layout.VBox; import javafx.stage.FileChooser; +import javafx.util.Duration; import nl.andrewlalis.crystalkeep.io.ClusterIO; import nl.andrewlalis.crystalkeep.model.*; import nl.andrewlalis.crystalkeep.view.ClusterTreeItem; import nl.andrewlalis.crystalkeep.view.CrystalItemTreeCell; import nl.andrewlalis.crystalkeep.view.ShardTreeItem; +import org.controlsfx.control.Notifications; import java.io.File; import java.nio.file.Path; @@ -82,8 +84,11 @@ public class MainViewController implements ModelListener { this.model.setActiveClusterPassword(pw); } } catch (Exception e) { - e.printStackTrace(); - new Alert(Alert.AlertType.WARNING, "Could not load cluster.").showAndWait(); + Notifications.create() + .text("Could not load cluster. Check that your password is correct.") + .hideAfter(Duration.seconds(3)) + .owner(this.shardDetailContainer.getScene().getWindow()) + .show(); return; } model.setActiveCluster(cluster); @@ -115,6 +120,8 @@ public class MainViewController implements ModelListener { chooser.setSelectedExtensionFilter(new FileChooser.ExtensionFilter("Cluster Files", "cts")); if (path != null) { chooser.setInitialDirectory(path.getParent().toFile()); + } else { + chooser.setInitialDirectory(ClusterIO.CLUSTER_PATH.toFile()); } File file = chooser.showSaveDialog(this.clusterTreeView.getScene().getWindow()); if (file == null) return; @@ -154,16 +161,27 @@ public class MainViewController implements ModelListener { pw = this.promptPassword().orElse(new char[0]); } ClusterIO loader = new ClusterIO(); + if (!path.getFileName().toString().trim().toLowerCase().endsWith(".cts")) { + path = path.resolveSibling(path.getFileName() + ".cts"); + } try { if (pw.length == 0) { loader.saveUnencrypted(model.getActiveCluster(), path); } else { loader.save(model.getActiveCluster(), path, pw); } + Notifications.create() + .text("Cluster saved to " + path) + .hideAfter(Duration.seconds(3)) + .owner(this.shardDetailContainer.getScene().getWindow()) + .show(); } catch (Exception e) { e.printStackTrace(); - var alert = new Alert(Alert.AlertType.ERROR, "Could not save cluster."); - alert.showAndWait(); + Notifications.create() + .text("Could not save cluster.") + .hideAfter(Duration.seconds(3)) + .owner(this.shardDetailContainer.getScene().getWindow()) + .show(); } } } diff --git a/src/main/java/nl/andrewlalis/crystalkeep/io/ClusterIO.java b/src/main/java/nl/andrewlalis/crystalkeep/io/ClusterIO.java index 884b0e2..f4b3ce0 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/io/ClusterIO.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/io/ClusterIO.java @@ -33,8 +33,15 @@ import java.security.spec.KeySpec; * @see nl.andrewlalis.crystalkeep.io.serialization.ClusterSerializer */ public class ClusterIO { - public static final Path CLUSTER_PATH = Path.of("clusters"); + public static final Path CLUSTER_PATH = Path.of(System.getProperty("user.home"), ".crystalkeep", "clusters"); public static final int FILE_VERSION = 1; + static { + try { + Files.createDirectories(CLUSTER_PATH); + } catch (IOException e) { + e.printStackTrace(); + } + } private final SecureRandom random; diff --git a/src/main/java/nl/andrewlalis/crystalkeep/util/StringUtils.java b/src/main/java/nl/andrewlalis/crystalkeep/util/StringUtils.java index 66d3d50..3a21a33 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/util/StringUtils.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/util/StringUtils.java @@ -1,6 +1,13 @@ package nl.andrewlalis.crystalkeep.util; public class StringUtils { + public static final String[] IMAGE_TYPES = { + "png", "jpg", "jpeg", "gif" + }; + public static final String[] PLAIN_TEXT_TYPES = { + "txt" + }; + public static boolean endsWithAny(String s, String... suffixes) { for (String suffix : suffixes) { if (s.endsWith(suffix)) return true; diff --git a/src/main/java/nl/andrewlalis/crystalkeep/view/shards/FileShardViewModel.java b/src/main/java/nl/andrewlalis/crystalkeep/view/shards/FileShardViewModel.java index 51066bf..1b1e363 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/view/shards/FileShardViewModel.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/view/shards/FileShardViewModel.java @@ -74,12 +74,18 @@ public class FileShardViewModel extends ShardViewModel { gp.add(extractFileButton, 1, 2); container.getChildren().add(gp); - if (StringUtils.endsWithAny(shard.getFileName().toLowerCase(), ".png", ".jpg", ".jpeg", ".gif")) { + if (StringUtils.endsWithAny(shard.getFileName().toLowerCase(), StringUtils.IMAGE_TYPES)) { container.getChildren().add(new Separator(Orientation.HORIZONTAL)); ImageView imageView = new ImageView(new Image(new ByteArrayInputStream(shard.getContents()))); imageView.setPreserveRatio(true); ScrollPane scrollPane = new ScrollPane(imageView); container.getChildren().add(scrollPane); + } else if (StringUtils.endsWithAny(shard.getFileName().toLowerCase(), StringUtils.PLAIN_TEXT_TYPES)) { + container.getChildren().add(new Separator(Orientation.HORIZONTAL)); + TextArea textArea = new TextArea(new String(shard.getContents())); + textArea.setEditable(false); + textArea.setWrapText(true); + container.getChildren().add(textArea); } return container;