KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > viewer > PreviewDialog


1 /*
2  * $Id: PreviewDialog.java,v 1.7.2.5 2003/02/25 15:25:15 jeremias Exp $
3  * ============================================================================
4  * The Apache Software License, Version 1.1
5  * ============================================================================
6  *
7  * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without modifica-
10  * tion, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if any, must
20  * include the following acknowledgment: "This product includes software
21  * developed by the Apache Software Foundation (http://www.apache.org/)."
22  * Alternately, this acknowledgment may appear in the software itself, if
23  * and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. The names "FOP" and "Apache Software Foundation" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * apache@apache.org.
29  *
30  * 5. Products derived from this software may not be called "Apache", nor may
31  * "Apache" appear in their name, without prior written permission of the
32  * Apache Software Foundation.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
35  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
36  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
37  * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
38  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
39  * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
40  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
41  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44  * ============================================================================
45  *
46  * This software consists of voluntary contributions made by many individuals
47  * on behalf of the Apache Software Foundation and was originally created by
48  * James Tauber <jtauber@jtauber.com>. For more information on the Apache
49  * Software Foundation, please see <http://www.apache.org/>.
50  */

51 package org.apache.fop.viewer;
52
53 /*
54  * originally contributed by
55  * Juergen Verwohlt: Juergen.Verwohlt@jCatalog.com,
56  * Rainer Steinkuhle: Rainer.Steinkuhle@jCatalog.com,
57  * Stanislav Gorkhover: Stanislav.Gorkhover@jCatalog.com
58  * Doro Wiarda (wiarda@dwiarda.com):
59  * added MessageListener support and made the showing of the progress and error
60  * messages Swing thread safe. This is needed as xml parse errors do not
61  * necessarily occur in the EventDispatchThread.
62  */

63
64 import java.awt.*;
65 import java.awt.print.*;
66 import java.awt.event.*;
67 import java.awt.image.BufferedImage JavaDoc;
68 import java.util.StringTokenizer JavaDoc;
69 import java.util.Vector JavaDoc;
70
71 import javax.swing.*;
72
73 import org.apache.fop.render.awt.*;
74 import org.apache.fop.messaging.*;
75 import org.apache.fop.apps.AWTStarter;
76 import org.apache.fop.apps.FOPException;
77
78 /**
79  * Frame and User Interface for Preview
80  */

