Package org.pentaho.reporting.engine.classic.core.modules.gui.commonswing

Source Code of org.pentaho.reporting.engine.classic.core.modules.gui.commonswing.ReportProgressDialog$ScreenUpdateRunnable

/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2001 - 2009 Object Refinery Ltd, Pentaho Corporation and Contributors..  All rights reserved.
*/

package org.pentaho.reporting.engine.classic.core.modules.gui.commonswing;

import java.awt.Dialog;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.MessageFormat;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

import org.pentaho.reporting.engine.classic.core.event.ReportProgressEvent;
import org.pentaho.reporting.engine.classic.core.event.ReportProgressListener;
import org.pentaho.reporting.libraries.base.util.Messages;
import org.pentaho.reporting.libraries.base.util.ObjectUtilities;

/**
* A progress monitor dialog component that visualizes the report processing progress. It will receive update events
* from the report processors and updates the UI according to the latest event data.
* <p/>
* The progress will be computed according to the currently processed table row. This approach provides relativly
* accurate data, but assumes that processing all bands consumes roughly the same time.
*
* @author Thomas Morgner
*/
public class ReportProgressDialog extends JDialog implements ReportProgressListener
{
  /**
   * Handles the update event processing as a separate thread
   *
   * @author Thomas Morgner
   */
  private class ScreenUpdateRunnable implements Runnable
  {
    /**
     * The event upon which this update event processing will occur
     */
    private ReportProgressEvent event;

    /**
     * Initializes the update event processing thread with the event information
     */
    protected ScreenUpdateRunnable()
    {
    }

    /**
     * Performs the process of updating all the pieces of the progress dialog with the update event information.
     */
    public synchronized void run()
    {
      if (event == null)
      {
        return;
      }
      updatePageMessage(event.getPage());
      updateRowsMessage(event.getRow(), event.getMaximumRow());
      updateActivityMessage(event.getActivity());
      updateProgressBar(event);
      this.event = null;
    }

    public synchronized boolean update(final ReportProgressEvent event)
    {
      final boolean retval = (this.event == null);
      this.event = event;
      return retval;
    }
  }

  /**
   * Event handles that will ensure this dialog will remain on top
   *
   * @author Thomas Morgner
   */
  private static class ToFrontHandler extends WindowAdapter
  {
    protected ToFrontHandler()
    {
    }

    /**
     * Invoked when a window has been opened.
     */
    public void windowOpened(final WindowEvent e)
    {
      e.getWindow().toFront();
    }
  }

  /**
   * A label that carries the global message that describes the current task.
   */
  private JLabel messageCarrier;

  /**
   * A label containing the report processing pass count.
   */
  private JLabel passCountMessage;

  /**
   * A label containing the current page.
   */
  private JLabel pageCountMessage;

  /**
   * A label containing the currently processed row.
   */
  private JLabel rowCountMessage;

  /**
   * The progress bar that is used to visualize the progress.
   */
  private JProgressBar progressBar;

  /**
   * The reuseable message format for the page label.
   */
  private MessageFormat pageMessageFormatter;

  /**
   * The reuseable message format for the rows label.
   */
  private MessageFormat rowsMessageFormatter;

  /**
   * The reuseable message format for the pass label.
   */
  private MessageFormat passMessageFormatter;

  /**
   * The last page received.
   */
  private int lastPage;

  /**
   * The last pass values received.
   */
  private int lastActivity;

  /**
   * The last max-row received.
   */
  private int lastMaxRow;

  /**
   * the cached value for the max-row value as integer.
   */
  private Integer lastMaxRowInteger; // this values doesnt change much, so reduce GC work

  /**
   * a text which describes the layouting process.
   */
  private String layoutText;

  /**
   * a text that describes the export phase of the report processing.
   */
  private String outputText;

  /**
   * Localised messages.
   */
  private Messages messages;

  private boolean onlyPagination;

  private ScreenUpdateRunnable updateRunnable;

  /**
   * Creates a non-modal dialog without a title and with the specified Dialog owner.
   *
   * @param dialog the owner of the dialog
   */
  public ReportProgressDialog(final Dialog dialog)
  {
    super(dialog);
    setLocale(dialog.getLocale());
    initConstructor();
  }

  /**
   * Creates a non-modal dialog without a title and with the specified Frame owner.
   *
   * @param frame the owner of the dialog
   */
  public ReportProgressDialog(final Frame frame)
  {
    super(frame);
    setLocale(frame.getLocale());
    initConstructor();
  }

  /**
   * Creates a non-modal dialog without a title and without a specified Frame owner.  A shared, hidden frame will be set
   * as the owner of the Dialog.
   */
  public ReportProgressDialog()
  {
    initConstructor();
  }

  public boolean isOnlyPagination()
  {
    return onlyPagination;
  }

  public void setOnlyPagination(final boolean onlyPagination)
  {
    this.onlyPagination = onlyPagination;
  }

