Lots of cleanup.

This commit is contained in:
Andrew Lalis 2021-03-10 00:42:22 +01:00
parent 5c6587386e
commit ec06cf56cf
14 changed files with 91 additions and 25 deletions

View File

@ -56,5 +56,11 @@
<artifactId>jnativehook</artifactId> <artifactId>jnativehook</artifactId>
<version>2.1.0</version> <version>2.1.0</version>
</dependency> </dependency>
<dependency>
<groupId>com.formdev</groupId>
<artifactId>flatlaf</artifactId>
<version>1.0-rc3</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,5 +1,6 @@
package nl.andrewlalis.blockbookbinder; package nl.andrewlalis.blockbookbinder;
import com.formdev.flatlaf.FlatDarkLaf;
import nl.andrewlalis.blockbookbinder.view.MainFrame; import nl.andrewlalis.blockbookbinder.view.MainFrame;
import javax.swing.*; import javax.swing.*;
@ -10,6 +11,7 @@ import javax.swing.*;
public class BlockBookBinder { public class BlockBookBinder {
public static void main(String[] args) { public static void main(String[] args) {
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
FlatDarkLaf.install();
var mainFrame = new MainFrame(); var mainFrame = new MainFrame();
mainFrame.setupAndShow(); mainFrame.setupAndShow();
}); });

View File

@ -1,7 +1,7 @@
package nl.andrewlalis.blockbookbinder.control; package nl.andrewlalis.blockbookbinder.control;
import nl.andrewlalis.blockbookbinder.model.build.BookBuilder; 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 nl.andrewlalis.blockbookbinder.view.SourceTextPanel;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;

View File

@ -39,7 +39,7 @@ public class BookExporter implements Runnable {
@Setter @Setter
private volatile boolean nextPageRequested; private volatile boolean nextPageRequested;
private final PagePasteListener pagePasteListener; private final ExporterKeyListener exporterKeyListener;
private final Clipboard clipboard; private final Clipboard clipboard;
private Robot robot; private Robot robot;
@ -61,7 +61,7 @@ public class BookExporter implements Runnable {
this.beginningExportClip = this.loadAudioClip(ApplicationProperties.getProp("export_dialog.beginning_export")); this.beginningExportClip = this.loadAudioClip(ApplicationProperties.getProp("export_dialog.beginning_export"));
this.finishClip = this.loadAudioClip(ApplicationProperties.getProp("export_dialog.finish_sound")); this.finishClip = this.loadAudioClip(ApplicationProperties.getProp("export_dialog.finish_sound"));
this.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 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. if (this.autoPaste) { // Only initialize the robot if we'll need it.
try { try {
this.robot = new Robot(); this.robot = new Robot();
@ -193,7 +193,7 @@ public class BookExporter implements Runnable {
logger.setLevel(Level.WARNING); logger.setLevel(Level.WARNING);
logger.setUseParentHandlers(false); logger.setUseParentHandlers(false);
GlobalScreen.registerNativeHook(); GlobalScreen.registerNativeHook();
GlobalScreen.addNativeKeyListener(this.pagePasteListener); GlobalScreen.addNativeKeyListener(this.exporterKeyListener);
} catch (NativeHookException nativeHookException) { } catch (NativeHookException nativeHookException) {
System.err.println("Could not register native hook."); System.err.println("Could not register native hook.");
nativeHookException.printStackTrace(); nativeHookException.printStackTrace();
@ -202,7 +202,7 @@ public class BookExporter implements Runnable {
private void stopNativeListener() { private void stopNativeListener() {
try { try {
GlobalScreen.removeNativeKeyListener(this.pagePasteListener); GlobalScreen.removeNativeKeyListener(this.exporterKeyListener);
GlobalScreen.unregisterNativeHook(); GlobalScreen.unregisterNativeHook();
} catch (NativeHookException nativeHookException) { } catch (NativeHookException nativeHookException) {
System.err.println("Could not unregister a native hook."); System.err.println("Could not unregister a native hook.");
@ -243,9 +243,7 @@ public class BookExporter implements Runnable {
} }
private void updateStatusLabel(String text) { private void updateStatusLabel(String text) {
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> this.statusPanel.getStatusLabel().setText(text));
this.statusPanel.getStatusLabel().setText(text);
});
} }
private void updateStatusProgressBar(int nextPage) { private void updateStatusProgressBar(int nextPage) {
@ -257,8 +255,6 @@ public class BookExporter implements Runnable {
} }
private void addStatusMessage(String message) { private void addStatusMessage(String message) {
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> this.statusPanel.getOutputTextArea().append(message + "\n"));
this.statusPanel.getOutputTextArea().append(message + "\n");
});
} }
} }

View File

@ -3,10 +3,14 @@ package nl.andrewlalis.blockbookbinder.control.export;
import org.jnativehook.keyboard.NativeKeyEvent; import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener; 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; this.exporterRunnable = exporterRunnable;
} }

View File

@ -1,6 +1,7 @@
package nl.andrewlalis.blockbookbinder.model; package nl.andrewlalis.blockbookbinder.model;
import lombok.Getter; import lombok.Getter;
import nl.andrewlalis.blockbookbinder.util.ApplicationProperties;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -35,6 +36,20 @@ public class Book {
return book; return book;
} }
public List<Book> splitByPageLimit() {
final int pagesPerBook = ApplicationProperties.getIntProp("book.max_pages");
List<Book> 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 @Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder("Book of " + this.getPageCount() + " pages:\n"); StringBuilder sb = new StringBuilder("Book of " + this.getPageCount() + " pages:\n");

View File

@ -13,7 +13,7 @@ public class BookPage {
} }
public boolean addLine(String line) { 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; return false;
} }
this.lines.add(line); this.lines.add(line);
@ -24,8 +24,24 @@ public class BookPage {
return !this.lines.isEmpty(); return !this.lines.isEmpty();
} }
public BookPage copy() {
BookPage c = new BookPage();
for (String line : this.lines) {
c.addLine(line);
}
return c;
}
@Override @Override
public String toString() { public String toString() {
return String.join("\n", this.lines); 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;
}
} }

