All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nl.siegmann.epublib.viewer.TableOfContentsPane Maven / Gradle / Ivy

The newest version!
package nl.siegmann.epublib.viewer;

import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import nl.siegmann.epublib.browsersupport.NavigationEvent;
import nl.siegmann.epublib.browsersupport.NavigationEventListener;
import nl.siegmann.epublib.browsersupport.Navigator;
import nl.siegmann.epublib.domain.Book;
import nl.siegmann.epublib.domain.Resource;
import nl.siegmann.epublib.domain.TOCReference;

import org.apache.commons.lang.StringUtils;

/**
 * Creates a JTree for navigating a Book via its Table of Contents.
 * 
 * @author paul
 *
 */
public class TableOfContentsPane extends JPanel implements NavigationEventListener {

	private static final long serialVersionUID = 2277717264176049700L;
	
	private Map> href2treeNode = new HashMap>();
	private JScrollPane scrollPane;
	private Navigator navigator;
	private JTree tree;
	
	/**
	 * Creates a JTree that displays all the items in the table of contents from the book in SectionWalker.
	 * Also sets up a selectionListener that updates the SectionWalker when an item in the tree is selected.
	 * 
	 * @param navigator
	 */
	public TableOfContentsPane(Navigator navigator) {
		super(new GridLayout(1, 0));
		this.navigator = navigator;
		navigator.addNavigationEventListener(this);

		this.scrollPane = new JScrollPane();
		add(scrollPane);
		initBook(navigator.getBook());
	}
	
	/**
	 * Wrapper around a TOCReference that gives the TOCReference's title when toString() is called
	 * .createTableOfContentsTree
	 * @author paul
	 *
	 */
	private static class TOCItem {
		private TOCReference tocReference;
		
		public TOCItem(TOCReference tocReference) {
			super();
			this.tocReference = tocReference;
		}
		
		public TOCReference getTOCReference() {
			return tocReference;
		}

		public String toString() {
			return tocReference.getTitle();
		}
	}
	
	private void addToHref2TreeNode(Resource resource, DefaultMutableTreeNode treeNode) {
		if (resource == null || StringUtils.isBlank(resource.getHref())) {
			return;
		}
		Collection treeNodes = href2treeNode.get(resource.getHref());
		if (treeNodes == null) {
			treeNodes = new ArrayList();
			href2treeNode.put(resource.getHref(), treeNodes);
		}
		treeNodes.add(treeNode);
	}
	
	private DefaultMutableTreeNode createTree(Book book) {
		TOCItem rootTOCItem = new TOCItem(new TOCReference(book.getTitle(), book.getCoverPage()));
		DefaultMutableTreeNode top = new DefaultMutableTreeNode(rootTOCItem);
		addToHref2TreeNode(book.getCoverPage(), top);
		createNodes(top, book);
		return top;
	}
	
	private void createNodes(DefaultMutableTreeNode top, Book book) {
		addNodesToParent(top, book.getTableOfContents().getTocReferences());
	}
	
	private void addNodesToParent(DefaultMutableTreeNode parent, List tocReferences) {
		if (tocReferences == null) {
			return;
		}
		for (TOCReference tocReference: tocReferences) {
			TOCItem tocItem = new TOCItem(tocReference);
			DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode(tocItem);
			addToHref2TreeNode(tocReference.getResource(), treeNode);
			addNodesToParent(treeNode, tocReference.getChildren());
			parent.add(treeNode);
		}
	}

	
	@Override
	public void navigationPerformed(NavigationEvent navigationEvent) {
		if (this == navigationEvent.getSource()) {
			return;
		}
		if (navigationEvent.isBookChanged()) {
			initBook(navigationEvent.getCurrentBook());
			return;
		}
		if (this.tree == null) {
			return;
		}
		if (navigationEvent.getCurrentResource() == null) {
			return;
		}
		Collection treeNodes = href2treeNode.get(navigationEvent.getCurrentResource().getHref());
		if (treeNodes == null || treeNodes.isEmpty()) {
			if (navigationEvent.getCurrentSpinePos() == (navigationEvent.getOldSpinePos() + 1)) {
				return;
			}
			tree.setSelectionPath(null);
			return;
		}
		for (DefaultMutableTreeNode treeNode: treeNodes) {
			TreeNode[] path = treeNode.getPath();
			TreePath treePath = new TreePath(path);
			tree.setSelectionPath(treePath);
		}
	}

	private void initBook(Book book) {
		if (book == null) {
			return;
		}
		this.tree = new JTree(createTree(book));
		tree.addMouseListener(new MouseAdapter() {

			public void mouseClicked(MouseEvent me) {
				DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
				TOCItem tocItem = (TOCItem) node.getUserObject();
				navigator.gotoResource(tocItem.getTOCReference().getResource(), tocItem.getTOCReference().getFragmentId(), TableOfContentsPane.this);
			}
		});

		tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
//		tree.setRootVisible(false);
		tree.setSelectionRow(0);
		this.scrollPane.getViewport().removeAll();
		this.scrollPane.getViewport().add(tree);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy