Package kameleon.gui.view

Source Code of kameleon.gui.view.ViewGenerationMessage

/*
* Copyright (c) 2012, Fromentin Xavier, Schnell Michaël, Dervin Cyrielle, Brabant Quentin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*      * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*      * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*      * The names of its contributors may not be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Fromentin Xavier, Schnell Michaël, Dervin Cyrielle OR Brabant Quentin
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package kameleon.gui.view ;

import java.awt.Cursor;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

import kameleon.exception.FileReadingException;
import kameleon.exception.KameleonException;
import kameleon.gui.exception.UnknownKeyException;
import kameleon.gui.language.SwitchLanguage;
import kameleon.gui.model.FileModel;
import kameleon.gui.model.GenerationMessage;
import kameleon.gui.model.GenerationMessage.State;
import kameleon.gui.model.Message;
import kameleon.gui.model.Model;
import kameleon.gui.util.FileConstants;
import kameleon.gui.util.ImageUtility;
import kameleon.gui.util.LanguageConstants;

/**
* View displaying the progress of a file generation process. Displays the names
* of the source files and the target files. Also offers the possibility to re-run
* the generation process.
*
* @author    Schnell Michaël
* @version    1.0
*/
class ViewGenerationMessage extends ViewMessage
implements FileConstants, LanguageConstants {

  /**
   * Needed to serialize this class.
   *
   * @see    java.io.Serializable
   */
  private static final long serialVersionUID = -1477193510863283257L ;
 
  /**
   * Font used by file paths.
   */
  private final Font TRUETYPE = new Font(
      this.getFont().getName(), Font.TRUETYPE_FONT, this.getFont().getSize()) ;

  /**
   * Label displaying the title for the source file.
   */
  private JLabel convertingTitle ;

  /**
   * Labels displaying the title for every generated file.
   */
  private JLabel[] toTitles ;

  /**
   * Label displaying the status of the generation process.
   */
  private JLabel messageLabel ;

  /**
   * Button used to trigger the re-run of the generation process.
   */
  private JButton fastGeneration ;

  /**
   * Layout manager used by this component.
   */
  private GridBagLayout gridbag ;

  /**
   * Icons displaying the progress for every generated file.
   */
  private JLabel[] progressIcons ;

  /**
   * Sole constructor.
   *
   * @param   model
   *       model used by this view
   *
   * @param   message
   *       model backing the information about the displayed message
   *
   * @throws   FileReadingException
   *       If a format icon could not be loaded
   *
   * @throws   UnknownKeyException
   *       if an error occurred while updating the text of this view
   */
  public ViewGenerationMessage(Model model, final GenerationMessage message)
      throws FileReadingException, UnknownKeyException  {
    this(new GridBagLayout(), model, message) ;
  }// ViewGenerationMessage(Model, GenerationMessage)

  /**
   * Private constructor.
   *
   * @param  gridbag
   *       layout manager used by this instance
   *
   * @param   model
   *       model used by this view
   *
   * @param   message
   *       model backing the information about the displayed message
   *
   * @throws   FileReadingException
   *       If a format icon could not be loaded
   *
   * @throws   UnknownKeyException
   *       if an error occurred while updating the text of this view
   */
  private ViewGenerationMessage(GridBagLayout gridbag, Model model,
      final GenerationMessage message)
          throws FileReadingException, UnknownKeyException {
    super(model, message) ;
    this.gridbag = gridbag ;
    this.setLayout(this.gridbag) ;
    this.setBorder(BorderFactory.createTitledBorder(
        FileModel.DATE_FORMATTER.format(message.getLastGeneration()))) ;

    this.build(message) ;
  }// ViewGenerationMessage(GridBagLayout, Model, GenerationMessage)

  /**
   * Builds the content of this instance.
   *
   * @param   gMessage
   *       model backing the information about the displayed message
   *
   * @throws   FileReadingException
   *       If a format icon could not be loaded
   *
   * @throws   UnknownKeyException
   *       if an error occurred while updating the text of this view
   */
  private void build(final GenerationMessage gMessage)
    throws FileReadingException, UnknownKeyException {
    makeSourceRow(gMessage) ;
    makeSeparator() ;     
    makeTargetRows(gMessage) ;
    makeSeparator()
    makeMessageRow(gMessage) ;
   
    this.reloadLanguage() ;
  }// build(GenerationMessage)

  /**
   * Updates the model backing the information about the displayed message.
   *
   * @param  newMessage
   *       new content for the model
   *
   * @throws   UnknownKeyException
   *       if an error occurred while updating the text of this view
   */
  @Override
  public void updateMessage(final Message newMessage) throws UnknownKeyException {
    this.message = newMessage ;
    GenerationMessage gMessage = (GenerationMessage) newMessage ;
   
    // Update progress icons
    int rowIndex = 0 ;
    for(JLabel progressIcon : this.progressIcons) {
      try {
        this.initProgressIcon(progressIcon, gMessage.getState(rowIndex)) ;
      } catch (KameleonException ke) {
        this.model.displayDebugInformation(ke) ;
      }// try
      ++rowIndex ;
    }// for
   
    // Update message
    this.reloadLanguage() ;
   
    // Update generation date
    TitledBorder border = (TitledBorder) this.getBorder() ;
    border.setTitle(FileModel.DATE_FORMATTER.format(gMessage.getLastGeneration())) ;
  }// updateMessage(Message)

  /**
   * Builds the source row of this instance. Displays the name and format
   * of the source file for the matching generation process.
   *
   * @param  gMessage
   *       model backing the information about the displayed message
   */
  private void makeSourceRow(final GenerationMessage gMessage) {
    JLabel label ;
    GridBagConstraints constraints ;

    // -----
    this.convertingTitle = new JLabel() ;
    constraints = new GridBagConstraints() ;
    constraints.gridwidth = 2 ;
    constraints.anchor = GridBagConstraints.ABOVE_BASELINE_LEADING ;
    constraints.insets = new Insets(2, 2, 2, 2) ;
    constraints.weightx = 0.0 ;
    constraints.weighty = 0.0 ;
    this.add(this.convertingTitle) ;
    this.gridbag.setConstraints(this.convertingTitle, constraints) ;
   
    // -----
    try {
      label = new JLabel(new ImageIcon(
          ImageUtility.getImageBytes(String.format(
              MINI_ICON, gMessage.getIdFormat())))) ;
      label.setToolTipText(this.model.getAnalyzer(
          gMessage.getIdFormat()).getFormatName()) ;
      constraints = new GridBagConstraints() ;
      constraints.gridwidth = 1 ;
      constraints.anchor = GridBagConstraints.ABOVE_BASELINE_LEADING ;
      constraints.insets = new Insets(2, 2, 2, 2) ;
      constraints.weightx = 0.0 ;
      constraints.weighty = 0.0 ;
      this.add(label) ;
      this.gridbag.setConstraints(label, constraints) ;
    } catch(KameleonException ke) {
      this.model.displayDebugInformation(ke) ;
    }// try
   
    // -----
    label = new JLabel(gMessage.getPath()) ;
    label.setFont(this.TRUETYPE) ;
    constraints = new GridBagConstraints() ;
    constraints.gridwidth = GridBagConstraints.REMAINDER ;
    constraints.anchor = GridBagConstraints.ABOVE_BASELINE_LEADING ;
    constraints.insets = new Insets(2, 2, 2, 2) ;
    constraints.weightx = 1.0 ;
    constraints.weighty = 0.0 ;
    this.add(label) ;
    this.gridbag.setConstraints(label, constraints) ;
  }// makeSourceRow(GenerationMessage)

  /**
   * Builds the rows for every generated file. Displays the name, format
   * and generation state for each target file.
   *
   * @param  gMessage
   *       model backing the information about the displayed message
   *
   * @throws   FileReadingException
   *       If a format icon could not be loaded
   */
  private void makeTargetRows(final GenerationMessage gMessage)
      throws FileReadingException{
    String[] paths = gMessage.getTargetPath() ;
    String[] formatsIds = gMessage.getTargetFormatId() ;
    State[] states = gMessage.getStates() ;
    int nRows = paths.length ;
    this.toTitles = new JLabel[nRows] ;
    this.progressIcons = new JLabel[nRows] ;
    for(int row=0; row < nRows; ++row) {
      if ((paths[row] != null) && (formatsIds[row] != null)) {
        makeTargetRow(row, paths[row], formatsIds[row], states[row]) ;
      }// if
    }// for
  }// makeTargetRows(GenerationMessage)

  /**
   * Utility function, simply calls
   * <pre>makeRow(rowIndex, "To", path, formatId,
   * GridBagConstraints.ABOVE_BASELINE_TRAILING,
   * this.model.getGenerator(formatId).getFormatName(),
   * state) ;
   * </pre>
   * (the "To" is translated into the correct language.)
   *
   * @param   rowIndex
   *       index of the generated row
   *
   * @param   path
   *       path of the target file
   *
   * @param   formatId
   *       identifier of the format of the target file
   *
   * @param   state
   *       current state of the generation process for the target file
   *
   * @throws   FileReadingException
   *       If a format icon could not be loaded
   */
  private void makeTargetRow(int rowIndex, String path, String formatId, State state)
      throws FileReadingException {
    makeRow(rowIndex, "To", path, formatId, //$NON-NLS-1$
        GridBagConstraints.ABOVE_BASELINE_TRAILING,
        this.model.getGenerator(formatId).getFormatName(),
        state) ;
  }// makeTargetRow(int, String, String, State)

  /**
   * Builds a rowa for a generated file. Displays the name, format
   * and generation state using the given values.
   *
   * @param   rowIndex
   *       index of the generated row
   *
   * @param  title
   *       text displayed in the first column (title of the row)
   *
   * @param   path
   *       path of the target file
   *
   * @param   formatId
   *       identifier of the format of the target file
   *
   * @param  firstCellAnchor
   *       anchor used by this row
   *
   * @param  tooltip
   *       tool tip displayed when hovering the format icon
   *
   * @param   state
   *       current state of the generation process for the target file
   *
   * @throws   FileReadingException
   *       If a format icon could not be loaded
   */
  private void makeRow(int rowIndex, String title, String path, String formatId,
      int firstCellAnchor, String tooltip, State state)
          throws FileReadingException {
    JLabel label ;
    GridBagConstraints constraints ;

    // -----
    this.progressIcons[rowIndex] = this.makeProgressIcon(state) ;

    // -----
    label = new JLabel(title) ;
    constraints = new GridBagConstraints() ;
    constraints.gridwidth = 1 ;
    constraints.anchor = firstCellAnchor ;
    constraints.insets = new Insets(2, 2, 2, 2) ;
    constraints.weightx = 0.0 ;
    constraints.weighty = 0.0 ;
    this.add(label) ;
    this.gridbag.setConstraints(label, constraints) ;
    this.toTitles[rowIndex] = label ;

    // -----
    try {
      label = new JLabel(new ImageIcon(
          ImageUtility.getImageBytes(String.format(
              MINI_ICON, formatId)))) ;
      label.setToolTipText(tooltip) ;
      constraints = new GridBagConstraints() ;
      constraints.gridwidth = 1 ;
      constraints.anchor = GridBagConstraints.ABOVE_BASELINE_LEADING ;
      constraints.insets = new Insets(2, 2, 2, 2) ;
      constraints.weightx = 0.0 ;
      constraints.weighty = 0.0 ;
      this.add(label) ;
      this.gridbag.setConstraints(label, constraints) ;
    } catch(KameleonException ke) {
      this.model.displayDebugInformation(ke) ;
    }// try

    // -----
    label = new JLabel(path) ;
    label.setFont(this.TRUETYPE) ;
    constraints = new GridBagConstraints() ;
    constraints.gridwidth = GridBagConstraints.REMAINDER ;
    constraints.anchor = GridBagConstraints.ABOVE_BASELINE_LEADING ;
    constraints.insets = new Insets(2, 2, 2, 2) ;
    constraints.weightx = 1.0 ;
    constraints.weighty = 0.0 ;
    this.add(label) ;
    this.gridbag.setConstraints(label, constraints) ;
  }// makeRow(int, String, String, String, int, String, State)

  /**
   * Builds a message resuming the global state of the generation process
   * and a button to trigger a re-run of the generation process.
   *
   * @param  gMessage
   *       model backing the information about the current generation process
   *
   * @throws   FileReadingException
   *       If a format icon could not be loaded
   */
  private void makeMessageRow(final GenerationMessage gMessage)
      throws FileReadingException {
    GridBagConstraints constraints ;

    makeReGenerateButton(gMessage) ;

    this.messageLabel = new JLabel() ;
    constraints = new GridBagConstraints() ;
    constraints.gridwidth = GridBagConstraints.REMAINDER ;
    constraints.anchor = GridBagConstraints.ABOVE_BASELINE_LEADING ;
    constraints.weightx = 1.0 ;
    constraints.weighty = 0.0 ;
    this.add(this.messageLabel) ;
    this.gridbag.setConstraints(this.messageLabel, constraints) ;
  }// makeMessageRow(GenerationMessage)

  /**
   * Builds the button used to trigger a re-run of the generation process.
   *
   * @param   gMessage
   *       model backing the information about the current generation process
   *
   * @throws   FileReadingException
   *       If a format icon could not be loaded
   */
  private void makeReGenerateButton(final GenerationMessage gMessage)
      throws FileReadingException {
    GridBagConstraints constraints ;

    InputStream src = this.getClass().getResourceAsStream(REGENERATE_FILE) ;
    Icon refreshIcon = new ImageIcon(
        ImageUtility.getImageBytes(new BufferedInputStream(src))) ;
   
    final JButton button = new JButton(refreshIcon) ;
    button.setContentAreaFilled(false) ;
    button.setBorder(null) ;
    button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)) ;
    final Model fViewModel = this.model ;
    button.addActionListener(new ActionListener() {       
      @Override
      public void actionPerformed(ActionEvent e) {
        button.setEnabled(false) ;
        fViewModel.fastGeneration(gMessage) ;
      }// actionPerformed(ActionEvent)
    }) ;

    constraints = new GridBagConstraints() ;
    constraints.gridwidth = 2 ;
    constraints.anchor = GridBagConstraints.ABOVE_BASELINE_LEADING ;
    constraints.weightx = 0.0 ;
    constraints.weighty = 0.0 ;
    this.add(button) ;
    this.gridbag.setConstraints(button, constraints) ;

    this.fastGeneration = button ;
  }// makeReGenerateButton(GenerationMessage)

  /**
   * Builds an invisible separator row.
   */
  private void makeSeparator() {
    JPanel separator = new JPanel() ;
    GridBagConstraints constraints = new GridBagConstraints() ;
    constraints.gridwidth = GridBagConstraints.REMAINDER ;
    constraints.fill = GridBagConstraints.BOTH ;
    this.add(separator) ;
    this.gridbag.setConstraints(separator, constraints) ;
  }// makeSeparator()

  /**
   * Builds a progress icon for a given state.
   *
   * @param   state
   *       state used to determine the matching progress icon
   *
   * @return  A {@code JLabel} with the matching progress icon
   *
   * @throws   FileReadingException
   *       If a format icon could not be loaded
   */
  private JLabel makeProgressIcon(State state) throws FileReadingException {
    JLabel label = null ;
    GridBagConstraints constraints ;

    label = new JLabel() ;
    this.initProgressIcon(label, state) ;

    constraints = new GridBagConstraints() ;
    constraints.gridwidth = 1 ;
    constraints.anchor = GridBagConstraints.ABOVE_BASELINE ;
    constraints.insets = new Insets(2, 2, 2, 2) ;
    constraints.weightx = 0.0 ;
    constraints.weighty = 0.0 ;
    this.add(label) ;
    this.gridbag.setConstraints(label, constraints) ;

    return label ;
  }// makeProgressIcon(State)

  /**
   * Initializes the progress icon of the given label using the
   * given state.
   *
   * @param   label
   *       label that will contain the progress icon
   *
   * @param   state
   *       state used to determine the matching progress icon
   *
   * @throws   FileReadingException
   *       If a format icon could not be loaded
   */
  private void initProgressIcon(JLabel label, State state)
      throws FileReadingException {
    String icon = null ;
   
    switch(state) {
    case WAITING:
      icon = WAITING_FILE ;
      break ;
     
    case CONVERTING:
      icon = CONVERTING_FILE ;
      break ;

    case CONVERTED:
      icon = CONVERTED_FILE ;
      break ;

    case ERROR:
      icon = ERROR_FILE ;
    }// switch
   
    InputStream src = new BufferedInputStream(ViewGenerationMessage.class
        .getResourceAsStream(icon)) ;
    label.setIcon(new ImageIcon(
        ImageUtility.getImageBytes(src))) ;
    try {
      src.close() ;
    } catch(IOException ioe) {
      this.model.displayDebugInformation(
          new FileReadingException(ioe.getMessage())) ;
    }// try
  }// initProgressIcon(JLabel, State)

  /**
   * Enables or disables the regenerate button.
   */
  @Override
  public void update() {
    if (!this.fastGeneration.isEnabled() && this.model.generationFinished()) {
      this.fastGeneration.setEnabled(true) ;
    }// if
  }// update()

  /**
   * Updates the text to match the currently selected language.
   *
   * @throws   UnknownKeyException
   *       if an error occurred while updating the text of this view
   */
  @Override
  public void reloadLanguage() throws UnknownKeyException {
    SwitchLanguage sl = SwitchLanguage.getInstance() ;
    GenerationMessage gMessage = (GenerationMessage) this.message ;
   
    this.convertingTitle.setText(sl.getText(CONVERTING)) ;
    State[] states = gMessage.getStates() ;
    int nRows = states.length ;
    for(int row=0; row < nRows; ++row) {
      this.toTitles[row].setText(sl.getText(TO)) ;
      this.progressIcons[row].setToolTipText(
          sl.getText(getTextKey(states[row]))) ;
    }// for
    this.fastGeneration.setText(sl.getText(REGENERATE)) ;
    this.messageLabel.setText(this.getMessageText()) ;
  }// reloadLanguage()
 
  /**
   * Returns the language key used to describe the given state.
   *
   * @param   state
   *       state whose language key is requested
   *
   * @return  Language key for the given state
   */
  private static String getTextKey(State state) {
    switch(state) {
    case WAITING:    return STATE_WAITING ;
    case CONVERTING: return STATE_CONVERTING ;
    case CONVERTED:  return STATE_CONVERTED ;
    default: /* case ERROR */
    }// switch
    return STATE_ERROR ;
  }// getTextKey(State)
 
  /**
   * Returns a description for the current state of the generation process.
   *
   * @return  Description for the current state of the generation process
   *
   * @throws   UnknownKeyException
   *       if an error occurred while updating the text of this view
   */
  private String getMessageText() throws UnknownKeyException {
    SwitchLanguage sl = SwitchLanguage.getInstance() ;
    GenerationMessage gMessage = (GenerationMessage) this.message ;
    String textKey, filePath = null ;
    switch(gMessage.getState()) {
    case ANALYZING: {
      textKey = GENERATION_ANALYZING_START ;
      break ;
    }// case
    case GENERATING: {
      State[] states = gMessage.getStates() ;
      if (states[0].equals(State.WAITING)) {
        textKey = GENERATION_ANALYZING_SUCCESS ;
      } else {
        textKey = GENERATION_GENERATING ;
        int i = 0, nStates = states.length ;
        while((i < nStates) && (filePath == null)) {
          if (states[i].equals(State.CONVERTING)) {
            filePath = gMessage.getTargetPath()[i] ;
          }// if
          ++i ;
        }// while
      }// if
      break ;
    }// case
    case PARTIAL_SUCESS: {
      textKey = GENERATION_PARTIAL_SUCCESS ;
      break ;
    }// case
    case COMPLETE_SUCESS: {
      textKey = GENERATION_SUCCESS ;
      break ;
    }// clase
    default: {/* ERROR */
      textKey = GENERATION_ERROR ;
    }// default
    }// switch
   
    return sl.getText(textKey, filePath) ;
  }// getMessageText()

}// class ViewGenerationMessage
TOP

Related Classes of kameleon.gui.view.ViewGenerationMessage

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.