/*
* Copyright (c) 1997-2024 IDRsolutions (https://www.idrsolutions.com)
*/
package org.jpedal.examples.baseviewer;
import org.jpedal.PdfDecoder;
import org.jpedal.examples.viewer.commands.OpenFile;
import org.jpedal.exception.PdfException;
import org.jpedal.objects.PdfPageData;
import org.jpedal.utils.LogWriter;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.border.EmptyBorder;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
/**
* <h2><b>BaseViewer</b></h2>
* <br>
* <p><b>Run directly from jar with java -cp jpedal.jar org/jpedal/examples/baseviewer/BaseViewer</b></p>
* <br>
* <p>There are plenty of tutorials on how to configure the Viewer on our website
* <a href="https://support.idrsolutions.com/jpedal/tutorials/viewer/">Support Section.</a></p>
* <br>
* <p><a href="https://support.idrsolutions.com/jpedal/">
* For more help and tutorials, visit our websites Support Section.</a></p>
*/
public class BaseViewer {
/**
* Enum to control how we fit the content to the page.
* <p>
* AUTO will automatically fit the content to the stage depending on its orientation
* WIDTH will fit the content to the stage width depending on its orientation
* HEIGHT will fit the content to the stage height depending on its orientation
*/
public enum FitToPage {
AUTO, WIDTH, HEIGHT
}
private final JFrame mainFrame = new JFrame("Base Viewer - " + PdfDecoder.version);
private JScrollPane scrollPdf = new JScrollPane();
private final JPanel insets = new JPanel();
final PdfDecoder pdf = new PdfDecoder();
private int currentPage = 1;
private float scale = 1.0f;
private final float[] scalings = {0.01f, 0.1f, 0.25f, 0.5f, 0.75f, 1.0f, 1.25f, 1.5f, 2.0f, 4.0f, 7.5f, 10.0f};
private static final int insetV = 25;
private static final int insetH = 25;
private String filename;
private final JPanel top = new JPanel();
private final JToolBar toolBar = new JToolBar("Tool Bar");
private final JButton open = new JButton("Open");
private final JButton back = new JButton("Back");
private final JButton forward = new JButton("Forward");
private final JButton zoomIn = new JButton("Zoom in");
private final JButton zoomOut = new JButton("Zoom out");
private final JButton fitWidth = new JButton("Fit to Width");
private final JButton fitHeight = new JButton("Fit to Height");
private final JButton fitPage = new JButton("Fit to Page");
private final JLabel pageCounter = new JLabel("Page 0 of 0");
/**
* @param args is of type String[]
*/
@SuppressWarnings("unused")
public static void main(final String[] args) {
final int argLength = args.length;
switch (argLength) {
case 0:
new BaseViewer();
break;
case 1:
new BaseViewer(args[0]);
break;
default:
System.out.println("You need 0 or 1 parameters");
break;
}
}
BaseViewer(final String value) {
filename = value;
init();
}
BaseViewer() {
init();
}
private void init() {
PdfDecoder.init(true);
setupListeners();
createGUI();
mainFrame.setVisible(true);
}
private void setupListeners() {
open.addActionListener(arg0 -> openFile());
back.addActionListener(arg0 -> {
if (currentPage > 1) {
currentPage--;
}
decodePage();
});
forward.addActionListener(arg0 -> {
if (currentPage < pdf.getPageCount()) {
currentPage++;
}
decodePage();
});
final int defaultScaling = 5;
zoomIn.addActionListener(arg0 -> {
//zoom in
System.out.println("Zoom in");
if (defaultScaling < scalings.length - 1) {
int currentScaling = closestIndex(scale, scalings);
if (scale >= scalings[closestIndex(scale, scalings)]) {
currentScaling++;
}
System.out.println("Current Scale ======= " + currentScaling);
scale = scalings[currentScaling];
}
pdf.setPageParameters(scale, currentPage);
pdf.updateUI();
System.out.println("Scaling =========== " + pdf.getScaling());
});
zoomOut.addActionListener(arg0 -> {
//zoom out
System.out.println("Zoom out");
int currentScaling = closestIndex(scale, scalings);
if (scale <= scalings[closestIndex(scale, scalings)]) {
currentScaling--;
}
System.out.println("Current Scale ======= " + currentScaling);
scale = scalings[currentScaling];
pdf.setPageParameters(scale, currentPage);
pdf.updateUI();
System.out.println("Scaling =========== " + pdf.getScaling());
});
fitWidth.addActionListener(arg0 -> {
// Fit to height
System.out.println("Fit to Width");
fitToX(FitToPage.WIDTH);
});
fitHeight.addActionListener(arg0 -> {
// Fit to height
System.out.println("Fit to Height");
fitToX(FitToPage.HEIGHT);
});
fitPage.addActionListener(arg0 -> {
// Fit to height
System.out.println("Fit to Page");
fitToX(FitToPage.AUTO);
});
mainFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(final WindowEvent e) {
if (filename != null) {
try {
pdf.openPdfFile(filename);
decodePage();
} catch (final PdfException ex) {
LogWriter.writeLog(ex);
}
} else {
openFile();
}
}
});
}
private void createGUI() {
toolBar.add(open);
toolBar.add(back);
toolBar.add(forward);
toolBar.add(zoomIn);
toolBar.add(zoomOut);
toolBar.add(fitWidth);
toolBar.add(fitHeight);
toolBar.add(fitPage);
toolBar.setFloatable(false);
top.setLayout(new GridLayout(1, 1));
top.add(toolBar);
((FlowLayout) insets.getLayout()).setVgap(0);
((FlowLayout) insets.getLayout()).setHgap(0);
insets.add(pdf);
if (insetV > 0 || insetH > 0) {
insets.setBorder(new EmptyBorder(insetH, insetV, insetH, insetV));
}
scrollPdf = new JScrollPane(insets);
scrollPdf.getVerticalScrollBar().setUnitIncrement(32);
scrollPdf.getHorizontalScrollBar().setUnitIncrement(32);
mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
mainFrame.getContentPane().add(top, BorderLayout.NORTH);
mainFrame.getContentPane().add(scrollPdf, BorderLayout.CENTER);
mainFrame.getContentPane().add(pageCounter, BorderLayout.SOUTH);
mainFrame.setSize(800, 600);
//make viewer open in the center of the screen
mainFrame.setLocationRelativeTo(null);
}
private void openFile() {
try {
final File f = OpenFile.showFileDialog(mainFrame, null, null, true);
if (f != null) {
pdf.openPdfFile(f.getAbsolutePath());
decodePage();
fitToX(FitToPage.AUTO);
}
} catch (final PdfException e) {
LogWriter.writeLog(e);
}
}
private void fitToX(final FitToPage fitToPage) {
//Handle how we fit the content to the page
switch (fitToPage) {
case AUTO:
if (pdf.getPDFWidth() < pdf.getPDFHeight()) {
fitToX(FitToPage.HEIGHT);
} else {
fitToX(FitToPage.WIDTH);
}
break;
case WIDTH:
final float pageW = pdf.getPdfPageData().getCropBoxWidth2D(currentPage);
scale = ((float) (scrollPdf.getViewportBorderBounds().getWidth() - insetV - insetV) / pageW);
System.out.println("SCALE ==== " + scale);
pdf.setPageParameters(scale, currentPage);
break;
case HEIGHT:
final float pageH = pdf.getPdfPageData().getCropBoxHeight2D(currentPage);
scale = ((float) (scrollPdf.getViewportBorderBounds().getHeight() - insetH - insetH) / pageH);
pdf.setPageParameters(scale, currentPage);
break;
}
pdf.updateUI();
}
private static int closestIndex(final float scale, final float[] scalings) {
float currentMinDiff = Float.MAX_VALUE;
int closest = 0;
for (int i = 0; i < scalings.length - 1; i++) {
final float diff = Math.abs(scalings[i] - scale);
if (diff < currentMinDiff) {
currentMinDiff = diff;
closest = i;
}
}
return closest;
}
private void decodePage() {
try {
pageCounter.setText("Page " + currentPage + " of " + pdf.getPageCount());
final PdfPageData pageData = pdf.getPdfPageData();
final int inset = 10;
final int cw;
final int ch;
final int rotation = pageData.getRotation(currentPage);
if (rotation == 90 || rotation == 270) {
cw = pageData.getCropBoxHeight(currentPage);
ch = pageData.getCropBoxWidth(currentPage);
} else {
cw = pageData.getCropBoxWidth(currentPage);
ch = pageData.getCropBoxHeight(currentPage);
}
//define pdf view width and height
final float width = (pdf.getWidth() - inset - inset);
final float height = (pdf.getHeight() - inset - inset);
if ((width > 0) && (height > 0)) {
final float x_factor;
final float y_factor;
x_factor = width / cw;
y_factor = height / ch;
scale = Math.min(x_factor, y_factor);
}
pdf.setPageParameters(scale, currentPage);
pdf.decodePage(currentPage);
//wait to ensure decoded
pdf.waitForDecodingToFinish();
pdf.invalidate();
pdf.updateUI();
pdf.validate();
} catch (final Exception e) {
LogWriter.writeLog(e);
}
}
}
|