Some final cleanup
This commit is contained in:
parent
e2ebb3085f
commit
6da3127427
2
pom.xml
2
pom.xml
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<groupId>nl.andrewlalis</groupId>
|
<groupId>nl.andrewlalis</groupId>
|
||||||
<artifactId>BlockBookBinder</artifactId>
|
<artifactId>BlockBookBinder</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.1.0</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>12</maven.compiler.source>
|
<maven.compiler.source>12</maven.compiler.source>
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
package nl.andrewlalis.blockbookbinder.control;
|
|
||||||
|
|
||||||
import nl.andrewlalis.blockbookbinder.model.Book;
|
|
||||||
import nl.andrewlalis.blockbookbinder.view.BookPreviewPanel;
|
|
||||||
import nl.andrewlalis.blockbookbinder.view.export.ExportToBookDialog;
|
|
||||||
import org.jnativehook.GlobalScreen;
|
|
||||||
import org.jnativehook.NativeHookException;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.datatransfer.Clipboard;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Action listener that is used for when a user decides to begin exporting a
|
|
||||||
* book to minecraft.
|
|
||||||
*/
|
|
||||||
public class BookExportActionListener implements ActionListener {
|
|
||||||
private final BookPreviewPanel bookPreviewPanel;
|
|
||||||
private final Clipboard clipboard;
|
|
||||||
private final JButton cancelExportButton;
|
|
||||||
|
|
||||||
public BookExportActionListener(BookPreviewPanel bookPreviewPanel, JButton cancelExportButton) {
|
|
||||||
this.bookPreviewPanel = bookPreviewPanel;
|
|
||||||
this.cancelExportButton = cancelExportButton;
|
|
||||||
this.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
System.out.println("Starting export.");
|
|
||||||
final Book book = this.bookPreviewPanel.getBook();
|
|
||||||
int choice = JOptionPane.showConfirmDialog(
|
|
||||||
this.bookPreviewPanel.getRootPane(),
|
|
||||||
"Press OK to initialize export.",
|
|
||||||
"Confirm Export",
|
|
||||||
JOptionPane.OK_CANCEL_OPTION
|
|
||||||
);
|
|
||||||
if (choice == JOptionPane.CANCEL_OPTION) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.cancelExportButton.setEnabled(true);
|
|
||||||
BookPagePasteListener pasteListener = new BookPagePasteListener(book, clipboard, this.bookPreviewPanel, this.cancelExportButton);
|
|
||||||
this.bookPreviewPanel.enableNavigation(false);
|
|
||||||
pasteListener.exportNextPage(); // Start by exporting the first page right away.
|
|
||||||
try {
|
|
||||||
// For catching native events, set logging here.
|
|
||||||
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
|
|
||||||
logger.setLevel(Level.WARNING);
|
|
||||||
logger.setUseParentHandlers(false);
|
|
||||||
GlobalScreen.registerNativeHook();
|
|
||||||
GlobalScreen.addNativeKeyListener(pasteListener);
|
|
||||||
} catch (NativeHookException nativeHookException) {
|
|
||||||
System.err.println("Could not register native hook.");
|
|
||||||
nativeHookException.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,125 +0,0 @@
|
||||||
package nl.andrewlalis.blockbookbinder.control;
|
|
||||||
|
|
||||||
import nl.andrewlalis.blockbookbinder.model.Book;
|
|
||||||
import nl.andrewlalis.blockbookbinder.view.BookPreviewPanel;
|
|
||||||
import org.jnativehook.GlobalScreen;
|
|
||||||
import org.jnativehook.NativeHookException;
|
|
||||||
import org.jnativehook.keyboard.NativeKeyEvent;
|
|
||||||
import org.jnativehook.keyboard.NativeKeyListener;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.datatransfer.Clipboard;
|
|
||||||
import java.awt.datatransfer.StringSelection;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.awt.event.KeyEvent;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listener that listens for native key-presses that indicate the user has
|
|
||||||
* pasted something into a book.
|
|
||||||
*/
|
|
||||||
public class BookPagePasteListener implements NativeKeyListener {
|
|
||||||
private final Book book;
|
|
||||||
private final Clipboard clipboard;
|
|
||||||
private final BookPreviewPanel bookPreviewPanel;
|
|
||||||
private final JButton cancelExportButton;
|
|
||||||
private final ActionListener cancelExportActionListener;
|
|
||||||
private Robot robot;
|
|
||||||
private int nextPage;
|
|
||||||
|
|
||||||
public BookPagePasteListener(Book book, Clipboard clipboard, BookPreviewPanel bookPreviewPanel, JButton cancelExportButton) {
|
|
||||||
this.book = book;
|
|
||||||
this.clipboard = clipboard;
|
|
||||||
this.bookPreviewPanel = bookPreviewPanel;
|
|
||||||
this.cancelExportButton = cancelExportButton;
|
|
||||||
this.nextPage = 0;
|
|
||||||
this.cancelExportActionListener = (e) -> this.cancelExport();
|
|
||||||
this.cancelExportButton.addActionListener(this.cancelExportActionListener);
|
|
||||||
try {
|
|
||||||
this.robot = new Robot();
|
|
||||||
} catch (AWTException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void exportNextPage() {
|
|
||||||
// Sleep a little bit to avoid rapid repeats.
|
|
||||||
try {
|
|
||||||
Thread.sleep(1000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
this.bookPreviewPanel.setCurrentPage(this.nextPage);
|
|
||||||
boolean clipboardSuccess = false;
|
|
||||||
while (!clipboardSuccess) {
|
|
||||||
try {
|
|
||||||
clipboard.setContents(
|
|
||||||
new StringSelection(book.getPages().get(this.nextPage).toString()),
|
|
||||||
null
|
|
||||||
);
|
|
||||||
clipboardSuccess = true;
|
|
||||||
} catch (IllegalStateException e) {
|
|
||||||
System.err.println("Could not open and set contents of system clipboard.");
|
|
||||||
}
|
|
||||||
if (!clipboardSuccess) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(500);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("Copied page " + this.nextPage + " into clipboard.");
|
|
||||||
this.nextPage++;
|
|
||||||
|
|
||||||
// If we've reached the end of the book, unregister this listener and remove native hooks.
|
|
||||||
if (this.nextPage >= this.book.getPageCount()) {
|
|
||||||
this.cancelExport();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Automatically do a CTRL+V and click the mouse to go to the next page.
|
|
||||||
this.robot.keyPress(KeyEvent.VK_CONTROL);
|
|
||||||
this.robot.keyPress(KeyEvent.VK_V);
|
|
||||||
try {
|
|
||||||
Thread.sleep(50);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
this.robot.keyRelease(KeyEvent.VK_V);
|
|
||||||
this.robot.keyRelease(KeyEvent.VK_CONTROL);
|
|
||||||
|
|
||||||
this.robot.mousePress(MouseEvent.BUTTON1_DOWN_MASK);
|
|
||||||
this.robot.mouseRelease(MouseEvent.BUTTON1_DOWN_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancelExport() {
|
|
||||||
try {
|
|
||||||
this.bookPreviewPanel.enableNavigation(true);
|
|
||||||
this.cancelExportButton.setEnabled(false);
|
|
||||||
this.cancelExportButton.removeActionListener(this.cancelExportActionListener);
|
|
||||||
GlobalScreen.removeNativeKeyListener(this);
|
|
||||||
GlobalScreen.unregisterNativeHook();
|
|
||||||
System.out.println("Done pasting.");
|
|
||||||
} catch (NativeHookException nativeHookException) {
|
|
||||||
System.err.println("Could not unregister a native hook.");
|
|
||||||
nativeHookException.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void nativeKeyTyped(NativeKeyEvent nativeKeyEvent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void nativeKeyPressed(NativeKeyEvent nativeKeyEvent) {
|
|
||||||
if (nativeKeyEvent.getKeyCode() == NativeKeyEvent.VC_V && (nativeKeyEvent.getModifiers() & NativeKeyEvent.CTRL_MASK) > 0) {
|
|
||||||
this.exportNextPage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void nativeKeyReleased(NativeKeyEvent nativeKeyEvent) {}
|
|
||||||
}
|
|
|
@ -3,10 +3,13 @@ package nl.andrewlalis.blockbookbinder.control.export;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
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.export.ExportStatusPanel;
|
||||||
|
import nl.andrewlalis.blockbookbinder.view.export.ExportToBookDialog;
|
||||||
import org.jnativehook.GlobalScreen;
|
import org.jnativehook.GlobalScreen;
|
||||||
import org.jnativehook.NativeHookException;
|
import org.jnativehook.NativeHookException;
|
||||||
|
|
||||||
import javax.sound.sampled.*;
|
import javax.sound.sampled.*;
|
||||||
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.datatransfer.Clipboard;
|
import java.awt.datatransfer.Clipboard;
|
||||||
import java.awt.datatransfer.StringSelection;
|
import java.awt.datatransfer.StringSelection;
|
||||||
|
@ -24,10 +27,10 @@ import java.util.logging.Logger;
|
||||||
public class BookExporter implements Runnable {
|
public class BookExporter implements Runnable {
|
||||||
private final static int START_DELAY = 10;
|
private final static int START_DELAY = 10;
|
||||||
private final static int CLIPBOARD_RETRY_DELAY_MS = 100;
|
private final static int CLIPBOARD_RETRY_DELAY_MS = 100;
|
||||||
private final static int ROBOT_ACTION_DELAY_MS = 100;
|
|
||||||
|
|
||||||
private final Book book;
|
private final Book book;
|
||||||
private final boolean autoPaste;
|
private final boolean autoPaste;
|
||||||
|
private final int autoPasteDelay;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private volatile boolean running;
|
private volatile boolean running;
|
||||||
|
@ -39,13 +42,19 @@ public class BookExporter implements Runnable {
|
||||||
private final Clipboard clipboard;
|
private final Clipboard clipboard;
|
||||||
private Robot robot;
|
private Robot robot;
|
||||||
|
|
||||||
|
private final ExportStatusPanel statusPanel;
|
||||||
|
private final ExportToBookDialog dialog;
|
||||||
|
|
||||||
// Some sound clips to play as user feedback.
|
// Some sound clips to play as user feedback.
|
||||||
private final Clip beepClip;
|
private final Clip beepClip;
|
||||||
private final Clip beginningExportClip;
|
private final Clip beginningExportClip;
|
||||||
|
|
||||||
public BookExporter(Book book, boolean autoPaste) {
|
public BookExporter(ExportToBookDialog dialog, ExportStatusPanel exportStatusPanel, Book book, boolean autoPaste, int autoPasteDelay) {
|
||||||
|
this.dialog = dialog;
|
||||||
|
this.statusPanel = exportStatusPanel;
|
||||||
this.book = book;
|
this.book = book;
|
||||||
this.autoPaste = autoPaste;
|
this.autoPaste = autoPaste;
|
||||||
|
this.autoPasteDelay = autoPasteDelay;
|
||||||
this.beepClip = this.loadAudioClip(ApplicationProperties.getProp("export_dialog.beep_sound"));
|
this.beepClip = this.loadAudioClip(ApplicationProperties.getProp("export_dialog.beep_sound"));
|
||||||
this.beginningExportClip = this.loadAudioClip(ApplicationProperties.getProp("export_dialog.beginning_export"));
|
this.beginningExportClip = this.loadAudioClip(ApplicationProperties.getProp("export_dialog.beginning_export"));
|
||||||
this.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
this.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
|
@ -77,26 +86,30 @@ public class BookExporter implements Runnable {
|
||||||
}
|
}
|
||||||
// Otherwise, export one page.
|
// Otherwise, export one page.
|
||||||
if (!inStartPhase && this.nextPageRequested) {
|
if (!inStartPhase && this.nextPageRequested) {
|
||||||
System.out.println("Page requested: " + nextPageToExport);
|
|
||||||
this.nextPageRequested = false; // Reset the flag so that some other process has to set it before the next page is exported.
|
this.nextPageRequested = false; // Reset the flag so that some other process has to set it before the next page is exported.
|
||||||
// If this is the first time we're exporting, play a sound.
|
// If this is the first time we're exporting, play a sound.
|
||||||
if (lastPageExportedAt == 0) {
|
if (lastPageExportedAt == 0) {
|
||||||
|
this.initStatusPanel();
|
||||||
this.initNativeListener();
|
this.initNativeListener();
|
||||||
this.playAudioClip(this.beginningExportClip);
|
this.playAudioClip(this.beginningExportClip);
|
||||||
}
|
}
|
||||||
this.exportPageToClipboard(nextPageToExport);
|
this.exportPageToClipboard(nextPageToExport);
|
||||||
if (this.autoPaste) {
|
if (this.autoPaste) {
|
||||||
this.pasteAndTurnPage();
|
this.pasteAndTurnPage();
|
||||||
|
} else {
|
||||||
|
this.addStatusMessage("Waiting to detect a CTRL+V keypress...");
|
||||||
}
|
}
|
||||||
this.playAudioClip(this.beepClip);
|
|
||||||
nextPageToExport++;
|
nextPageToExport++;
|
||||||
|
this.updateStatusProgressBar(nextPageToExport);
|
||||||
// If we've reached the end of the book, stop the exporter.
|
// If we've reached the end of the book, stop the exporter.
|
||||||
if (nextPageToExport >= this.book.getPageCount()) {
|
if (nextPageToExport >= this.book.getPageCount()) {
|
||||||
System.out.println("Export finished: " + this.book.getPageCount() + " pages exported.");
|
this.addStatusMessage("Export finished: " + this.book.getPageCount() + " pages exported.");
|
||||||
if (!this.autoPaste) {
|
if (!this.autoPaste) {
|
||||||
this.stopNativeListener();
|
this.stopNativeListener();
|
||||||
}
|
}
|
||||||
this.running = false;
|
this.running = false;
|
||||||
|
this.updateStatusLabel("Export finished");
|
||||||
|
SwingUtilities.invokeLater(dialog::onExportFinished);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Since there may be significant delay, get a fresh timestamp.
|
// Since there may be significant delay, get a fresh timestamp.
|
||||||
|
@ -132,7 +145,7 @@ public class BookExporter implements Runnable {
|
||||||
throw new RuntimeException("Could not insert page into clipboard after " + attempts + " attempts.");
|
throw new RuntimeException("Could not insert page into clipboard after " + attempts + " attempts.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("Exported page " + page + " to clipboard.");
|
this.addStatusMessage("Exported page " + (page + 1) + " to clipboard.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -143,26 +156,26 @@ public class BookExporter implements Runnable {
|
||||||
this.robot.keyPress(KeyEvent.VK_CONTROL);
|
this.robot.keyPress(KeyEvent.VK_CONTROL);
|
||||||
this.robot.keyPress(KeyEvent.VK_V);
|
this.robot.keyPress(KeyEvent.VK_V);
|
||||||
try {
|
try {
|
||||||
Thread.sleep(ROBOT_ACTION_DELAY_MS);
|
Thread.sleep(this.autoPasteDelay);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
this.robot.keyRelease(KeyEvent.VK_V);
|
this.robot.keyRelease(KeyEvent.VK_V);
|
||||||
this.robot.keyRelease(KeyEvent.VK_CONTROL);
|
this.robot.keyRelease(KeyEvent.VK_CONTROL);
|
||||||
System.out.println("Pasted.");
|
this.addStatusMessage("Pasted page into book.");
|
||||||
this.robot.mousePress(MouseEvent.BUTTON1_DOWN_MASK);
|
this.robot.mousePress(MouseEvent.BUTTON1_DOWN_MASK);
|
||||||
try {
|
try {
|
||||||
Thread.sleep(ROBOT_ACTION_DELAY_MS);
|
Thread.sleep(this.autoPasteDelay);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
this.robot.mouseRelease(MouseEvent.BUTTON1_DOWN_MASK);
|
this.robot.mouseRelease(MouseEvent.BUTTON1_DOWN_MASK);
|
||||||
try { // Wait for minecraft to turn the page.
|
try { // Wait for minecraft to turn the page.
|
||||||
Thread.sleep(ROBOT_ACTION_DELAY_MS);
|
Thread.sleep(this.autoPasteDelay);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
System.out.println("Clicked mouse.");
|
this.addStatusMessage("Clicked to turn the page.");
|
||||||
this.nextPageRequested = true;
|
this.nextPageRequested = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,4 +224,34 @@ public class BookExporter implements Runnable {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initStatusPanel() {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
JProgressBar bar = this.statusPanel.getExportProgressBar();
|
||||||
|
bar.setMinimum(0);
|
||||||
|
bar.setMaximum(this.book.getPageCount());
|
||||||
|
bar.setStringPainted(true);
|
||||||
|
this.updateStatusProgressBar(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateStatusLabel(String text) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
this.statusPanel.getStatusLabel().setText(text);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateStatusProgressBar(int nextPage) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
JProgressBar bar = this.statusPanel.getExportProgressBar();
|
||||||
|
bar.setValue(nextPage);
|
||||||
|
bar.setString(String.format("%d of %d pages exported", nextPage, this.book.getPageCount()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addStatusMessage(String message) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
this.statusPanel.getOutputTextArea().append(message + "\n");
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package nl.andrewlalis.blockbookbinder.view;
|
package nl.andrewlalis.blockbookbinder.view;
|
||||||
|
|
||||||
import nl.andrewlalis.blockbookbinder.control.BookExportActionListener;
|
|
||||||
import nl.andrewlalis.blockbookbinder.control.ImportAction;
|
import nl.andrewlalis.blockbookbinder.control.ImportAction;
|
||||||
import nl.andrewlalis.blockbookbinder.model.Book;
|
import nl.andrewlalis.blockbookbinder.model.Book;
|
||||||
import nl.andrewlalis.blockbookbinder.util.ApplicationProperties;
|
import nl.andrewlalis.blockbookbinder.util.ApplicationProperties;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package nl.andrewlalis.blockbookbinder.view.export;
|
package nl.andrewlalis.blockbookbinder.view.export;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
|
@ -8,11 +10,29 @@ import java.awt.*;
|
||||||
* job.
|
* job.
|
||||||
*/
|
*/
|
||||||
public class ExportStatusPanel extends JPanel {
|
public class ExportStatusPanel extends JPanel {
|
||||||
private JProgressBar exportProgressBar;
|
@Getter
|
||||||
|
private final JLabel statusLabel;
|
||||||
|
@Getter
|
||||||
|
private final JTextArea outputTextArea;
|
||||||
|
@Getter
|
||||||
|
private final JProgressBar exportProgressBar;
|
||||||
|
|
||||||
public ExportStatusPanel() {
|
public ExportStatusPanel() {
|
||||||
this.setLayout(new BorderLayout());
|
this.setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
this.statusLabel = new JLabel("Exporting...");
|
||||||
|
this.add(this.statusLabel, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
this.outputTextArea = new JTextArea();
|
||||||
|
this.outputTextArea.setEditable(false);
|
||||||
|
this.outputTextArea.setLineWrap(true);
|
||||||
|
this.outputTextArea.setWrapStyleWord(true);
|
||||||
|
this.outputTextArea.setAutoscrolls(true);
|
||||||
|
JScrollPane scrollPane = new JScrollPane(this.outputTextArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||||
|
scrollPane.setAutoscrolls(true);
|
||||||
|
this.add(scrollPane, BorderLayout.CENTER);
|
||||||
|
|
||||||
this.exportProgressBar = new JProgressBar();
|
this.exportProgressBar = new JProgressBar();
|
||||||
|
this.add(this.exportProgressBar, BorderLayout.SOUTH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ public class ExportToBookDialog extends JDialog {
|
||||||
private JCheckBox autoCheckbox;
|
private JCheckBox autoCheckbox;
|
||||||
private JSpinner firstPageSpinner;
|
private JSpinner firstPageSpinner;
|
||||||
private JSpinner lastPageSpinner;
|
private JSpinner lastPageSpinner;
|
||||||
|
private JSpinner autoPasteDelaySpinner;
|
||||||
|
|
||||||
private JButton startButton;
|
private JButton startButton;
|
||||||
private JButton stopButton;
|
private JButton stopButton;
|
||||||
|
@ -54,10 +55,21 @@ public class ExportToBookDialog extends JDialog {
|
||||||
setupPanel.setLayout(new BoxLayout(setupPanel, BoxLayout.PAGE_AXIS));
|
setupPanel.setLayout(new BoxLayout(setupPanel, BoxLayout.PAGE_AXIS));
|
||||||
this.autoCheckbox = new JCheckBox("Auto-paste", true);
|
this.autoCheckbox = new JCheckBox("Auto-paste", true);
|
||||||
this.firstPageSpinner = new JSpinner(new SpinnerNumberModel(1, 1, this.book.getPageCount(), 1));
|
this.firstPageSpinner = new JSpinner(new SpinnerNumberModel(1, 1, this.book.getPageCount(), 1));
|
||||||
|
JPanel firstPageSpinnerPanel = new JPanel(new BorderLayout());
|
||||||
|
firstPageSpinnerPanel.add(new JLabel("First Page:"), BorderLayout.WEST);
|
||||||
|
firstPageSpinnerPanel.add(this.firstPageSpinner, BorderLayout.CENTER);
|
||||||
this.lastPageSpinner = new JSpinner(new SpinnerNumberModel(this.book.getPageCount(), 1, this.book.getPageCount(), 1));
|
this.lastPageSpinner = new JSpinner(new SpinnerNumberModel(this.book.getPageCount(), 1, this.book.getPageCount(), 1));
|
||||||
|
JPanel lastPageSpinnerPanel = new JPanel(new BorderLayout());
|
||||||
|
lastPageSpinnerPanel.add(new JLabel("Last Page:"), BorderLayout.WEST);
|
||||||
|
lastPageSpinnerPanel.add(this.lastPageSpinner, BorderLayout.CENTER);
|
||||||
|
this.autoPasteDelaySpinner = new JSpinner(new SpinnerNumberModel(0.2, 0.1, 5.0, 0.1));
|
||||||
|
JPanel autoPasteDelaySpinnerPanel = new JPanel(new BorderLayout());
|
||||||
|
autoPasteDelaySpinnerPanel.add(new JLabel("Auto-Paste Delay (s):"), BorderLayout.WEST);
|
||||||
|
autoPasteDelaySpinnerPanel.add(this.autoPasteDelaySpinner, BorderLayout.CENTER);
|
||||||
setupPanel.add(this.autoCheckbox);
|
setupPanel.add(this.autoCheckbox);
|
||||||
setupPanel.add(this.firstPageSpinner);
|
setupPanel.add(firstPageSpinnerPanel);
|
||||||
setupPanel.add(this.lastPageSpinner);
|
setupPanel.add(lastPageSpinnerPanel);
|
||||||
|
setupPanel.add(autoPasteDelaySpinnerPanel);
|
||||||
|
|
||||||
this.exportStatusPanel = new ExportStatusPanel();
|
this.exportStatusPanel = new ExportStatusPanel();
|
||||||
|
|
||||||
|
@ -71,6 +83,9 @@ public class ExportToBookDialog extends JDialog {
|
||||||
JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
|
JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
|
||||||
this.startButton = new JButton("Start");
|
this.startButton = new JButton("Start");
|
||||||
this.startButton.addActionListener(e -> {
|
this.startButton.addActionListener(e -> {
|
||||||
|
if (!this.checkSpinnerValues()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
int choice = JOptionPane.showConfirmDialog(
|
int choice = JOptionPane.showConfirmDialog(
|
||||||
this.rootPane,
|
this.rootPane,
|
||||||
"Exporting will begin after roughly 10 seconds.\n" +
|
"Exporting will begin after roughly 10 seconds.\n" +
|
||||||
|
@ -97,21 +112,36 @@ public class ExportToBookDialog extends JDialog {
|
||||||
return mainPanel;
|
return mainPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts up the exporter thread.
|
||||||
|
*/
|
||||||
private void startExporter() {
|
private void startExporter() {
|
||||||
final int firstPage = (int) this.firstPageSpinner.getValue();
|
final int firstPage = (int) this.firstPageSpinner.getValue();
|
||||||
final int lastPage = (int) this.lastPageSpinner.getValue();
|
final int lastPage = (int) this.lastPageSpinner.getValue();
|
||||||
final Book pagesRange = this.book.getPageRange(firstPage - 1, lastPage - firstPage + 1);
|
final Book pagesRange = this.book.getPageRange(firstPage - 1, lastPage - firstPage + 1);
|
||||||
|
|
||||||
|
final double autoPasteDelay = (double) this.autoPasteDelaySpinner.getValue();
|
||||||
|
final int autoPasteDelayMillis = (int) (autoPasteDelay * 1000);
|
||||||
|
|
||||||
this.startButton.setEnabled(false);
|
this.startButton.setEnabled(false);
|
||||||
this.startButton.setVisible(false);
|
this.startButton.setVisible(false);
|
||||||
this.stopButton.setEnabled(true);
|
this.stopButton.setEnabled(true);
|
||||||
this.stopButton.setVisible(true);
|
this.stopButton.setVisible(true);
|
||||||
this.showCardByName(STATUS_CARD);
|
this.showCardByName(STATUS_CARD);
|
||||||
this.exporterRunnable = new BookExporter(pagesRange, this.autoCheckbox.isSelected());
|
this.exporterRunnable = new BookExporter(
|
||||||
|
this,
|
||||||
|
this.exportStatusPanel,
|
||||||
|
pagesRange,
|
||||||
|
this.autoCheckbox.isSelected(),
|
||||||
|
autoPasteDelayMillis
|
||||||
|
);
|
||||||
this.exporterThread = new Thread(this.exporterRunnable);
|
this.exporterThread = new Thread(this.exporterRunnable);
|
||||||
this.exporterThread.start();
|
this.exporterThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shuts down the exporter thread.
|
||||||
|
*/
|
||||||
private void stopExporter() {
|
private void stopExporter() {
|
||||||
this.exporterRunnable.setRunning(false);
|
this.exporterRunnable.setRunning(false);
|
||||||
try {
|
try {
|
||||||
|
@ -126,8 +156,49 @@ public class ExportToBookDialog extends JDialog {
|
||||||
this.startButton.setVisible(true);
|
this.startButton.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called by the exporter thread once it is done.
|
||||||
|
*/
|
||||||
|
public void onExportFinished() {
|
||||||
|
JOptionPane.showMessageDialog(
|
||||||
|
this,
|
||||||
|
"Book export has finished.",
|
||||||
|
"Export Complete",
|
||||||
|
JOptionPane.INFORMATION_MESSAGE
|
||||||
|
);
|
||||||
|
this.stopExporter();
|
||||||
|
this.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
private void showCardByName(String name) {
|
private void showCardByName(String name) {
|
||||||
CardLayout cl = (CardLayout) this.centerCardPanel.getLayout();
|
CardLayout cl = (CardLayout) this.centerCardPanel.getLayout();
|
||||||
cl.show(this.centerCardPanel, name);
|
cl.show(this.centerCardPanel, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the values of the spinners that are used to select the first and
|
||||||
|
* last pages, and shows a popup warning if they're not correct.
|
||||||
|
*/
|
||||||
|
private boolean checkSpinnerValues() {
|
||||||
|
final int firstPage = (int) this.firstPageSpinner.getValue();
|
||||||
|
final int lastPage = (int) this.lastPageSpinner.getValue();
|
||||||
|
|
||||||
|
if (
|
||||||
|
firstPage < 1
|
||||||
|
|| lastPage > this.book.getPageCount()
|
||||||
|
|| firstPage > lastPage
|
||||||
|
|| (lastPage - firstPage + 1 > ApplicationProperties.getIntProp("book.max_pages"))
|
||||||
|
) {
|
||||||
|
JOptionPane.showMessageDialog(
|
||||||
|
this,
|
||||||
|
"Invalid page range. Please follow the rules below:\n" +
|
||||||
|
"1. First page must be lower or equal to the last page.\n" +
|
||||||
|
"2. Number of pages to export cannot exceed 100.\n",
|
||||||
|
"Invalid Page Range",
|
||||||
|
JOptionPane.WARNING_MESSAGE
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue