Package jmt.manual

Source Code of jmt.manual.PDFViewerBuffer$CloseHelpFileAdapter

package jmt.manual;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Scrollbar;
import java.awt.Toolkit;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.WindowConstants;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreePath;

import jmt.gui.common.Defaults;

import com.sun.pdfview.OutlineNode;
import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;
import com.sun.pdfview.action.GoToAction;

/**
* @author Lucia Guglielmetti
*/
public class PDFViewerBuffer extends JFrame implements AdjustmentListener,
TreeSelectionListener {
  /**
   *
   */
  private static final long serialVersionUID = 1L;
  private static final int PAGE_NUM_RESERVED = -1;
  private static final String MANUAL_RESOURCE = "manuals/manual.pdf";
  private static final String EMPTY_RESOURCE = "emptyFile.txt";

  //size of buffer
  private static int BUFFER_SIZE = 3;// MUST BE ODD
  //size of page display
  private static int PAGE_DIMENSION_RATIO = 65;

  //buffer to memory use for load manual
  private Image buffer[];
  private int bufferIndex[];

  //manual
  private PDFFile pdfFile;
  //page start and page end to section of manual specified
  private int pageStart;
  private int pageEnd;

  // use to create bar in the panel
  private Scrollbar bar;
  private static int SCROLLBAR_ACCURANCY = 1;

  // Panel where upload manual
  private JPanel canvas;

  //size of image displayed
  private double imageWidth;
  private double imageHeight;

  //grid with one row and one column for displayed images
  private GridLayout canvasLayout;

  private OutlineNode outline;

  //Second Panel to display index
  private JDialog olf;

  private OutlineNode currentOutline;

  //tree use to display index
  private JTree jt;
 
  //help file
  private RandomAccessFile raf;

  /**
   * It render the section of the manual specified by @marker.
   *
   * @param title
   * @param marker
   * @throws IOException
   */
  public PDFViewerBuffer(String title, ManualBookmarkers marker)
      throws IOException {
    super(title);

    /**  To avoid out of
     * memory issue, it uses a buffer to load the pages. 
     */ 
    buffer = new Image[BUFFER_SIZE];
    bufferIndex = new int[BUFFER_SIZE];
    JPanel omni = new JPanel(new BorderLayout());
    canvas = new JPanel();

    loadManual(marker);
    loadPage(0);

    updateCanvas();

    /** 
     * creation and management scrollbars 
     */ 

    bar = new Scrollbar(Scrollbar.VERTICAL, 0, 1, 0, (pageEnd - pageStart)
        * SCROLLBAR_ACCURANCY);
    bar.addAdjustmentListener(this);
    JScrollPane scroller = new JScrollPane(canvas);
    scroller.getVerticalScrollBar().setPreferredSize(new Dimension(0, 0));
    scroller.getHorizontalScrollBar().setPreferredSize(new Dimension(0, 0));
    omni.add(scroller, BorderLayout.CENTER);

    omni.add(bar, BorderLayout.WEST);
    omni.add(bar, BorderLayout.EAST);
    setContentPane(omni);

    this.addWindowListener(new CloseHelpFileAdapter());
    this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    Toolkit tk = Toolkit.getDefaultToolkit();
    setPreferredSize(new Dimension((int) Math.min(imageWidth, tk.getScreenSize().getWidth()),
        (int) Math.min(imageHeight * 1.9, tk.getScreenSize().getHeight())));
    pack();
    setVisible(true);

  }



  /**
   * Creating jpanel with image upload and creation secondary window
   * with index
   */
  private void updateCanvas() {
    canvas.removeAll();
    canvasLayout = new GridLayout(1, 1);
    canvas.setLayout(canvasLayout);
    JPanel panel = new JPanel(new BorderLayout());

    JLabel labelImg = new JLabel(new ImageIcon(buffer[BUFFER_SIZE / 2]));
    JPanel panelSep = new JPanel(new FlowLayout());
    panelSep.setOpaque(true);
    panelSep.setBackground(Color.BLACK);

    panel.add(labelImg, BorderLayout.CENTER);
    panel.add(panelSep, BorderLayout.SOUTH);

    try {
      outline = pdfFile.getOutline();
    } catch (IOException ioe) {
    }

    /**
     * Creation a secondary window.
     * This window see with tree hierarchy of the index menu.
     */
    if (outline != null && jt == null) {
      if (outline.getChildCount() > 0) {
        olf = new JDialog(this, "Menù");
        olf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        olf.setLocation(876, 0);

        jt = new JTree(currentOutline);
        jt.setRootVisible(false);
        jt.addTreeSelectionListener(this);

        JScrollPane jsp = new JScrollPane(jt);
        olf.getContentPane().add(jsp);
        olf.pack();
        olf.setVisible(true);
      } else {
        if (olf != null) {
          olf.setVisible(false);
          olf = null;
        }
      }
    }
    canvas.add(panel);
    validate();
  }

  /**
   * Loads the pdf manual file from the file system and set pageStart and
   * pageEnd accordingly with @marker  the manual you want to open
   *
   * @param marker
   *          
   * @throws IOException
   */
  private void loadManual(ManualBookmarkers marker) throws IOException {
    // Search for manual in default path
    File manualFile = new File(MANUAL_RESOURCE);
    // Try to search starting from JMT.jar location
    if (!manualFile.isFile()) {
      try {
        URI uri = PDFViewerBuffer.class.getResource(EMPTY_RESOURCE).toURI();
        manualFile = new File(new File(uri).getParentFile(), MANUAL_RESOURCE);
      } catch (Exception ex) {
        //Nothing to do here, we will throw exceptions later.
      }
    }
    // Finally search in Working dir
    if (!manualFile.isFile()) {
      manualFile = new File(Defaults.getWorkingPath(), MANUAL_RESOURCE);
    }

    if (!manualFile.isFile()) {
      throw new IOException("Could not find JMT manual.pdf file. Please place it in " + manualFile.getCanonicalPath() + " location.");
    }

    raf = new RandomAccessFile(manualFile, "r");

    FileChannel fc = raf.getChannel();
    ByteBuffer buf = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
    pdfFile = new PDFFile(buf);

    pageStart = 0;
    pageEnd = pdfFile.getNumPages();
    OutlineNode on = pdfFile.getOutline();
    if (on != null) {
      for (int i = 0; i < on.getChildCount(); i++) {
        OutlineNode child = (OutlineNode) on.getChildAt(i);
        GoToAction act = (GoToAction) child.getAction();

        //Find the beginning of the chapter selected,
        //then take the page start and page end number
        if (child.toString().toLowerCase().startsWith(marker.getChapterPrefix().toLowerCase())) {
          currentOutline = child;
          pageStart = pdfFile.getPageNumber(act.getDestination()
              .getPage());
          if (i + 1 < on.getChildCount()) {
            OutlineNode childAfter = (OutlineNode) on
                .getChildAt(i + 1);
            GoToAction actAfter = (GoToAction) childAfter
                .getAction();
            pageEnd = pdfFile.getPageNumber(actAfter
                .getDestination().getPage());
          }// else if child is the last one, pageEnd is already set.
          break;
        }
      }
    }

  }
  /**
   * Loads the number of pages (indicated to @num ) of the selected section
   * of the manual.
   * To avoid problems of memory used is a buffer memory
   **/
  private void loadPage(int num) {

    for (int i = 0; i < BUFFER_SIZE; i++) {
      int page = pageStart + num - (BUFFER_SIZE / 2) + i;
      if (page < pageStart || page >= pageEnd) {
        buffer[i] = null;
        bufferIndex[i] = PAGE_NUM_RESERVED;
        continue;
      }
      buffer[i] = getPageFromBuffer(page);
      if (buffer[i] == null) {
        buffer[i] = getPageFromDisk(page);
      } else {
      }
      // TODO check this update
      bufferIndex[i] = page;
    }
  }
  /**
   *
   * @param page
   * @return
   */
  private Image getPageFromBuffer(int page) {
    Image res = null;
    for (int i = 0; i < BUFFER_SIZE; i++) {
      if (bufferIndex[i] == page)
        return buffer[i];
    }
    return res;
  }

  /**
   * create the image to load
   **/
  private Image getPageFromDisk(int pageNum) {
    PDFPage page = pdfFile.getPage(pageNum + 1);
    Rectangle2D r2d = page.getBBox();
    imageWidth = r2d.getWidth();
    imageHeight = r2d.getHeight();
    imageWidth /= PAGE_DIMENSION_RATIO;
    imageHeight /= PAGE_DIMENSION_RATIO;
    int res = Toolkit.getDefaultToolkit().getScreenResolution();
    imageWidth *= res;
    imageHeight *= res;
    return page.getImage((int) imageWidth, (int) imageHeight, r2d, null,
        true, true);
  }

  public static void main(final String[] args) throws IOException {
    Runnable r = new Runnable() {
      @Override
      public void run() {
        try {
          new PDFViewerBuffer("PDF Viewer",
              ManualBookmarkers.JSIMgraph);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    };
    EventQueue.invokeLater(r);

  }

  @Override
  public void adjustmentValueChanged(AdjustmentEvent ev) {
    int value = bar.getValue();
    int page = value;
    validate();
    loadPage(page);
    updateCanvas();
  }

  /**
   * Once you select a subsection from the menu window,
   * it does refer to the correct page
   */
  @Override
  public void valueChanged(TreeSelectionEvent e) {

    TreePath path = e.getNewLeadSelectionPath();
    OutlineNode selectedNode = (OutlineNode) path.getLastPathComponent();
    GoToAction act = (GoToAction) selectedNode.getAction();

    try {
      int pageNode = pdfFile
          .getPageNumber(act.getDestination().getPage());
      bar.setValue(pageNode - pageStart);
      loadPage(pageNode - pageStart);
      updateCanvas();
    } catch (IOException e1) {

    }

  }
 
  /** Close PDF file when help window is closed */
  private class CloseHelpFileAdapter extends WindowAdapter {

    @Override
    public void windowClosing(WindowEvent e) {
      if (raf != null) {
        try {
          raf.close();
        } catch (Exception ex) {
          ex.printStackTrace();
        }
      }
    }
   
  }

}
TOP

Related Classes of jmt.manual.PDFViewerBuffer$CloseHelpFileAdapter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.