Package edu.wpi.cs.wpisuitetng.modules.defecttracker.defect

Source Code of edu.wpi.cs.wpisuitetng.modules.defecttracker.defect.DefectPanel

/*******************************************************************************
* Copyright (c) 2013 -- WPI Suite
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    Chris Casola
*    Andrew Hurle
*    JPage
******************************************************************************/

package edu.wpi.cs.wpisuitetng.modules.defecttracker.defect;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.HashSet;

import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SpringLayout;

import edu.wpi.cs.wpisuitetng.modules.core.models.User;
import edu.wpi.cs.wpisuitetng.modules.defecttracker.defect.comments.NewCommentPanel;
import edu.wpi.cs.wpisuitetng.modules.defecttracker.defect.defectevents.model.DefectEventListModel;
import edu.wpi.cs.wpisuitetng.modules.defecttracker.defect.defectevents.view.DefectEventListCellRenderer;
import edu.wpi.cs.wpisuitetng.modules.defecttracker.models.Defect;
import edu.wpi.cs.wpisuitetng.modules.defecttracker.models.DefectStatus;
import edu.wpi.cs.wpisuitetng.modules.defecttracker.models.Tag;

/**
* Panel to display the fields of a Defect and allow editing
*/
@SuppressWarnings({"serial"})
public class DefectPanel extends JPanel {
  public enum Mode {
    CREATE,
    EDIT;
  }

  /** The parent view **/
  protected DefectView parent;
 
  /** The Defect displayed in this panel */
  protected Defect model;

  /*
   * Form elements
   */
  protected JTextField txtTitle;
  protected JTextArea txtDescription;
  protected JComboBox cmbStatus;
  protected JLabel txtCreatedDate;
  protected JLabel txtModifiedDate;
  protected JTextField txtCreator;
  protected JTextField txtAssignee;
  protected JLabel lblCreatedDate;
  protected JLabel lblModifiedDate;
 
  /** The panel containing GUI components for adding tags to defects */
  protected TagPanel tagPanel;
 
  /** A JList containing the change history for the defect */
  protected JList changeSetsList;
 
  /** The data model for the ChangeSet list */
  protected DefectEventListModel defectEventListModel;
 
  /** A panel containing GUI components for adding comments to the defect */
  protected NewCommentPanel commentPanel;
 
  /** The layout manager for this panel */
  protected SpringLayout layout;
 
  /*
   * Listeners for the form fields
   */
  protected final TextUpdateListener txtTitleListener;
  protected final TextUpdateListener txtDescriptionListener;
  protected final ComboUpdateListener cmbStatusListener;
  protected final TextUpdateListener txtCreatorListener;
  protected final TextUpdateListener txtAssigneeListener;

  /** A flag indicating if input is enabled on the form */
  protected boolean inputEnabled;
 
  /** An enum indicating if the form is in create mode or edit mode */
  protected Mode editMode;

  /*
   * Constants used to layout the form
   */
  protected static final int HORIZONTAL_PADDING = 5;
  protected static final int VERTICAL_PADDING = 15;
  protected static final int LABEL_ALIGNMENT = JLabel.TRAILING;

  /**
   * Constructs a DefectPanel for creating or editing a given Defect.
   *
   * @param parent  The parent DefectView.
   * @param defect  The Defect to edit.
   * @param mode    Whether or not the given Defect should be treated as if it already exists
   *           on the server ({@link Mode#EDIT}) or not ({@link Mode#CREATE}).
   */
  public DefectPanel(DefectView parent, Defect defect, Mode mode) {
    this.parent = parent;
    this.model = defect;
    editMode = mode;
   
    // Indicate that input is enabled
    inputEnabled = true;

    // Use a SpringLayout manager
    layout = new SpringLayout();
    this.setLayout(layout);

    // Add all components to this panel
    addComponents();

    // Add TextUpdateListeners. These check if the text component's text differs from the panel's Defect
    // model and highlights them accordingly every time a key is pressed.
    txtTitleListener = new TextUpdateListener(this, txtTitle);
    txtTitle.addKeyListener(txtTitleListener);

    txtDescriptionListener = new TextUpdateListener(this, txtDescription);
    txtDescription.addKeyListener(txtDescriptionListener);
   
    cmbStatusListener = new ComboUpdateListener(this, cmbStatus);
    cmbStatus.addItemListener(cmbStatusListener);

    txtCreatorListener = new TextUpdateListener(this, txtCreator);
    txtCreator.addKeyListener(txtCreatorListener);

    txtAssigneeListener = new TextUpdateListener(this, txtAssignee);
    txtAssignee.addKeyListener(txtAssigneeListener);
   
    // prevent tab key from inserting tab characters into the description field
    txtDescription.addKeyListener(new KeyAdapter() {
      @Override
      public void keyPressed(KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.VK_TAB) {
          if (event.getModifiers() == 0) {
            txtDescription.transferFocus();
          }
          else {
            txtDescription.transferFocusBackward();
          }
          event.consume();
        }
      }
    });
   