  /**
   * Initializes the dialog (Non-GUI stuff).
   */
  private void initConstructor()
  {
    updateRunnable = new ScreenUpdateRunnable();
    messages = new Messages(getLocale(), SwingCommonModule.BUNDLE_NAME,
          ObjectUtilities.getClassLoader(SwingCommonModule.class));
    initialize();
    addWindowListener(new ToFrontHandler());

    setOutputText(messages.getString("progress-dialog.perform-output")); //$NON-NLS-1$
    setLayoutText(messages.getString("progress-dialog.prepare-layout")); //$NON-NLS-1$

    lastActivity = -1;
    lastMaxRow = -1;
    lastPage = -1;
  }

  /**
   * Initializes the GUI components of this dialog.
   */
  private void initialize()
  {
    final JPanel contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new GridBagLayout());

    pageMessageFormatter = new MessageFormat(messages.getString("progress-dialog.page-label")); //$NON-NLS-1$
    rowsMessageFormatter = new MessageFormat(messages.getString("progress-dialog.rows-label")); //$NON-NLS-1$
    passMessageFormatter = new MessageFormat(messages.getString("progress-dialog.pass-label-0")); //$NON-NLS-1$

    messageCarrier = new JLabel(" "); //$NON-NLS-1$
    passCountMessage = new JLabel(" "); //$NON-NLS-1$
    rowCountMessage = new JLabel(" "); //$NON-NLS-1$
    pageCountMessage = new JLabel(" "); //$NON-NLS-1$
    progressBar = new JProgressBar(SwingConstants.HORIZONTAL, 0, 100);
    progressBar.setStringPainted(true);

    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridx = 0;
    gbc.gridy = 0;
    gbc.gridwidth = 2;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.weightx = 1;
    gbc.anchor = GridBagConstraints.WEST;
    gbc.insets = new Insets(3, 1, 5, 1);
    gbc.ipadx = 200;
    contentPane.add(messageCarrier, gbc);

    gbc = new GridBagConstraints();
    gbc.gridx = 0;
    gbc.gridy = 1;
    gbc.gridwidth = 2;
    gbc.anchor = GridBagConstraints.SOUTHWEST;
    gbc.insets = new Insets(3, 1, 1, 1);
    contentPane.add(passCountMessage, gbc);

    gbc = new GridBagConstraints();
    gbc.gridx = 0;
    gbc.gridy = 2;
    gbc.gridwidth = 2;
    gbc.anchor = GridBagConstraints.WEST;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.weightx = 1;
    gbc.insets = new Insets(3, 1, 1, 1);
    contentPane.add(progressBar, gbc);

    gbc = new GridBagConstraints();
    gbc.gridx = 0;
    gbc.gridy = 3;
    gbc.gridwidth = 1;
    gbc.weighty = 1;
    gbc.anchor = GridBagConstraints.NORTHWEST;
    gbc.insets = new Insets(3, 1, 1, 1);
    contentPane.add(pageCountMessage, gbc);

    gbc = new GridBagConstraints();
    gbc.gridx = 1;
    gbc.gridy = 3;
    gbc.gridwidth = 1;
    gbc.anchor = GridBagConstraints.NORTHWEST;
    gbc.insets = new Insets(3, 10, 1, 1);
    gbc.weightx = 1;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    contentPane.add(rowCountMessage, gbc);