81 public class PreviewDialog extends JFrame implements ProgressListener,
82         MessageListener {
83
84     protected Translator res;
85
86     protected int currentPage = 0;
87     protected int pageCount = 0;
88
89     protected AWTRenderer renderer;
90     protected AWTStarter starter;
91
92     protected IconToolBar toolBar = new IconToolBar();
93
94     protected Command printAction;
95     protected Command firstPageAction;
96     protected Command previousPageAction;
97     protected Command nextPageAction;
98     protected Command lastPageAction;
99     protected Command reloadAction;
100     protected Reloader reloader;
101
102     protected JLabel zoomLabel =
103         new JLabel(); // {public float getAlignmentY() { return 0.0f; }};
104

105     protected JComboBox scale = new JComboBox() {
106         public float getAlignmentY() {
107             return 0.5f;
108         }
109     };
110
111     protected JScrollPane previewArea = new JScrollPane();
112     // protected JLabel statusBar = new JLabel();
113
protected JPanel statusBar = new JPanel();
114     protected GridBagLayout statusBarLayout = new GridBagLayout();
115
116     protected JLabel statisticsStatus = new JLabel();
117     protected JLabel processStatus = new JLabel();
118     protected JLabel infoStatus = new JLabel();
119     protected JLabel previewImageLabel = new JLabel();
120
121      /**
122      * Create a new PreviewDialog that uses the given starter, renderer and translator.
123      *
124      * @param aStarter the to use starter
125      * @param aRenderer the to use renderer
126      * @param aRes the to use translator
127      */

128     public PreviewDialog(AWTStarter aStarter, AWTRenderer aRenderer, Translator aRes) {
129         this(aRenderer, aRes);
130         starter = aStarter;
131     }
132
133     /**
134      * Create a new PreviewDialog that uses the given renderer and translator.
135      *
136      * @param aRenderer the to use renderer
137      * @param aRes the to use translator
138      */

139     public PreviewDialog(AWTRenderer aRenderer, Translator aRes) {
140         res = aRes;
141         renderer = aRenderer;
142
143         printAction = new Command(res.getString("Print"), "Print") {
144             public void doit() {
145                 print();
146             }
147         };
148
149         firstPageAction = new Command(res.getString("First page"),
150                                       "firstpg") {
151             public void doit() {
152                 goToFirstPage(null);
153             }
154
155         };
156
157         previousPageAction = new Command(res.getString("Previous page"),
158                                          "prevpg") {
159             public void doit() {
160                 goToPreviousPage(null);
161             }
162         };
163
164         nextPageAction = new Command(res.getString("Next page"), "nextpg") {
165             public void doit() {
166                 goToNextPage(null);
167             }
168         };
169
170         lastPageAction = new Command(res.getString("Last page"), "lastpg") {
171             public void doit() {
172                 goToLastPage(null);
173             }
174         };
175
176         reloadAction = new Command(res.getString("Reload"), "reload") {
177             public void doit() {
178                 reload(null);
179             }
180         };
181
182         setDefaultCloseOperation(DISPOSE_ON_CLOSE);
183         this.setSize(new Dimension(379, 476));
184         previewArea.setMinimumSize(new Dimension(50, 50));
185
186         this.setTitle("FOP: AWT-" + res.getString("Preview"));
187
188         scale.addItem("25");
189         scale.addItem("50");
190         scale.addItem("75");
191         scale.addItem("100");
192         scale.addItem("150");
193         scale.addItem("200");
194
195         scale.setMaximumSize(new Dimension(80, 24));
196         scale.setPreferredSize(new Dimension(80, 24));
197
198         scale.addActionListener(new java.awt.event.ActionListener JavaDoc() {
199             public void actionPerformed(ActionEvent e) {
200                 scale_actionPerformed(e);
201             }
202         });
203
204         scale.setSelectedItem("100");
205         renderer.setScaleFactor(100.0);
206
207         zoomLabel.setText(res.getString("Zoom"));
208
209         this.setJMenuBar(setupMenue());
210
211         this.getContentPane().add(toolBar, BorderLayout.NORTH);
212
213         toolBar.add(printAction);
214         toolBar.add(reloadAction);
215         toolBar.addSeparator();
216         toolBar.add(firstPageAction);
217         toolBar.add(previousPageAction);
218         toolBar.add(nextPageAction);
219         toolBar.add(lastPageAction);
220         toolBar.addSeparator();
221         toolBar.add(zoomLabel, null);
222         toolBar.addSeparator();
223         toolBar.add(scale, null);
224
225         this.getContentPane().add(previewArea, BorderLayout.CENTER);
226         this.getContentPane().add(statusBar, BorderLayout.SOUTH);
227
228         statisticsStatus.setBorder(BorderFactory.createEtchedBorder());
229         processStatus.setBorder(BorderFactory.createEtchedBorder());
230         infoStatus.setBorder(BorderFactory.createEtchedBorder());
231
232         statusBar.setLayout(statusBarLayout);
233
234         processStatus.setPreferredSize(new Dimension(200, 21));
235         statisticsStatus.setPreferredSize(new Dimension(100, 21));
236         infoStatus.setPreferredSize(new Dimension(100, 21));
237         processStatus.setMinimumSize(new Dimension(200, 21));
238         statisticsStatus.setMinimumSize(new Dimension(100, 21));
239         infoStatus.setMinimumSize(new Dimension(100, 21));
240         statusBar.add(processStatus,
241                       new GridBagConstraints(0, 0, 2, 1, 2.0, 0.0,
242                                              GridBagConstraints.CENTER,
243                                              GridBagConstraints.HORIZONTAL,
244                                              new Insets(0, 0, 0, 5), 0, 0));
245         statusBar.add(statisticsStatus,
246                       new GridBagConstraints(2, 0, 1, 2, 1.0, 0.0,
247                                              GridBagConstraints.CENTER,
248                                              GridBagConstraints.HORIZONTAL,
249                                              new Insets(0, 0, 0, 5), 0, 0));
250         statusBar.add(infoStatus,
251                       new GridBagConstraints(3, 0, 1, 1, 1.0, 0.0,
252                                              GridBagConstraints.CENTER,
253                                              GridBagConstraints.HORIZONTAL,
254                                              new Insets(0, 0, 0, 0), 0, 0));
255
256         previewArea.getViewport().add(previewImageLabel);
257         showPage();
258     }
259
260     /**
261      * Create a new menubar to be shown in this window.
262      *
263      * @return the newly created menubar
264      */

265     private JMenuBar setupMenue() {
266         JMenuBar menuBar;
267         JMenuItem menuItem;
268         JMenu menu;
269         JMenu subMenu;
270
271         menuBar = new JMenuBar();
272         menu = new JMenu(res.getString("File"));
273         subMenu = new JMenu("OutputFormat");
274         subMenu.add(new Command("mHTML"));
275         subMenu.add(new Command("mPDF"));
276         subMenu.add(new Command("mRTF"));
277         subMenu.add(new Command("mTEXT"));
278         // menu.add(subMenu);
279
// menu.addSeparator();
280
menu.add(new Command(res.getString("Print")) {
281             public void doit() {
282                 print();
283             }
284         });
285         menu.add(new Command(res.getString("Reload")) {
286             public void doit() {
287                 reload(null);
288             }
289         });
290         menu.addSeparator();
291         menu.add(new Command(res.getString("Exit")) {
292             public void doit() {
293                 dispose();
294             }
295         });
296         menuBar.add(menu);
297         menu = new JMenu(res.getString("View"));
298         menu.add(new Command(res.getString("First page")) {
299             public void doit() {
300                 goToFirstPage(null);
301             }
302         });
303         menu.add(new Command(res.getString("Previous page")) {
304             public void doit() {
305                 goToPreviousPage(null);
306             }
307         });
308         menu.add(new Command(res.getString("Next page")) {
309             public void doit() {
310                 goToNextPage(null);
311             }
312         });
313         menu.add(new Command(res.getString("Last page")) {
314             public void doit() {
315                 goToLastPage(null);
316             }
317         });
318         menu.add(new Command(res.getString("Go to Page") + " ...") {
319             public void doit() {
320                 goToPage(null);
321             }
322         });
323         menu.addSeparator();
324         subMenu = new JMenu(res.getString("Zoom"));
325         subMenu.add(new Command("25%") {
326             public void doit() {
327                 setScale(25.0);
328             }
329         });
330         subMenu.add(new Command("50%") {
331             public void doit() {
332                 setScale(50.0);
333             }
334         });
335         subMenu.add(new Command("75%") {
336             public void doit() {
337                 setScale(75.0);
338             }
339         });
340         subMenu.add(new Command("100%") {
341             public void doit() {
342                 setScale(100.0);
343             }
344         });
345         subMenu.add(new Command("150%") {
346             public void doit() {
347                 setScale(150.0);
348             }
349         });
350         subMenu.add(new Command("200%") {
351             public void doit() {
352                 setScale(200.0);
353             }
354         });
355         menu.add(subMenu);
356         menu.addSeparator();
357         menu.add(new Command(res.getString("Default zoom")) {
358             public void doit() {
359                 setScale(100.0);
360             }
361         });
362         menuBar.add(menu);
363         menu = new JMenu(res.getString("Help"));
364         menu.add(new Command(res.getString("Index")));
365         menu.addSeparator();
366         menu.add(new Command(res.getString("Introduction")));
367         menu.addSeparator();
368         menu.add(new Command(res.getString("About")) {
369             public void doit() {
370                 startHelpAbout(null);
371             }
372         });
373         menuBar.add(menu);
374         return menuBar;
375     }
376
377     /**
378      * Show the About box
379      *
380      * @param e a value of type 'ActionEvent'
381      */

382     public void startHelpAbout(ActionEvent e) {
383         PreviewDialogAboutBox dlg = new PreviewDialogAboutBox(this);
384         Dimension dlgSize = dlg.getPreferredSize();
385         Dimension frmSize = getSize();
386         Point loc = getLocation();
387         dlg.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x,
388                         (frmSize.height - dlgSize.height) / 2 + loc.y);
389         dlg.setModal(true);
390         dlg.show();
391     }
392
393     /**
394      * Change the current visible page
395      *
396      * @param number the page number to go to
397      */

