/* * $Id$ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. * For details on use and redistribution please refer to the * LICENSE file included with these sources. */ package org.apache.fop.viewer; //Java import java.awt.*; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.print.PrinterJob; import java.awt.print.PrinterException; import java.awt.image.BufferedImage; //FOP import org.apache.fop.apps.AWTStarter; import org.apache.fop.apps.FOPException; import org.apache.fop.render.awt.AWTRenderer; /** * AWT Viewer main window. * Originally contributed by: * Juergen Verwohlt: Juergen.Verwohlt@jCatalog.com, * Rainer Steinkuhle: Rainer.Steinkuhle@jCatalog.com, * Stanislav Gorkhover: Stanislav.Gorkhover@jCatalog.com */ public class PreviewDialog extends JFrame { protected Translator translator; protected AWTRenderer renderer; protected AWTStarter starter; private int currentPage = 0; private int pageCount = 0; private Reloader reloader; private JComboBox scale; private JLabel processStatus; private JLabel pageLabel; private JLabel infoStatus; /** * Creates a new PreviewDialog that uses the given starter, renderer and translator. * @param aStarter the to use starter * @param aRenderer the to use renderer * @param aRes the to use translator */ public PreviewDialog(AWTStarter aStarter, AWTRenderer aRenderer, Translator aRes) { this(aRenderer, aRes); starter = aStarter; } /** * Creates a new PreviewDialog that uses the given renderer and translator. * @param aRenderer the to use renderer * @param aRes the to use translator */ public PreviewDialog(AWTRenderer aRenderer, Translator aRes) { translator = aRes; renderer = aRenderer; //Commands aka Actions Command printAction = new Command(translator.getString("Menu.Print"), "Print") { public void doit() { print(); } }; Command firstPageAction = new Command(translator.getString("Menu.First.page"), "firstpg") { public void doit() { goToFirstPage(); } }; Command previousPageAction = new Command(translator.getString("Menu.Prev.page"), "prevpg") { public void doit() { goToPreviousPage(); } }; Command nextPageAction = new Command(translator.getString("Menu.Next.page"), "nextpg") { public void doit() { goToNextPage(); } }; Command lastPageAction = new Command(translator.getString("Menu.Last.page"), "lastpg") { public void doit() { goToLastPage(); } }; Command reloadAction = new Command(translator.getString("Menu.Reload"), "reload") { public void doit() { reload(); } }; setTitle("FOP: AWT-" + translator.getString("Title.Preview")); setDefaultCloseOperation(DISPOSE_ON_CLOSE); //Sets size to be 61%x90% of the screen size Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); //Rather frivolous size - fits A4 page width in 1024x768 screen on my desktop setSize(screen.width*61/100, screen.height*9/10); //Page view stuff pageLabel = new JLabel(); JScrollPane previewArea = new JScrollPane(pageLabel); previewArea.getViewport().setBackground(Color.gray); previewArea.setMinimumSize(new Dimension(50, 50)); getContentPane().add(previewArea, BorderLayout.CENTER); //Scaling combobox scale = new JComboBox(); scale.addItem("25%"); scale.addItem("50%"); scale.addItem("75%"); scale.addItem("100%"); scale.addItem("150%"); scale.addItem("200%"); scale.setMaximumSize(new Dimension(80, 24)); scale.setPreferredSize(new Dimension(80, 24)); scale.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { scale_actionPerformed(e); } }); scale.setSelectedItem("100%"); renderer.setScaleFactor(100.0); //Menu setJMenuBar(setupMenu()); //Toolbar JToolBar toolBar = new JToolBar(); toolBar.add(printAction); toolBar.add(reloadAction); toolBar.addSeparator(); toolBar.add(firstPageAction); toolBar.add(previousPageAction); toolBar.add(nextPageAction); toolBar.add(lastPageAction); toolBar.addSeparator(); toolBar.add(new JLabel(translator.getString("Menu.Zoom"))); toolBar.addSeparator(); toolBar.add(scale); getContentPane().add(toolBar, BorderLayout.NORTH); //Status bar JPanel statusBar = new JPanel(); processStatus = new JLabel(); processStatus.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createEtchedBorder(), BorderFactory.createEmptyBorder(0,3,0,0))); infoStatus = new JLabel(); infoStatus.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createEtchedBorder(), BorderFactory.createEmptyBorder(0,3,0,0))); statusBar.setLayout(new GridBagLayout()); processStatus.setPreferredSize(new Dimension(200, 21)); processStatus.setMinimumSize(new Dimension(200, 21)); infoStatus.setPreferredSize(new Dimension(100, 21)); infoStatus.setMinimumSize(new Dimension(100, 21)); statusBar.add(processStatus, new GridBagConstraints(0, 0, 1, 0, 2.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 3), 0, 0)); statusBar.add(infoStatus, new GridBagConstraints(1, 0, 1, 0, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); getContentPane().add(statusBar, BorderLayout.SOUTH); } /** * Creates a new menubar to be shown in this window. * @return the newly created menubar */ private JMenuBar setupMenu() { JMenuBar menuBar = new JMenuBar(); JMenu menu = new JMenu(translator.getString("Menu.File")); //Adds mostly the same actions, but without icons menu.add(new Command(translator.getString("Menu.Print")) { public void doit() { print(); } }); menu.add(new Command(translator.getString("Menu.Reload")) { public void doit() { reload(); } }); menu.addSeparator(); menu.add(new Command(translator.getString("Menu.Exit")) { public void doit() { dispose(); } }); menuBar.add(menu); menu = new JMenu(translator.getString("Menu.View")); menu.add(new Command(translator.getString("Menu.First.page")) { public void doit() { goToFirstPage(); } }); menu.add(new Command(translator.getString("Menu.Prev.page")) { public void doit() { goToPreviousPage(); } }); menu.add(new Command(translator.getString("Menu.Next.page")) { public void doit() { goToNextPage(); } }); menu.add(new Command(translator.getString("Menu.Last.page")) { public void doit() { goToLastPage(); } }); menu.add(new Command(translator.getString("Menu.Go.to.Page") + " ...") { public void doit() { showGoToPageDialog(); } }); menu.addSeparator(); JMenu subMenu = new JMenu(translator.getString("Menu.Zoom")); subMenu.add(new Command("25%") { public void doit() { setScale(25.0); } }); subMenu.add(new Command("50%") { public void doit() { setScale(50.0); } }); subMenu.add(new Command("75%") { public void doit() { setScale(75.0); } }); subMenu.add(new Command("100%") { public void doit() { setScale(100.0); } }); subMenu.add(new Command("150%") { public void doit() { setScale(150.0); } }); subMenu.add(new Command("200%") { public void doit() { setScale(200.0); } }); menu.add(subMenu); menu.addSeparator(); menu.add(new Command(translator.getString("Menu.Default.zoom")) { public void doit() { setScale(100.0); } }); menuBar.add(menu); menu = new JMenu(translator.getString("Menu.Help")); menu.add(new Command(translator.getString("Menu.About")) { public void doit() { startHelpAbout(); } }); menuBar.add(menu); return menuBar; } /** * Shows the About box */ private void startHelpAbout() { PreviewDialogAboutBox dlg = new PreviewDialogAboutBox(this, translator); //Centers the box Dimension dlgSize = dlg.getPreferredSize(); Dimension frmSize = getSize(); Point loc = getLocation(); dlg.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x, (frmSize.height - dlgSize.height) / 2 + loc.y); dlg.setVisible(true); } /** * Changes the current visible page * @param number the page number to go to */ private void goToPage(int number) { currentPage = number; renderer.setPageNumber(number); showPage(); } /** * Shows the previous page. */ private void goToPreviousPage() { if (currentPage <= 0) return; currentPage--; goToPage(currentPage); } /** * Shows the next page. */ private void goToNextPage() { if (currentPage >= pageCount - 1) return; currentPage++; goToPage(currentPage); } /** * Shows the last page. */ private void goToLastPage() { if (currentPage == pageCount - 1) return; currentPage = pageCount - 1; goToPage(currentPage); } /** * Reloads and reformats document. */ private synchronized void reload() { if (reloader == null || !reloader.isAlive()) { reloader = new Reloader(); reloader.start(); } } /** * This class is used to reload document in * a thread safe way. */ private class Reloader extends Thread { public void run() { pageLabel.setIcon(null); infoStatus.setText(""); currentPage = 0; //Cleans up renderer - to be done //while (renderer.getPageCount() != 0) // renderer.removePage(0); try { starter.run(); } catch (FOPException e) { reportException(e); } } } /** * Shows "go to page" dialog and then goes to the selected page */ private void showGoToPageDialog() { GoToPageDialog d = new GoToPageDialog(this, translator.getString("Menu.Go.to.Page"), translator); d.setLocation((int)getLocation().getX() + 50, (int)getLocation().getY() + 50); d.setVisible(true); currentPage = d.getPageNumber(); if (currentPage < 1 || currentPage > pageCount) return; currentPage--; goToPage(currentPage); } /** * Shows the first page. */ private void goToFirstPage() { if (currentPage == 0) return; currentPage = 0; goToPage(currentPage); } /** * Prints the document */ private void print() { PrinterJob pj = PrinterJob.getPrinterJob(); pj.setPageable(renderer); if (pj.printDialog()) { try { pj.print(); } catch (PrinterException pe) { pe.printStackTrace(); } } } /** * Scales page image */ private void setScale(double scaleFactor) { if (scaleFactor == 25.0) scale.setSelectedIndex(0); else if (scaleFactor == 50.0) scale.setSelectedIndex(1); else if (scaleFactor == 75.0) scale.setSelectedIndex(2); else if (scaleFactor == 100.0) scale.setSelectedIndex(3); else if (scaleFactor == 150.0) scale.setSelectedIndex(4); else if (scaleFactor == 200.0) scale.setSelectedIndex(5); renderer.setScaleFactor(scaleFactor); showPage(); } private void scale_actionPerformed(ActionEvent e) { String item = (String)scale.getSelectedItem(); setScale(Double.parseDouble(item.substring(0, item.indexOf('%')))); } /** * Sets message to be shown in the status bar in a thread safe way. */ public void setStatus(String message) { SwingUtilities.invokeLater(new ShowStatus(message)); } /** * This class is used to show status in a thread safe way. */ private class ShowStatus implements Runnable { /** * The message to display */ String message; /** * Constructs ShowStatus thread * @param message message to display */ public ShowStatus(String message) { this.message = message; } public void run() { processStatus.setText(message.toString()); } } /** * Starts rendering process and shows the current page. */ public void showPage() { ShowPageImage viewer = new ShowPageImage(); if (SwingUtilities.isEventDispatchThread()) { viewer.run(); } else SwingUtilities.invokeLater(viewer); } /** * This class is used to update the page image * in a thread safe way. */ private class ShowPageImage implements Runnable { /** * The run method that does the actual updating */ public void run() { //Rendering a page - to be done /* renderer.render(currentPage); BufferedImage pageImage = renderer.getLastRenderedPage(); if (pageImage == null) return; pageLabel.setIcon(new ImageIcon(pageImage)); pageCount = renderer.getPageCount(); //Updates status bar infoStatus.setText(translator.getString("Status.Page") + " " + (currentPage + 1) + " " + translator.getString("Status.of") + " " + pageCount); */ } } /** * Opens standard Swing error dialog box and reports given exception details. */ public void reportException(Exception e) { String msg = translator.getString("Exception.Occured"); setStatus(msg); JOptionPane.showMessageDialog( getContentPane(), "" + msg + ":
" + e.getClass().getName() + "
" + e.getMessage() + "", translator.getString("Exception.Error"), JOptionPane.ERROR_MESSAGE ); } }