package de.juwimm.cms.content.panel.util; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import org.apache.log4j.Logger; import com.sun.pdfview.PDFFile; import com.sun.pdfview.PDFPage; import com.sun.pdfview.PagePanel; import de.juwimm.cms.content.panel.PanDocuments; public class PdfPreviewFrame extends JFrame implements DocumentPreviewComponent { private static Logger log = Logger.getLogger(PanDocuments.class); public PdfPreviewFrame() { this("Document preview"); } private PDFFile pdffile; private PagePanel pagePanel = new PagePanel(); private int currentPage; private JButton next; private JButton previous; public PdfPreviewFrame(String windowTitle) { super(windowTitle); this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); this.centerWithinParent(); } /** * @inheritDoc */ public void displayComponent() { // show the first page PDFPage page = pdffile.getPage(0); currentPage = 0; Dimension dimension = new Dimension(Float.valueOf(page.getWidth()).intValue(), Float.valueOf(page.getHeight()).intValue()); pagePanel.setSize(dimension); pagePanel.setMinimumSize(dimension); pagePanel.setMaximumSize(dimension); this.getContentPane().setLayout(new BorderLayout()); this.getContentPane().add(pagePanel, BorderLayout.CENTER); this.getContentPane().add(getButtonsPanel(), BorderLayout.SOUTH); this.pack(); this.setVisible(true); pagePanel.showPage(page); centerWithinParent(); } /** * Creates and returns the <b>Previous</b> and <b>Next</b> buttons panel to be displayed underneath the visible area of the document. * @return */ private JPanel getButtonsPanel() { next = new JButton(">"); next.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { actionNext(e); } }); previous = new JButton("<"); previous.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { actionPrevious(e); } }); JPanel panel = new JPanel(); panel.setLayout(new GridBagLayout()); panel.add(previous, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.LINE_END, GridBagConstraints.VERTICAL, new Insets(0, 0, 0, 0), 0, 0)); panel.add(next, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.VERTICAL, new Insets(0, 0, 0, 0), 0, 0)); return panel; } /** * @inheritDoc */ public void setDocumentContent(byte[] content) { File file = null; try { file = File.createTempFile("doc_", ".pdf"); OutputStream out = new FileOutputStream(file); out.write(content); out.close(); RandomAccessFile raf = new RandomAccessFile(file, "r"); FileChannel channel = raf.getChannel(); ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); pdffile = new PDFFile(buf); } catch (IOException e) { log.error(e); } } /** * Centers the component <b>wind</b> into the visible rectangle of the parent component. If parent is not found, will call <i>centerWithinScreen</i> method. */ private void centerWithinParent() { final Container parent = this.getParent(); if (parent != null && parent.isVisible()) { center(this, new Rectangle(parent.getLocationOnScreen(), parent.getSize())); } else { centerWithinScreen(this); } } /** * Centers the component <b>wind</b> into the visible areea of the screen. * @param wind */ private void centerWithinScreen(Window wind) { if (wind == null) { throw new IllegalArgumentException("null Window passed"); } final Toolkit toolKit = Toolkit.getDefaultToolkit(); final Rectangle rcScreen = new Rectangle(toolKit.getScreenSize()); final Dimension windSize = wind.getSize(); final Dimension parentSize = new Dimension(rcScreen.width, rcScreen.height); if (windSize.height > parentSize.height) { windSize.height = parentSize.height; } if (windSize.width > parentSize.width) { windSize.width = parentSize.width; } center(wind, rcScreen); } /** * Centers the component <b>wind</b> into the given rectangle <b>rect</b> * @param wind * @param rect */ private void center(Component wind, Rectangle rect) { if (wind == null || rect == null) { throw new IllegalArgumentException("null Window or Rectangle passed"); } Dimension windSize = wind.getSize(); int x = ((rect.width - windSize.width) / 2) + rect.x; int y = ((rect.height - windSize.height) / 2) + rect.y; if (y < rect.y) { y = rect.y; } wind.setLocation(x, y); } /** * Method called when pressing <b>Next</b> button. * Should display the next page. * @param e */ private void actionNext(ActionEvent e) { if (currentPage == pdffile.getNumPages() - 1) { return; } currentPage++; PDFPage page = pdffile.getPage(currentPage); pagePanel.showPage(page); } /** * Method called when pressing <b>Previous</b> button. * Should display the previous page. * @param e */ private void actionPrevious(ActionEvent e) { if (currentPage == 0) { return; } currentPage--; PDFPage page = pdffile.getPage(currentPage); pagePanel.showPage(page); } }