398     private void goToPage(int number) {
399         currentPage = number;
400         renderer.setPageNumber(number);
401         showPage();
402     }
403
404     /**
405      * Shows the previous page.
406      */

407     private void goToPreviousPage(ActionEvent e) {
408         if (currentPage <= 0)
409             return;
410         currentPage--;
411         goToPage(currentPage);
412     }
413
414     /**
415      * Shows the next page.
416      */

417     private void goToNextPage(ActionEvent e) {
418         if (currentPage >= pageCount - 1)
419             return;
420         currentPage++;
421         goToPage(currentPage);
422     }
423
424     /**
425      * Shows the last page.
426      */

427     private void goToLastPage(ActionEvent e) {
428         if (currentPage == pageCount - 1)
429             return;
430         currentPage = pageCount - 1;
431         goToPage(currentPage);
432     }
433
434     /**
435      * Reloads and reformats document.
436      */

437     private synchronized void reload(ActionEvent e) {
438         if (reloader == null || !reloader.isAlive()) {
439             reloader = new Reloader();
440             reloader.start();
441         }
442     }
443
444     /**
445      * This class is used to reload document in
446      * a thread safe way.
447      */

448     private class Reloader extends Thread JavaDoc {
449         public void run() {
450             previewImageLabel.setIcon(null);
451             statisticsStatus.setText("");
452             //Cleans up renderer
453
while (renderer.getPageCount() != 0)
454                 renderer.removePage(0);
455             try {
456                 starter.run();
457             } catch (FOPException e) {
458                 e.printStackTrace();
459             }
460         }
461     }
462
463     /**
464      * Shows a page by number.
465      */