View File

@ -1,11 +1,15 @@
package nl.andrewlalis.blockbookbinder.model; package nl.andrewlalis.blockbookbinder.model;
import lombok.Getter;
import nl.andrewlalis.blockbookbinder.util.ApplicationProperties; import nl.andrewlalis.blockbookbinder.util.ApplicationProperties;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class CharWidthMapper { public class CharWidthMapper {
@Getter
private static final CharWidthMapper instance = new CharWidthMapper();
private final Map<Character, Integer> charWidthMap; private final Map<Character, Integer> charWidthMap;
public CharWidthMapper() { public CharWidthMapper() {

View File

@ -9,8 +9,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
public class BookBuilder { public class BookBuilder {
private final CharWidthMapper charWidthMapper = new CharWidthMapper();
/** /**
* Builds a full book of pages from the given source text. * Builds a full book of pages from the given source text.
* @param source The source text to convert. * @param source The source text to convert.
@ -60,7 +58,7 @@ public class BookBuilder {
sourceIndex++; sourceIndex++;
symbolBuilder.setLength(0); symbolBuilder.setLength(0);
symbolBuilder.append(c); 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. // 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) { if (lineBuilder.length() > 0) {
@ -88,7 +86,7 @@ public class BookBuilder {
) { ) {
char nextChar = sourceChars[sourceIndex]; char nextChar = sourceChars[sourceIndex];
symbolBuilder.append(nextChar); symbolBuilder.append(nextChar);
symbolWidth += 1 + this.charWidthMapper.getWidth(nextChar); symbolWidth += 1 + CharWidthMapper.getInstance().getWidth(nextChar);
sourceIndex++; sourceIndex++;
} }
} }

View File

@ -3,6 +3,7 @@ package nl.andrewlalis.blockbookbinder.view;
import nl.andrewlalis.blockbookbinder.model.Book; import nl.andrewlalis.blockbookbinder.model.Book;
import nl.andrewlalis.blockbookbinder.util.ApplicationProperties; import nl.andrewlalis.blockbookbinder.util.ApplicationProperties;
import nl.andrewlalis.blockbookbinder.view.about.AboutDialog; import nl.andrewlalis.blockbookbinder.view.about.AboutDialog;
import nl.andrewlalis.blockbookbinder.view.book.BookPreviewPanel;
import nl.andrewlalis.blockbookbinder.view.export.ExportToBookDialog; import nl.andrewlalis.blockbookbinder.view.export.ExportToBookDialog;
import javax.swing.*; import javax.swing.*;
@ -13,11 +14,11 @@ import java.net.URL;
* The main window of the application. * The main window of the application.
*/ */
public class MainFrame extends JFrame { public class MainFrame extends JFrame {
public void setupAndShow() { public void setupAndShow() {
final int width = Integer.parseInt(ApplicationProperties.getProp("frame.default_width")); this.setPreferredSize(new Dimension(
final int height = Integer.parseInt(ApplicationProperties.getProp("frame.default_height")); ApplicationProperties.getIntProp("frame.default_width"),
this.setPreferredSize(new Dimension(width, height)); ApplicationProperties.getIntProp("frame.default_height")
));
this.setTitle(ApplicationProperties.getProp("frame.title")); this.setTitle(ApplicationProperties.getProp("frame.title"));
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
final URL iconUrl = this.getClass().getClassLoader().getResource("images/book_and_quill.png"); final URL iconUrl = this.getClass().getClassLoader().getResource("images/book_and_quill.png");

View File

@ -2,6 +2,7 @@ package nl.andrewlalis.blockbookbinder.view;
import nl.andrewlalis.blockbookbinder.control.CleanSourceActionListener; import nl.andrewlalis.blockbookbinder.control.CleanSourceActionListener;
import nl.andrewlalis.blockbookbinder.control.ConvertToBookActionListener; import nl.andrewlalis.blockbookbinder.control.ConvertToBookActionListener;
import nl.andrewlalis.blockbookbinder.view.book.BookPreviewPanel;
import javax.swing.*; import javax.swing.*;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;

View File

@ -9,7 +9,6 @@ import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -31,6 +30,7 @@ public class AboutDialog extends JDialog {
textPane.setEditable(false); textPane.setEditable(false);
textPane.setContentType("text/html"); textPane.setContentType("text/html");
textPane.setText(this.getAboutHtml()); textPane.setText(this.getAboutHtml());
textPane.setCaretPosition(0);
textPane.addHyperlinkListener(e -> { textPane.addHyperlinkListener(e -> {
try { try {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {

View File

@ -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);
}
}

View File

@ -1,4 +1,4 @@
package nl.andrewlalis.blockbookbinder.view; package nl.andrewlalis.blockbookbinder.view.book;
import lombok.Getter; import lombok.Getter;
import nl.andrewlalis.blockbookbinder.model.Book; import nl.andrewlalis.blockbookbinder.model.Book;