
org.jpedal.examples.viewer.gui.JavaFxGUI Maven / Gradle / Ivy
/*
* ===========================================
* Java Pdf Extraction Decoding Access Library
* ===========================================
*
* Project Info: http://www.idrsolutions.com
* Help section for developers at http://www.idrsolutions.com/support/
*
* (C) Copyright 1997-2015 IDRsolutions and Contributors.
*
* This file is part of JPedal/JPDF2HTML5
*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---------------
* JavaFxGUI.java
* ---------------
*/
package org.jpedal.examples.viewer.gui;
import org.jpedal.utils.BrowserLauncher;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.*;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.animation.Transition;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.geometry.Side;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.control.Labeled;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.ScrollBar;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.control.Separator;
import javafx.scene.control.SplitPane;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextField;
import javafx.scene.control.ToolBar;
import javafx.scene.control.Tooltip;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Background;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.TextAlignment;
import javafx.stage.*;
import javafx.util.Duration;
import javax.imageio.ImageIO;
import org.jpedal.*;
import org.jpedal.display.*;
import org.jpedal.display.javafx.*;
import org.jpedal.examples.viewer.Commands;
import org.jpedal.examples.viewer.JavaFXRecentDocuments;
import org.jpedal.examples.viewer.RecentDocumentsFactory;
import org.jpedal.examples.viewer.Values;
import org.jpedal.examples.viewer.commands.OpenFile;
import org.jpedal.examples.viewer.commands.javafx.JavaFXOpenFile;
import org.jpedal.examples.viewer.gui.generic.GUIButtons;
import org.jpedal.examples.viewer.gui.generic.GUICombo;
import org.jpedal.examples.viewer.gui.generic.GUIMenuItems;
import org.jpedal.examples.viewer.gui.generic.GUIMouseHandler;
import org.jpedal.examples.viewer.gui.generic.GUISearchList;
import org.jpedal.examples.viewer.gui.generic.GUISearchWindow;
import org.jpedal.examples.viewer.gui.javafx.*;
import org.jpedal.examples.viewer.gui.javafx.FXViewerTransitions.TransitionDirection;
import org.jpedal.examples.viewer.gui.javafx.FXViewerTransitions.TransitionType;
import org.jpedal.examples.viewer.gui.javafx.dialog.FXInputDialog;
import org.jpedal.examples.viewer.gui.javafx.dialog.FXMessageDialog;
import org.jpedal.examples.viewer.gui.javafx.dialog.FXOptionDialog;
import org.jpedal.examples.viewer.gui.popups.PrintPanelFX;
import org.jpedal.examples.viewer.paper.PaperSizes;
import org.jpedal.examples.viewer.utils.PropertiesFile;
import org.jpedal.external.ExternalHandlers;
import org.jpedal.external.Options;
import org.jpedal.external.RenderChangeListener;
import org.jpedal.fonts.tt.TTGlyph;
import org.jpedal.gui.*;
import org.jpedal.io.StatusBarFX;
import org.jpedal.objects.PdfPageData;
import org.jpedal.objects.acroforms.AcroRenderer;
import org.jpedal.objects.acroforms.actions.ActionHandler;
import org.jpedal.objects.layers.PdfLayerList;
import org.jpedal.objects.raw.FormObject;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.objects.raw.PdfObject;
import org.jpedal.parser.DecoderOptions;
import org.jpedal.render.DynamicVectorRenderer;
import org.jpedal.utils.*;
import org.w3c.dom.Node;
/**
*
Description: GUI functions in Viewer implemented in JavaFX
*
*
*/
@SuppressWarnings("MagicConstant")
public class JavaFxGUI extends GUI implements GUIFactory {
private RefreshLayout viewListener;
private static final int bottomPaneHeight = 40;
protected final JavaFXButtons fxButtons;
//GUICursor object that holds everything todo with Cursor for SwingGUI
private final SwingCursor guiCursor = new SwingCursor();
/**
* all mouse actions
*/
private GUIMouseHandler mouseHandler;
private Timeline memoryMonitor;
//flag for marks new thumbnail preview
private boolean debugThumbnail;
private boolean sideTabBarOpenByDefault;
private String startSelectedTab = "Pages";
//
//use new GUI layout
public static String windowTitle;
private boolean hasListener;
private boolean isSetup;
private int lastTabSelected = -1;
private boolean tabsExpanded;
private PaperSizes paperSizes;
/**
* Multibox for new GUI Layout Component to contain memory, cursor and
* loading bars IMPORTANT : the width of the multibox needs to be the same
* size as the width of pagesToolBar to ensure that it is centered on the
* page.
*/
private HBox multiboxfx;
private FXProgressBarWithText memoryBarFX;
/**
* visual display of current cursor co-ords on page
*/
private TextField coordsFX;
/**
* Track whether both pages are properly displayed
*/
private final static boolean pageTurnScalingAppropriate = true;
/**
* holds back/forward buttons at bottom of page
*/
private HBox navButtons;
/**
* displayed on left to hold thumbnails, bookmarks
*/
private TabPane navOptionsPanel;
/**
* tell user on first form change it can be saved
*/
private static final boolean firstTimeFormMessage = true;
/**
* flag to disable functions
*/
private boolean isSingle = true;
private Label pageCounter1;
public TextField pageCounter2;
private Label pageCounter3;
private final JavaFXSignaturesPanel signaturesPanel;
private final JavaFXLayersPanel layersPanel;
/**
* user dir in which program can write
*/
private String user_dir = System.getProperty("user.dir");
/**
* stop user forcing open tab before any pages loaded
*/
private boolean tabsNotInitialised = true;
// private boolean thumbnailsInitialised;
private boolean hasPageChanged;
private ToolBar navToolBar;
private ToolBar pagesToolBar;
//
//The main JavaFX Stage
private final Stage stage;
//The main JavaFX Scene
private Scene scene;
//BorderPane lays out children in top, left, right, bottom, and center positions.
private final BorderPane root;
private static final int dropshadowDepth = 40;
//
private Group group;
// Scrollpane to contain the PDF page
private ScrollPane pageContainer;
private SplitPane center;
private final VBox topPane;
/**
* Interactive display object - needs to be added to PdfDecoder
*/
// private StatusBarFX statusBar=new StatusBarFX(new Color((235.0d/255.0d), (154.0d/255.0d), 0, 1));
private StatusBarFX downloadBar;
private boolean addSearchTab;
private boolean searchInMenu;
private TextField searchText;
private GUISearchList results;
private MenuBar options;
private boolean cursorOverPage;
private PrintPanelFX printPanel;
//
private TransitionType transitionType = TransitionType.None;
// Scrolls between pages when the pdf is not zoomed in
private ScrollBar pageScroll;
private ChangeListener fxChangeListener;
public JavaFxGUI(final Stage stage, final PdfDecoderInt decode_pdf, final Values commonValues, final GUIThumbnailPanel thumbnails, final PropertiesFile properties) {
super(decode_pdf, commonValues, thumbnails, properties);
isJavaFX = true;
if (debugFX) {
System.out.println("JavaFxGUI");
}
this.stage = stage;
root = new BorderPane();
topPane = new VBox();
pageCounter2 = new TextField();
navButtons = new HBox();
fxButtons = new JavaFXButtons();
pageCounter3 = new Label();
navToolBar = new ToolBar();
pagesToolBar = new ToolBar();
tree = new JavaFXOutline();
layersPanel = new JavaFXLayersPanel();
signaturesPanel = new JavaFXSignaturesPanel();
setLookAndFeel();
setupDisplay();
}
/*
For the following methods getThumbnailScrollBar, setThumbnailScrollBarVisibility and setThumbnailScrollBarValue:
These methods have not been implemented yet as they do not have the equivalent to SwingGUI.thumbscroll
implemented in FX.
*/
@Override
public Object getThumbnailScrollBar() {
if (debugFX) {
System.out.println("getThumbnailScrollBar - Implemented");
}
return pageScroll;
}
@Override
public void setThumbnailScrollBarVisibility(final boolean isVisible) {
if (debugFX) {
System.out.println("setThumbnailScrollBarVisibility - Implemented");
}
pageScroll.setVisible(isVisible);
}
@Override
public void setThumbnailScrollBarValue(final int pageNum) {
if (debugFX) {
System.out.println("setThumbnailScrollBarValue - Implemented");
}
pageScroll.setValue(pageNum);
}
/**
* set the look and feel for the GUI components to be the default for the
* system it is running on
*/
private void setLookAndFeel() {
if (debugFX) {
System.out.println("setLookAndFeel - Not yet implemented in JavaFX");
}
/**
* JavaFX has not look and feel option, 2.2 has a theme called Caspian
* (the default theme) only. FX8 has Moderna and Caspian, which can be
* set in the class which overrides Application with
* setUserAgentStylesheet(url)
*
* We can also define our own rules on top of this with:
* root.getStylesheets().clear();
* root.getStylesheets().add("stylesheetlocation"); Also see:
* http://blog.idrsolutions.com/2014/04/use-external-css-files-javafx/
*/
root.getStylesheets().clear();
root.getStylesheets().add(getClass().getResource("/org/jpedal/examples/viewer/res/css/JavaFXForms.css").toExternalForm());
root.getStylesheets().add(getClass().getResource("/org/jpedal/examples/viewer/res/css/JavaFXPages.css").toExternalForm());
}
/**
* setup display
*/
private void setupDisplay() {
if (debugFX) {
System.out.println("setupDisplay - Not yet implemented in JavaFX");
}
setDisplayView(Display.SINGLE_PAGE, Display.DISPLAY_CENTERED);
//pass in SwingGUI so we can call via callback
decode_pdf.addExternalHandler(this, Options.GUIContainer);
menuItems = new JavaFXMenuItems(properties);
/**
* setup display multiview display
*/
// if (isSingle) {
// desktopPane.setBackground(frame.getBackground());
// desktopPane.setVisible(true);
// if(frame instanceof JFrame)
// ((JFrame)frame).getContentPane().add(desktopPane, BorderLayout.CENTER);
// else
// frame.add(desktopPane, BorderLayout.CENTER);
//
// }
}
@Override
public SplitPane getDisplayPane() {
return center;
}
@Override
public Object getMultiViewerFrames() {
if (debugFX) {
System.out.println("getMultiViewerFrames");
}
//return desktopPane;
return null;
}
@Override
public String getPropertiesFileLocation() {
if (debugFX) {
System.out.println("getPropertiesFileLocation");
}
return properties.getConfigFile();
}
@Override
public String getBookmark(final String bookmark) {
if (debugFX) {
System.out.println("getBookmark");
}
return tree.getPage(bookmark);
}
@Override
public void reinitialiseTabs(final boolean showVisible) {
if (debugFX) {
System.out.println("reinitialiseTabs");
}
//not needed
if (commonValues.getModeOfOperation() == Values.RUNNING_PLUGIN) {
return;
}
if (properties.getValue("ShowSidetabbar").equalsIgnoreCase("true")) {
if (!isSingle) {
return;
}
if (!showVisible && !properties.getValue("consistentTabBar").equalsIgnoreCase("true")) {
if (sideTabBarOpenByDefault) {
setSplitDividerLocation(expandedSize);
tabsExpanded = true;
} else {
setSplitDividerLocation(collapsedSize);
tabsExpanded = false;
}
}
lastTabSelected = -1;
if (!commonValues.isPDF()) {
navOptionsPanel.setVisible(false);
} else {
navOptionsPanel.setVisible(true);
/**
* add/remove optional tabs
*/
if (!decode_pdf.hasOutline()) {
int outlineTab = -1;
if (DecoderOptions.isRunningOnMac) {
//String tabName="";
//see if there is an outlines tab
for (int jj = 0; jj < navOptionsPanel.getTabs().size(); jj++) {
if (navOptionsPanel.getTabs().get(jj).getText().equals(bookmarksTitle)) {
outlineTab = jj;
}
}
} else {
//String tabName="";
//see if there is an outlines tab
for (int jj = 0; jj < navOptionsPanel.getTabs().size(); jj++) {
//@Simon recode to use VTextIcon
if (navOptionsPanel.getTabs().get(jj).getText().equals(bookmarksTitle)) {
outlineTab = jj;
}
}
}
if (outlineTab != -1) {
navOptionsPanel.getTabs().remove(outlineTab);
}
} else if (properties.getValue("Bookmarkstab").equalsIgnoreCase("true")) {
int outlineTab = -1;
if (DecoderOptions.isRunningOnMac) {
//String tabName="";
//see if there is an outlines tab
for (int jj = 0; jj < navOptionsPanel.getTabs().size(); jj++) {
if (navOptionsPanel.getTabs().get(jj).getText().equals(bookmarksTitle)) {
outlineTab = jj;
}
}
if (outlineTab == -1) // navOptionsPanel.addTab(bookmarksTitle,(SwingOutline) tree);
//@Simon Change to add JavaFXOutline tab
{
navOptionsPanel.getTabs().add(navOptionsPanel.getTabs().size() - 1, (JavaFXOutline) tree);
}
} else {
//String tabName="";
//see if there is an outlines tab
for (int jj = 0; jj < navOptionsPanel.getTabs().size(); jj++) {
//@Simon recode to use VTextIcon
if (navOptionsPanel.getTabs().get(jj).getText().equals(bookmarksTitle)) {
outlineTab = jj;
}
}
if (outlineTab == -1) {
//@Simon Recode
// VTextIcon textIcon2 = new VTextIcon(navOptionsPanel, bookmarksTitle, VTextIcon.ROTATE_LEFT);
// navOptionsPanel.addTab(null, textIcon2, (SwingOutline) tree);
navOptionsPanel.getTabs().add(navOptionsPanel.getTabs().size() - 1, (JavaFXOutline) tree);
}
}
}
/**
* handle signatures pane
*/
final AcroRenderer currentFormRenderer = decode_pdf.getFormRenderer();
Iterator signatureObjects = null;
if (currentFormRenderer != null) {
signatureObjects = currentFormRenderer.getSignatureObjects();
}
if (signatureObjects != null) {
signaturesPanel.reinitialise(decode_pdf, signatureObjects);
checkTabShown(signaturesTitle);
} else {
removeTab(signaturesTitle);
}
//
/**
* add a control Panel to enable/disable layers
*/
//layers object
layersObject = (PdfLayerList) decode_pdf.getJPedalObject(PdfDictionary.Layer);
if (layersObject != null && layersObject.getLayersCount() > 0) { //some files have empty Layers objects
checkTabShown(layersTitle);
layersPanel.reinitialise(layersObject, decode_pdf, null, commonValues.getCurrentPage());
} else {
removeTab(layersTitle);
}
setBookmarks(false);
}
if (tabsNotInitialised) {
//@Simon selected index
for (int i = 0; i != navOptionsPanel.getTabs().size(); i++) {
if (DecoderOptions.isRunningOnMac) {
if (navOptionsPanel.getTabs().get(i).getText().equals(startSelectedTab)) {
navOptionsPanel.getSelectionModel().select(i);
break;
}
} else {
if (navOptionsPanel.getTabs().get(i).getGraphic().toString().equals(startSelectedTab)) {
navOptionsPanel.getSelectionModel().select(i);
break;
}
}
}
}
}
}
private void checkTabShown(final String title) {
if (debugFX) {
System.out.println("checkTabShown");
}
int outlineTab = -1;
if (DecoderOptions.isRunningOnMac) {
//see if there is an outlines tab
for (int jj = 0; jj < navOptionsPanel.getTabs().size(); jj++) {
if (navOptionsPanel.getTabs().get(jj).getText().equals(title)) {
outlineTab = jj;
}
}
if (outlineTab == -1) {
if (title.equals(signaturesTitle) && properties.getValue("Signaturestab").equalsIgnoreCase("true")) {
navOptionsPanel.getTabs().add(navOptionsPanel.getTabs().size() - 1, signaturesPanel);
} else if (title.equals(layersTitle) && properties.getValue("Layerstab").equalsIgnoreCase("true")) {
navOptionsPanel.getTabs().add(navOptionsPanel.getTabs().size() - 1, layersPanel);
}
}
} else {
//see if there is an outlines tab
for (int jj = 0; jj < navOptionsPanel.getTabs().size(); jj++) {
//@Simon to getIcon
if (navOptionsPanel.getTabs().get(jj).getText().equals(title)) {
outlineTab = jj;
}
}
if (outlineTab == -1) {
if (title.equals(signaturesTitle) && properties.getValue("Signaturestab").equalsIgnoreCase("true")) { //stop spurious display of Sig tab
//@Simon Signatures panel
navOptionsPanel.getTabs().add(navOptionsPanel.getTabs().size() - 1, signaturesPanel);
} else if (title.equals(layersTitle) && properties.getValue("Layerstab").equalsIgnoreCase("true")) {
navOptionsPanel.getTabs().add(navOptionsPanel.getTabs().size() - 1, layersPanel);
}
}
}
}
private void removeTab(final String title) {
if (debugFX) {
System.out.println("removeTab");
}
int outlineTab = -1;
if (DecoderOptions.isRunningOnMac) {
//String tabName="";
//see if there is an outlines tab
for (int jj = 0; jj < navOptionsPanel.getTabs().size(); jj++) {
if (navOptionsPanel.getTabs().get(jj).getText().equals(title)) {
outlineTab = jj;
}
}
} else {
//String tabName="";
//see if there is an outlines tab
// @Simon to getIcon
for (int jj = 0; jj < navOptionsPanel.getTabs().size(); jj++) {
if (navOptionsPanel.getTabs().get(jj).getText().equals(title)) {
outlineTab = jj;
}
}
}
if (outlineTab != -1) // navOptionsPanel.remove(outlineTab);
{
navOptionsPanel.getTabs().remove(outlineTab);
}
}
@Override
public void stopThumbnails() {
if (debugFX) {
System.out.println("stopThumbnails");
}
if (!isSingle) {
return;
}
if (thumbnails.isShownOnscreen()) {
/**
* if running terminate first
*/
thumbnails.terminateDrawing();
thumbnails.removeAllListeners();
}
}
@Override
public void reinitThumbnails() {
if (debugFX) {
System.out.println("reinitThumbnails");
}
isSetup = false;
}
/**
* reset so appears closed
*/
@Override
public void resetNavBar() {
if (debugFX) {
System.out.println("resetNavBar");
}
if (!isSingle) {
return;
}
if (!properties.getValue("consistentTabBar").equalsIgnoreCase("true")) {
setSplitDividerLocation(collapsedSize);
tabsExpanded = false;
tabsNotInitialised = true;
}
//also reset layers
// layersPanel.resetLayers();
//disable page view buttons until we know we have multiple pages
fxButtons.setPageLayoutButtonsEnabled(false);
}
/* (non-Javadoc)
* @see org.jpedal.examples.viewer.gui.swing.GUIFactory#setNoPagesDecoded()
*
* Called when new file opened so we set flags here
*/
@Override
public void setNoPagesDecoded() {
if (debugFX) {
System.out.println("setNoPagesDecoded");
}
bookmarksGenerated = false;
resetNavBar();
}
@Override
public void setDisplayMode(final Integer mode) {
if (debugFX) {
System.out.println("setDisplayMode");
}
if (mode.equals(GUIFactory.MULTIPAGE)) {
isSingle = false;
}
}
@Override
public boolean isSingle() {
if (debugFX) {
System.out.println("isSingle");
}
return isSingle;
}
@Override
public Object getThumbnailPanel() {
if (debugFX) {
System.out.println("getThumbnailPanel");
}
return thumbnails;
}
@Override
public Object getOutlinePanel() {
if (debugFX) {
System.out.println("getOutlinePanel");
}
return tree;
}
/**
* Can't get the scrollbar from a scroll pane, other methods should be
* implemented to circumvent this when needed
*/
@Override
public Object getVerticalScrollBar() {
if (debugFX) {
System.out.println("getVerticalScrollBar");
}
// Altered function due to above comments, return thumbscroll only when shown
if (pageScroll.isVisible()) {
return pageScroll;
} else {
return null;
}
}
/*
*Allows user to embed viewer into own application�
*/
@Override
public void setRootContainer(final Object rawValue) {
if (rawValue == null) {
throw new RuntimeException("Null containers not allowed.");
}
final Parent parentPane = (Parent) rawValue;
//We add the Viewer to the parent pane depending on its type.
if (parentPane instanceof Pane) {
((Pane) parentPane).getChildren().add(root);
} else if (parentPane instanceof ScrollPane) {
((ScrollPane) parentPane).setContent(root);
}
//Load width and height from properties file
int width = Integer.parseInt(properties.getValue("startViewerWidth"));
int height = Integer.parseInt(properties.getValue("startViewerHeight"));
//Used to prevent infinite scroll issue as a preferred size has been set
final Rectangle2D d = Screen.getPrimary().getVisualBounds();
if (width < 0) {
width = (int) (d.getWidth() / 2);
if (width < 700) {
width = 700;
}
properties.setValue("startViewerWidth", String.valueOf(width));
}
if (height < 0) {
height = (int) (d.getHeight() / 2);
properties.setValue("startViewerHeight", String.valueOf(height));
}
//allow user to alter size
final String customWindowSize = System.getProperty("org.jpedal.startWindowSize");
if (customWindowSize != null) {
final StringTokenizer values = new StringTokenizer(customWindowSize, "x");
System.out.println(values.countTokens());
if (values.countTokens() != 2) {
throw new RuntimeException("Unable to use value for org.jpedal.startWindowSize=" + customWindowSize + "\nValue should be in format org.jpedal.startWindowSize=200x300");
}
//try {
//width = Integer.parseInt(values.nextToken().trim());
//height = Integer.parseInt(values.nextToken().trim());
// } catch (Exception ee) {
// throw new RuntimeException("Unable to use value for org.jpedal.startWindowSize=" + customWindowSize + "\nValue should be in format org.jpedal.startWindowSize=200x300");
// }
}
}
/* (non-Javadoc)
* @see org.jpedal.examples.viewer.gui.swing.GUIFactory#resetRotationBox()
*/
@Override
public void resetRotationBox() {
if (debugFX) {
System.out.println("resetRotationBox");
}
final PdfPageData currentPageData = decode_pdf.getPdfPageData();
//>>> DON'T UNCOMMENT THIS LINE, causes major rotation issues, only useful for debuging <<<
if (decode_pdf.getDisplayView() == Display.SINGLE_PAGE) {
rotation = currentPageData.getRotation(commonValues.getCurrentPage());
}
//else
//rotation=0;
if (getSelectedComboIndex(Commands.ROTATION) != (rotation / 90)) {
setSelectedComboIndex(Commands.ROTATION, (rotation / 90));
} else if (!Values.isProcessing()) {
// ((PdfDecoder)decode_pdf).repaint();
}
}
/* (non-Javadoc)
* @see org.jpedal.examples.viewer.gui.swing.GUIFactory#getProperties()
*/
@Override
public PropertiesFile getProperties() {
return properties;
}
/**
* display form data in popup
*
* private class ShowFormDataListener implements ActionListener{
*
* private String formName;
*
* public ShowFormDataListener(String formName){ this.formName=formName; }
*
* public void actionPerformed(ActionEvent e) {
*
*
* //will return Object or Object[] if multiple items of same name Object[]
* values=decode_pdf.getFormRenderer().getCompData().getRawForm(formName);
*
* int count=values.length;
*
* JTabbedPane valueDisplay=new JTabbedPane(); for(int jj=0;jj() {
@Override
public void changed(final ObservableValue ov,
final Boolean old_val, final Boolean new_val) {
searchFrame.setWholeWords(cb1.isSelected());
}
});
cb2.selectedProperty().addListener(new ChangeListener() {
@Override
public void changed(final ObservableValue ov,
final Boolean old_val, final Boolean new_val) {
searchFrame.setCaseSensitive(cb2.isSelected());
}
});
cb3.selectedProperty().addListener(new ChangeListener() {
@Override
public void changed(final ObservableValue ov,
final Boolean old_val, final Boolean new_val) {
searchFrame.setMultiLine(cb3.isSelected());
}
});
/**
* Setup Menu Apply Image, and Add Items.
*/
final Menu menu = new Menu();
final Image image = new Image(guiCursor.getURLForImage("menuSearchOptions.png").toString());
menu.setGraphic(new ImageView(image));
menu.getItems().addAll(cb1, cb2, cb3);
/**
* Setup Menu Bar and Add Menu.
*/
options = new MenuBar();
options.setBackground(Background.EMPTY);
options.setFocusTraversable(false);
options.setTooltip(new Tooltip(Messages.getMessage("PdfViewerSearch.Options")));
options.getMenus().add(menu);
return options;
}
/*
* Set Search Bar to be in the Top Button Bar
*/
private void searchInMenu(final GUISearchWindow searchFrame) {
this.searchFrame = searchFrame;
searchInMenu = true;
searchFrame.find(decode_pdf, commonValues);
fxButtons.getTopButtons().getItems().add(searchText);
fxButtons.getTopButtons().getItems().add(createMenuBarSearchOptions());
fxButtons.addButton(GUIFactory.BUTTONBAR, Messages.getMessage("PdfViewerSearch.Previous"), "search_previous.gif", Commands.PREVIOUSRESULT, menuItems, this, currentCommandListener, pagesToolBar, navToolBar);
fxButtons.addButton(GUIFactory.BUTTONBAR, Messages.getMessage("PdfViewerSearch.Next"), "search_next.gif", Commands.NEXTRESULT, menuItems, this, currentCommandListener, pagesToolBar, navToolBar);
fxButtons.getButton(Commands.NEXTRESULT).setEnabled(false);
fxButtons.getButton(Commands.PREVIOUSRESULT).setEnabled(false);
fxButtons.getButton(Commands.NEXTRESULT).setVisible(true);
fxButtons.getButton(Commands.PREVIOUSRESULT).setVisible(true);
}
@Override
public void setPropertiesFileLocation(final String file) {
properties.loadProperties(file);
}
@Override
public Commands getCommand() {
return currentCommands;
}
/* (non-Javadoc)
* @see org.jpedal.examples.viewer.gui.swing.GUIFactory#init(java.lang.String[], org.jpedal.examples.viewer.Commands, org.jpedal.examples.viewer.utils.Printer)
*/
@Override
public void init(final Commands currentCommands, final Object currentPrinter) {
if (debugFX) {
System.out.println("init");
}
updateTransitionType();
mouseHandler = new JavaFXMouseListener((PdfDecoderFX) decode_pdf, this, commonValues, currentCommands);
mouseHandler.setupMouse();
super.init(currentCommands);
/**
* Set up from properties
*/
try {
//Set whether to use hinting
propValue = properties.getValue("useHinting");
propValue2 = System.getProperty("org.jpedal.useTTFontHinting");
//check JVM flag first
if (propValue2 != null) {
//check if properties file conflicts
if (!propValue.isEmpty() && !propValue2.equalsIgnoreCase(propValue.toLowerCase())) {
showMessageDialog(Messages.getMessage("PdfCustomGui.hintingFlagFileConflict"));
}
TTGlyph.useHinting = propValue2.equalsIgnoreCase("true");
//check properties file
} else {
TTGlyph.useHinting = !propValue.isEmpty() && propValue.equalsIgnoreCase("true");
}
//Set icon location
propValue = properties.getValue("iconLocation");
if (!propValue.isEmpty() && GUI.debugFX) {
System.out.println("guiCursor is not set to JavaFXCursor in method init() in class JavaFxGUI.java");
}
//guiCursor.setIconLocation(propValue);
} catch (final Exception e) {
e.printStackTrace();
}
/**
* setup combo boxes
*/
setupComboBoxes();
//
/**
* Initialise the Swing Buttons *
*/
fxButtons.init(isSingle);
/**
* create a menu bar and add to display
*/
createTopMenuBar();
/**
* create other tool bars and add to display
*/
createOtherToolBars();
/**
* set colours on display boxes and add listener to page number
*/
setupBottomToolBarItems();
/**
* Menu bar for using the majority of functions
*/
//menuItems.createMainMenu(true, currentCommandListener, isSingle, commonValues, currentCommands, fxButtons);
//createSwingMenu(true);
/**
* sets up all the toolbar items
*/
fxButtons.addButton(GUIFactory.BUTTONBAR, Messages.getMessage("PdfViewerToolbarTooltip.openFile"), "open.gif", Commands.OPENFILE, menuItems, this, currentCommandListener, pagesToolBar, navToolBar);
fxButtons.addButton(GUIFactory.BUTTONBAR, Messages.getMessage("PdfViewerToolbarTooltip.print"), "print.gif", Commands.PRINT, menuItems, this, currentCommandListener, pagesToolBar, navToolBar);
if (searchFrame != null && (searchFrame.getViewStyle() == GUISearchWindow.SEARCH_EXTERNAL_WINDOW || (searchFrame.getViewStyle() == GUISearchWindow.SEARCH_MENU_BAR && !isSingle))) {
searchFrame.setViewStyle(GUISearchWindow.SEARCH_EXTERNAL_WINDOW);
fxButtons.addButton(GUIFactory.BUTTONBAR, Messages.getMessage("PdfViewerToolbarTooltip.search"), "find.gif", Commands.FIND, menuItems, this, currentCommandListener, pagesToolBar, navToolBar);
}
fxButtons.addButton(GUIFactory.BUTTONBAR, Messages.getMessage("PdfViewerToolbarTooltip.properties"), "properties.gif", Commands.DOCINFO, menuItems, this, currentCommandListener, pagesToolBar, navToolBar);
if (commonValues.getModeOfOperation() == Values.RUNNING_PLUGIN) {
fxButtons.addButton(GUIFactory.BUTTONBAR, Messages.getMessage("PdfViewerToolbarTooltip.about"), "about.gif", Commands.ABOUT, menuItems, this, currentCommandListener, pagesToolBar, navToolBar);
}
/**
* snapshot screen function
*/
fxButtons.addButton(GUIFactory.BUTTONBAR, Messages.getMessage("PdfViewerToolbarTooltip.snapshot"), "snapshot.gif", Commands.SNAPSHOT, menuItems, this, currentCommandListener, pagesToolBar, navToolBar);
final Separator sep = new Separator();
sep.setPrefSize(5, 32);
/**
* combo boxes on toolbar
*/
addCombo(Messages.getMessage("PdfViewerToolbarScaling.text"), Messages.getMessage("PdfViewerToolbarTooltip.zoomin"), Commands.SCALING);
addCombo(Messages.getMessage("PdfViewerToolbarRotation.text"), Messages.getMessage("PdfViewerToolbarTooltip.rotation"), Commands.ROTATION);
fxButtons.addButton(GUIFactory.BUTTONBAR, Messages.getMessage("PdfViewerToolbarTooltip.mouseMode"), "mouse_select.png", Commands.MOUSEMODE, menuItems, this, currentCommandListener, pagesToolBar, navToolBar);
fxButtons.getTopButtons().getItems().add(sep);
//
/**
* add cursor location
*/
initMultiBox();
/**
* navigation toolbar for moving between pages
*/
createNavbar();
// p.setButtonDefaults(defaultValues);
//
/**
* external/itext button option example adding new option to Export menu
* an icon is set wtih location on classpath
* "/org/jpedal/examples/viewer/res/newfunction.gif" Make sure it exists
* at location and is copied into jar if recompiled
*/
//currentGUI.addButton(currentGUI.BUTTONBAR,tooltip,"/org/jpedal/examples/viewer/res/newfunction.gif",Commands.NEWFUNCTION);
/**
* external/itext menu option example adding new option to Export menu
* Tooltip text can be externalised in
* Messages.getMessage("PdfViewerTooltip.NEWFUNCTION") and text added
* into files in res package
*/
if (searchFrame != null && searchFrame.getViewStyle() == GUISearchWindow.SEARCH_MENU_BAR && isSingle) {
searchInMenu(searchFrame);
}
/**
* status object on toolbar showing 0 -100 % completion
*/
initStatus();
// p.setDisplayDefaults(defaultValues);
//Ensure all gui sections are displayed correctly
//Issues found when removing some sections
/////////////////////////////////////
if (GUI.debugFX) {
System.out.println("Swing specific invalidate(), validate(), repaint() not implemented for JavaFX in JavaFxGUI");
}
//frame.invalidate();
//frame.validate();
//frame.repaint();
/////////////////////////////////////
// //
/**
// //
//
/**/
/**
* set display to occupy half screen size and display, add listener and
* make sure appears in centre
*/
if (commonValues.getModeOfOperation() != Values.RUNNING_APPLET) {
//Load width and height from properties file
int width = Integer.parseInt(properties.getValue("startViewerWidth"));
int height = Integer.parseInt(properties.getValue("startViewerHeight"));
//Used to prevent infinite scroll issue as a preferred size has been set
//Used to prevent infinite scroll issue as a preferred size has been set
final Rectangle2D d = Screen.getPrimary().getVisualBounds();
if (width < 0) {
width = ((int) d.getWidth()) / 2;
if (width < minimumScreenWidth) {
width = minimumScreenWidth;
}
properties.setValue("startViewerWidth", String.valueOf(width));
}
if (height < 0) {
height = ((int) d.getHeight()) / 2;
properties.setValue("startViewerHeight", String.valueOf(height));
}
//allow user to alter size
final String customWindowSize = System.getProperty("org.jpedal.startWindowSize");
if (customWindowSize != null) {
final StringTokenizer values = new StringTokenizer(customWindowSize, "x");
System.out.println(values.countTokens());
if (values.countTokens() != 2) {
throw new RuntimeException("Unable to use value for org.jpedal.startWindowSize=" + customWindowSize + "\nValue should be in format org.jpedal.startWindowSize=200x300");
}
try {
width = Integer.parseInt(values.nextToken().trim());
height = Integer.parseInt(values.nextToken().trim());
} catch (final Exception ee) {
throw new RuntimeException("Unable to use value for org.jpedal.startWindowSize=" + customWindowSize + "\nValue should be in format org.jpedal.startWindowSize=200x300 " + ee);
}
}
/**
* add the pdf display to show page
*/
setupPDFDisplayPane(width, height);
/**
* add the pdf display left and right panes
*/
setupBorderPanes();
createMainViewerWindow(width, height);
}
/*
* Add Background color to the JavaFX panel to help break up view
*/
setupCenterPanelBackground();
setupPDFBorder();
//@Simon temp
//initThumbnails();
//Set side tab bar state at start up
if (sideTabBarOpenByDefault) {
setSplitDividerLocation(expandedSize);
tabsExpanded = true;
} else {
setSplitDividerLocation(collapsedSize);
tabsExpanded = false;
}
/**
* Load properties
*/
try {
GUIModifier.load(properties, this);
} catch (final Exception e) {
e.printStackTrace();
}
//DELETE This code block once all items are implemented.
//This code is here so the loading of properties does not override
//the disabling of unimplemented items in the FXViewer.
final int ALL = -10;
((JavaFXMenuItems) menuItems).disableUnimplementedItems(ALL, false);
fxButtons.disableUnimplementedItems(ALL);
}
//
/**
* method being called from within init to create other tool bars to add to
* display
*/
@Override
protected void createOtherToolBars() {
if (GUI.debugFX) {
System.out.println("createOtherToolBars almost finished for JavaFX");
}
/**
* This is where we setup the top most menu
*/
menuItems.createMainMenu(true, currentCommandListener, isSingle, commonValues, currentCommands, fxButtons);
topPane.getChildren().add(((JavaFXMenuItems) menuItems).getCurrentMenuFX());
/**
* This is where we add the Buttons for the top ToolBar
*/
topPane.getChildren().add(fxButtons.getTopButtons());
}
private void handleTabbedPanes() {
if (tabsNotInitialised) {
return;
}
if (debugFX) {
System.out.println("handleTabbedPanes");
}
/**
* expand size if not already at size
*/
//int currentSize=displayPane.getDividerLocation();
final int tabSelected;
tabSelected = navOptionsPanel.getSelectionModel().getSelectedIndex();
if (tabSelected == -1) {
return;
}
if (!tabsExpanded) {
/**
* workout selected tab
*/
final String tabName = navOptionsPanel.getTabs().get(tabSelected).getText();
// if(DecoderOptions.isRunningOnMac){
// tabName=navOptionsPanelFX.getTabs().get(tabSelected).getText();
// } else
// tabName=navOptionsPanelFX.getTabs().get(tabSelected).getGraphic().toString();
if (tabName != null && tabName.equals(pageTitle)) {
thumbnails.setIsDisplayedOnscreen(true);
} else {
thumbnails.setIsDisplayedOnscreen(false);
}
// Don't expand on dummy tab
if (!navOptionsPanel.getSelectionModel().getSelectedItem().isDisable()) {
setSplitDividerLocation(expandedSize);
tabsExpanded = true;
}
} else if (lastTabSelected == tabSelected && !hasPageChanged) {
setSplitDividerLocation(collapsedSize);
tabsExpanded = false;
thumbnails.setIsDisplayedOnscreen(false);
}
lastTabSelected = tabSelected;
hasPageChanged = false;
}
private void initMultiBox() {
multiboxfx = new HBox();
initCoordBox();
initMemoryBar();
initDownloadBar();
// Temp code to demonstrate functionality - move to JavaFXMouseListener when implmented
// Show coords
// ((PdfDecoderFX)decode_pdf).setOnMouseEntered(new EventHandler(){
// @Override
// public void handle(javafx.scene.input.MouseEvent t) {
// System.out.println(t.getX() + " " + t.getY());
// if(t.getX() < 0){
// t.consume();
// return;
// }
// cursorOverPage = true;
// memoryBarFX.setVisible(false);
// coordsFX.setVisible(true);
// setMultibox(new int[]{});
// }
// });
// Show memory bar
// ((PdfDecoderFX)decode_pdf).setOnMouseExited(new EventHandler(){
// @Override
// public void handle(javafx.scene.input.MouseEvent t) {
// cursorOverPage = false;
// memoryBarFX.setVisible(true);
// coordsFX.setVisible(false);
// setMultibox(new int[]{});
// }
// });
// ((PdfDecoderFX)decode_pdf).setOnMouseMoved(new EventHandler() {
// @Override
// public void handle(javafx.scene.input.MouseEvent t) {
// double maxX = (((PdfDecoderFX)decode_pdf).getBoundsInLocal().getMaxX()) + (dropshadowDepth /2);
// double maxY = (((PdfDecoderFX)decode_pdf).getBoundsInLocal().getMaxY()) + (dropshadowDepth /2);
// double minX = ((PdfDecoderFX)decode_pdf).getBoundsInLocal().getMinX() + (dropshadowDepth /2);
// double minY = ((PdfDecoderFX)decode_pdf).getBoundsInLocal().getMinY() + (dropshadowDepth /2);
//
// if(!cursorOverPage){
// if((t.getX() > minX && t.getX() <= maxX)
// && (t.getY() > minY && t.getY() <= maxY)){
// cursorOverPage = true;
// memoryBarFX.setVisible(false);
// coordsFX.setVisible(true);
// setMultibox(new int[]{});
// }
// }else{
// if((t.getX() < minX || t.getX() > maxX)
// || (t.getY() < minY || t.getY() >= maxY)){
// cursorOverPage = false;
// memoryBarFX.setVisible(true);
// coordsFX.setVisible(false);
// setMultibox(new int[]{});
// }
// }
// //(String.format("X: %d Y: %d", (int)(t.getX() - minX), (int)(t.getY() - minY)));
// }
// });
// multiboxfx.getChildren().add(memoryBarFX);
}
@Override
public void setMultibox(final int[] flags) {
//
//deal with flags
if (flags.length > 1 && flags[0] == CURSOR) {
//if no change, return
if (cursorOverPage != (flags[1] == 1)) {
cursorOverPage = flags[1] == 1;
} else {
return;
}
}
//LOAD_PROGRESS:
// if (statusBar.isEnabled() && statusBar.isVisible() && !statusBar.isDone()) {
// multibox.removeAll();
// statusBar.getStatusObject().setSize(multibox.getSize());
// multibox.add(statusBar.getStatusObject(), BorderLayout.CENTER);
//
// multibox.repaint();
// return;
// }
//CURSOR:
if (cursorOverPage && decode_pdf.isOpen()) {
multiboxfx.getChildren().clear();
multiboxfx.getChildren().add(coordsFX);
return;
}
//DOWNLOAD_PROGRESS:
if (!downloadBar.isDisable() && downloadBar.isVisible() && !downloadBar.isDone() && (decode_pdf.isLoadingLinearizedPDF() || !decode_pdf.isOpen())) {
multiboxfx.getChildren().clear();
multiboxfx.getChildren().add(downloadBar.getStatusObject());
return;
}
//MEMORY:
if (memoryBarFX.isVisible()) {
multiboxfx.getChildren().clear();
multiboxfx.getChildren().add(memoryBarFX);
}
}
private void initDownloadBar() {
downloadBar = new StatusBarFX(new Color((185.0d / 255.0d), (209.0d / 255.0d), 0, 1));
downloadBar.getStatusObject().prefHeightProperty().bind(multiboxfx.heightProperty());
downloadBar.getStatusObject().prefWidthProperty().bind(multiboxfx.widthProperty());
downloadBar.setVisible(false);
}
private void initMemoryBar() {
memoryBarFX = new FXProgressBarWithText();
memoryBarFX.prefHeightProperty().bind(multiboxfx.heightProperty());
memoryBarFX.prefWidthProperty().bind(multiboxfx.widthProperty());
if (memoryMonitor == null) { //ensure only 1 instance
memoryMonitor = new Timeline(new KeyFrame(Duration.seconds(0.5), new EventHandler() {
@Override
public void handle(final ActionEvent event) {
final int free = (int) (Runtime.getRuntime().freeMemory() / (1024 * 1024));
final int total = (int) (Runtime.getRuntime().totalMemory() / (1024 * 1024));
final double used = (double) (total - free) / (double) total;
//this broke the image saving when it was run every time
if (finishedDecoding) {
finishedDecoding = false;
}
if (Platform.isFxApplicationThread()) {
memoryBarFX.setProgress(used);
memoryBarFX.setText((total - free) + "M of " + total + 'M');
} else {
// Needs to be done on the FX Thread
Platform.runLater(new Runnable() {
@Override
public void run() {
memoryBarFX.setProgress(used);
memoryBarFX.setText((total - free) + "M of " + total + 'M');
}
});
}
}
}));
memoryMonitor.setCycleCount(Timeline.INDEFINITE);
memoryMonitor.play();
}
}
/**
* Overrides method from GUI.java, see GUI.java for DOCS.
*/
@Override
protected void setViewerIcon() {
//Check if file location provided
final URL path = guiCursor.getURLForImage("icon.png");
if (stage != null && path != null) {
try {
//Converting Swing BufferedImage to FX WritableImage
final BufferedImage bi = ImageIO.read(path);
WritableImage fontIcon = new WritableImage(bi.getWidth(), bi.getHeight());
fontIcon = SwingFXUtils.toFXImage(bi, fontIcon);
stage.getIcons().add(fontIcon);
} catch (final Exception e) {
//
if (LogWriter.isOutput()) {
LogWriter.writeLog("Exception attempting to set Icon " + e);
}
}
}
}
private boolean setDisplayView2(final int displayView, final int orientation) {
DecoderOptions options = decode_pdf.getDecoderOptions();
Display pages = decode_pdf.getPages();
int lastDisplayView = decode_pdf.getDisplayView();
FileAccess fileAccess = (FileAccess) decode_pdf.getExternalHandler(Options.FileAccess);
int pageNumber = decode_pdf.getPageNumber();
ExternalHandlers externalHandlers = decode_pdf.getExternalHandler();
final PdfDecoderFX comp = (PdfDecoderFX) decode_pdf;
final Pane highlightsPane = comp.highlightsPane;
options.setPageAlignment(orientation);
if (pages != null) {
pages.stopGeneratingPage();
}
if (Platform.isFxApplicationThread()) {
if (highlightsPane != null && highlightsPane.getParent() != null) {
((Group) highlightsPane.getParent()).getChildren().remove(highlightsPane);
}
} else {
final Runnable doPaintComponent = new Runnable() {
@Override
public void run() {
if (highlightsPane != null && highlightsPane.getParent() != null) {
((Group) highlightsPane.getParent()).getChildren().remove(highlightsPane);
}
}
};
Platform.runLater(doPaintComponent);
}
boolean needsReset = (displayView != Display.SINGLE_PAGE || lastDisplayView != Display.SINGLE_PAGE);
if (needsReset && (lastDisplayView == Display.FACING || displayView == Display.FACING)) {
needsReset = false;
}
final boolean hasChanged = displayView != lastDisplayView;
options.setDisplayView(displayView);
if (lastDisplayView != displayView && lastDisplayView == Display.PAGEFLOW) {
pages.dispose();
}
final Object customFXHandle = externalHandlers.getExternalHandler(Options.MultiPageUpdate);
switch (displayView) {
case Display.SINGLE_PAGE:
if (pages == null || hasChanged) {
final DynamicVectorRenderer currentDisplay = decode_pdf.getDynamicRenderer();
pages = new SingleDisplayFX(pageNumber, currentDisplay, comp, options);
}
break;
case Display.PAGEFLOW:
if (pages instanceof PageFlowDisplayFX) {
return hasChanged;
}
if (lastDisplayView != Display.SINGLE_PAGE) {
setDisplayView(Display.SINGLE_PAGE, 0);
setDisplayView(Display.PAGEFLOW, 0);
return hasChanged;
}
pages = new PageFlowDisplayFX((GUIFactory) customFXHandle, comp);
break;
/**/
default:
//
break;
}
/**
* enable pageFlow mode and setup slightly different display
* configuration
*/
if (lastDisplayView == Display.PAGEFLOW && displayView != Display.PAGEFLOW) {
//@swing
/*
removeAll();
//forms needs null layout manager
this.setLayout(null);
((JScrollPane)getParent().getParent()).setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
((JScrollPane)getParent().getParent()).setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
javax.swing.Timer t = new javax.swing.Timer(1000,new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
repaint();
}
});
t.setRepeats(false);
t.start();
/**/
}
/**
* setup once per page getting all page sizes and working out settings
* for views
*/
if (fileAccess.getOffset() == null) {
fileAccess.setOffset(new PageOffsets(decode_pdf.getPageCount(), decode_pdf.getPdfPageData()));
}
pages.setup(options.useHardwareAcceleration(), fileAccess.getOffset());
final DynamicVectorRenderer currentDisplay = decode_pdf.getDynamicRenderer();
if (decode_pdf.isOpen()) {
pages.init(scaling, decode_pdf.getDisplayRotation(), pageNumber, currentDisplay, true);
}
// force redraw
pages.forceRedraw();
pages.refreshDisplay();
//needs to be realigned (in longer term refactored out)
comp.pages = pages;
return hasChanged;
}
/**
* set view mode used in panel and redraw in new mode
* SINGLE_PAGE,CONTINUOUS,FACING,CONTINUOUS_FACING delay is the time in
* milli-seconds which scrolling can stop before background page drawing
* starts Multipage views not in OS releases
*/
@Override
public void setDisplayView(final int displayView, final int orientation) {
// remove listener if setup
if (viewListener != null) {
removeComponentListener(viewListener);
viewListener.dispose();
viewListener = null;
}
boolean hasChanged = setDisplayView2(displayView, orientation);
//move to correct page
final int pageNumber = decode_pdf.getPageNumber();
if (pageNumber > 0) {
if (hasChanged && displayView == Display.SINGLE_PAGE && decode_pdf.isOpen()) {
try {
decode_pdf.setPageParameters(scaling, pageNumber, decode_pdf.getDisplayRotation());
//@swing
// invalidate();
// updateUI();
decode_pdf.decodePage(pageNumber);
} catch (final Exception e) {
//tell user and log
if (LogWriter.isOutput()) {
LogWriter.writeLog("Exception: " + e.getMessage());
}
//
}
} else if (displayView != Display.SINGLE_PAGE && displayView != Display.PAGEFLOW) {
scrollToPage(pageNumber);
}
}
//Only all search in certain modes
if (displayView != Display.SINGLE_PAGE
&& displayView != Display.CONTINUOUS
&& displayView != Display.CONTINUOUS_FACING) {
enableSearchItems(false);
} else {
enableSearchItems(true);
}
// add listener if one not already there
if (viewListener == null) {
viewListener = new RefreshLayout(decode_pdf);
addComponentListener(viewListener);
}
}
/**
* Overrides method from GUI.java, see GUI.java for DOCS.
*/
@Override
protected void setTitle(final String title) {
if (stage != null) {
stage.setTitle(title);
}
}
/* (non-Javadoc)
* @see org.jpedal.examples.viewer.gui.swing.GUIFactory#resetComboBoxes(boolean)
*/
@Override
public void resetComboBoxes(final boolean value) {
if (debugFX) {
System.out.println("resetComboBoxes");
}
if (properties.getValue("Imageopdisplay").equalsIgnoreCase("true")) {
qualityBox.setEnabled(value);
}
scalingBox.setEnabled(value);
rotationBox.setEnabled(value);
}
/* (non-Javadoc)
* @see org.jpedal.examples.viewer.gui.swing.GUIFactory#getCombo(int)
*/
@Override
public GUICombo getCombo(final int ID) {
if (debugFX) {
System.out.println("getCombo");
}
switch (ID) {
case Commands.QUALITY:
return qualityBox;
case Commands.SCALING:
return scalingBox;
case Commands.ROTATION:
return rotationBox;
}
return null;
}
/**
* all scaling and rotation should go through this.
*/
@Override
public void scaleAndRotate() {
if (decode_pdf.getDisplayView() == Display.PAGEFLOW) {
decode_pdf.setPageParameters(scaling, commonValues.getCurrentPage(), rotation);
return;
}
//ignore if called too early
if (!decode_pdf.isOpen() && OpenFile.isPDf) {
return;
}
final double width = pageContainer.getViewportBounds().getWidth() * 0.95;
final double height = pageContainer.getViewportBounds().getHeight() * 0.95;
float tempScaling = 1.5f;
// if(sudaDebug){
// System.out.println("scaleAndRotate");
// System.out.println("\tScaling "+scaling);
// System.out.println("\tbar: "+pageContainer.getViewportBounds());
// System.out.println("\tGL: "+group.getBoundsInLocal());
// System.out.println("\tGP: "+group.getBoundsInParent());
// }
/**
* update value and GUI
*/
if (decode_pdf != null) {
int index = getSelectedComboIndex(Commands.SCALING);
if (decode_pdf.getDisplayView() == Display.PAGEFLOW) {
//Ensure we only display in window mode
setSelectedComboIndex(Commands.SCALING, 0);
index = 0;
//Disable scaling option
scalingBox.setEnabled(false);
} else if (decode_pdf.getDisplayView() != Display.PAGEFLOW) {
//No long pageFlow. enable scaling option
scalingBox.setEnabled(true);
}
int page = commonValues.getCurrentPage();
//Multipage tiff should be treated as a single page
if (commonValues.isMultiTiff()) {
page = 1;
}
if (index != -1) {
//always check in facing mode with turnover on
int tw = 0, th = 0;//temp width and temp hegiht;
double sw = 0, sh = 0;//scalled width and height;
PdfPageData pData = decode_pdf.getPdfPageData();
int curPW = pData.getCropBoxWidth(page); //current page width
int curPH = pData.getCropBoxHeight(page); //current page height
switch (rotation) {
case 0:
tw = curPW;
th = curPH;
break;
case 90:
tw = curPH;
th = curPW;
break;
case 180:
tw = curPW;
th = curPH;
break;
case 270:
tw = curPH;
th = curPW;
break;
}
switch (decode_pdf.getDisplayView()) {
case Display.SINGLE_PAGE:
switch (index) {
case 0://fit page
tempScaling = (float) getScalingRatio(tw, th, width, height);
break;
case 1://fit height;
tempScaling = (float) (height / th);
break;
case 2://fit width;
tempScaling = (float) (width / tw);
break;
default://other percentages;
tempScaling = decode_pdf.getDPIFactory().adjustScaling(scalingFloatValues[index]);
break;
}
sw = (int) (tempScaling * tw);
sh = (int) (tempScaling * th);
if (sw < width) {
group.setTranslateX((width - sw) / 2.0);
} else {
group.setTranslateX(0);
}
// if (sh < height) {
// group.setTranslateY((height - sh) / 2.0);
// } else {
// group.setTranslateY(0);
// }
group.setTranslateY(0);
break;
case Display.CONTINUOUS:
switch (index) {
case 0://fit page
tempScaling = (float) getScalingRatio(tw, th, width, height);
break;
case 1://fit height;
tempScaling = (float) (height / th);
break;
case 2://fit width;
tempScaling = (float) (width / tw);
break;
default://other percentages;
tempScaling = decode_pdf.getDPIFactory().adjustScaling(scalingFloatValues[index]);
break;
}
sw = (int) (tempScaling * tw);
if (sw < width) {
group.setTranslateX((width - sw) / 2.0);
} else {
group.setTranslateX(0);
}
group.setTranslateY(0);
break;
case Display.CONTINUOUS_FACING:
tw = tw * 2;
switch (index) {
case 0://fit page
tempScaling = (float) getScalingRatio(tw, th, width, height);
break;
case 1://fit height;
tempScaling = (float) (height / th);
break;
case 2://fit width;
tempScaling = (float) (width / tw);
break;
default://other percentages;
tempScaling = decode_pdf.getDPIFactory().adjustScaling(scalingFloatValues[index]);
break;
}
sw = (int) (tempScaling * tw);
if (sw < width) {
group.setTranslateX((width - sw) / 2.0);
} else {
group.setTranslateX(0);
}
group.setTranslateY(0);
break;
case Display.FACING:
break;
case Display.PAGEFLOW:
break;
default:
System.err.println("unsupported page display ");
break;
}
}
scaling = tempScaling;
// Avoid infinty
if (Float.isInfinite(scaling)) {
scaling = 1f;
}
decode_pdf.setPageParameters(scaling, page, rotation);
//Ensure the page is displayed in the correct rotation
// setRotation();
}
// double h = pageContainer.getContent().getBoundsInLocal().getHeight();
// System.out.println("scrolling " + pageContainer.getVvalue() + " height of container: " + h);
// adjustGroupToCenter();
//
}
public static double getScalingRatio(final double actualW, final double actualH, final double maxW, final double maxH) {
return Math.min((maxW / actualW), (maxH / actualH));
}
@Override
public void snapScalingToDefaults(float newScaling) {
if (debugFX) {
System.out.println("snapScalingToDefaults");
}
newScaling = decode_pdf.getDPIFactory().adjustScaling(newScaling / 100);
final float width;
final float height;
//if(isSingle){
width = (float) pageContainer.getWidth() * 0.95f;
height = (float) pageContainer.getHeight() * 0.95f;
//}else{
// width=desktopPane.getWidth();
// height=desktopPane.getHeight();
//}
final PdfPageData pageData = decode_pdf.getPdfPageData();
int cw, ch, raw_rotation = 0;
if (decode_pdf.getDisplayView() == Display.FACING) {
raw_rotation = pageData.getRotation(commonValues.getCurrentPage());
}
final boolean isRotated = (rotation + raw_rotation) % 180 == 90;
final PageOffsets offsets = (PageOffsets) decode_pdf.getExternalHandler(Options.CurrentOffset);
switch (decode_pdf.getDisplayView()) {
case Display.CONTINUOUS_FACING:
if (isRotated) {
cw = offsets.getMaxH() * 2;
ch = offsets.getMaxW();
} else {
cw = offsets.getMaxW() * 2;
ch = offsets.getMaxH();
}
break;
case Display.CONTINUOUS:
if (isRotated) {
cw = offsets.getMaxH();
ch = offsets.getMaxW();
} else {
cw = offsets.getMaxW();
ch = offsets.getMaxH();
}
break;
case Display.FACING:
int leftPage;
if (decode_pdf.getPages().getBoolean(Display.BoolValue.SEPARATE_COVER)) {
leftPage = (commonValues.getCurrentPage() / 2) * 2;
if (commonValues.getPageCount() == 2) {
leftPage = 1;
}
} else {
leftPage = commonValues.getCurrentPage();
if ((leftPage & 1) == 0) {
leftPage--;
}
}
if (isRotated) {
cw = pageData.getCropBoxHeight(leftPage);
//if first or last page double the width, otherwise add other page width
if (leftPage + 1 > commonValues.getPageCount() || leftPage == 1) {
cw *= 2;
} else {
cw += pageData.getCropBoxHeight(leftPage + 1);
}
ch = pageData.getCropBoxWidth(leftPage);
if (leftPage + 1 <= commonValues.getPageCount() && ch < pageData.getCropBoxWidth(leftPage + 1)) {
ch = pageData.getCropBoxWidth(leftPage + 1);
}
} else {
cw = pageData.getCropBoxWidth(leftPage);
//if first or last page double the width, otherwise add other page width
if (leftPage + 1 > commonValues.getPageCount()) {
cw *= 2;
} else {
cw += pageData.getCropBoxWidth(leftPage + 1);
}
ch = pageData.getCropBoxHeight(leftPage);
if (leftPage + 1 <= commonValues.getPageCount() && ch < pageData.getCropBoxHeight(leftPage + 1)) {
ch = pageData.getCropBoxHeight(leftPage + 1);
}
}
break;
default:
if (isRotated) {
cw = pageData.getCropBoxHeight(commonValues.getCurrentPage());
ch = pageData.getCropBoxWidth(commonValues.getCurrentPage());
} else {
cw = pageData.getCropBoxWidth(commonValues.getCurrentPage());
ch = pageData.getCropBoxHeight(commonValues.getCurrentPage());
}
}
float x_factor;
float y_factor;
final float window_factor;
x_factor = width / cw;
y_factor = height / ch;
if (x_factor < y_factor) {
window_factor = x_factor;
x_factor = -1;
} else {
window_factor = y_factor;
y_factor = -1;
}
if (getSelectedComboIndex(Commands.SCALING) != 0
&& ((newScaling < window_factor * 1.1 && newScaling > window_factor * 0.91)
|| ((window_factor > scaling && window_factor < newScaling) || (window_factor < scaling && window_factor > newScaling)))) {
setSelectedComboIndex(Commands.SCALING, 0);
scaling = window_factor;
} else if (y_factor != -1
&& getSelectedComboIndex(Commands.SCALING) != 1
&& ((newScaling < y_factor * 1.1 && newScaling > y_factor * 0.91)
|| ((y_factor > scaling && y_factor < newScaling) || (y_factor < scaling && y_factor > newScaling)))) {
setSelectedComboIndex(Commands.SCALING, 1);
scaling = y_factor;
} else if (x_factor != -1
&& getSelectedComboIndex(Commands.SCALING) != 2
&& ((newScaling < x_factor * 1.1 && newScaling > x_factor * 0.91)
|| ((x_factor > scaling && x_factor < newScaling) || (x_factor < scaling && x_factor > newScaling)))) {
setSelectedComboIndex(Commands.SCALING, 2);
scaling = x_factor;
} else {
setSelectedComboItem(Commands.SCALING, String.valueOf((int) decode_pdf.getDPIFactory().removeScaling(newScaling * 100)));
scaling = newScaling;
}
}
/* (non-Javadoc)
* @see org.jpedal.examples.viewer.gui.swing.GUIFactory#rotate()
*/
@Override
public void rotate() {
rotation = Integer.parseInt((String) getSelectedComboItem(Commands.ROTATION));
scaleAndRotate();
}
@Override
public void scrollToPage(final int page) {
if (debugFX) {
System.out.println("scrollToPage");
}
commonValues.setCurrentPage(page);
if (commonValues.getCurrentPage() > 0) {
int xCord = 0;
int yCord = decode_pdf.getPages().getYCordForPage(page, scaling);
if (decode_pdf.getDisplayView() != Display.SINGLE_PAGE) {
xCord = 0;
}
//System.out.println("Before="+decode_pdf.getVisibleRect()+" "+decode_pdf.getPreferredSize());
final PdfPageData pageData = decode_pdf.getPdfPageData();
final int ch = (int) (pageData.getCropBoxHeight(page) * scaling);
final int cw = (int) (pageData.getCropBoxWidth(page) * scaling);
double totalHeight = 0;
double curY = 0;
int pw = pageData.getScaledCropBoxWidth(page);
int ph = pageData.getScaledCropBoxHeight(page);
int pageCount = pageData.getPageCount();
double localH = pageContainer.getContent().getBoundsInLocal().getHeight();
double localW = pageContainer.getContent().getBoundsInLocal().getWidth();
double viewH = pageContainer.getViewportBounds().getHeight();
double viewW = pageContainer.getViewportBounds().getWidth();
switch (decode_pdf.getDisplayView()) {
case Display.SINGLE_PAGE:
break;
case Display.CONTINUOUS:
for (int i = 1; i <= pageCount; i++) {
totalHeight += pageData.getScaledCropBoxHeight(i);
}
int marginGap = (page - 1) * 20;
double vv = (yCord + marginGap) / localH;
pageContainer.setVvalue(vv);
// System.out.println("localH: " + localH + " totalHeight: " + totalHeight + " viewH: " + viewH + " curY: " + curY + " " + paddingH);
//
break;
case Display.CONTINUOUS_FACING:
break;
}
// if (decode_pdf.getDisplayView() != Display.SINGLE_PAGE) {
// final double centerH = xCord + ((cw-pageContainer.getHvalue())/2);
// final double centerV = yCord + (ch-pageContainer.getVvalue())/2;
//
// int[] dim=decode_pdf.getMaxSizeWH();
// //
// System.out.println(">>"+centerH+ " "+centerV+" "+dim[0]+" "+dim[1]);
// pageContainer.setHvalue(centerH/dim[0]);
// pageContainer.setVvalue(centerV/dim[1]);
// final Bounds r = ((PdfDecoderFX)decode_pdf).getBoundsInLocal();
// int[] pageW=multiDisplayOptions.getPageW();
// int[] pageH=multiDisplayOptions.getPageH();
//if(!(pw>r.getWidth() || ph>r.getHeight())){
//final ScrollPane customFXHandle= ((JavaFxGUI)decode_pdf.getExternalHandler(Options.MultiPageUpdate)).getPageContainer();
// yCord = (int) (yCord + (ph * ((float) page / (float) pageCount)));
//yCord=(int) (yCord-((customFXHandle.getLayoutBounds().getHeight()-ph)/2)+(ph*(((float)page)/39)));
// yCord=(int) (yCord-((customFXHandle.getLayoutBounds().getHeight()-ph)/2));
// yCord=(int) ((PdfDecoderFX)decode_pdf).getHeight();
// System.out.println("y="+yCord+" for page "+getPageNumber());
// System.out.println("y="+yCord+" page="+pageNumber+" "+Platform.isFxApplicationThread());
//s scrollRectToVisible(new Rectangle(0, yCord, (int) r.getWidth() - 1, (int) r.getHeight() - 1));
// ((PdfDecoderFX)decode_pdf).scrollRectToVisible(new Rectangle(0, yCord, pw - 1, ph - 1));
// }
// } else {
// final double centerH = xCord + ((cw - pageContainer.getHvalue()) / 2);
// final double centerV = yCord + (ch - pageContainer.getVvalue()) / 2;
//
// pageContainer.setHvalue(centerH);
// pageContainer.setVvalue(centerV);
// }
// decode_pdf.scrollRectToVisible(new Rectangle(0,(int) (yCord),(int)r.width-1,(int)r.height-1));
// decode_pdf.scrollRectToVisible(new Rectangle(0,(int) (yCord),(int)r.width-1,(int)r.height-1));
//System.out.println("After="+decode_pdf.getVisibleRect()+" "+decode_pdf.getPreferredSize());
//System.out.println("Scroll to page="+commonValues.getCurrentPage()+" "+yCord+" "+(yCord*scaling)+" "+scaling);
}
if (decode_pdf.getPageCount() > 1) {
fxButtons.setPageLayoutButtonsEnabled(true);
}
}
//
/**
* put the outline data into a display panel which we can pop up for the
* user - outlines, thumbnails
*
* private void createOutlinePanels() {
*
* //boolean hasNavBars=false;
*
* // set up first 10 thumbnails by default. Rest created as needed.
*
* //add if statement or comment out this section to remove thumbnails
* setupThumbnailPanel();
*
* // add any outline
*
* setBookmarks(false);
*
* /**
* resize to show if there are nav bars
*
* if(hasNavBars){ if(!thumbnails.isShownOnscreen()){ if(
* !commonValues.isContentExtractor()) navOptionsPanel.setVisible(true);
* displayPane.setDividerLocation(divLocation); //displayPane.invalidate();
* //displayPane.repaint();
*
* }
* }
* }/*
*/
@Override
public void setupThumbnailPanel() {
if (debugFX) {
System.out.println("setupThumbnailPanel");
}
decode_pdf.addExternalHandler(thumbnails, Options.ThumbnailHandler);
if (isSetup) {
return;
}
isSetup = true;
if (thumbnails.isShownOnscreen()) {
//setup and add to display
thumbnails.setupThumbnails(decode_pdf.getPageCount(), null, Messages.getMessage("PdfViewerPageLabel.text"), decode_pdf.getPdfPageData());
//add listener so clicking on button changes to page - has to be in Viewer so it can update it
final Button[] buttons = (Button[]) thumbnails.getButtons();
for (int i = 0; i < commonValues.getPageCount(); i++) {
buttons[i].setOnAction(new JavaFXPageChanger(this, commonValues, i));
}
//add global listener
thumbnails.addComponentListener();
}
}
@Override
public void setBookmarks(final boolean alwaysGenerate) {
if (debugFX) {
System.out.println("setBookmarks");
//ignore if not opened
System.out.println("currentSize in setBookmarks() in JavaFXGUI requires JavaFX implementation");
}
// int currentSize=center.getDividerPosition();
//
// if((currentSize==startSize)&& !alwaysGenerate)
// return;
//ignore if already done and flag
if (bookmarksGenerated) {
return;
}
bookmarksGenerated = true;
final org.w3c.dom.Document doc = decode_pdf.getOutlineAsXML();
Node rootNode = null;
if (doc != null) {
rootNode = doc.getFirstChild();
}
if (rootNode != null) {
tree.reset(rootNode);
// Allows an already selected node to be clicked again
final EventHandler reselectionListener = new EventHandler() {
@Override
public void handle(final MouseEvent event) {
final String ref = ((JavaFXOutline.OutlineNode) ((Labeled) event.getSource()).getUserData()).getObjectRef();
gotoPageByRef(ref);
}
};
((TreeView
© 2015 - 2025 Weber Informatics LLC | Privacy Policy