Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline; import java.awt.Color; import java.io.IOException; import org.apache.pdfbox.cos.COSArray; import org.apache.pdfbox.cos.COSDictionary; import org.apache.pdfbox.cos.COSFloat; import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureElement; import org.apache.pdfbox.pdmodel.graphics.color.PDColor; import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB; import org.apache.pdfbox.pdmodel.interactive.action.PDActionFactory; import org.apache.pdfbox.pdmodel.interactive.action.PDAction; import org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDNamedDestination; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageDestination; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageXYZDestination; /** * This represents an outline item in a pdf document. The items at each level of the hierarchy form an iterable linked * list, chained together through their Prev and Next entries. * * @author Ben Litchfield */ public final class PDOutlineItem extends PDOutlineNode { private static final int ITALIC_FLAG = 1; private static final int BOLD_FLAG = 2; /** * Default Constructor. */ public PDOutlineItem() { super(); } /** * Constructor for an existing outline item. * * @param dic The storage dictionary. */ public PDOutlineItem(COSDictionary dic) { super(dic); } /** * Insert a single sibling after this node. * * @param newSibling The item to insert. * @throws IllegalArgumentException if the given sibling node is part of a list * (i.e. if it has a previous or a next sibling) */ public void insertSiblingAfter(PDOutlineItem newSibling) { requireSingleNode(newSibling); PDOutlineNode parent = getParent(); newSibling.setParent(parent); PDOutlineItem next = getNextSibling(); setNextSibling(newSibling); newSibling.setPreviousSibling(this); if (next != null) { newSibling.setNextSibling(next); next.setPreviousSibling(newSibling); } else if (parent != null) { getParent().setLastChild(newSibling); } updateParentOpenCountForAddedChild(newSibling); } /** * Insert a single sibling before this node. * * @param newSibling The item to insert. * @throws IllegalArgumentException if the given sibling node is part of a list * (i.e. if it has a previous or a next sibling) */ public void insertSiblingBefore(PDOutlineItem newSibling) { requireSingleNode(newSibling); PDOutlineNode parent = getParent(); newSibling.setParent(parent); PDOutlineItem previous = getPreviousSibling(); setPreviousSibling(newSibling); newSibling.setNextSibling(this); if (previous != null) { previous.setNextSibling(newSibling); newSibling.setPreviousSibling(previous); } else if (parent != null) { getParent().setFirstChild(newSibling); } updateParentOpenCountForAddedChild(newSibling); } /** * Return the previous sibling or null if there is no sibling. * * @return The previous sibling. */ public PDOutlineItem getPreviousSibling() { return getOutlineItem(COSName.PREV); } /** * Set the previous sibling, this will be maintained by this class. * * @param outlineNode The new previous sibling. */ void setPreviousSibling(PDOutlineNode outlineNode) { getCOSObject().setItem(COSName.PREV, outlineNode); } /** * @return The next sibling or null if there is no next sibling. */ public PDOutlineItem getNextSibling() { return getOutlineItem(COSName.NEXT); } /** * Set the next sibling, this will be maintained by this class. * * @param outlineNode The new next sibling. */ void setNextSibling(PDOutlineNode outlineNode) { getCOSObject().setItem(COSName.NEXT, outlineNode); } /** * Get the title of this node. * * @return The title of this node. */ public String getTitle() { return getCOSObject().getString(COSName.TITLE); } /** * Set the title for this node. * * @param title The new title for this node. */ public void setTitle(String title) { getCOSObject().setString(COSName.TITLE, title); } /** * Get the page destination of this node. * * @return The page destination of this node. * @throws IOException If there is an error creating the destination. */ public PDDestination getDestination() throws IOException { return PDDestination.create(getCOSObject().getDictionaryObject(COSName.DEST)); } /** * Set the page destination for this node. * * @param dest The new page destination for this node. */ public void setDestination(PDDestination dest) { getCOSObject().setItem(COSName.DEST, dest); } /** * A convenience method that will create an XYZ destination using only the defaults. * * @param page The page to refer to. */ public void setDestination(PDPage page) { PDPageXYZDestination dest = null; if (page != null) { dest = new PDPageXYZDestination(); dest.setPage(page); } setDestination(dest); } /** * This method will attempt to find the page in this PDF document that this outline points to. * If the outline does not point to anything then this method will return null. If the outline * is an action that is not a GoTo action then this method will also return null. * * @param doc The document to get the page from. * * @return The page that this outline will go to when activated or null if it does not point to * anything. * @throws IOException If there is an error when trying to find the page. */ public PDPage findDestinationPage(PDDocument doc) throws IOException { PDDestination dest = getDestination(); if (dest == null) { PDAction outlineAction = getAction(); if (outlineAction instanceof PDActionGoTo) { dest = ((PDActionGoTo) outlineAction).getDestination(); } } if (dest == null) { return null; } PDPageDestination pageDestination = null; if (dest instanceof PDNamedDestination) { pageDestination = doc.getDocumentCatalog().findNamedDestinationPage((PDNamedDestination) dest); if (pageDestination == null) { return null; } } else if (dest instanceof PDPageDestination) { pageDestination = (PDPageDestination) dest; } else { throw new IOException("Error: Unknown destination type " + dest); } PDPage page = pageDestination.getPage(); if (page == null) { // Malformed PDF: local destinations must have a page object, // not a page number, these are meant for remote destinations. int pageNumber = pageDestination.getPageNumber(); if (pageNumber != -1) { page = doc.getPage(pageNumber); } } return page; } /** * Get the action of this node. * * @return The action of this node. */ public PDAction getAction() { return PDActionFactory.createAction((COSDictionary) getCOSObject().getDictionaryObject(COSName.A)); } /** * Set the action for this node. * * @param action The new action for this node. */ public void setAction(PDAction action) { getCOSObject().setItem(COSName.A, action); } /** * Get the structure element of this node. * * @return The structure element of this node. */ public PDStructureElement getStructureElement() { PDStructureElement se = null; COSDictionary dic = (COSDictionary) getCOSObject().getDictionaryObject(COSName.SE); if (dic != null) { se = new PDStructureElement(dic); } return se; } /** * Set the structure element for this node. * * @param structureElement The new structure element for this node. */ public void setStructureElement(PDStructureElement structureElement) { getCOSObject().setItem(COSName.SE, structureElement); } /** * Get the RGB text color of this node. Default is black and this method * will never return null. * * @return The structure element of this node. */ public PDColor getTextColor() { COSArray csValues = (COSArray) getCOSObject().getDictionaryObject(COSName.C); if (csValues == null) { csValues = new COSArray(); csValues.growToSize(3, new COSFloat(0)); getCOSObject().setItem(COSName.C, csValues); } return new PDColor(csValues, PDDeviceRGB.INSTANCE); } /** * Set the RGB text color for this node. * * @param textColor The text color for this node. */ public void setTextColor(PDColor textColor) { getCOSObject().setItem(COSName.C, textColor.toCOSArray()); } /** * Set the RGB text color for this node. * * @param textColor The text color for this node. */ public void setTextColor(Color textColor) { COSArray array = new COSArray(); array.add(new COSFloat(textColor.getRed() / 255f)); array.add(new COSFloat(textColor.getGreen() / 255f)); array.add(new COSFloat(textColor.getBlue() / 255f)); getCOSObject().setItem(COSName.C, array); } /** * A flag telling if the text should be italic. * * @return The italic flag. */ public boolean isItalic() { return getCOSObject().getFlag(COSName.F, ITALIC_FLAG); } /** * Set the italic property of the text. * * @param italic The new italic flag. */ public void setItalic(boolean italic) { getCOSObject().setFlag(COSName.F, ITALIC_FLAG, italic); } /** * A flag telling if the text should be bold. * * @return The bold flag. */ public boolean isBold() { return getCOSObject().getFlag(COSName.F, BOLD_FLAG); } /** * Set the bold property of the text. * * @param bold The new bold flag. */ public void setBold(boolean bold) { getCOSObject().setFlag(COSName.F, BOLD_FLAG, bold); } }