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}
+ ${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;