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 3525 2007-10-16 11:43:48Z tmorgner $ 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 private PreviewGuiContext() 084 { 085 } 086 087 public Window getWindow() 088 { 089 return SwingUtil.getWindowAncestor(PreviewPane.this); 090 } 091 092 public Locale getLocale() 093 { 094 final 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 final 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 private RepaginationRunnable(final 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 private 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 private PreviewUpdateHandler() 220 { 221 } 222 223 public void propertyChange(final 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 private 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(final 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 final 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 final 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 final 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 final 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 final 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 final 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 final 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(final IconTheme theme) 649 { 650 final 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 final 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 final 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 final 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 final int count = PreviewPaneUtilities.buildMenu(menu, plugins, this); 775 menus.put(cat, menu); 776 } 777 778 final CategoryTreeItem[] categoryTreeItems = 779 PreviewPaneUtilities.buildMenuTree(categories); 780 781 final 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 final 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 final ArrayList retval = new ArrayList(); 807 for (int i = 0; i < menuList.size(); i++) 808 { 809 final CategoryTreeItem item = (CategoryTreeItem) menuList.get(i); 810 final 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 final 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 final 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 final 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(final 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 }