Lots of cleanup.
This commit is contained in:
parent
5c6587386e
commit
ec06cf56cf
6
pom.xml
6
pom.xml
|
@ -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>
|
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
Loading…
Reference in New Issue