    setContentPane(contentPane);
  }

  /**
   * Returns the current message.
   *
   * @return the current global message.
   */
  public String getMessage()
  {
    return messageCarrier.getText();
  }

  /**
   * Defines the current message.
   *
   * @param message the current global message.
   */
  public void setMessage(final String message)
  {
    messageCarrier.setText(message);
  }

  /**
   * Updates the page message label if the current page has changed.
   *
   * @param page the new page parameter.
   */
  protected void updatePageMessage(final int page)
  {
    if (lastPage != page)
    {
      final Object[] parameters = new Object[]{new Integer(page)};
      pageCountMessage.setText(pageMessageFormatter.format(parameters));
      lastPage = page;
    }
  }

  /**
   * Updates the rows message label if either the rows or maxrows changed.
   *
   * @param rows    the currently processed rows.
   * @param maxRows the maximum number of rows in the report.
   */
  protected void updateRowsMessage(final int rows, final int maxRows)
  {
    if (maxRows != lastMaxRow)
    {
      lastMaxRowInteger = new Integer(maxRows);
      lastMaxRow = maxRows;
    }
    final Object[] parameters = new Object[]{new Integer(rows), lastMaxRowInteger};
    rowCountMessage.setText(rowsMessageFormatter.format(parameters));
  }

  /**
   * Updates the pass message label if either the pass or prepare state changed. The pass reflects the current
   * processing level, one level for every function dependency level.
   *
   * @param activity the current reporting pass.
   */
  protected void updateActivityMessage(final int activity)
  {
    if (lastActivity != activity)
    {
      lastActivity = activity;
      final Object[] parameters = new Object[]{new Integer(activity)};
      passCountMessage.setText(passMessageFormatter.format(parameters));
    }
  }

  /**
   * Updates the progress bar to show the current progress
   *
   * @param event the event data used to update the progress bar
   */
  protected void updateProgressBar(final ReportProgressEvent event)
  {
    progressBar.setValue((int) ReportProgressEvent.computePercentageComplete(event, isOnlyPagination()));
  }

  /**
   * Returns the current pass message component.
   *
   * @return the pass message component.
   */
  protected final JLabel getPassCountMessage()
  {
    return passCountMessage;
  }

  /**
   * Returns the current pagecount message component.
   *
   * @return the page message component.
   */
  protected final JLabel getPageCountMessage()
  {
    return pageCountMessage;
  }

  /**
   * Returns the current row message component.
   *
   * @return the row message component.
   */
  protected final JLabel getRowCountMessage()
  {
    return rowCountMessage;
  }

  /**
   * Returns the current pass message component.
   *
   * @return the pass message component.
   */
  protected final MessageFormat getPageMessageFormatter()
  {
    return pageMessageFormatter;
  }

  /**
   * Returns the current pass message component.
   *
   * @return the pass message component.
   */
  protected final MessageFormat getRowsMessageFormatter()
  {
    return rowsMessageFormatter;
  }

  /**
   * Returns the current pass message component.
   *
   * @return the pass message component.
   */
  protected final MessageFormat getPassMessageFormatter()
  {
    return passMessageFormatter;
  }

  /**
   * Returns the output text message. This text describes the export phases of the report processing.
   *
   * @return the output phase description.
   */
  public String getOutputText()
  {
    return outputText;
  }

  /**
   * Defines the output text message. This text describes the export phases of the report processing.
   *
   * @param outputText the output message.
   */
  public void setOutputText(final String outputText)
  {
    if (outputText == null)
    {
      throw new NullPointerException(messages.getErrorString(
          "ReportProgressDialog.ERROR_0001_OUTPUT_TEXT_NULL")); //$NON-NLS-1$
    }
    this.outputText = outputText;
  }

  /**
   * Returns the layout text. This text describes the prepare phases of the report processing.
   *
   * @return the layout text.
   */
  public String getLayoutText()
  {
    return layoutText;
  }

  /**
   * Defines the layout text message. This text describes the prepare phases of the report processing.
   *
   * @param layoutText the layout message.
   */
  public void setLayoutText(final String layoutText)
  {
    if (layoutText == null)
    {
      throw new NullPointerException(messages.getErrorString(
          "ReportProgressDialog.ERROR_0002_LAYOUT_TEXT_NULL")); //$NON-NLS-1$
    }
    this.layoutText = layoutText;
  }

  protected boolean isSameMaxRow(final int row)
  {
    return lastMaxRow == row;
  }

  public void reportProcessingStarted(final ReportProgressEvent event)
  {
    postUpdate(event);
  }

  public void reportProcessingUpdate(final ReportProgressEvent event)
  {
    postUpdate(event);
  }

  public void reportProcessingFinished(final ReportProgressEvent event)
  {
    postUpdate(event);
  }

  private void postUpdate(final ReportProgressEvent event)
  {
    synchronized (this.updateRunnable)
    {
      if (this.updateRunnable.update(event))
      {
        if (SwingUtilities.isEventDispatchThread())
        {
          this.updateRunnable.run();
        }
        else
        {
          SwingUtilities.invokeLater(this.updateRunnable);
        }
      }
    }
  }

  public void setVisibleInEDT(final boolean b)
  {
    if (SwingUtilities.isEventDispatchThread())
    {
      if (b)
      {
        setVisible(true);
      }
      else
      {
        setVisible(false);
      }
    }
    else
    {
      try
      {
        SwingUtilities.invokeAndWait(new ShowHideTask(this, b));
      }
      catch (Exception e)
      {
        // something has to be done!
        if (b)
        {
          setVisible(true);
        }
        else
        {
          setVisible(false);
        }
      }
    }
  }

  private static class ShowHideTask implements Runnable
  {
    private Dialog parent;
    private boolean visible;

    private ShowHideTask(final Dialog parent, final boolean visible)
    {
      this.parent = parent;
      this.visible = visible;
    }

    /**
     * When an object implementing interface <code>Runnable</code> is used to create a thread, starting the thread
     * causes the object's <code>run</code> method to be called in that separately executing thread.
     * <p/>
     * The general contract of the method <code>run</code> is that it may take any action whatsoever.
     *
     * @see Thread#run()
     */
    public void run()
    {
      if (visible)
      {
        parent.setVisible(true);
      }
      else
      {
        parent.setVisible(false);
      }
    }
  }

}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.modules.gui.commonswing.ReportProgressDialog$ScreenUpdateRunnable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.