diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a87e6df
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,39 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+.idea/
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/README.md b/README.md
index e5ed2eb..3bd145c 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,5 @@
-# perfin
-Personal accounting desktop app to track your finances.
+# Perfin
+
+> *Per*sonal *Fin*ance
+
+Personal accounting desktop app to track your finances using common file formats.
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..928fd11
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,49 @@
+
+
+ 4.0.0
+
+ com.andrewlalis
+ perfin
+ 0.0.1-SNAPSHOT
+
+
+ 21
+ 21
+ UTF-8
+ 21.0.1
+
+
+
+
+ org.openjfx
+ javafx-controls
+ ${javafx.version}
+
+
+ org.openjfx
+ javafx-fxml
+ ${javafx.version}
+
+
+
+ org.xerial
+ sqlite-jdbc
+ 3.44.1.0
+
+
+
+
+
+
+ org.openjfx
+ javafx-maven-plugin
+ 0.0.8
+
+ com.andrewlalis.perfin.PerfinApp
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/andrewlalis/perfin/PerfinApp.java b/src/main/java/com/andrewlalis/perfin/PerfinApp.java
new file mode 100644
index 0000000..74a6e44
--- /dev/null
+++ b/src/main/java/com/andrewlalis/perfin/PerfinApp.java
@@ -0,0 +1,49 @@
+package com.andrewlalis.perfin;
+
+import javafx.application.Application;
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+
+public class PerfinApp extends Application {
+ public static void main(String[] args) {
+ launch(args);
+ }
+
+ @Override
+ public void start(Stage stage) {
+ initMainScreen(stage);
+ Stage splashStage = showStartupSplashScreen();
+ // Once the splash stage is hidden, show the main stage.
+ splashStage.showingProperty().not().addListener((v, old, hidden) -> {
+ if (hidden) {
+ showMainScreen(stage);
+ }
+ });
+ }
+
+ private void initMainScreen(Stage stage) {
+ stage.hide();
+ stage.setScene(SceneUtil.load("/main.fxml"));
+ stage.setTitle("Perfin");
+ }
+
+ private void showMainScreen(Stage stage) {
+ System.out.println("Showing the main application.");
+// stage.setMaximized(true);
+ stage.show();
+ }
+
+ /**
+ * Shows a startup "splash" screen for a short time.
+ * @return The stage in which the splash screen is shown.
+ */
+ private Stage showStartupSplashScreen() {
+ Stage stage = new Stage();
+ stage.initStyle(StageStyle.UNDECORATED);
+ stage.setScene(SceneUtil.load("/startup-splash-screen.fxml"));
+ stage.setTitle("Loading");
+ stage.setResizable(false);
+ stage.show();
+ return stage;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/andrewlalis/perfin/SceneUtil.java b/src/main/java/com/andrewlalis/perfin/SceneUtil.java
new file mode 100644
index 0000000..7c984a3
--- /dev/null
+++ b/src/main/java/com/andrewlalis/perfin/SceneUtil.java
@@ -0,0 +1,37 @@
+package com.andrewlalis.perfin;
+
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Scene;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.URL;
+
+public class SceneUtil {
+ public static Scene load(String fxml, Object controller) {
+ FXMLLoader loader = new FXMLLoader(SceneUtil.class.getResource(fxml));
+ if (controller != null) {
+ if (loader.getController() != null) {
+ throw new IllegalStateException("Cannot set loader for resource " + fxml + " because it has declared one already.");
+ }
+ loader.setController(controller);
+ }
+ try {
+ return new Scene(loader.load());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ public static Scene load(String fxml) {
+ return load(fxml, null);
+ }
+
+ public static void addStylesheets(Scene scene, String... resources) {
+ for (String resource : resources) {
+ URL url = SceneUtil.class.getResource(resource);
+ if (url == null) throw new RuntimeException("Could not load resource " + resource);
+ scene.getStylesheets().add(url.toExternalForm());
+ }
+ }
+}
diff --git a/src/main/java/com/andrewlalis/perfin/control/MainController.java b/src/main/java/com/andrewlalis/perfin/control/MainController.java
new file mode 100644
index 0000000..c8847c3
--- /dev/null
+++ b/src/main/java/com/andrewlalis/perfin/control/MainController.java
@@ -0,0 +1,10 @@
+package com.andrewlalis.perfin.control;
+
+import javafx.fxml.FXML;
+
+public class MainController {
+
+ @FXML
+ public void initialize() {
+ }
+}
diff --git a/src/main/java/com/andrewlalis/perfin/control/StartupSplashScreenController.java b/src/main/java/com/andrewlalis/perfin/control/StartupSplashScreenController.java
new file mode 100644
index 0000000..b8a37aa
--- /dev/null
+++ b/src/main/java/com/andrewlalis/perfin/control/StartupSplashScreenController.java
@@ -0,0 +1,36 @@
+package com.andrewlalis.perfin.control;
+
+import javafx.application.Platform;
+import javafx.fxml.FXML;
+import javafx.scene.control.Label;
+import javafx.stage.Stage;
+
+public class StartupSplashScreenController {
+ @FXML
+ public Label content;
+
+ @FXML
+ public void initialize() {
+ content.setText("Loading Perfin...");
+ Thread.ofVirtual().start(() -> {
+ try {
+ Thread.sleep(1000);
+
+ Platform.runLater(() -> content.setText("Still loading..."));
+ Thread.sleep(1000);
+
+ Platform.runLater(() -> content.setText("Almost done..."));
+ Thread.sleep(1000);
+
+ Platform.runLater(() -> content.setText("Done!"));
+ Thread.sleep(500);
+
+ System.out.println("Closing splash screen...");
+ Stage stage = (Stage) content.getScene().getWindow();
+ Platform.runLater(stage::close);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+}
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
new file mode 100644
index 0000000..b4b18d2
--- /dev/null
+++ b/src/main/java/module-info.java
@@ -0,0 +1,11 @@
+module com.andrewlalis.perfin {
+ requires javafx.base;
+ requires javafx.controls;
+ requires javafx.fxml;
+ requires javafx.graphics;
+
+ requires org.xerial.sqlitejdbc;
+
+ exports com.andrewlalis.perfin to javafx.graphics;
+ opens com.andrewlalis.perfin.control to javafx.fxml;
+}
\ No newline at end of file
diff --git a/src/main/resources/main.fxml b/src/main/resources/main.fxml
new file mode 100644
index 0000000..2af8d64
--- /dev/null
+++ b/src/main/resources/main.fxml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
diff --git a/src/main/resources/startup-splash-screen.fxml b/src/main/resources/startup-splash-screen.fxml
new file mode 100644
index 0000000..e88644c
--- /dev/null
+++ b/src/main/resources/startup-splash-screen.fxml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+