001 /**
002 * ========================================
003 * JFreeReport : a free Java report library
004 * ========================================
005 *
006 * Project Info: http://reporting.pentaho.org/
007 *
008 * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
009 *
010 * This library is free software; you can redistribute it and/or modify it under the terms
011 * of the GNU Lesser General Public License as published by the Free Software Foundation;
012 * either version 2.1 of the License, or (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016 * See the GNU Lesser General Public License for more details.
017 *
018 * You should have received a copy of the GNU Lesser General Public License along with this
019 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020 * Boston, MA 02111-1307, USA.
021 *
022 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023 * in the United States and other countries.]
024 *
025 * ------------
026 * $Id: PreviewPane.java,v 1.8 2007/04/01 18:49:31 taqua Exp $
027 * ------------
028 * (C) Copyright 2000-2005, by Object Refinery Limited.
029 * (C) Copyright 2005-2007, by Pentaho Corporation.
030 */
031
032 package org.jfree.report.modules.gui.swing.preview;
033
034 import java.awt.BorderLayout;
035 import java.awt.Color;
036 import java.awt.Window;
037 import java.beans.PropertyChangeEvent;
038 import java.beans.PropertyChangeListener;
039 import java.text.NumberFormat;
040 import java.util.ArrayList;
041 import java.util.Arrays;
042 import java.util.Collections;
043 import java.util.HashMap;
044 import java.util.Iterator;
045 import java.util.Locale;
046 import java.util.Map;
047 import javax.swing.BorderFactory;
048 import javax.swing.JComponent;
049 import javax.swing.JMenu;
050 import javax.swing.JPanel;
051 import javax.swing.JScrollPane;
052 import javax.swing.JToolBar;
053 import javax.swing.SwingUtilities;
054
055 import org.jfree.layout.CenterLayout;
056 import org.jfree.layouting.modules.output.graphics.PageDrawable;
057 import org.jfree.report.JFreeReportBoot;
058 import org.jfree.report.flow.ReportJob;
059 import org.jfree.report.flow.ReportStructureRoot;
060 import org.jfree.report.modules.gui.common.IconTheme;
061 import org.jfree.report.modules.gui.swing.common.ActionPlugin;
062 import org.jfree.report.modules.gui.swing.common.SwingGuiContext;
063 import org.jfree.report.modules.gui.swing.common.SwingUtil;
064 import org.jfree.report.modules.gui.swing.printing.PrintReportProcessor;
065 import org.jfree.report.util.Worker;
066 import org.jfree.report.util.TextUtilities;
067 import org.jfree.ui.Drawable;
068 import org.jfree.ui.DrawablePanel;
069 import org.jfree.ui.KeyedComboBoxModel;
070 import org.jfree.util.Configuration;
071 import org.jfree.util.Log;
072 import org.jfree.util.ObjectUtilities;
073
074 /**
075 * Creation-Date: 11.11.2006, 19:36:13
076 *
077 * @author Thomas Morgner
078 */
079 public class PreviewPane extends JPanel
080 {
081 private class PreviewGuiContext implements SwingGuiContext
082 {
083 public PreviewGuiContext()
084 {
085 }
086
087 public Window getWindow()
088 {
089 return SwingUtil.getWindowAncestor(PreviewPane.this);
090 }
091
092 public Locale getLocale()
093 {
094 ReportJob report = getReportJob();
095 if (report != null)
096 {
097 return report.getReportStructureRoot().getLocale();
098 }
099 return Locale.getDefault();
100 }
101
102 public IconTheme getIconTheme()
103 {
104 return PreviewPane.this.getIconTheme();
105 }
106
107 public Configuration getConfiguration()
108 {
109 ReportJob report = getReportJob();
110 if (report != null)
111 {
112 return report.getConfiguration();
113 }
114 return JFreeReportBoot.getInstance().getGlobalConfig();
115 }
116 }
117
118 private class RepaginationRunnable implements Runnable
119 {
120 private PrintReportProcessor processor;
121
122 public RepaginationRunnable(PrintReportProcessor processor)
123 {
124 this.processor = processor;
125 }
126
127 /**
128 * When an object implementing interface <code>Runnable</code> is used to
129 * create a thread, starting the thread causes the object's <code>run</code>
130 * method to be called in that separately executing thread.
131 * <p/>
132 * The general contract of the method <code>run</code> is that it may take
133 * any action whatsoever.
134 *
135 * @see Thread#run()
136 */
137 public void run()
138 {
139 final UpdatePaginatingPropertyHandler startPaginationNotify =
140 new UpdatePaginatingPropertyHandler(processor, true, 0);
141 if (SwingUtilities.isEventDispatchThread())
142 {
143 startPaginationNotify.run();
144 }
145 else
146 {
147 SwingUtilities.invokeLater(startPaginationNotify);
148 }
149
150 // Perform the pagination ..
151 final int pageCount = processor.getNumberOfPages();
152
153 final UpdatePaginatingPropertyHandler endPaginationNotify =
154 new UpdatePaginatingPropertyHandler(processor, false, pageCount);
155 if (SwingUtilities.isEventDispatchThread())
156 {
157 endPaginationNotify.run();
158 }
159 else
160 {
161 SwingUtilities.invokeLater(endPaginationNotify);
162 }
163
164 }
165 }
166
167 private class UpdatePaginatingPropertyHandler implements Runnable
168 {
169 private boolean paginating;
170 private int pageCount;
171 private PrintReportProcessor processor;
172
173 public UpdatePaginatingPropertyHandler(final PrintReportProcessor processor,
174 final boolean paginating,
175 final int pageCount)
176 {
177 this.processor = processor;
178 this.paginating = paginating;
179 this.pageCount = pageCount;
180 }
181
182 /**
183 * When an object implementing interface <code>Runnable</code> is used to
184 * create a thread, starting the thread causes the object's <code>run</code>
185 * method to be called in that separately executing thread.
186 * <p/>
187 * The general contract of the method <code>run</code> is that it may take
188 * any action whatsoever.
189 *
190 * @see Thread#run()
191 */
192 public void run()
193 {
194 if (processor != getPrintReportProcessor())
195 {
196 Log.debug("No longer valid");
197 return;
198 }
199
200 Log.debug("Pagination: " + paginating + " No. " + pageCount);
201 if (paginating == false)
202 {
203 setNumberOfPages(pageCount);
204 if (getPageNumber() < 1)
205 {
206 setPageNumber(1);
207 }
208 else if (getPageNumber() > pageCount)
209 {
210 setPageNumber(pageCount);
211 }
212 }
213 setPaginating(paginating);
214 }
215 }
216
217 private class PreviewUpdateHandler implements PropertyChangeListener
218 {
219 public PreviewUpdateHandler()
220 {
221 }
222
223 public void propertyChange(PropertyChangeEvent evt)
224 {
225 final String propertyName = evt.getPropertyName();
226 if (PAGINATING_PROPERTY.equals(propertyName))
227 {
228 if (isPaginating())
229 {
230 drawablePanel.setDrawable(getPaginatingDrawable());
231 }
232 else
233 {
234 updateVisiblePage(getPageNumber());
235 }
236 }
237 else if (REPORT_JOB_PROPERTY.equals(propertyName))
238 {
239 if (getReportJob() == null)
240 {
241 drawablePanel.setDrawable(getNoReportDrawable());
242 }
243 // else the paginating property will be fired anyway ..
244 }
245 else if (PAGE_NUMBER_PROPERTY.equals(propertyName))
246 {
247 if (isPaginating())
248 {
249 return;
250 }
251
252 updateVisiblePage(getPageNumber());
253 }
254 }
255 }
256
257 private class UpdateZoomHandler implements PropertyChangeListener
258 {
259 public UpdateZoomHandler()
260 {
261 }
262
263 /**
264 * This method gets called when a bound property is changed.
265 *
266 * @param evt A PropertyChangeEvent object describing the event source and
267 * the property that has changed.
268 */
269
270 public void propertyChange(PropertyChangeEvent evt)
271 {
272 if ("zoom".equals(evt.getPropertyName()) == false)
273 {
274 return;
275 }
276 Log.debug ("Zooming: " + zoom);
277 if (zoom == 1.0)
278 {
279 Log.debug ("JERE");
280 }
281 final double zoom = getZoom();
282 pageDrawable.setZoom(zoom);
283 zoomModel.setSelectedKey(new Double(zoom));
284 if (zoomModel.getSelectedKey() == null)
285 {
286 Log.debug ("Zooming: (2) " + zoom);
287 zoomModel.setSelectedItem(formatZoomText(zoom));
288 }
289 drawablePanel.revalidate();
290 }
291 }
292
293 private static final double ZOOM_FACTORS[] = {
294 0.5, 0.75, 1, 1.20, 1.50, 2.00
295 };
296 private static final int DEFAULT_ZOOM_INDEX = 2;
297 public static final String PAGE_NUMBER_PROPERTY = "pageNumber";
298 public static final String NUMBER_OF_PAGES_PROPERTY = "numberOfPages";
299 public static final String STATUS_TEXT_PROPERTY = "statusText";
300 public static final String STATUS_TYPE_PROPERTY = "statusType";
301 public static final String REPORT_CONTROLLER_PROPERTY = "reportController";
302 public static final String REPORT_JOB_PROPERTY = "reportJob";
303 public static final String ZOOM_PROPERTY = "zoom";
304 public static final String CLOSED_PROPERTY = "closed";
305 public static final String PAGINATING_PROPERTY = "paginating";
306 public static final String ICON_THEME_PROPERTY = "iconTheme";
307 public static final String TITLE_PROPERTY = "title";
308 public static final String MENU_PROPERTY = "menu";
309
310 private Drawable paginatingDrawable;
311 private Drawable noReportDrawable;
312 private PageBackgroundDrawable pageDrawable;
313
314 private DrawablePanel drawablePanel;
315 private ReportController reportController;
316 private JMenu[] menus;
317 private JToolBar toolBar;
318 private String statusText;
319 private String title;
320 private int statusType;
321 private boolean closed;
322 private ReportJob reportJob;
323
324 private int numberOfPages;
325 private int pageNumber;
326 private SwingGuiContext swingGuiContext;
327 private IconTheme iconTheme;
328 private double zoom;
329 private boolean paginating;
330
331 private PrintReportProcessor printReportProcessor;
332
333
334 private Worker paginationWorker;
335 private JPanel innerReportControllerHolder;
336 private JPanel toolbarHolder;
337 private JPanel outerReportControllerHolder;
338 private boolean reportControllerInner;
339 private String reportControllerLocation;
340 private JComponent reportControllerComponent;
341 private KeyedComboBoxModel zoomModel;
342
343
344 /**
345 * Creates a new <code>JPanel</code> with a double buffer and a flow layout.
346 */
347 public PreviewPane()
348 {
349 this.menus = new JMenu[0];
350 setLayout(new BorderLayout());
351
352 zoomModel = new KeyedComboBoxModel();
353 zoomModel.setAllowOtherValue(true);
354 zoom = ZOOM_FACTORS[DEFAULT_ZOOM_INDEX];
355
356 pageDrawable = new PageBackgroundDrawable();
357
358 drawablePanel = new DrawablePanel();
359 drawablePanel.setOpaque(false);
360 drawablePanel.setBackground(Color.green);
361
362 swingGuiContext = new PreviewGuiContext();
363
364 final JPanel reportPaneHolder = new JPanel(new CenterLayout());
365 reportPaneHolder.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
366 reportPaneHolder.add(drawablePanel);
367
368 final JScrollPane s1 = new JScrollPane(reportPaneHolder);
369 s1.getVerticalScrollBar().setUnitIncrement(20);
370
371 innerReportControllerHolder = new JPanel();
372 innerReportControllerHolder.setLayout(new BorderLayout());
373 innerReportControllerHolder.add(s1, BorderLayout.CENTER);
374
375 toolbarHolder = new JPanel();
376 toolbarHolder.setLayout(new BorderLayout());
377 toolbarHolder.add(innerReportControllerHolder, BorderLayout.CENTER);
378
379 outerReportControllerHolder = new JPanel();
380 outerReportControllerHolder.setLayout(new BorderLayout());
381 outerReportControllerHolder.add(toolbarHolder, BorderLayout.CENTER);
382
383 add(outerReportControllerHolder, BorderLayout.CENTER);
384
385 addPropertyChangeListener(new PreviewUpdateHandler());
386 addPropertyChangeListener("zoom", new UpdateZoomHandler());
387 }
388
389 public synchronized PrintReportProcessor getPrintReportProcessor()
390 {
391 return printReportProcessor;
392 }
393
394 protected synchronized void setPrintReportProcessor(final PrintReportProcessor printReportProcessor)
395 {
396 this.printReportProcessor = printReportProcessor;
397 }
398
399 public JMenu[] getMenu()
400 {
401 return menus;
402 }
403
404 protected void setMenu(final JMenu[] menus)
405 {
406 if (menus == null)
407 {
408 throw new NullPointerException();
409 }
410 final JMenu[] oldmenu = this.menus;
411 this.menus = (JMenu[]) menus.clone();
412 firePropertyChange(MENU_PROPERTY, oldmenu, this.menus);
413 }
414
415 public JToolBar getToolBar()
416 {
417 return toolBar;
418 }
419
420 public String getStatusText()
421 {
422 return statusText;
423 }
424
425 public void setStatusText(final String statusText)
426 {
427 String oldStatus = this.statusText;
428 this.statusText = statusText;
429
430 firePropertyChange(STATUS_TEXT_PROPERTY, oldStatus, statusText);
431 }
432
433 public int getStatusType()
434 {
435 return statusType;
436 }
437
438 public void setStatusType(final int statusType)
439 {
440 int oldType = this.statusType;
441 this.statusType = statusType;
442
443 firePropertyChange(STATUS_TYPE_PROPERTY, oldType, statusType);
444 }
445
446 public ReportController getReportController()
447 {
448 return reportController;
449 }
450
451 public void setReportController(final ReportController reportController)
452 {
453 ReportController oldController = this.reportController;
454 this.reportController = reportController;
455 firePropertyChange(REPORT_CONTROLLER_PROPERTY, oldController, reportController);
456
457 // Now add the controller to the GUI ..
458 refreshReportController(reportController);
459 }
460
461 public void refreshReportController(final ReportController newReportController)
462 {
463 if (newReportController != null)
464 {
465 final JComponent rcp = newReportController.getControlPanel();
466 // if either the controller component or its position (inner vs outer)
467 // and border-position has changed, then refresh ..
468 if (reportControllerComponent != rcp ||
469 reportControllerInner != newReportController.isInnerComponent() ||
470 ObjectUtilities.equal(reportControllerLocation,
471 newReportController.getControllerLocation()))
472 {
473 if (reportControllerComponent != null)
474 {
475 outerReportControllerHolder.remove(reportControllerComponent);
476 innerReportControllerHolder.remove(reportControllerComponent);
477 }
478 final String sanLocation = sanitizeLocation(
479 newReportController.getControllerLocation());
480 final boolean innerComponent = newReportController.isInnerComponent();
481 if (rcp != null)
482 {
483 if (innerComponent)
484 {
485 innerReportControllerHolder.add(rcp, sanLocation);
486 }
487 else
488 {
489 outerReportControllerHolder.add(rcp, sanLocation);
490 }
491 }
492 reportControllerComponent = rcp;
493 reportControllerLocation = sanLocation;
494 reportControllerInner = innerComponent;
495 }
496 }
497 else
498 {
499 if (reportControllerComponent != null)
500 {
501 outerReportControllerHolder.remove(reportControllerComponent);
502 innerReportControllerHolder.remove(reportControllerComponent);
503 }
504 reportControllerComponent = null;
505 }
506 }
507
508
509 private String sanitizeLocation(final String location)
510 {
511 if (BorderLayout.NORTH.equals(location))
512 {
513 return BorderLayout.NORTH;
514 }
515 if (BorderLayout.SOUTH.equals(location))
516 {
517 return BorderLayout.SOUTH;
518 }
519 if (BorderLayout.WEST.equals(location))
520 {
521 return BorderLayout.WEST;
522 }
523 if (BorderLayout.EAST.equals(location))
524 {
525 return BorderLayout.EAST;
526 }
527 return BorderLayout.NORTH;
528 }
529
530 public ReportJob getReportJob()
531 {
532 return reportJob;
533 }
534
535 public void setReportJob(final ReportJob reportJob)
536 {
537 ReportJob oldJob = this.reportJob;
538 this.reportJob = reportJob;
539
540 firePropertyChange(REPORT_JOB_PROPERTY, oldJob, reportJob);
541 if (reportJob == null)
542 {
543 initializeWithoutJob();
544 }
545 else
546 {
547 initializeFromReport();
548 }
549 }
550
551 public double getZoom()
552 {
553 return zoom;
554 }
555
556 public void setZoom(final double zoom)
557 {
558 double oldZoom = this.zoom;
559 this.zoom = zoom;
560 firePropertyChange(ZOOM_PROPERTY, oldZoom, zoom);
561 }
562
563 public boolean isClosed()
564 {
565 return closed;
566 }
567
568 public void setClosed(final boolean closed)
569 {
570 boolean oldClosed = this.closed;
571 this.closed = closed;
572 firePropertyChange(CLOSED_PROPERTY, oldClosed, closed);
573 if (closed)
574 {
575 prepareShutdown();
576 }
577 }
578
579 private void prepareShutdown()
580 {
581 synchronized (this)
582 {
583 if (paginationWorker != null)
584 {
585 synchronized (paginationWorker)
586 {
587 paginationWorker.finish();
588 }
589 paginationWorker = null;
590 }
591 if (printReportProcessor != null)
592 {
593 printReportProcessor.close();
594 printReportProcessor = null;
595 }
596 closeToolbar();
597 }
598 }
599
600 private int getUserDefinedCategoryPosition()
601 {
602 return TextUtilities.parseInt
603 (swingGuiContext.getConfiguration().getConfigProperty
604 ("org.jfree.report.modules.gui.swing.user-defined-category.position"), 15000);
605 }
606
607
608 public Locale getLocale()
609 {
610 ReportStructureRoot report = getReportJob().getReportStructureRoot();
611 if (report != null)
612 {
613 return report.getLocale();
614 }
615 return super.getLocale();
616 }
617
618 public int getNumberOfPages()
619 {
620 return numberOfPages;
621 }
622
623 public void setNumberOfPages(final int numberOfPages)
624 {
625 final int oldPageNumber = this.numberOfPages;
626 this.numberOfPages = numberOfPages;
627 firePropertyChange(NUMBER_OF_PAGES_PROPERTY, oldPageNumber, numberOfPages);
628 }
629
630 public int getPageNumber()
631 {
632 return pageNumber;
633 }
634
635 public void setPageNumber(final int pageNumber)
636 {
637 final int oldPageNumber = this.pageNumber;
638 this.pageNumber = pageNumber;
639 Log.debug("Setting PageNumber: " + pageNumber);
640 firePropertyChange(PAGE_NUMBER_PROPERTY, oldPageNumber, pageNumber);
641 }
642
643 public IconTheme getIconTheme()
644 {
645 return iconTheme;
646 }
647
648 protected void setIconTheme(IconTheme theme)
649 {
650 IconTheme oldTheme = this.iconTheme;
651 this.iconTheme = theme;
652 firePropertyChange(ICON_THEME_PROPERTY, oldTheme, theme);
653 }
654
655 protected void initializeFromReport()
656 {
657 setIconTheme(PreviewPaneUtilities.createIconTheme(reportJob.getConfiguration()));
658
659 zoomModel.clear();
660 for (int i = 0; i < ZOOM_FACTORS.length; i++)
661 {
662 zoomModel.add(new Double(ZOOM_FACTORS[i]), formatZoomText(ZOOM_FACTORS[i]));
663 }
664 zoom = ZOOM_FACTORS[DEFAULT_ZOOM_INDEX];
665 zoomModel.setSelectedKey(new Double(ZOOM_FACTORS[DEFAULT_ZOOM_INDEX]));
666
667 HashMap actions = PreviewPaneUtilities.loadActions(swingGuiContext);
668 buildMenu(actions);
669
670
671 if (toolBar != null)
672 {
673 toolbarHolder.remove(toolBar);
674 }
675 toolBar = buildToolbar(actions);
676 if (toolBar != null)
677 {
678 toolbarHolder.add(toolBar, BorderLayout.NORTH);
679 }
680
681 startPagination();
682 }
683
684 private JToolBar buildToolbar(final HashMap actions)
685 {
686 JToolBar toolBar = new JToolBar();
687 toolBar.setFloatable(false);
688
689 final ActionCategory[] cats = (ActionCategory[])
690 actions.keySet().toArray(new ActionCategory[actions.size()]);
691 Arrays.sort(cats);
692
693 for (int i = 0; i < cats.length; i++)
694 {
695 final ActionCategory cat = cats[i];
696 final ActionPlugin[] plugins = (ActionPlugin[]) actions.get(cat);
697 PreviewPaneUtilities.addActionsToToolBar(toolBar, plugins, this);
698 }
699
700 return toolBar;
701 }
702
703 private void closeToolbar()
704 {
705 if (toolBar.getParent() != toolbarHolder)
706 {
707 // ha!, we detected that the toolbar is floating ...
708 // Log.debug (currentToolbar.getParent());
709 final Window w = SwingUtilities.windowForComponent(toolBar);
710 if (w != null)
711 {
712 w.setVisible(false);
713 w.dispose();
714 }
715 }
716 toolBar.setVisible(false);
717 }
718
719 public SwingGuiContext getSwingGuiContext()
720 {
721 return swingGuiContext;
722 }
723
724 public KeyedComboBoxModel getZoomModel()
725 {
726 return zoomModel;
727 }
728
729 private String formatZoomText(final double zoom)
730 {
731 final NumberFormat numberFormat =
732 NumberFormat.getPercentInstance(swingGuiContext.getLocale());
733 return (numberFormat.format(zoom));
734 }
735
736
737 private void buildMenu(final HashMap actions)
738 {
739 final HashMap menus = new HashMap();
740 final int userPos = getUserDefinedCategoryPosition();
741
742 final ActionCategory[] categories = new ActionCategory[actions.size()];
743 boolean insertedUserDefinedActions = false;
744 int catCount = 0;
745 final Iterator iterator = actions.entrySet().iterator();
746 while (iterator.hasNext())
747 {
748 final Map.Entry entry = (Map.Entry) iterator.next();
749 final ActionCategory cat = (ActionCategory) entry.getKey();
750 categories[catCount] = cat;
751 catCount += 1;
752 final ActionPlugin[] plugins = (ActionPlugin[]) entry.getValue();
753
754 if (insertedUserDefinedActions == false && cat.getPosition() > userPos)
755 {
756 ReportController controller = getReportController();
757 if (controller != null)
758 {
759 controller.initialize(this);
760 final JMenu[] controlerMenus = controller.getMenus();
761 for (int i = 0; i < controlerMenus.length; i++)
762 {
763 final ActionCategory userCategory = new ActionCategory();
764 userCategory.setName("X-User-Category-" + i);
765 userCategory.setPosition(userPos + i);
766 menus.put(userCategory, controlerMenus[i]);
767 }
768 }
769
770 insertedUserDefinedActions = true;
771 }
772
773 final JMenu menu = PreviewPaneUtilities.createMenu(cat);
774 int count = PreviewPaneUtilities.buildMenu(menu, plugins, this);
775 menus.put(cat, menu);
776 }
777
778 final CategoryTreeItem[] categoryTreeItems =
779 PreviewPaneUtilities.buildMenuTree(categories);
780
781 ArrayList menuList = new ArrayList();
782 for (int i = 0; i < categoryTreeItems.length; i++)
783 {
784 final CategoryTreeItem item = categoryTreeItems[i];
785 final JMenu menu = (JMenu) menus.get(item.getCategory());
786 // now connect all menus ..
787 final CategoryTreeItem[] childs = item.getChilds();
788 Arrays.sort(childs);
789 for (int j = 0; j < childs.length; j++)
790 {
791 CategoryTreeItem child = childs[j];
792 final JMenu childMenu = (JMenu) menus.get(child.getCategory());
793 if (childMenu != null)
794 {
795 menu.add(childMenu);
796 }
797 }
798
799 if (item.getParent() == null)
800 {
801 menuList.add(item);
802 }
803 }
804
805 Collections.sort(menuList);
806 ArrayList retval = new ArrayList();
807 for (int i = 0; i < menuList.size(); i++)
808 {
809 final CategoryTreeItem item = (CategoryTreeItem) menuList.get(i);
810 JMenu menu = (JMenu) menus.get(item.getCategory());
811 if (menu.getItemCount() > 0)
812 {
813 retval.add(menu);
814 }
815 }
816
817 setMenu((JMenu[]) retval.toArray(new JMenu[retval.size()]));
818 }
819
820 // private JMenu createViewMenu(ActionCategory cat)
821 // {
822 // JMenu zoom = new JMenu("Zoom");
823 // zoom.add(new ActionMenuItem(new ZoomOutAction(this)));
824 // zoom.add(new ActionMenuItem(new ZoomInAction(this)));
825 // zoom.addSeparator();
826 //
827 // for (int i = 0; i < ZOOM_FACTORS.length; i++)
828 // {
829 // double factor = ZOOM_FACTORS[i];
830 // zoom.add(new ActionMenuItem(new ZoomAction(factor, this)));
831 // }
832 //
833 // zoom.addSeparator();
834 // zoom.add(new ActionMenuItem(new ZoomCustomAction(this)));
835 //
836 // JMenu menu = new JMenu("View");
837 // menu.add(zoom);
838 // menu.addSeparator();
839 // menu.add(new ActionMenuItem("Paginated"));
840 // menu.add(new ActionMenuItem("Flow"));
841 // return menu;
842 // }
843
844 protected void initializeWithoutJob()
845 {
846 final Configuration globalConfig =
847 JFreeReportBoot.getInstance().getGlobalConfig();
848 setIconTheme(PreviewPaneUtilities.createIconTheme(globalConfig));
849
850 zoomModel.clear();
851 for (int i = 0; i < ZOOM_FACTORS.length; i++)
852 {
853 zoomModel.add(new Double(ZOOM_FACTORS[i]), formatZoomText(ZOOM_FACTORS[i]));
854 }
855 zoom = ZOOM_FACTORS[DEFAULT_ZOOM_INDEX];
856 zoomModel.setSelectedKey(new Double(ZOOM_FACTORS[DEFAULT_ZOOM_INDEX]));
857
858 HashMap actions = PreviewPaneUtilities.loadActions(swingGuiContext);
859 buildMenu(actions);
860 if (toolBar != null)
861 {
862 toolbarHolder.remove(toolBar);
863 }
864 toolBar = buildToolbar(actions);
865 if (toolBar != null)
866 {
867 toolbarHolder.add(toolBar, BorderLayout.NORTH);
868 }
869
870 }
871
872 public String getTitle()
873 {
874 return title;
875 }
876
877 public void setTitle(final String title)
878 {
879 String oldTitle = this.title;
880 this.title = title;
881 firePropertyChange(TITLE_PROPERTY, oldTitle, title);
882 }
883
884 public double[] getZoomFactors()
885 {
886 return (double[]) ZOOM_FACTORS.clone();
887 }
888
889 public boolean isPaginating()
890 {
891 return paginating;
892 }
893
894 public void setPaginating(final boolean paginating)
895 {
896 boolean oldPaginating = this.paginating;
897 this.paginating = paginating;
898 firePropertyChange(PAGINATING_PROPERTY, oldPaginating, paginating);
899 }
900
901 private synchronized void startPagination()
902 {
903 if (paginationWorker != null)
904 {
905 // make sure that old pagination handler does not run longer than
906 // necessary..
907 synchronized(paginationWorker)
908 {
909 paginationWorker.finish();
910 }
911 paginationWorker = null;
912 }
913
914 if (printReportProcessor != null)
915 {
916 printReportProcessor.close();
917 printReportProcessor = null;
918 }
919
920 final ReportJob reportJob = getReportJob();
921 printReportProcessor = new PrintReportProcessor(reportJob.derive());
922
923 paginationWorker = new Worker();
924 paginationWorker.setWorkload
925 (new RepaginationRunnable(printReportProcessor));
926 }
927
928 public Drawable getNoReportDrawable()
929 {
930 return noReportDrawable;
931 }
932
933 public void setNoReportDrawable(final Drawable noReportDrawable)
934 {
935 this.noReportDrawable = noReportDrawable;
936 }
937
938 public Drawable getPaginatingDrawable()
939 {
940 return paginatingDrawable;
941 }
942
943 public void setPaginatingDrawable(final Drawable paginatingDrawable)
944 {
945 this.paginatingDrawable = paginatingDrawable;
946 }
947
948 protected void updateVisiblePage(int pageNumber)
949 {
950 //
951 if (printReportProcessor == null)
952 {
953 throw new IllegalStateException();
954 }
955
956 // todo: This can be very expensive - so we better move this off the event-dispatcher
957 final int pageIndex = getPageNumber() - 1;
958 if (pageIndex < 0 || pageIndex >= printReportProcessor.getNumberOfPages())
959 {
960 drawablePanel.setDrawable(null);
961 pageDrawable.setBackend(null);
962 }
963 else
964 {
965 final PageDrawable drawable = printReportProcessor.getPageDrawable(pageIndex);
966 Log.debug("Drawable: " + drawable);
967 this.pageDrawable.setBackend(drawable);
968 this.drawablePanel.setDrawable(pageDrawable);
969 }
970 }
971 }