Java tutorial
/* * 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; } }