diff --git a/pom.xml b/pom.xml index b097caf..4af87d0 100644 --- a/pom.xml +++ b/pom.xml @@ -56,5 +56,11 @@ jnativehook 2.1.0 + + + com.formdev + flatlaf + 1.0-rc3 + \ 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 index 80f0b23..a31fda5 100644 --- a/src/main/java/nl/andrewlalis/blockbookbinder/BlockBookBinder.java +++ b/src/main/java/nl/andrewlalis/blockbookbinder/BlockBookBinder.java @@ -1,5 +1,6 @@ package nl.andrewlalis.blockbookbinder; +import com.formdev.flatlaf.FlatDarkLaf; import nl.andrewlalis.blockbookbinder.view.MainFrame; import javax.swing.*; @@ -10,6 +11,7 @@ import javax.swing.*; public class BlockBookBinder { public static void main(String[] args) { SwingUtilities.invokeLater(() -> { + FlatDarkLaf.install(); var mainFrame = new MainFrame(); mainFrame.setupAndShow(); }); diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/control/ConvertToBookActionListener.java b/src/main/java/nl/andrewlalis/blockbookbinder/control/ConvertToBookActionListener.java index bff51d3..b2b1c73 100644 --- a/src/main/java/nl/andrewlalis/blockbookbinder/control/ConvertToBookActionListener.java +++ b/src/main/java/nl/andrewlalis/blockbookbinder/control/ConvertToBookActionListener.java @@ -1,7 +1,7 @@ package nl.andrewlalis.blockbookbinder.control; import nl.andrewlalis.blockbookbinder.model.build.BookBuilder; -import nl.andrewlalis.blockbookbinder.view.BookPreviewPanel; +import nl.andrewlalis.blockbookbinder.view.book.BookPreviewPanel; import nl.andrewlalis.blockbookbinder.view.SourceTextPanel; import java.awt.event.ActionEvent; diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/control/export/BookExporter.java b/src/main/java/nl/andrewlalis/blockbookbinder/control/export/BookExporter.java index 563b85a..1444376 100644 --- a/src/main/java/nl/andrewlalis/blockbookbinder/control/export/BookExporter.java +++ b/src/main/java/nl/andrewlalis/blockbookbinder/control/export/BookExporter.java @@ -39,7 +39,7 @@ public class BookExporter implements Runnable { @Setter private volatile boolean nextPageRequested; - private final PagePasteListener pagePasteListener; + private final ExporterKeyListener exporterKeyListener; private final Clipboard clipboard; private Robot robot; @@ -61,7 +61,7 @@ public class BookExporter implements Runnable { this.beginningExportClip = this.loadAudioClip(ApplicationProperties.getProp("export_dialog.beginning_export")); this.finishClip = this.loadAudioClip(ApplicationProperties.getProp("export_dialog.finish_sound")); this.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - this.pagePasteListener = new PagePasteListener(this); + this.exporterKeyListener = new ExporterKeyListener(this); if (this.autoPaste) { // Only initialize the robot if we'll need it. try { this.robot = new Robot(); @@ -193,7 +193,7 @@ public class BookExporter implements Runnable { logger.setLevel(Level.WARNING); logger.setUseParentHandlers(false); GlobalScreen.registerNativeHook(); - GlobalScreen.addNativeKeyListener(this.pagePasteListener); + GlobalScreen.addNativeKeyListener(this.exporterKeyListener); } catch (NativeHookException nativeHookException) { System.err.println("Could not register native hook."); nativeHookException.printStackTrace(); @@ -202,7 +202,7 @@ public class BookExporter implements Runnable { private void stopNativeListener() { try { - GlobalScreen.removeNativeKeyListener(this.pagePasteListener); + GlobalScreen.removeNativeKeyListener(this.exporterKeyListener); GlobalScreen.unregisterNativeHook(); } catch (NativeHookException nativeHookException) { System.err.println("Could not unregister a native hook."); @@ -243,9 +243,7 @@ public class BookExporter implements Runnable { } private void updateStatusLabel(String text) { - SwingUtilities.invokeLater(() -> { - this.statusPanel.getStatusLabel().setText(text); - }); + SwingUtilities.invokeLater(() -> this.statusPanel.getStatusLabel().setText(text)); } private void updateStatusProgressBar(int nextPage) { @@ -257,8 +255,6 @@ public class BookExporter implements Runnable { } private void addStatusMessage(String message) { - SwingUtilities.invokeLater(() -> { - this.statusPanel.getOutputTextArea().append(message + "\n"); - }); + SwingUtilities.invokeLater(() -> this.statusPanel.getOutputTextArea().append(message + "\n")); } } diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/control/export/PagePasteListener.java b/src/main/java/nl/andrewlalis/blockbookbinder/control/export/ExporterKeyListener.java similarity index 71% rename from src/main/java/nl/andrewlalis/blockbookbinder/control/export/PagePasteListener.java rename to src/main/java/nl/andrewlalis/blockbookbinder/control/export/ExporterKeyListener.java index a5b0899..53746bf 100644 --- a/src/main/java/nl/andrewlalis/blockbookbinder/control/export/PagePasteListener.java +++ b/src/main/java/nl/andrewlalis/blockbookbinder/control/export/ExporterKeyListener.java @@ -3,10 +3,14 @@ package nl.andrewlalis.blockbookbinder.control.export; import org.jnativehook.keyboard.NativeKeyEvent; import org.jnativehook.keyboard.NativeKeyListener; -public class PagePasteListener implements NativeKeyListener { - private BookExporter exporterRunnable; +/** + * Native key listener that's used during the export process, to detect when the + * user performs certain key actions outside of the focus of this program. + */ +public class ExporterKeyListener implements NativeKeyListener { + private final BookExporter exporterRunnable; - public PagePasteListener(BookExporter exporterRunnable) { + public ExporterKeyListener(BookExporter exporterRunnable) { this.exporterRunnable = exporterRunnable; } diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/model/Book.java b/src/main/java/nl/andrewlalis/blockbookbinder/model/Book.java index 9277706..290dab1 100644 --- a/src/main/java/nl/andrewlalis/blockbookbinder/model/Book.java +++ b/src/main/java/nl/andrewlalis/blockbookbinder/model/Book.java @@ -1,6 +1,7 @@ package nl.andrewlalis.blockbookbinder.model; import lombok.Getter; +import nl.andrewlalis.blockbookbinder.util.ApplicationProperties; import java.util.ArrayList; import java.util.List; @@ -35,6 +36,20 @@ public class Book { return book; } + public List splitByPageLimit() { + final int pagesPerBook = ApplicationProperties.getIntProp("book.max_pages"); + List books = new ArrayList<>((this.getPageCount() / pagesPerBook) + 1); + Book currentBook = new Book(); + for (BookPage page : this.getPages()) { + currentBook.addPage(page.copy()); + if (currentBook.getPageCount() == pagesPerBook) { + books.add(currentBook); + currentBook = new Book(); + } + } + return books; + } + @Override public String toString() { StringBuilder sb = new StringBuilder("Book of " + this.getPageCount() + " pages:\n"); diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/model/BookPage.java b/src/main/java/nl/andrewlalis/blockbookbinder/model/BookPage.java index 17f903f..d246466 100644 --- a/src/main/java/nl/andrewlalis/blockbookbinder/model/BookPage.java +++ b/src/main/java/nl/andrewlalis/blockbookbinder/model/BookPage.java @@ -13,7 +13,7 @@ public class BookPage { } public boolean addLine(String line) { - if (this.lines.size() == ApplicationProperties.getIntProp("book.page_max_lines")) { + if (this.lines.size() >= ApplicationProperties.getIntProp("book.page_max_lines")) { return false; } this.lines.add(line); @@ -24,8 +24,24 @@ public class BookPage { return !this.lines.isEmpty(); } + public BookPage copy() { + BookPage c = new BookPage(); + for (String line : this.lines) { + c.addLine(line); + } + return c; + } + @Override public String toString() { return String.join("\n", this.lines); } + + public static BookPage fromString(String s) { + BookPage p = new BookPage(); + for (String line : s.split("\n")) { + p.addLine(line); + } + return p; + } } diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/model/CharWidthMapper.java b/src/main/java/nl/andrewlalis/blockbookbinder/model/CharWidthMapper.java index 9e31ede..ad5351b 100644 --- a/src/main/java/nl/andrewlalis/blockbookbinder/model/CharWidthMapper.java +++ b/src/main/java/nl/andrewlalis/blockbookbinder/model/CharWidthMapper.java @@ -1,11 +1,15 @@ package nl.andrewlalis.blockbookbinder.model; +import lombok.Getter; import nl.andrewlalis.blockbookbinder.util.ApplicationProperties; import java.util.HashMap; import java.util.Map; public class CharWidthMapper { + @Getter + private static final CharWidthMapper instance = new CharWidthMapper(); + private final Map charWidthMap; public CharWidthMapper() { diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/model/build/BookBuilder.java b/src/main/java/nl/andrewlalis/blockbookbinder/model/build/BookBuilder.java index 20115eb..c9bd747 100644 --- a/src/main/java/nl/andrewlalis/blockbookbinder/model/build/BookBuilder.java +++ b/src/main/java/nl/andrewlalis/blockbookbinder/model/build/BookBuilder.java @@ -9,8 +9,6 @@ import java.util.ArrayList; import java.util.List; public class BookBuilder { - private final CharWidthMapper charWidthMapper = new CharWidthMapper(); - /** * Builds a full book of pages from the given source text. * @param source The source text to convert. @@ -60,7 +58,7 @@ public class BookBuilder { sourceIndex++; symbolBuilder.setLength(0); symbolBuilder.append(c); - int symbolWidth = this.charWidthMapper.getWidth(c); + int symbolWidth = CharWidthMapper.getInstance().getWidth(c); // Since there's a 1-pixel gap between characters, add it to the width if this isn't the first char. if (lineBuilder.length() > 0) { @@ -88,7 +86,7 @@ public class BookBuilder { ) { char nextChar = sourceChars[sourceIndex]; symbolBuilder.append(nextChar); - symbolWidth += 1 + this.charWidthMapper.getWidth(nextChar); + symbolWidth += 1 + CharWidthMapper.getInstance().getWidth(nextChar); sourceIndex++; } } diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/view/MainFrame.java b/src/main/java/nl/andrewlalis/blockbookbinder/view/MainFrame.java index b99f662..53df354 100644 --- a/src/main/java/nl/andrewlalis/blockbookbinder/view/MainFrame.java +++ b/src/main/java/nl/andrewlalis/blockbookbinder/view/MainFrame.java @@ -3,6 +3,7 @@ package nl.andrewlalis.blockbookbinder.view; import nl.andrewlalis.blockbookbinder.model.Book; import nl.andrewlalis.blockbookbinder.util.ApplicationProperties; import nl.andrewlalis.blockbookbinder.view.about.AboutDialog; +import nl.andrewlalis.blockbookbinder.view.book.BookPreviewPanel; import nl.andrewlalis.blockbookbinder.view.export.ExportToBookDialog; import javax.swing.*; @@ -13,11 +14,11 @@ import java.net.URL; * The main window of the application. */ public class MainFrame extends JFrame { - 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.setPreferredSize(new Dimension( + ApplicationProperties.getIntProp("frame.default_width"), + ApplicationProperties.getIntProp("frame.default_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"); diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/view/SourceTextPanel.java b/src/main/java/nl/andrewlalis/blockbookbinder/view/SourceTextPanel.java index 0815a65..8ca6319 100644 --- a/src/main/java/nl/andrewlalis/blockbookbinder/view/SourceTextPanel.java +++ b/src/main/java/nl/andrewlalis/blockbookbinder/view/SourceTextPanel.java @@ -2,6 +2,7 @@ package nl.andrewlalis.blockbookbinder.view; import nl.andrewlalis.blockbookbinder.control.CleanSourceActionListener; import nl.andrewlalis.blockbookbinder.control.ConvertToBookActionListener; +import nl.andrewlalis.blockbookbinder.view.book.BookPreviewPanel; import javax.swing.*; import javax.swing.border.EmptyBorder; diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/view/about/AboutDialog.java b/src/main/java/nl/andrewlalis/blockbookbinder/view/about/AboutDialog.java index f42523e..81ffcc7 100644 --- a/src/main/java/nl/andrewlalis/blockbookbinder/view/about/AboutDialog.java +++ b/src/main/java/nl/andrewlalis/blockbookbinder/view/about/AboutDialog.java @@ -9,7 +9,6 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.net.URI; import java.net.URISyntaxException; import java.util.stream.Collectors; @@ -31,6 +30,7 @@ public class AboutDialog extends JDialog { textPane.setEditable(false); textPane.setContentType("text/html"); textPane.setText(this.getAboutHtml()); + textPane.setCaretPosition(0); textPane.addHyperlinkListener(e -> { try { if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/view/book/BookPageDocumentFilter.java b/src/main/java/nl/andrewlalis/blockbookbinder/view/book/BookPageDocumentFilter.java new file mode 100644 index 0000000..0acc323 --- /dev/null +++ b/src/main/java/nl/andrewlalis/blockbookbinder/view/book/BookPageDocumentFilter.java @@ -0,0 +1,23 @@ +package nl.andrewlalis.blockbookbinder.view.book; + +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.DocumentFilter; + +public class BookPageDocumentFilter extends DocumentFilter { + + @Override + public void remove(FilterBypass fb, int offset, int length) throws BadLocationException { + super.remove(fb, offset, length); + } + + @Override + public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException { + super.insertString(fb, offset, string, attr); + } + + @Override + public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { + super.replace(fb, offset, length, text, attrs); + } +} diff --git a/src/main/java/nl/andrewlalis/blockbookbinder/view/BookPreviewPanel.java b/src/main/java/nl/andrewlalis/blockbookbinder/view/book/BookPreviewPanel.java similarity index 98% rename from src/main/java/nl/andrewlalis/blockbookbinder/view/BookPreviewPanel.java rename to src/main/java/nl/andrewlalis/blockbookbinder/view/book/BookPreviewPanel.java index 35f710a..f7b5299 100644 --- a/src/main/java/nl/andrewlalis/blockbookbinder/view/BookPreviewPanel.java +++ b/src/main/java/nl/andrewlalis/blockbookbinder/view/book/BookPreviewPanel.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.blockbookbinder.view; +package nl.andrewlalis.blockbookbinder.view.book; import lombok.Getter; import nl.andrewlalis.blockbookbinder.model.Book;