466     private void goToPage(ActionEvent e) {
467         GoToPageDialog d = new GoToPageDialog(this,
468                                               res.getString("Go to Page"),
469                                               true,
470                                               res);
471         d.setLocation((int)getLocation().getX() + 50,
472                       (int)getLocation().getY() + 50);
473         d.show();
474         currentPage = d.getPageNumber();
475
476         if (currentPage < 1 || currentPage > pageCount)
477             return;
478
479         currentPage--;
480
481         goToPage(currentPage);
482     }
483
484     /**
485      * Shows the first page.
486      */

487     private void goToFirstPage(ActionEvent e) {
488         if (currentPage == 0)
489             return;
490         currentPage = 0;
491         goToPage(currentPage);
492     }
493
494     private void print() {
495         PrinterJob pj = PrinterJob.getPrinterJob();
496         // Not necessary, Pageable gets a Printable.
497
// pj.setPrintable(renderer);
498
pj.setPageable(renderer);
499
500         if (pj.printDialog()) {
501             try {
502                 pj.print();
503             } catch (PrinterException pe) {
504                 pe.printStackTrace();
505             }
506         }
507     }
508
509     public void setScale(double scaleFactor) {
510         if (scaleFactor == 25.0)
511             scale.setSelectedIndex(0);
512         else if (scaleFactor == 50.0)
513             scale.setSelectedIndex(1);
514         else if (scaleFactor == 75.0)
515             scale.setSelectedIndex(2);
516         else if (scaleFactor == 100.0)
517             scale.setSelectedIndex(3);
518         else if (scaleFactor == 150.0)
519             scale.setSelectedIndex(4);
520         else if (scaleFactor == 200.0)
521             scale.setSelectedIndex(5);
522
523         renderer.setScaleFactor(scaleFactor);
524         showPage();
525     }
526
527     void scale_actionPerformed(ActionEvent e) {
528         setScale(new Double JavaDoc((String JavaDoc)scale.getSelectedItem()).doubleValue());
529     }
530
531     public void progress(int percentage) {
532         progress(new String JavaDoc(percentage + "%"));
533     }
534
535     public void progress(int percentage, String JavaDoc message) {
536         progress(new String JavaDoc(message + " " + percentage + "%"));
537     }
538
539     /**
540      * Setting the text of a JLabel is not thread save, it
541      * needs to be done in the EventThread. Here we make sure
542      * it is done.
543      */

544     public void progress(String JavaDoc message) {
545         SwingUtilities.invokeLater(new showProgress(message, false));
546     }
547
548     /**
549      * This class is used to show status and error messages in
550      * a thread safe way.
551      */

552     class showProgress implements Runnable JavaDoc {
553         /**
554          * The message to display
555          */

556         Object JavaDoc message;
557
558         /**
559          * Is this an errorMessage, i.e. should it be shown in
560          * an JOptionPane or in the status bar.
561          */

562         boolean isErrorMessage = false;
563
564         /**
565          * Constructs showProgress thread
566          * @param message message to display
567          * @param isErrorMessage show in status bar or in JOptionPane
568          */

569         public showProgress(Object JavaDoc message, boolean isErrorMessage) {
570             this.message = message;
571             this.isErrorMessage = isErrorMessage;
572         }
573
574         public void run() {
575             if (isErrorMessage) {
576                 JOptionPane.showMessageDialog(null, message, "Error",
577                                               JOptionPane.ERROR_MESSAGE);
578             } else
579                 processStatus.setText(message.toString());
580         }
581     }
582
583     public void showPage() {
584         showPageImage viewer = new showPageImage();
585
586         if (SwingUtilities.isEventDispatchThread()) {
587             viewer.run();
588         } else
589             SwingUtilities.invokeLater(viewer);
590     }
591
592     /**
593      * This class is used to update the page image
594      * in a thread safe way.
595      */

