org.jpedal.examples.viewer.gui.JavaFxGUI Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of OpenViewerFX Show documentation
Show all versions of OpenViewerFX Show documentation
An Open Source JavaFX PDF Viewer
/*
* ===========================================
* 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 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.OpenViewerFX;
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 static final 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;
/**
* 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 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);
//#making invisible still shows the gap so iam padding negative to hide it
if(isVisible){
pageScroll.setStyle("-fx-padding:0px");
}else{
pageScroll.setStyle("-fx-padding:-10px");
}
}
@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();
/**
* single listener to execute all commands
*/
currentCommandListener = new CommandListenerFX(currentCommands);
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();
if(LogWriter.isRunningFromIDE || org.jpedal.DevFlags.GUITESTINGINPROGRESS){
nameElements();
}
/**
* 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);
if(includeExtraMenus && commonValues.getModeOfOperation() != Values.RUNNING_PLUGIN) {
fxButtons.addButton(GUIFactory.BUTTONBAR, Messages.getMessage("PdfViewerToolbarTooltip.help"), "help.png", Commands.HELP, menuItems, this, currentCommandListener, pagesToolBar, navToolBar);
}
//addButton(GUIFactory.BUTTONBAR,Messages.getMessage("PdfViewerToolbarTooltip.buy"),iconLocation+"buy.png",Commands.BUY);
if(includeExtraMenus && commonValues.getModeOfOperation() != Values.RUNNING_PLUGIN) {
fxButtons.addButton(GUIFactory.BUTTONBAR, "RSS", "rss.gif", Commands.RSS, menuItems, this, currentCommandListener, pagesToolBar, navToolBar);
}
/**
* 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);
}
private void nameElements() {
((JavaFXMenuItems) menuItems).getCurrentMenuFX().setId("menuBar");
pageCounter2.setId("pageCounter");
if (org.jpedal.DevFlags.GUITESTINGINPROGRESS) {
rotationBox.setName("rotationBox");
scalingBox.setName("scalingBox");
}
}
/**
* 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) {
//debug code for formclicktests
if (GUI.alwaysShowMouse) {
multiboxfx.getChildren().clear();
multiboxfx.getChildren().add(coordsFX);
return;
}
//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) {
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:
if (needsReset) {
pages = new MultiDisplayFX(this, pageNumber, decode_pdf.getDynamicRenderer(), displayView, comp, options, fileAccess);
//displayRotation = displayRotation;
pages.setPageRotation(decode_pdf.getDisplayRotation()); //force update
} else {
pages = new MultiDisplayFX(this, pageNumber, decode_pdf.getDynamicRenderer(), displayView, comp, options, fileAccess);
}
//pass in value if needed
final RenderChangeListener customRenderChangeListener = (RenderChangeListener) externalHandlers.getExternalHandler(Options.RenderChangeListener);
if (customRenderChangeListener != null) {
pages.setObjectValue(Options.RenderChangeListener, customRenderChangeListener);
}
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.getPages().getYCordForPage(pageNumber, scaling);
decode_pdf.setPageParameters(scaling, pageNumber, decode_pdf.getDisplayRotation());
//@swing
// invalidate();
// updateUI();
decode_pdf.decodePage(pageNumber);
} catch (final Exception e) {
LogWriter.writeLog("Exception: " + e.getMessage());
}
} else if (displayView == Display.CONTINUOUS || displayView == Display.CONTINUOUS_FACING) {
try {
decode_pdf.getPages().getYCordForPage(pageNumber, scaling);
decode_pdf.setPageParameters(scaling, pageNumber, decode_pdf.getDisplayRotation());
decode_pdf.decodePage(pageNumber);
scrollToPage(pageNumber);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
//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) {
for(int i=0;i 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 pageCount = decode_pdf.getPageCount();
double yCord;// = decode_pdf.getPages().getYCordForPage(page, scaling);
//$$$$$$$$$$$$$ call it and ignore please dont delete as it has affect in continuous mode
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;
//int pw = pageData.getScaledCropBoxWidth(page);
//int ph = pageData.getScaledCropBoxHeight(page);
//double localH = pageContainer.getContent().getBoundsInLocal().getHeight();
//double localW = pageContainer.getContent().getBoundsInLocal().getWidth();
//double viewH = pageContainer.getViewportBounds().getHeight();
//double viewW = pageContainer.getViewportBounds().getWidth();
double vv;
switch (decode_pdf.getDisplayView()) {
case Display.SINGLE_PAGE:
break;
case Display.CONTINUOUS:
yCord = 0;
for (int i = 1; i < pageCount; i++) {
totalHeight+= pageData.getScaledCropBoxHeight(i);
}
for (int i = 1; i < page; i++) {
yCord+= pageData.getScaledCropBoxHeight(i);
}
vv = yCord/totalHeight;
pageContainer.setVvalue(vv);//
break;
case Display.CONTINUOUS_FACING:
yCord = 0;
for (int i = 1; i < pageCount; i+=2) {
totalHeight+= pageData.getScaledCropBoxHeight(i);
}
for (int i = 1; i < page; i+=2) {
yCord+= pageData.getScaledCropBoxHeight(i);
}
vv = yCord/totalHeight;
pageContainer.setVvalue(vv);//
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