summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEthan Vrhel <ethanvrhel@gmail.com>2020-08-24 21:16:56 -0700
committerRobin Watts <Robin.Watts@artifex.com>2020-09-24 14:33:49 +0100
commit765d86b489dda64913cff9a0973a6ad820b9200d (patch)
treeafa8d7006545f5277102e5df80fe02708bdda46a
parent1f9321e9848517ee87106fe60193e146c6e47d90 (diff)
downloadghostpdl-765d86b489dda64913cff9a0973a6ad820b9200d.tar.gz
Updated to newer Ghostscript version and fixed a bug
Updated to the newest Ghostscript version and fixed an ArrayIndexOutOfBoundsException bug when unloading zoomed pages.
-rw-r--r--demos/java/gsviewer/src/com/artifex/gsviewer/Document.java32
-rw-r--r--demos/java/gsviewer/src/com/artifex/gsviewer/Main.java18
-rw-r--r--demos/java/gsviewer/src/com/artifex/gsviewer/PDFFileFilter.java28
-rw-r--r--demos/java/gsviewer/src/com/artifex/gsviewer/Page.java10
-rw-r--r--demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java51
-rw-r--r--demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java312
6 files changed, 294 insertions, 157 deletions
diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/Document.java b/demos/java/gsviewer/src/com/artifex/gsviewer/Document.java
index f6dfd3cbf..6000d3e44 100644
--- a/demos/java/gsviewer/src/com/artifex/gsviewer/Document.java
+++ b/demos/java/gsviewer/src/com/artifex/gsviewer/Document.java
@@ -6,6 +6,7 @@ import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
@@ -22,6 +23,8 @@ import com.artifex.gsjava.util.BytePointer;
import com.artifex.gsjava.util.Reference;
import com.artifex.gsviewer.ImageUtil.ImageParams;
+import sun.misc.Unsafe;
+
/**
* <p>A Document stores an ordered list of Pages. This class implements
* <code>java.util.List</code>, so it inherits all of a list's capabilities,
@@ -561,7 +564,7 @@ public class Document implements List<Page> {
documentLoader.callback = loadCallback;
- code = gsInstance.set_param("HWResolution", Page.PAGE_LOW_DPI_STR, GS_SPT_PARSED);
+ code = gsInstance.set_param("HWResolution", Page.toDPIString(Page.PAGE_LOW_DPI), GS_SPT_PARSED);
if (code != GS_ERROR_OK)
throw new IllegalStateException("Failed to set HWResolution (code = " + code + ")");
@@ -571,8 +574,14 @@ public class Document implements List<Page> {
if (code != GS_ERROR_OK)
throw new IllegalStateException("Failed to run file (code = " + code + ")");
- gsInstance.set_param("TextAlphaBits", 4, GS_SPT_INT);
- gsInstance.set_param("GraphicsAlphaBits", 4, GS_SPT_INT);
+ boolean aa = Settings.SETTINGS.getSetting("antialiasing");
+ if (aa) {
+ gsInstance.set_param("TextAlphaBits", 4, GS_SPT_INT);
+ gsInstance.set_param("GraphicsAlphaBits", 4, GS_SPT_INT);
+ } else {
+ gsInstance.set_param("TextAlphaBits", 0, GS_SPT_INT);
+ gsInstance.set_param("GraphicsAlphaBits", 0, GS_SPT_INT);
+ }
this.pages = new ArrayList<>(documentLoader.images.size());
for (BufferedImage img : documentLoader.images) {
@@ -769,7 +778,7 @@ public class Document implements List<Page> {
*/
public void unloadZoomed(int startPage, int endPage) throws IndexOutOfBoundsException {
checkBounds(startPage, endPage);
- for (int i = startPage; i <= endPage; i++) {
+ for (int i = startPage; i < endPage; i++) {
pages.get(i).unloadZoomed();
}
}
@@ -1024,8 +1033,19 @@ public class Document implements List<Page> {
}
@Override
- public List<Page> subList(int fromIndex, int toIndex) {
- return pages.subList(fromIndex, toIndex);
+ public Document subList(int fromIndex, int toIndex) {
+ try {
+ Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
+ unsafeField.setAccessible(true);
+ Unsafe unsafe = (Unsafe)unsafeField.get(null);
+ Document doc = (Document)unsafe.allocateInstance(Document.class);
+ doc.pages = pages.subList(fromIndex, toIndex);
+ doc.file = file;
+ return doc;
+ } catch (NoSuchFieldException | SecurityException | IllegalArgumentException
+ | IllegalAccessException | InstantiationException e) {
+ throw new RuntimeException("Failed to create sublist: " + e);
+ }
}
@Override
diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/Main.java b/demos/java/gsviewer/src/com/artifex/gsviewer/Main.java
index e8c63b7af..beecdd3b0 100644
--- a/demos/java/gsviewer/src/com/artifex/gsviewer/Main.java
+++ b/demos/java/gsviewer/src/com/artifex/gsviewer/Main.java
@@ -1,5 +1,7 @@
package com.artifex.gsviewer;
+import java.io.IOException;
+
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
@@ -9,6 +11,8 @@ import com.artifex.gsviewer.gui.ViewerWindow;
public class Main {
public static void main(String[] args) {
+ Runtime.getRuntime().addShutdownHook(new Thread(new Shutdown()));
+
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
@@ -21,4 +25,18 @@ public class Main {
win.setVisible(true);
});
}
+
+ private static class Shutdown implements Runnable {
+
+ @Override
+ public void run() {
+ try {
+ Settings.SETTINGS.save();
+ } catch (IOException e) {
+ System.err.println("Failed to write settings file");
+ e.printStackTrace();
+ }
+ }
+
+ }
}
diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/PDFFileFilter.java b/demos/java/gsviewer/src/com/artifex/gsviewer/PDFFileFilter.java
new file mode 100644
index 000000000..e7bd7046f
--- /dev/null
+++ b/demos/java/gsviewer/src/com/artifex/gsviewer/PDFFileFilter.java
@@ -0,0 +1,28 @@
+package com.artifex.gsviewer;
+
+import java.io.File;
+
+import javax.swing.filechooser.FileFilter;
+
+public class PDFFileFilter extends FileFilter {
+
+ public static final PDFFileFilter INSTANCE = new PDFFileFilter();
+
+ @Override
+ public boolean accept(File f) {
+ if (f.isDirectory())
+ return true;
+ String filename = f.getName();
+ int ind = filename.lastIndexOf('.');
+ if (ind == -1)
+ return false;
+ String ext = filename.substring(ind);
+ return ext.equalsIgnoreCase(".pdf");
+ }
+
+ @Override
+ public String getDescription() {
+ return "PDF Files";
+ }
+
+}
diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/Page.java b/demos/java/gsviewer/src/com/artifex/gsviewer/Page.java
index 612029af3..a3435f56c 100644
--- a/demos/java/gsviewer/src/com/artifex/gsviewer/Page.java
+++ b/demos/java/gsviewer/src/com/artifex/gsviewer/Page.java
@@ -22,21 +22,11 @@ public class Page {
public static final int PAGE_HIGH_DPI = 72;
/**
- * The high-resolution DPI to use as a Ghostscript-friendly string
- */
- public static final String PAGE_HIGH_DPI_STR = toDPIString(PAGE_HIGH_DPI);
-
- /**
* The low-resolution DPI to use.
*/
public static final int PAGE_LOW_DPI = 10;
/**
- * The low-resolution DPI to use as a Ghostscript-friendly string
- */
- public static final String PAGE_LOW_DPI_STR = toDPIString(PAGE_LOW_DPI);
-
- /**
* Converts a dpi value to a Ghostscript-friendly string.
*
* @param dpi The dpi to convert.
diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java b/demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java
index f69615580..f2801426c 100644
--- a/demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java
+++ b/demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java
@@ -11,6 +11,7 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.swing.JFileChooser;
+import com.artifex.gsviewer.gui.SettingsDialog;
import com.artifex.gsviewer.gui.ViewerGUIListener;
import com.artifex.gsviewer.gui.ViewerWindow;
@@ -46,6 +47,7 @@ public class ViewerController implements ViewerGUIListener {
private ViewerWindow source; // The viewer window where documents will be displayed
private Document currentDocument; // The current document loaded in the viewer
private SmartLoader smartLoader; // The SmartLoader used to load pages based on scroll and zoom
+ private boolean loadingDocument;
/**
* <p>Opens a document from a files asynchronously.</p>
@@ -66,6 +68,10 @@ public class ViewerController implements ViewerGUIListener {
public void open(File file)
throws NullPointerException, IllegalArgumentException, FileNotFoundException, IOException,
HeadlessException, RuntimeException {
+ if (loadingDocument) {
+ source.showWarningDialog("Error", "A document is already loading");
+ return;
+ }
if (Document.shouldDistill(file)) {
int ret = source.showConfirmDialog("Distill", "Would you like to distill this document before opening?");
if (ret == ViewerWindow.CANCEL)
@@ -98,16 +104,22 @@ public class ViewerController implements ViewerGUIListener {
if (currentDocument != null)
close();
+ loadingDocument = true;
Document.loadDocumentAsync(file, (final Document doc, final Exception exception) -> {
- source.loadDocumentToViewer(doc);
- source.setLoadProgress(0);
- if (exception != null) {
- source.showErrorDialog("Failed to load", exception.toString());
- } else {
- this.currentDocument = doc;
- dispatchSmartLoader();
+ try {
+ source.loadDocumentToViewer(doc);
+ source.setLoadProgress(0);
+ if (exception != null) {
+ throw new RuntimeException("Failed to load", exception);
+ //source.showErrorDialog("Failed to load", exception.toString());
+ } else {
+ this.currentDocument = doc;
+ dispatchSmartLoader();
+ }
+ source.revalidate();
+ } finally {
+ loadingDocument = false;
}
- source.revalidate();
}, (int progress) -> {
source.setLoadProgress(progress);
}, Document.OPERATION_RETURN);
@@ -118,6 +130,11 @@ public class ViewerController implements ViewerGUIListener {
* is loaded, this method does nothing.
*/
public void close() {
+ if (loadingDocument) {
+ source.showWarningDialog("Error", "A document is already loading");
+ return;
+ }
+
if (smartLoader != null) {
smartLoader.stop();
smartLoader = null;
@@ -192,7 +209,10 @@ public class ViewerController implements ViewerGUIListener {
}
@Override
- public void onSettingsOpen() { }
+ public void onSettingsOpen() {
+ SettingsDialog dialog = new SettingsDialog(source, true);
+ dialog.setVisible(true);
+ }
/**
* Starts the SmartLoader on the currently loaded document. If a
@@ -290,9 +310,7 @@ public class ViewerController implements ViewerGUIListener {
System.out.println("Smart loader dispatched.");
while (shouldRun) {
int currentPage = source.getCurrentPage();
- int[] toLoad = new int[] {
- currentPage, currentPage - 1, currentPage + 1,
- currentPage - 2, currentPage + 2 };
+ int[] toLoad = genToLoad(currentPage);
if (loaded.length != currentDocument.size())
throw new IllegalStateException("Array is size " + loaded.length + " while doc size is " + currentDocument.size());
@@ -341,5 +359,14 @@ public class ViewerController implements ViewerGUIListener {
}
}
}
+
+ int[] genToLoad(int page) {
+ int range = Settings.SETTINGS.getSetting("preloadRange");
+ int[] arr = new int[range * 2 + 1];
+ for (int i = -range; i <= range; i++) {
+ arr[i + range] = page + i;
+ }
+ return arr;
+ }
}
}
diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java
index 27557b566..48b399534 100644
--- a/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java
+++ b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java
@@ -10,6 +10,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.image.BufferedImage;
+import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Box;
@@ -25,6 +26,7 @@ import javax.swing.SwingUtilities;
import com.artifex.gsviewer.Document;
import com.artifex.gsviewer.Page;
import com.artifex.gsviewer.PageUpdateCallback;
+import com.artifex.gsviewer.Settings;
/**
* <p>Used to display documents into a window.</p>
@@ -74,6 +76,8 @@ public class ViewerWindow extends javax.swing.JFrame {
private boolean gotoPage; // Whether the viewer should jump to currentPage
+ private boolean isLoading;
+
/**
* Creates new ViewerWindow.
*/
@@ -97,6 +101,7 @@ public class ViewerWindow extends javax.swing.JFrame {
// Adjustment listener looks for any change in the scroll value of the scrollbar
this.viewerScrollPane.getVerticalScrollBar().addAdjustmentListener((AdjustmentEvent evt) -> {
+ this.viewerScrollPane.getVerticalScrollBar().setUnitIncrement(Settings.SETTINGS.getSetting("scrollSens"));
if (scrollMap != null) {
Adjustable adjustable = evt.getAdjustable();
int currentPage = scrollMap.getPageFor(adjustable.getValue());
@@ -132,28 +137,28 @@ public class ViewerWindow extends javax.swing.JFrame {
}
/**
- * This method is called from within the constructor to initialize the form.
- * WARNING: Do NOT modify this code. The content of this method is always
- * regenerated by the Form Editor.
- */
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
- // <editor-fold defaultstate="collapsed" desc="Generated
- // Code">//GEN-BEGIN:initComponents
- private void initComponents() {
+ // <editor-fold defaultstate="collapsed" desc="Generated Code">
+ private void initComponents() {
viewerScrollPane = new javax.swing.JScrollPane();
viewerContentPane = new javax.swing.JPanel();
miniViewerScrollPane = new javax.swing.JScrollPane();
miniViewerContentPane = new javax.swing.JPanel();
+ toolbarPanel = new javax.swing.JPanel();
+ decreaseZoomButton = new javax.swing.JButton();
zoomSlider = new javax.swing.JSlider();
increaseZoomButton = new javax.swing.JButton();
- decreaseZoomButton = new javax.swing.JButton();
- lastPageButton = new javax.swing.JButton();
- maxPagesLabel = new javax.swing.JTextField();
- nextPageButton = new javax.swing.JButton();
progressBar = new javax.swing.JProgressBar();
+ lastPageButton = new javax.swing.JButton();
pageNumberField = new javax.swing.JTextField();
pageSlashLabel = new javax.swing.JLabel();
+ maxPagesLabel = new javax.swing.JTextField();
+ nextPageButton = new javax.swing.JButton();
menuBar = new javax.swing.JMenuBar();
fileMenu = new javax.swing.JMenu();
openMenu = new javax.swing.JMenuItem();
@@ -179,7 +184,7 @@ public class ViewerWindow extends javax.swing.JFrame {
viewerContentPane.setLayout(viewerContentPaneLayout);
viewerContentPaneLayout.setHorizontalGroup(
viewerContentPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 502, Short.MAX_VALUE)
+ .addGap(0, 623, Short.MAX_VALUE)
);
viewerContentPaneLayout.setVerticalGroup(
viewerContentPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -203,6 +208,14 @@ public class ViewerWindow extends javax.swing.JFrame {
miniViewerScrollPane.setViewportView(miniViewerContentPane);
+ decreaseZoomButton.setText("-");
+ decreaseZoomButton.addActionListener(new java.awt.event.ActionListener() {
+ @Override
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ decreaseZoomButtonActionPerformed(evt);
+ }
+ });
+
zoomSlider.setMajorTickSpacing(25);
zoomSlider.setMinorTickSpacing(5);
zoomSlider.setPaintTicks(true);
@@ -213,12 +226,6 @@ public class ViewerWindow extends javax.swing.JFrame {
zoomSliderMouseReleased(evt);
}
});
- zoomSlider.addKeyListener(new java.awt.event.KeyAdapter() {
- @Override
- public void keyReleased(java.awt.event.KeyEvent evt) {
- zoomSliderKeyReleased(evt);
- }
- });
increaseZoomButton.setText("+");
increaseZoomButton.addActionListener(new java.awt.event.ActionListener() {
@@ -228,22 +235,24 @@ public class ViewerWindow extends javax.swing.JFrame {
}
});
- decreaseZoomButton.setText("-");
- decreaseZoomButton.addActionListener(new java.awt.event.ActionListener() {
+ lastPageButton.setText("<");
+ lastPageButton.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
- decreaseZoomButtonActionPerformed(evt);
+ lastPageButtonActionPerformed(evt);
}
});
- lastPageButton.setText("<");
- lastPageButton.addActionListener(new java.awt.event.ActionListener() {
+ pageNumberField.setText("0");
+ pageNumberField.addKeyListener(new java.awt.event.KeyAdapter() {
@Override
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- lastPageButtonActionPerformed(evt);
+ public void keyPressed(java.awt.event.KeyEvent evt) {
+ pageNumberFieldKeyPressed(evt);
}
});
+ pageSlashLabel.setText("/");
+
maxPagesLabel.setEditable(false);
maxPagesLabel.setText("0");
@@ -255,15 +264,50 @@ public class ViewerWindow extends javax.swing.JFrame {
}
});
- pageNumberField.setText("0");
- pageNumberField.addKeyListener(new java.awt.event.KeyAdapter() {
- @Override
- public void keyPressed(java.awt.event.KeyEvent evt) {
- pageNumberFieldKeyPressed(evt);
- }
- });
-
- pageSlashLabel.setText("/");
+ javax.swing.GroupLayout toolbarPanelLayout = new javax.swing.GroupLayout(toolbarPanel);
+ toolbarPanel.setLayout(toolbarPanelLayout);
+ toolbarPanelLayout.setHorizontalGroup(
+ toolbarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(toolbarPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(toolbarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(toolbarPanelLayout.createSequentialGroup()
+ .addComponent(decreaseZoomButton, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(zoomSlider, javax.swing.GroupLayout.PREFERRED_SIZE, 111, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(increaseZoomButton)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lastPageButton)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pageNumberField, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pageSlashLabel)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(maxPagesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(nextPageButton))
+ .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addContainerGap())
+ );
+ toolbarPanelLayout.setVerticalGroup(
+ toolbarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(toolbarPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(toolbarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addGroup(toolbarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(increaseZoomButton)
+ .addComponent(lastPageButton)
+ .addComponent(pageNumberField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(pageSlashLabel)
+ .addComponent(maxPagesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(nextPageButton))
+ .addComponent(zoomSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(decreaseZoomButton))
+ .addGap(17, 17, 17)
+ .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
+ );
fileMenu.setText("File");
@@ -318,31 +362,11 @@ public class ViewerWindow extends javax.swing.JFrame {
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
+ .addComponent(miniViewerScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addGroup(layout.createSequentialGroup()
- .addComponent(miniViewerScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addGap(2, 2, 2)
- .addComponent(decreaseZoomButton, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(zoomSlider, javax.swing.GroupLayout.PREFERRED_SIZE, 111, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(increaseZoomButton)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(lastPageButton)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(pageNumberField, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(pageSlashLabel)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(maxPagesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(4, 4, 4)
- .addComponent(nextPageButton)
- .addGap(2, 2, 2))
- .addComponent(viewerScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
+ .addComponent(toolbarPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(viewerScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 642, Short.MAX_VALUE))
.addContainerGap())
);
layout.setVerticalGroup(
@@ -350,23 +374,10 @@ public class ViewerWindow extends javax.swing.JFrame {
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(miniViewerScrollPane)
- .addComponent(viewerScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addComponent(miniViewerScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 592, Short.MAX_VALUE)
+ .addComponent(viewerScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 592, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(decreaseZoomButton)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(increaseZoomButton)
- .addComponent(nextPageButton)
- .addComponent(maxPagesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(pageNumberField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lastPageButton)
- .addComponent(pageSlashLabel)))
- .addComponent(zoomSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGap(14, 14, 14)
- .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addContainerGap())
+ .addComponent(toolbarPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
);
pack();
@@ -408,10 +419,6 @@ public class ViewerWindow extends javax.swing.JFrame {
tryChangeZoom(zoomSlider.getValue() / 50.0);
}// GEN-LAST:event_zoomSliderMouseReleased
- private void zoomSliderKeyReleased(java.awt.event.KeyEvent evt) {// GEN-FIRST:event_zoomSliderKeyReleased
- tryChangeZoom(zoomSlider.getValue() / 50.0);
- }// GEN-LAST:event_zoomSliderKeyReleased
-
private void increaseZoomButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_increaseZoomButtonActionPerformed
if (tryChangeZoom(Math.min(Math.ceil((currentZoom * 10) + 1) / 10, 2.0)))
zoomSlider.setValue((int)(currentZoom * 50));
@@ -440,6 +447,7 @@ public class ViewerWindow extends javax.swing.JFrame {
private void settingsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_settingsMenuItemActionPerformed
if (guiListener != null)
guiListener.onSettingsOpen();
+ tryChangeZoom(0.1);
}// GEN-LAST:event_settingsMenuItemActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
@@ -461,6 +469,7 @@ public class ViewerWindow extends javax.swing.JFrame {
private javax.swing.JLabel pageSlashLabel;
private javax.swing.JProgressBar progressBar;
private javax.swing.JMenuItem settingsMenuItem;
+ private javax.swing.JPanel toolbarPanel;
private javax.swing.JPanel viewerContentPane;
private javax.swing.JScrollPane viewerScrollPane;
private javax.swing.JSlider zoomSlider;
@@ -524,7 +533,7 @@ public class ViewerWindow extends javax.swing.JFrame {
Image result = img;
if (img == page.getLowResImage() || currentZoom < 1.0 ||
(img == page.getHighResImage() && currentZoom > 1.0 && page.getZoomedImage() == null)) {
- result = img.getScaledInstance(actualSize.width, actualSize.height, Image.SCALE_FAST);
+ result = img.getScaledInstance(actualSize.width, actualSize.height, Image.SCALE_SMOOTH);
}
return result;
} else {
@@ -645,60 +654,76 @@ public class ViewerWindow extends javax.swing.JFrame {
* @param document The document to load into the viewer.
*/
public void loadDocumentToViewer(final Document document) {
- unloadViewerDocument();
- if (document == null)
- return;
-
- lockSize();
-
- this.loadedDocument = document;
- viewerContentPane.setLayout(new BoxLayout(viewerContentPane, BoxLayout.Y_AXIS));
+ isLoading = true;
+ try {
+ unloadViewerDocument();
+ if (document == null)
+ return;
+ lockSize();
+
+ this.loadedDocument = document;
+ viewerContentPane.setLayout(new BoxLayout(viewerContentPane, BoxLayout.Y_AXIS));
+
+ // Generate the viewer page components
+ /*for (final Page page : document) {
+ final PagePanel panel = new PagePanel(page, 1.0);
+ viewerContentPane.add(panel);
+ viewerContentPane.add(Box.createVerticalStrut(VIEWER_PAGE_GAP));
+
+ viewerPagePanels.add(panel);
+ }*/
+
+ miniViewerContentPane.setLayout(new BoxLayout(miniViewerContentPane, BoxLayout.Y_AXIS));
+
+ int height = 0;
+ // Generate the mini viewer icons
+ int pageNum = 1;
+ for (final Page page : document) {
+
+ final PagePanel panel = new PagePanel(page, 1.0);
+ viewerContentPane.add(panel);
+ viewerContentPane.add(Box.createVerticalStrut(VIEWER_PAGE_GAP));
+
+ viewerPagePanels.add(panel);
+ height += page.getSize().height;
+ height += VIEWER_PAGE_GAP;
+
+ ImageIcon icon = new ImageIcon(page.getLowResImage());
+ JButton button = new JButton(icon);
+ button.setPreferredSize(page.getLowResSize());
+ button.addActionListener(new MiniViewerActionListener(pageNum++));
+ button.setFocusable(false);
+
+ miniViewerContentPane.add(button);
+ miniViewerContentPane.add(Box.createVerticalStrut(MINI_VIEWER_PAGE_GAP));
+ }
+ System.out.println(height);
- // Generate the viewer page components
- for (final Page page : document) {
- final PagePanel panel = new PagePanel(page, 1.0);
- viewerContentPane.add(panel);
- viewerContentPane.add(Box.createVerticalStrut(VIEWER_PAGE_GAP));
+ // Generate the scroll map
+ invokeAndWait(() -> {
+ revalidate();
+ this.scrollMap = new ScrollMap(document, this, VIEWER_PAGE_GAP);
+ });
+ assumePage(this.currentPage = 1);
+ assumeMaxPages(this.maxPage = document.size());
- viewerPagePanels.add(panel);
- }
+ setTitle("Viewer - " + document.getName());
- miniViewerContentPane.setLayout(new BoxLayout(miniViewerContentPane, BoxLayout.Y_AXIS));
+ // Enable all widgets
+ zoomSlider.setEnabled(true);
+ increaseZoomButton.setEnabled(true);
+ decreaseZoomButton.setEnabled(true);
+ zoomSlider.setValue(50);
+ zoomSlider.setFocusable(true);
- // Generate the mini viewer icons
- int pageNum = 1;
- for (final Page page : document) {
- ImageIcon icon = new ImageIcon(page.getLowResImage());
- JButton button = new JButton(icon);
- button.setPreferredSize(page.getLowResSize());
- button.addActionListener(new MiniViewerActionListener(pageNum++));
- button.setFocusable(false);
+ nextPageButton.setEnabled(true);
+ lastPageButton.setEnabled(true);
+ pageNumberField.setEditable(true);
- miniViewerContentPane.add(button);
- miniViewerContentPane.add(Box.createVerticalStrut(MINI_VIEWER_PAGE_GAP));
+ refreshButtons();
+ } finally {
+ isLoading = false;
}
-
- // Generate the scroll map
- this.scrollMap = new ScrollMap(document, this, VIEWER_PAGE_GAP);
- this.scrollMap.getScroll(1);
-
- assumePage(this.currentPage = 1);
- assumeMaxPages(this.maxPage = document.size());
-
- setTitle("Viewer - " + document.getName());
-
- // Enable all widgets
- zoomSlider.setEnabled(true);
- increaseZoomButton.setEnabled(true);
- decreaseZoomButton.setEnabled(true);
- zoomSlider.setValue(50);
- zoomSlider.setFocusable(true);
-
- nextPageButton.setEnabled(true);
- lastPageButton.setEnabled(true);
- pageNumberField.setEditable(true);
-
- refreshButtons();
}
/**
@@ -738,13 +763,14 @@ public class ViewerWindow extends javax.swing.JFrame {
System.gc();
- SwingUtilities.invokeLater(() -> {
+ invokeAndWait(() -> {
viewerContentPane.revalidate();
viewerContentPane.repaint();
miniViewerContentPane.revalidate();
miniViewerContentPane.repaint();
});
+
}
/**
@@ -885,6 +911,22 @@ public class ViewerWindow extends javax.swing.JFrame {
}
/**
+ * Returns whether the window is loading a document.
+ *
+ * @return <code>true</code> if the window is loading a document
+ * and <code>false</code> otherwise.
+ */
+ public boolean isLoading() {
+ return isLoading;
+ }
+
+ public void apply(Settings settings) {
+ int sens = settings.getSetting("scrollSens");
+ this.viewerScrollPane.getVerticalScrollBar().setUnitIncrement(sens);
+ this.miniViewerScrollPane.getVerticalScrollBar().setUnitIncrement(sens);
+ }
+
+ /**
* Refresh each button's state.
*/
private void refreshButtons() {
@@ -920,7 +962,7 @@ public class ViewerWindow extends javax.swing.JFrame {
viewerPagePanels.add(panel);
}
- SwingUtilities.invokeLater(() -> {
+ invokeAndWait(() -> {
gotoPage = true;
revalidate();
scrollMap.genMap(1.0);
@@ -963,4 +1005,16 @@ public class ViewerWindow extends javax.swing.JFrame {
private void assumeMaxPages(int pageCount) {
this.maxPagesLabel.setText(new StringBuilder().append(pageCount).toString());
}
+
+ private void invokeAndWait(Runnable r) {
+ if (!SwingUtilities.isEventDispatchThread()) {
+ try {
+ SwingUtilities.invokeAndWait(r);
+ } catch (InvocationTargetException | InterruptedException e) {
+ r.run();
+ }
+ } else {
+ r.run();
+ }
+ }
}