596     class showPageImage implements Runnable JavaDoc {
597
598         /**
599          * The run method that does the actuall updating
600          */

601
602         public void run() {
603             BufferedImage JavaDoc pageImage = null;
604             Graphics graphics = null;
605
606             renderer.render(currentPage);
607             pageImage = renderer.getLastRenderedPage();
608             if (pageImage == null)
609                 return;
610             graphics = pageImage.getGraphics();
611             graphics.setColor(Color.black);
612             graphics.drawRect(0, 0, pageImage.getWidth() - 1,
613                               pageImage.getHeight() - 1);
614
615             previewImageLabel.setIcon(new ImageIcon(pageImage));
616
617             pageCount = renderer.getPageCount();
618
619             statisticsStatus.setText(res.getString("Page") + " "
620                                      + (currentPage + 1) + " "
621                                      + res.getString("of") + " " + pageCount);
622         }
623     }
624
625     /**
626      * Called by MessageHandler if an error message or a
627      * log message is received.
628      */

629     public void processMessage(MessageEvent event) {
630         String JavaDoc error = event.getMessage();
631         String JavaDoc text = processStatus.getText();
632         FontMetrics fmt =
633             processStatus.getFontMetrics(processStatus.getFont());
634         int width = processStatus.getWidth() - fmt.stringWidth("...");
635         showProgress showIt;
636
637         if (event.getMessageType() == event.LOG) {
638             if (!text.endsWith("\n")) {
639                 text = text + error;
640                 while (fmt.stringWidth(text) > width) {
641                     text = text.substring(1);
642                     width = processStatus.getWidth() - fmt.stringWidth("...");
643                 }
644             } else
645                 text = error;
646             progress(text);
647         } else {
648             error = error.trim();
649             if (error.equals(">")) {
650                 text = text + error;
651                 while (fmt.stringWidth(text) > width) {
652                     text = text.substring(1);
653                     width = processStatus.getWidth() - fmt.stringWidth("...");
654                 }
655                 progress(processStatus.getText() + error);
656                 return;
657             }
658             if (error.equals(""))
659                 return;
660             if (error.length() < 60) {
661                 showIt = new showProgress(error, true);
662             } else {
663                 StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(error, " ");
664                 Vector JavaDoc labels = new Vector JavaDoc();
665                 StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
666                 String JavaDoc tmp, list[];
667
668                 while (tok.hasMoreTokens()) {
669                     tmp = tok.nextToken();
670                     if ((buffer.length() + tmp.length() + 1) < 60) {
671                         buffer.append(" ").append(tmp);
672                     } else {
673                         labels.add(buffer.toString());
674                         buffer = new StringBuffer JavaDoc();
675                         buffer.append(tmp);
676                     }
677                 }
678                 labels.add(buffer.toString());
679                 list = new String JavaDoc[labels.size()];
680                 for (int i = 0; i < labels.size(); i++) {
681                     list[i] = labels.get(i).toString();
682                 }
683                 showIt = new showProgress(list, true);
684             }
685             if (SwingUtilities.isEventDispatchThread()) {
686                 showIt.run();
687             } else {
688                 try {
689                     SwingUtilities.invokeAndWait(showIt);
690                 } catch (Exception JavaDoc e) {
691                     e.printStackTrace();
692                     progress(event.getMessage());
693                 }
694             }
695         }
696     }
697
698     public void reportException(Exception JavaDoc e) {
699         String JavaDoc msg = res.getString("An exception has occured");
700         progress(msg);
701         JOptionPane.showMessageDialog(
702             getContentPane(),
703             "<html><b>" + msg + ":</b><br>"
704              + e.getClass().getName() + "<br>" + e.getMessage() + "</html>", res.getString("Fatal error"),
705              JOptionPane.ERROR_MESSAGE
706         );
707     }
708
709 } // class PreviewDialog
710
Popular Tags