    // Populate the form with the contents of the Defect model and update the TextUpdateListeners.
    updateFields();
  }

  /**
   * Adds the components to the panel and places constraints on them
   * for the SpringLayout manager.
   * @param layout the layout manager
   */
  protected void addComponents() {
    // Construct all of the components for the form
    txtTitle = new JTextField(50);
    txtDescription = new JTextArea();
    txtDescription.setLineWrap(true);
    txtDescription.setWrapStyleWord(true);
    txtDescription.setBorder(txtTitle.getBorder());
    String[] defectStatusValues = new String[DefectStatus.values().length];
    for (int i = 0; i < DefectStatus.values().length; i++) {
      defectStatusValues[i] = DefectStatus.values()[i].toString();
    }
    cmbStatus = new JComboBox(defectStatusValues);
    txtCreatedDate = new JLabel();
    txtModifiedDate = new JLabel("");
    txtCreator = new JTextField(20);
    txtCreator.setEnabled(false);
    txtAssignee = new JTextField(20);
   
    // Construct the tab panel
    tagPanel = new TagPanel(model);
    commentPanel = new NewCommentPanel(getModel(), this);
    defectEventListModel = new DefectEventListModel(getModel());
    changeSetsList = new JList(defectEventListModel);
    changeSetsList.setCellRenderer(new DefectEventListCellRenderer());
   
    if (editMode == Mode.CREATE) {
      cmbStatus.setEnabled(false);
      commentPanel.setInputEnabled(false);
    }

    // Set text component names. These names correspond to method names in the Defect model (ex: "Title" => Defect#getTitle()).
    // These are required for TextUpdateListener to be able to get the correct field from panel's Defect model.
    txtTitle.setName("Title");
    txtDescription.setName("Description");
    cmbStatus.setName("Status");
    txtCreator.setName("Creator");
    txtAssignee.setName("Assignee");
   
    // set maximum widths of components so they are not stretched
    txtTitle.setMaximumSize(txtTitle.getPreferredSize());
    cmbStatus.setMaximumSize(cmbStatus.getPreferredSize());
    txtCreator.setMaximumSize(txtCreator.getPreferredSize());
    txtAssignee.setMaximumSize(txtAssignee.getPreferredSize());
    tagPanel.setMaximumSize(tagPanel.getPreferredSize());

    // Construct labels for the form fields
    JLabel lblTitle = new JLabel("Title:", LABEL_ALIGNMENT);
    JLabel lblDescription = new JLabel("Description:", LABEL_ALIGNMENT);
    JLabel lblStatus = new JLabel("Status:", LABEL_ALIGNMENT);
    lblCreatedDate = new JLabel("", LABEL_ALIGNMENT);
    lblModifiedDate = new JLabel("", LABEL_ALIGNMENT);
    JLabel lblCreator = new JLabel("Creator:", LABEL_ALIGNMENT);
    JLabel lblAssignee = new JLabel("Assignee:", LABEL_ALIGNMENT);

    int labelWidth = lblDescription.getPreferredSize().width;

    // Setup all of the spring constraints
    layout.putConstraint(SpringLayout.NORTH, lblTitle, VERTICAL_PADDING, SpringLayout.NORTH, this);
    layout.putConstraint(SpringLayout.WEST, lblTitle, 15, SpringLayout.WEST, this);
    layout.putConstraint(SpringLayout.EAST, lblTitle, labelWidth, SpringLayout.WEST, lblTitle);
    layout.putConstraint(SpringLayout.VERTICAL_CENTER, txtTitle, 0, SpringLayout.VERTICAL_CENTER, lblTitle);
    layout.putConstraint(SpringLayout.WEST, txtTitle, HORIZONTAL_PADDING, SpringLayout.EAST, lblTitle);
    layout.putConstraint(SpringLayout.EAST, txtTitle, txtTitle.getPreferredSize().width, SpringLayout.WEST, txtTitle);

    layout.putConstraint(SpringLayout.NORTH, txtDescription, VERTICAL_PADDING, SpringLayout.SOUTH, txtTitle);
    layout.putConstraint(SpringLayout.VERTICAL_CENTER, lblDescription, 0, SpringLayout.VERTICAL_CENTER, txtDescription);
    layout.putConstraint(SpringLayout.WEST, lblDescription, 0, SpringLayout.WEST, lblTitle);
    layout.putConstraint(SpringLayout.EAST, lblDescription, labelWidth, SpringLayout.WEST, lblDescription);
    layout.putConstraint(SpringLayout.WEST, txtDescription, HORIZONTAL_PADDING, SpringLayout.EAST, lblDescription);
    layout.putConstraint(SpringLayout.EAST, txtDescription, 0, SpringLayout.EAST, txtTitle);
    layout.putConstraint(SpringLayout.SOUTH, txtDescription, txtTitle.getPreferredSize().height * 4, SpringLayout.NORTH, txtDescription);

    layout.putConstraint(SpringLayout.NORTH, cmbStatus, VERTICAL_PADDING, SpringLayout.SOUTH, txtDescription);
    layout.putConstraint(SpringLayout.VERTICAL_CENTER, lblStatus, 0, SpringLayout.VERTICAL_CENTER, cmbStatus);
    layout.putConstraint(SpringLayout.WEST, lblStatus, 0, SpringLayout.WEST, lblTitle);
    layout.putConstraint(SpringLayout.EAST, lblStatus, labelWidth, SpringLayout.WEST, lblStatus);
    layout.putConstraint(SpringLayout.WEST, cmbStatus, HORIZONTAL_PADDING, SpringLayout.EAST, lblStatus);
   
    layout.putConstraint(SpringLayout.NORTH, txtCreatedDate, VERTICAL_PADDING, SpringLayout.SOUTH, cmbStatus);
    layout.putConstraint(SpringLayout.VERTICAL_CENTER, lblCreatedDate, 0, SpringLayout.VERTICAL_CENTER, txtCreatedDate);
    layout.putConstraint(SpringLayout.WEST, lblCreatedDate, 0, SpringLayout.WEST, lblTitle);
    layout.putConstraint(SpringLayout.EAST, lblCreatedDate, labelWidth, SpringLayout.WEST, lblCreatedDate);
    layout.putConstraint(SpringLayout.WEST, txtCreatedDate, HORIZONTAL_PADDING, SpringLayout.EAST, lblCreatedDate);
   
    layout.putConstraint(SpringLayout.NORTH, txtModifiedDate, VERTICAL_PADDING, SpringLayout.SOUTH, txtCreatedDate);
    layout.putConstraint(SpringLayout.VERTICAL_CENTER, lblModifiedDate, 0, SpringLayout.VERTICAL_CENTER, txtModifiedDate);
    layout.putConstraint(SpringLayout.WEST, lblModifiedDate, 0, SpringLayout.WEST, lblTitle);
    layout.putConstraint(SpringLayout.EAST, lblModifiedDate, labelWidth, SpringLayout.WEST, lblModifiedDate);
    layout.putConstraint(SpringLayout.WEST, txtModifiedDate, HORIZONTAL_PADDING, SpringLayout.EAST, lblModifiedDate);
   
    layout.putConstraint(SpringLayout.NORTH, txtCreator, VERTICAL_PADDING, SpringLayout.SOUTH, txtModifiedDate);
    layout.putConstraint(SpringLayout.VERTICAL_CENTER, lblCreator, 0, SpringLayout.VERTICAL_CENTER, txtCreator);
    layout.putConstraint(SpringLayout.WEST, lblCreator, 0, SpringLayout.WEST, lblTitle);
    layout.putConstraint(SpringLayout.EAST, lblCreator, labelWidth, SpringLayout.WEST, lblCreator);
    layout.putConstraint(SpringLayout.WEST, txtCreator, HORIZONTAL_PADDING, SpringLayout.EAST, lblCreator);

    layout.putConstraint(SpringLayout.NORTH, txtAssignee, VERTICAL_PADDING, SpringLayout.SOUTH, txtCreator);
    layout.putConstraint(SpringLayout.VERTICAL_CENTER, lblAssignee, 0, SpringLayout.VERTICAL_CENTER, txtAssignee);
    layout.putConstraint(SpringLayout.WEST, lblAssignee, 0, SpringLayout.WEST, lblTitle);
    layout.putConstraint(SpringLayout.EAST, lblAssignee, labelWidth, SpringLayout.WEST, lblAssignee);
    layout.putConstraint(SpringLayout.WEST, txtAssignee, HORIZONTAL_PADDING, SpringLayout.EAST, lblAssignee);

    layout.putConstraint(SpringLayout.NORTH, tagPanel, VERTICAL_PADDING * 3, SpringLayout.NORTH, txtAssignee);
    layout.putConstraint(SpringLayout.WEST, tagPanel, 0, SpringLayout.WEST, lblTitle);
    layout.putConstraint(SpringLayout.EAST, tagPanel, 0, SpringLayout.EAST, txtTitle);
   
   
    layout.putConstraint(SpringLayout.NORTH, changeSetsList, VERTICAL_PADDING, SpringLayout.SOUTH, tagPanel);
    layout.putConstraint(SpringLayout.WEST, changeSetsList, 0, SpringLayout.WEST, lblTitle);
    layout.putConstraint(SpringLayout.EAST, changeSetsList, 0, SpringLayout.EAST, txtTitle);
   
    layout.putConstraint(SpringLayout.NORTH, commentPanel, VERTICAL_PADDING, SpringLayout.SOUTH, changeSetsList);
    layout.putConstraint(SpringLayout.WEST, commentPanel, 0, SpringLayout.WEST, lblTitle);
    layout.putConstraint(SpringLayout.EAST, commentPanel, 0, SpringLayout.EAST, txtTitle);
    layout.putConstraint(SpringLayout.SOUTH, this, VERTICAL_PADDING, SpringLayout.SOUTH, commentPanel);

    // Add all of the components to this panel
    add(lblTitle);
    add(txtTitle);
    add(lblDescription);
    add(txtDescription);
    add(lblStatus);
    add(cmbStatus);
    add(lblCreatedDate);
    add(txtCreatedDate);
    add(lblModifiedDate);
    add(txtModifiedDate);
    add(lblCreator);
    add(txtCreator);
    add(lblAssignee);
    add(txtAssignee);
    add(tagPanel);
    add(changeSetsList);
    add(commentPanel);
  }

  /**
   * Sets whether input is enabled for this panel and its children. This should be used instead of
   * JComponent#setEnabled because setEnabled does not affect its children.
   *
   * @param enabled  Whether or not input is enabled.
   */
  protected void setInputEnabled(boolean enabled) {
    inputEnabled = enabled;

    txtTitle.setEnabled(enabled);
    txtDescription.setEnabled(enabled);
    cmbStatus.setEnabled(enabled);
    txtAssignee.setEnabled(enabled);
    tagPanel.setInputEnabled(enabled);
    commentPanel.setInputEnabled(enabled);
  }
 
  /**
   * Updates the DefectPanel's model to contain the values of the given Defect and sets the
   * DefectPanel's editMode to {@link Mode#EDIT}.
   *
   * @param defect  The Defect which contains the new values for the model.
   */
  protected void updateModel(Defect defect) {
    updateModel(defect, Mode.EDIT);
  }

  /**
   * Updates the DefectPanel's model to contain the values of the given Defect.
   *
   * @param  defect  The Defect which contains the new values for the model.
   * @param  mode  The new editMode.
   */
  protected void updateModel(Defect defect, Mode mode) {
    editMode = mode;
   
    model.setId(defect.getId());
    model.setTitle(defect.getTitle());
    model.setDescription(defect.getDescription());
    model.setAssignee(defect.getAssignee());
    model.setCreator(defect.getCreator());
    model.setCreationDate(defect.getCreationDate());
    model.setLastModifiedDate(defect.getLastModifiedDate());
    model.setStatus(defect.getStatus());
    tagPanel.updateModel(defect);
   
    updateFields();
    defectEventListModel.update(defect);
    this.revalidate();
    layout.invalidateLayout(this);
    layout.layoutContainer(this);
    this.repaint();
    parent.refreshScrollPane();
  }
 
  /**
   * Updates the DefectPanel's fields to match those in the current model.
   */
  private void updateFields() {
    txtTitle.setText(model.getTitle());
    txtDescription.setText(model.getDescription());
    for (int i = 0; i < cmbStatus.getItemCount(); i++) {
      if (model.getStatus() == DefectStatus.valueOf((String) cmbStatus.getItemAt(i))) {
        cmbStatus.setSelectedIndex(i);
      }
    }
    if (editMode == Mode.EDIT) {
      lblCreatedDate.setText("Created:");
      txtCreatedDate.setText(model.getCreationDate().toString());

      lblModifiedDate.setText("Modified:");
      txtModifiedDate.setText(model.getLastModifiedDate().toString());
    }
    if (model.getCreator() != null) {
      txtCreator.setText(model.getCreator().getUsername());
    }
    if (model.getAssignee() != null) {
      txtAssignee.setText(model.getAssignee().getUsername());
    }
   
    txtTitleListener.checkIfUpdated();
    txtDescriptionListener.checkIfUpdated();
    cmbStatusListener.checkIfUpdated();
    txtCreatorListener.checkIfUpdated();
    txtAssigneeListener.checkIfUpdated();
  }

  /**
   * Returns a boolean representing whether or not input is enabled for the DefectPanel and its children.
   *
   * @return  A boolean representing whether or not input is enabled for the DefectPanel and its children.
   */
  public boolean getInputEnabled() {
    return inputEnabled;
  }

  /**
   * Gets the DefectPanel's internal model.
   * @return
   */
  public Defect getModel() {
    return model;
  }
 
  /**
   * Returns the parent DefectView.
   *
   * @return the parent DefectView.
   */
  public DefectView getParent() {
    return parent;
  }

  /**
   * Returns the edit {@link Mode} for this DefectPanel.
   *
   * @return  The edit {@link Mode} for this DefectPanel.
   */
  public Mode getEditMode() {
    return editMode;
  }

  /**
   * Returns the model object represented by this view's fields.
   *
   * TODO: Do some basic input verification
   * @return the model represented by this view
   */
  public Defect getEditedModel() {
    Defect defect = new Defect();
    defect.setId(model.getId());
    defect.setTitle(txtTitle.getText());
    defect.setDescription(txtDescription.getText());
    defect.setStatus(DefectStatus.valueOf((String) cmbStatus.getSelectedItem()));
    if (!(txtAssignee.getText().equals(""))) {
      defect.setAssignee(new User("", txtAssignee.getText(), "", -1));
    }
    if (!(txtCreator.getText().equals(""))) {
      defect.setCreator(new User("", txtCreator.getText(), "", -1));
    }
    HashSet<Tag> tags = new HashSet<Tag>();
    for (int i = 0; i < tagPanel.lmTags.getSize(); i++) {
      tags.add(new Tag((String)tagPanel.lmTags.get(i)));
    }
    defect.setTags(tags);
   
    return defect;
  }

  /**
   * Returns the creator text field
   * @return the creator text field
   */
  public JTextField getCreatorField() {
    return txtCreator;
  }
 
  /**
   * Returns the list model for the list of DefectChangesets
   * @return the list model for the list of DefectChangesets
   */
  public DefectEventListModel getDefectEventListModel() {
    return defectEventListModel;
  }
}
TOP

Related Classes of edu.wpi.cs.wpisuitetng.modules.defecttracker.defect.DefectPanel

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.