org.jpedal.examples.viewer.gui.javafx.JavaFXLayersPanel Maven / Gradle / Ivy
Show all versions of OpenViewerFX Show documentation
/*
* ===========================================
* 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-2017 IDRsolutions and Contributors.
*
* This file is part of JPedal/JPDF2HTML5
*
@LICENSE@
*
* ---------------
* JavaFXLayersPanel.java
* ---------------
*/
package org.jpedal.examples.viewer.gui.javafx;
import java.util.Iterator;
import java.util.Map;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.scene.control.*;
import javafx.scene.control.cell.CheckBoxTreeCell;
import javafx.scene.layout.BorderPane;
import javafx.util.Callback;
import org.jpedal.PdfDecoderInt;
import org.jpedal.examples.viewer.gui.generic.GUILayersPanel;
import org.jpedal.objects.layers.PdfLayerList;
/**
* Interface class to display PDF layer data.
*/
public class JavaFXLayersPanel extends Tab implements GUILayersPanel {
private final BorderPane content;
private final TreeItem metaDataRoot;
private final TreeView layersTree;
/**
* An implementation of GUILayersPanel.
*
* This class is an extension of JPanel to display layer information from a PDF in the viewer.
*/
public JavaFXLayersPanel() {
final TreeView metaDataTree = new TreeView();
content = new BorderPane();
layersTree = new TreeView();
metaDataRoot = new TreeItem("Info");
// setup meta data view
metaDataTree.setRoot(metaDataRoot);
metaDataTree.setShowRoot(true);
metaDataTree.setTooltip(new Tooltip("Double click to see any metadata"));
metaDataTree.setPrefHeight(60);
// Use a custom callback to determine the style of the tree item
layersTree.setCellFactory(new Callback, TreeCell>() {
@Override
public TreeCell call(final TreeView param) {
return new LayersCell();
}
});
layersTree.setShowRoot(true);
content.setTop(metaDataTree);
content.setCenter(layersTree);
setContent(content);
}
/**
* Method to reinitialise the layer panels contents for the current page.
* This method is called by the Viewer when the page is changed.
*
* @param layersObject PdfLayerList containing the layer data to be loaded
* @param decode_pdf PdfDecoderInt used for the current PDF
* @param scrollPane Object representing the scrollpane used in displaying the PDF in the viewer
* @param currentPage int value representing the current page number
*/
@Override
public void reinitialise(final PdfLayerList layersObject, final PdfDecoderInt decode_pdf, final Object scrollPane, final int currentPage) {
metaDataRoot.getChildren().clear();
layersTree.setRoot(null);
final Map metaData = layersObject.getMetaData();
final Iterator metaDataKeys = metaData.keySet().iterator();
Object nextKey;
String value;
while (metaDataKeys.hasNext()) {
nextKey = metaDataKeys.next();
value = metaData.get(nextKey);
metaDataRoot.getChildren().add(new TreeItem(nextKey + "=" + value));
}
final Object[] layerNames = layersObject.getDisplayTree();
if (layerNames != null) {
final TreeItem layersRoot = new TreeItem("Layers");
addLayersToTree(layerNames, layersRoot, true, layersObject);
// Attach to the root node an event handler which handles checked events
// from nodes lower down the tree
layersRoot.addEventHandler(CheckBoxTreeItem.checkBoxSelectionChangedEvent(),
new EventHandler>() {
@Override
public void handle(final CheckBoxTreeItem.TreeModificationEvent t) {
final CheckBoxTreeItem node = t.getTreeItem();
final StringBuilder rawName = new StringBuilder(node.getValue());
TreeItem parent = node.getParent();
while (parent.getParent() != null) {
rawName.append(PdfLayerList.deliminator).append(parent.getValue());
parent = parent.getParent();
}
final String name = rawName.toString();
if (layersObject.isLayerName(name) && !layersObject.isLocked(name)) {
final Runnable updateComponent = new Runnable() {
@Override
public void run() {
layersObject.setVisiblity(name, node.isSelected());
try {
decode_pdf.decodePage(currentPage);
} catch (final Exception e) {
e.printStackTrace();
}
}
};
if (Platform.isFxApplicationThread()) {
updateComponent.run();
} else {
Platform.runLater(updateComponent);
}
}
}
});
// Tree listener here
layersRoot.setExpanded(true);
layersTree.setRoot(layersRoot);
}
}
private static void addLayersToTree(final Object[] layerNames, TreeItem topLayer, boolean isEnabled, final PdfLayerList layersObject) {
String name;
TreeItem currentNode = topLayer;
boolean parentEnabled = isEnabled, parentIsSelected = true;
for (final Object layerName : layerNames) {
if (layerName instanceof Object[]) {
final TreeItem oldNode = currentNode;
addLayersToTree((Object[]) layerName, currentNode, isEnabled && parentIsSelected, layersObject);
currentNode = oldNode;
isEnabled = parentEnabled;
} else {
//store possible recursive settings
parentEnabled = isEnabled;
if (layerName == null) {
continue;
}
if (layerName instanceof String) {
name = (String) layerName;
} else //its a byte[]
{
name = new String((byte[]) layerName);
}
// remove full path in name
String title = name;
final int ptr = name.indexOf(PdfLayerList.deliminator);
if (ptr != -1) {
title = title.substring(0, ptr);
}
if (name.endsWith(" R")) { //ignore
} else if (!layersObject.isLayerName(name)) { //just text
currentNode = new TreeItem(title);
topLayer.getChildren().add(currentNode);
topLayer = currentNode;
parentIsSelected = true;
//add a node
} else if (topLayer != null) {
currentNode = new CheckBoxTreeItem(title);
topLayer.getChildren().add(currentNode);
//see if showing and set box to match
if (layersObject.isVisible(name)) {
((CheckBoxTreeItem) currentNode).setSelected(true);
parentIsSelected = true;
} else {
((CheckBoxTreeItem) currentNode).setSelected(false);
parentIsSelected = false;
}
//check locks and allow Parents to disable children
if (isEnabled) {
isEnabled = !layersObject.isLocked(name);
}
// No set enabled for CheckBoxTreeItem
// (Node) currentNode).setEnabled(isEnabled);
}
}
}
}
/**
* rescanPdfLayers is unsupported in ViewerFX
*/
@Override
public void rescanPdfLayers() {
}
/**
* resetLayers is unsupported in ViewerFX
*/
@Override
public void resetLayers() {
}
/**
* The class used for the cell factory, what happens here is that we check that
* the related item on the tree is not a CheckBoxTreeItem and if so, remove the checkbox (graphic)
*/
private static class LayersCell extends CheckBoxTreeCell {
@Override
public void updateItem(final String item, final boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
setText(null);
} else if (!(getTreeItem() instanceof CheckBoxTreeItem)) {
setGraphic(null);
}
}
}
}