com.trollworks.gcs.pdfview.PdfDockable.java Source code

Java tutorial

Introduction

Here is the source code for com.trollworks.gcs.pdfview.PdfDockable.java

Source

/*
 * Copyright (c) 1998-2017 by Richard A. Wilkes. All rights reserved.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, version 2.0. If a copy of the MPL was not distributed with
 * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This Source Code Form is "Incompatible With Secondary Licenses", as
 * defined by the Mozilla Public License, version 2.0.
 */

package com.trollworks.gcs.pdfview;

import com.trollworks.toolkit.annotation.Localize;
import com.trollworks.toolkit.io.Log;
import com.trollworks.toolkit.ui.UIUtilities;
import com.trollworks.toolkit.ui.image.StdImage;
import com.trollworks.toolkit.ui.menu.file.CloseHandler;
import com.trollworks.toolkit.ui.widget.EditorField;
import com.trollworks.toolkit.ui.widget.IconButton;
import com.trollworks.toolkit.ui.widget.KeyStrokeDisplay;
import com.trollworks.toolkit.ui.widget.Toolbar;
import com.trollworks.toolkit.ui.widget.dock.DockContainer;
import com.trollworks.toolkit.ui.widget.dock.Dockable;
import com.trollworks.toolkit.utility.FileProxy;
import com.trollworks.toolkit.utility.FileType;
import com.trollworks.toolkit.utility.Localization;
import com.trollworks.toolkit.utility.PathUtils;
import com.trollworks.toolkit.utility.PrintProxy;
import com.trollworks.toolkit.utility.text.IntegerFormatter;

import java.awt.BorderLayout;
import java.awt.DefaultFocusTraversalPolicy;
import java.awt.Window;
import java.awt.event.KeyEvent;
import java.io.File;

import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.text.DefaultFormatterFactory;

import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.pdmodel.PDDocument;

/** Provides the ability to view a PDF. */
public class PdfDockable extends Dockable implements FileProxy, CloseHandler {
    @Localize("Previous Page")
    private static String PREVIOUS_PAGE;
    @Localize("Next Page")
    private static String NEXT_PAGE;
    @Localize("Scale Document Up")
    private static String SCALE_DOC_UP;
    @Localize("Scale Document Down")
    private static String SCALE_DOC_DOWN;
    @Localize("Actual Size")
    private static String ACTUAL_SIZE;

    static {
        Localization.initialize();
    }

    private File mFile;
    private PDDocument mPdf;
    private Toolbar mToolbar;
    private PdfPanel mPanel;
    private IconButton mZoomInButton;
    private IconButton mZoomOutButton;
    private IconButton mActualSizeButton;
    private JLabel mZoomStatus;
    private EditorField mPageField;
    private JLabel mPageStatus;
    private IconButton mPreviousPageButton;
    private IconButton mNextPageButton;

