diff --git a/.gitignore b/.gitignore
index 0e13eeb..efbf295 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,7 @@ buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
+
+# IntelliJ Configuration Files
+.idea/
+*.iml
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..0d82aea
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,25 @@
+
+
+ 4.0.0
+
+ nl.andrewlalis
+ BlockBookBinder
+ 0.0.1
+
+
+ 12
+ 12
+
+
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.14
+ provided
+
+
+
\ No newline at end of file
diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/BlockBookBinder.java b/src/main/java/nl/andrewlalis/blockbookbinder/BlockBookBinder.java
new file mode 100644
index 0000000..80f0b23
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/blockbookbinder/BlockBookBinder.java
@@ -0,0 +1,17 @@
+package nl.andrewlalis.blockbookbinder;
+
+import nl.andrewlalis.blockbookbinder.view.MainFrame;
+
+import javax.swing.*;
+
+/**
+ * The main class for the application.
+ */
+public class BlockBookBinder {
+ public static void main(String[] args) {
+ SwingUtilities.invokeLater(() -> {
+ var mainFrame = new MainFrame();
+ mainFrame.setupAndShow();
+ });
+ }
+}
diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/control/ImportAction.java b/src/main/java/nl/andrewlalis/blockbookbinder/control/ImportAction.java
new file mode 100644
index 0000000..f0c2b6e
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/blockbookbinder/control/ImportAction.java
@@ -0,0 +1,19 @@
+package nl.andrewlalis.blockbookbinder.control;
+
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+
+public class ImportAction extends AbstractAction {
+ public ImportAction(String name) {
+ super(name);
+ }
+
+ public ImportAction(String name, Icon icon) {
+ super(name, icon);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ System.out.println("Import!");
+ }
+}
diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/model/BookContents.java b/src/main/java/nl/andrewlalis/blockbookbinder/model/BookContents.java
new file mode 100644
index 0000000..3ef02a6
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/blockbookbinder/model/BookContents.java
@@ -0,0 +1,15 @@
+package nl.andrewlalis.blockbookbinder.model;
+
+import lombok.Getter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BookContents {
+ @Getter
+ private final List pages;
+
+ public BookContents() {
+ this.pages = new ArrayList<>();
+ }
+}
diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/model/BookPage.java b/src/main/java/nl/andrewlalis/blockbookbinder/model/BookPage.java
new file mode 100644
index 0000000..f05f87a
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/blockbookbinder/model/BookPage.java
@@ -0,0 +1,14 @@
+package nl.andrewlalis.blockbookbinder.model;
+
+import lombok.Getter;
+import lombok.Setter;
+
+public class BookPage {
+ @Getter
+ @Setter
+ private String content;
+
+ public BookPage() {
+ this.content = "";
+ }
+}
diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/util/ApplicationProperties.java b/src/main/java/nl/andrewlalis/blockbookbinder/util/ApplicationProperties.java
new file mode 100644
index 0000000..6e8dc0b
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/blockbookbinder/util/ApplicationProperties.java
@@ -0,0 +1,42 @@
+package nl.andrewlalis.blockbookbinder.util;
+
+import lombok.Getter;
+
+import java.io.IOException;
+import java.util.Properties;
+
+/**
+ * Singleton class which handles the properties defined in an external
+ * properties file.
+ */
+public class ApplicationProperties {
+ private static ApplicationProperties instance;
+ @Getter
+ private final Properties properties;
+
+ public static ApplicationProperties getInstance() {
+ if (instance == null) {
+ try {
+ instance = new ApplicationProperties();
+ } catch (IOException e) {
+ System.err.println("Could not load properties!");
+ System.exit(1);
+ }
+ }
+ return instance;
+ }
+
+ /**
+ * Shortcut for getting a property.
+ * @param key The property's key.
+ * @return The value for that property.
+ */
+ public static String getProp(String key) {
+ return getInstance().getProperties().getProperty(key);
+ }
+
+ private ApplicationProperties() throws IOException {
+ this.properties = new Properties();
+ this.properties.load(this.getClass().getClassLoader().getResourceAsStream("application.properties"));
+ }
+}
diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/view/MainFrame.java b/src/main/java/nl/andrewlalis/blockbookbinder/view/MainFrame.java
new file mode 100644
index 0000000..551ca21
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/blockbookbinder/view/MainFrame.java
@@ -0,0 +1,106 @@
+package nl.andrewlalis.blockbookbinder.view;
+
+import nl.andrewlalis.blockbookbinder.control.ImportAction;
+import nl.andrewlalis.blockbookbinder.util.ApplicationProperties;
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+import java.awt.datatransfer.StringSelection;
+import java.net.URL;
+
+/**
+ * The main window of the application.
+ */
+public class MainFrame extends JFrame {
+ private Action importAction;
+
+ public void setupAndShow() {
+ final int width = Integer.parseInt(ApplicationProperties.getProp("frame.default_width"));
+ final int height = Integer.parseInt(ApplicationProperties.getProp("frame.default_height"));
+ this.setPreferredSize(new Dimension(width, height));
+ this.setTitle(ApplicationProperties.getProp("frame.title"));
+ this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ final URL iconUrl = this.getClass().getClassLoader().getResource("images/book_and_quill.png");
+ if (iconUrl != null) {
+ this.setIconImage(new ImageIcon(iconUrl).getImage());
+ }
+
+ this.initActions();
+ this.setContentPane(this.buildContentPane());
+ this.setJMenuBar(this.buildMenuBar());
+
+ this.pack();
+ this.setLocationRelativeTo(null);
+ this.setVisible(true);
+ }
+
+ private void initActions() {
+ this.importAction = new ImportAction("Import");
+ }
+
+ private JMenuBar buildMenuBar() {
+ JMenuBar menuBar = new JMenuBar();
+
+ JMenu fileMenu = new JMenu("File");
+ fileMenu.add(new JMenuItem(this.importAction));
+ menuBar.add(fileMenu);
+
+ JMenu helpMenu = new JMenu("Help");
+ JMenuItem aboutItem = new JMenuItem("About");
+ helpMenu.add(aboutItem);
+ menuBar.add(helpMenu);
+
+ return menuBar;
+ }
+
+ private Container buildContentPane() {
+ JPanel mainPanel = new JPanel(new BorderLayout());
+
+ JPanel doublePanel = new JPanel(new GridLayout(1, 2));
+ mainPanel.add(doublePanel, BorderLayout.CENTER);
+ final Insets innerPanelInsets = new Insets(5, 5, 5, 5);
+
+
+ JPanel leftPanel = new JPanel(new BorderLayout());
+ doublePanel.add(leftPanel);
+ leftPanel.add(new JLabel("Book Preview"), BorderLayout.NORTH);
+ leftPanel.setBorder(new EmptyBorder(innerPanelInsets));
+
+ JTextArea previewPageTextArea = new JTextArea();
+ JScrollPane previewPageScrollPane = new JScrollPane(previewPageTextArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ leftPanel.add(previewPageScrollPane, BorderLayout.CENTER);
+
+ JPanel previewButtonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
+ previewButtonPanel.add(new JButton("<"));
+ previewButtonPanel.add(new JButton(">"));
+ leftPanel.add(previewButtonPanel, BorderLayout.SOUTH);
+
+
+ JPanel rightPanel = new JPanel(new BorderLayout());
+ doublePanel.add(rightPanel);
+ rightPanel.add(new JLabel("Source Text"), BorderLayout.NORTH);
+ rightPanel.setBorder(new EmptyBorder(innerPanelInsets));
+
+ JTextArea mainTextArea = new JTextArea();
+ JScrollPane scrollWrappedMainTextArea = new JScrollPane(mainTextArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ rightPanel.add(scrollWrappedMainTextArea, BorderLayout.CENTER);
+
+ JPanel rightPanelButtonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ rightPanel.add(rightPanelButtonPanel, BorderLayout.SOUTH);
+ rightPanelButtonPanel.add(new JButton(this.importAction));
+
+
+ JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ JButton exportButton = new JButton("Export to Book");
+ exportButton.addActionListener(e -> {
+ System.out.println("Starting export.");
+ final String fullText = mainTextArea.getText().trim();
+ Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(fullText.substring(0, 200)), null);
+ });
+ bottomPanel.add(exportButton);
+ mainPanel.add(bottomPanel, BorderLayout.SOUTH);
+
+ return mainPanel;
+ }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
new file mode 100644
index 0000000..c28913c
--- /dev/null
+++ b/src/main/resources/application.properties
@@ -0,0 +1,9 @@
+# Settings for the application's GUI.
+frame.title=Block Book Binder
+frame.default_width=800
+frame.default_height=600
+
+# Settings for Minecraft book interaction.
+book.max_pages=100
+book.page_max_lines=14
+book.page_max_width=113
diff --git a/src/main/resources/fonts/1_Minecraft-Regular.otf b/src/main/resources/fonts/1_Minecraft-Regular.otf
new file mode 100644
index 0000000..54f08ad
Binary files /dev/null and b/src/main/resources/fonts/1_Minecraft-Regular.otf differ
diff --git a/src/main/resources/images/book_and_quill.png b/src/main/resources/images/book_and_quill.png
new file mode 100644
index 0000000..2e29d63
Binary files /dev/null and b/src/main/resources/images/book_and_quill.png differ