    public PdfDockable(PdfRef pdfRef, int page, String highlight) {
        super(new BorderLayout());
        mFile = pdfRef.getFile();
        int pageCount = 9999;
        try {
            mPdf = PDDocument.load(pdfRef.getFile(), MemoryUsageSetting.setupMixed(50 * 1024 * 1024));
            pageCount = mPdf.getNumberOfPages();
        } catch (Exception exception) {
            Log.error(exception);
        }
        mToolbar = new Toolbar();

        mZoomInButton = new IconButton(StdImage.get("ZoomIn"), //$NON-NLS-1$
                formatWithKey(SCALE_DOC_UP, KeyStroke.getKeyStroke('=')), () -> mPanel.zoomIn());
        mToolbar.add(mZoomInButton);
        mZoomOutButton = new IconButton(StdImage.get("ZoomOut"), //$NON-NLS-1$
                formatWithKey(SCALE_DOC_DOWN, KeyStroke.getKeyStroke('-')), () -> mPanel.zoomOut());
        mToolbar.add(mZoomOutButton);
        mActualSizeButton = new IconButton(StdImage.get("ActualSize"), //$NON-NLS-1$
                formatWithKey(ACTUAL_SIZE, KeyStroke.getKeyStroke('1')), () -> mPanel.actualSize());
        mToolbar.add(mActualSizeButton);
        mZoomStatus = new JLabel("100%"); //$NON-NLS-1$
        mToolbar.add(mZoomStatus);

        mPageField = new EditorField(new DefaultFormatterFactory(new IntegerFormatter(1, pageCount, false)),
                event -> {
                    if (mPanel != null) {
                        int pageIndex = ((Integer) mPageField.getValue()).intValue() - 1;
                        int newPageIndex = mPanel.goToPageIndex(pageIndex, null);
                        if (pageIndex != newPageIndex) {
                            mPageField.setValue(Integer.valueOf(newPageIndex + 1));
                        } else {
                            mPanel.requestFocusInWindow();
                        }
                    }
                }, SwingConstants.RIGHT, Integer.valueOf(page), Integer.valueOf(9999), null);
        mToolbar.add(mPageField, Toolbar.LAYOUT_EXTRA_BEFORE);
        mPageStatus = new JLabel("/ -"); //$NON-NLS-1$
        mToolbar.add(mPageStatus);
        mPreviousPageButton = new IconButton(StdImage.get("PageUp"), //$NON-NLS-1$
                formatWithKey(PREVIOUS_PAGE, KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)),
                () -> mPanel.previousPage());
        mToolbar.add(mPreviousPageButton);
        mNextPageButton = new IconButton(StdImage.get("PageDown"), //$NON-NLS-1$
                formatWithKey(NEXT_PAGE, KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)), () -> mPanel.nextPage());
        mToolbar.add(mNextPageButton);

        add(mToolbar, BorderLayout.NORTH);
        mPanel = new PdfPanel(this, mPdf, pdfRef, page, highlight);
        add(new JScrollPane(mPanel), BorderLayout.CENTER);

        setFocusCycleRoot(true);
        setFocusTraversalPolicy(new DefaultFocusTraversalPolicy());
    }

    private static String formatWithKey(String title, KeyStroke key) {
        return title + " [" + KeyStrokeDisplay.getKeyStrokeDisplay(key) + "]"; //$NON-NLS-1$ //$NON-NLS-2$
    }

    public void updateStatus(int page, int pageCount, float scale) {
        mZoomInButton.setEnabled(PdfPanel.SCALES[PdfPanel.SCALES.length - 1] != scale);
        mZoomOutButton.setEnabled(PdfPanel.SCALES[0] != scale);
        mActualSizeButton.setEnabled(scale != 1f);
        boolean revalidate = updateZoomInfo(scale);
        revalidate |= updatePageInfo(page, pageCount);
        if (revalidate) {
            mToolbar.revalidate();
            mToolbar.repaint();
        }
    }

    private boolean updateZoomInfo(float scale) {
        String text = (int) (scale * 100) + "%"; //$NON-NLS-1$
        if (!text.equals(mZoomStatus.getText())) {
            mZoomStatus.setText(text);
            return true;
        }
        return false;
    }

    private boolean updatePageInfo(int page, int pageCount) {
        mPreviousPageButton.setEnabled(page > 0);
        mNextPageButton.setEnabled(page < pageCount - 1);
        mPageField.setValue(Integer.valueOf(page + 1));
        String text = "/ " + (pageCount > 0 ? Integer.valueOf(pageCount) : "-"); //$NON-NLS-1$ //$NON-NLS-2$
        if (!text.equals(mPageStatus.getText())) {
            mPageStatus.setText(text);
            return true;
        }
        return false;
    }

    public void goToPage(PdfRef pdfRef, int page, String highlight) {
        mPanel.goToPage(pdfRef, page, highlight);
    }

    @Override
    public boolean mayAttemptClose() {
        return true;
    }

    @Override
    public boolean attemptClose() {
        try {
            getDockContainer().close(this);
        } finally {
            if (mPdf != null) {
                try {
                    mPdf.close();
                } catch (Exception exception) {
                    Log.error(exception);
                }
                mPdf = null;
            }
        }
        return true;
    }

    @Override
    public String getDescriptor() {
        return null;
    }

    @Override
    public Icon getTitleIcon() {
        return FileType.getIconsForFileExtension(FileType.PDF_EXTENSION).getImage(16);
    }

    @Override
    public String getTitle() {
        return PathUtils.getLeafName(mFile.getName(), false);
    }

    @Override
    public String getTitleTooltip() {
        return null;
    }

    @Override
    public File getBackingFile() {
        return mFile;
    }

    @Override
    public void toFrontAndFocus() {
        Window window = UIUtilities.getAncestorOfType(this, Window.class);
        if (window != null) {
            window.toFront();
        }
        DockContainer dc = getDockContainer();
        dc.setCurrentDockable(this);
        dc.doLayout();
        dc.acquireFocus();
    }

    @Override
    public PrintProxy getPrintProxy() {
        return null;
    }
}