Package GUI

Source Code of GUI.SatedaTextPane

package GUI;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;

import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;

import Control.Contact;
import Control.DateFormatter;
import Control.Message;

/**
* Displays the outgoing or incoming {@link Message}s. If assigned as a {@link JTextPane} for the outgoing
* messages it only has to provide the possibility of writing in. Otherwise has to take {@link Message}s
* and display them properly, with a reference on the time and the corresponding user.
*
* @author Sebastian
*
*/
public class SatedaTextPane extends JTextPane implements MouseListener{

  /**
   * <code>true</code> when it is used as an outgoing {@link JTextPane}, <code>false</code> otherwise
   */
  private boolean outgoing;

  private StyledDocument styleDoc;

  /**
   * The {@link Style} of the text messages
   */
  private Style textStyle = new StyleContext().getStyle(StyleContext.DEFAULT_STYLE);

  /**
   * The style in which the name of the person writing the incoming message is displayed
   */
  private Style incomingStyle = new StyleContext().getStyle(StyleContext.DEFAULT_STYLE);

  /**
   * The style in which the name of the person sending the outgoing message is displayed
   */
  private Style outgoingStyle = new StyleContext().getStyle(StyleContext.DEFAULT_STYLE);

  /**
   * Is used to generate a little space between two lines of text
   */
  private Style littleSpaceStyle = new StyleContext().getStyle(StyleContext.DEFAULT_STYLE);

  /**
   * Is used to generate a bigger space between two lines of text
   */
  private Style biggerSpaceStyle = new StyleContext().getStyle(StyleContext.DEFAULT_STYLE);

  /**
   * The style used for the information about the start of the chat with a specific {@link Contact}
   */
  private Style startInformationStyle = new StyleContext().getStyle(StyleContext.DEFAULT_STYLE);
 
  /**
   * The list of all {@link Message}s to be displayed in case the pane shall display the history
   * of all incoming and outgoing messages
   */
  private ArrayList<Message> messages = new ArrayList<Message>();

  /**
   * Indicates when the chat with the current {@link Contact} was started
   */
  private Date dateChatStarted;

  public SatedaTextPane(boolean outgoing, Date dateChatStarted) {
    this.outgoing = outgoing;
    this.dateChatStarted = dateChatStarted;

   
    addMouseListener(this);
   
    if( ! outgoing){
      setEditable(false);
    }else{
      setFont(new Font("Verdana", Font.PLAIN, 12));
    }
   
    styleDoc = this.getStyledDocument();

    StyleConstants.setFontSize(textStyle, 12);
    StyleConstants.setFontFamily(textStyle, "Verdana");

    StyleConstants.setFontSize(incomingStyle, 12);
    StyleConstants.setFontFamily(incomingStyle, "Verdana");
    StyleConstants.setForeground(incomingStyle, new Color(230, 84, 4));

    StyleConstants.setFontSize(outgoingStyle, 12);
    StyleConstants.setFontFamily(outgoingStyle, "Verdana");
    StyleConstants.setForeground(outgoingStyle, new Color(96, 125, 193));

    StyleConstants.setFontSize(littleSpaceStyle, 1);

    StyleConstants.setFontSize(biggerSpaceStyle, 9);
   
    StyleConstants.setFontSize(startInformationStyle, 11);
    StyleConstants.setFontFamily(startInformationStyle, "Verdana");
    StyleConstants.setForeground(startInformationStyle, new Color(113, 124, 175));
  }

  /**
   * Deletes the reference on the current {@link Message}s, sets the forwarded one as current ones
   * and refreshes the appearance accordingly.
   *
   * All information displayed will disappear and be replaced by the new ones.
   *
   * @param messages
   */
  public void setMessages(ArrayList<Message> messages){
    if( ! outgoing){
      this.messages = messages;
      clearContent();
      if(messages.size() > 0){
        refreshAppearance();
      }
    }
  }

 
  /**
   * Adds a {@link Message} to the list of messages to be displayed. Then takes care
   * that the new message is added to the already displayed ones.
   *
   * @param message
   */
  public void addMessage(Message message){
    if( ! outgoing){
      messages.add(message);
      clearContent();
      refreshAppearance();
    }
  }


  private void clearContent(){

    try {
      styleDoc.remove(0, styleDoc.getLength());
    } catch (BadLocationException e) {
      e.printStackTrace();
    }
  }

  /**
   * Refreshes the appearance of the pane according to the list of {@link Message}s to be displayed.
   * Clears the pane first before inserting the {@link Message}s.
   */
  public void refreshAppearance(){

    boolean firstElement = true;
    boolean incomingOnFormer = false;
    boolean showHeader = true;
    Style headerStyle;

    try {

      String timeStarted = getDisplayedDate(dateChatStarted, true, false);
      DateFormatter formattedDate = new DateFormatter(dateChatStarted);

      styleDoc.insertString(styleDoc.getLength(), "Unterhaltung mit "
          + messages.get(0).getChatPartner().getDisplayedName() +" am "
          + formattedDate.getDay() + ". " + formattedDate.getMonthString()
          + " " + formattedDate.getYear() + " um "
          + timeStarted +" Uhr gestartet...", startInformationStyle);
      styleDoc.insertString(styleDoc.getLength(), "\n\n", biggerSpaceStyle);
      styleDoc.insertString(styleDoc.getLength(), "\n", littleSpaceStyle);

      for(Message message : messages){

        showHeader = true;

        if( ! firstElement && message.isIncoming() != incomingOnFormer){

          styleDoc.insertString(styleDoc.getLength(), "\n", biggerSpaceStyle);
        }else if( ! firstElement){

          if( ! isLongerOneMinute(message.getDate())){
            styleDoc.insertString(styleDoc.getLength(), "\n", littleSpaceStyle);
            styleDoc.insertString(styleDoc.getLength(), "\n", littleSpaceStyle);
            styleDoc.insertString(styleDoc.getLength(), "\n", littleSpaceStyle);
            showHeader = false;
          }else{
            styleDoc.insertString(styleDoc.getLength(), "\n", biggerSpaceStyle);           
          }
        }

        headerStyle = incomingStyle;
        incomingOnFormer = true;
        firstElement = false;

        if( ! message.isIncoming()){
          headerStyle = outgoingStyle;
          incomingOnFormer = false;
        }

        String date = getDisplayedDate(message.getDate(), false, false);

        if(showHeader){
          styleDoc.insertString(styleDoc.getLength(),
              message.getChatPartner().getDisplayedName() + " ("
              + date + ")\n", headerStyle);

          styleDoc.insertString(styleDoc.getLength(), "\n", littleSpaceStyle);
        }

        styleDoc.insertString(styleDoc.getLength(), message.getText() + "\n", textStyle);

      }
    } catch (BadLocationException e) {
      e.printStackTrace();
    }
  }


  /**
   * @param messageDate
   *
   * @return the forwarded {@link Date} according the way it shall be displayed behind the
   * chat contacts name. If the date is on the same day as today only the time itself gets displayed,
   * otherwise the day, month and year get added. That only is the case though when
   * <code>returnTime</code> and <code>completeDate</code> are both <code>false</code>.
   *
   * <p>In case <code>returnTime</code> is <code>true</code> only the time gets returned</p>
   * <p>In case <code>completeDate</code> is <code>true</code> the whole date gets returned</p>
   */
  public String getDisplayedDate(Date messageDate, boolean returnTime, boolean completeDate){

    DateFormatter formattedDate = new DateFormatter(messageDate);

    String date = formattedDate.getHour() + ":" + formattedDate.getMinutes();

    if(returnTime){
      return date;
    }
    if( (! isToday(messageDate)) || completeDate){
      String date2 = formattedDate.getDay() + ". " + formattedDate.getMonthString()
      + " " + formattedDate.getYear() + " - ";

      date = date2 + date;
    }

    return date;
  }


  /**
   *
   * @param date
   *
   * @return <code>true</code> in case the forwarded date indicates a time more distant than one
   * minute ago, <code>false</code> otherwise
   */
  public boolean isLongerOneMinute(Date date){

    Date now = new Date();

    if(now.getTime() - date.getTime() > 1000){
      return true;
    }
    return false;
  }


  /**
   * @param date
   *
   * @return <code>true</code> when the forwarded date is on the current day, <code>false</code> otherwise
   */
  private boolean isToday(Date date){

    DateFormatter today = new DateFormatter(new Date());
    DateFormatter forwarded = new DateFormatter(date);

    if(today.getYear() == forwarded.getYear() && today.getDay() == forwarded.getDay()
        && today.getMonth() == forwarded.getMonth()){
      return true;
    }
    return false;
  }

  @Override
  public void mouseClicked(MouseEvent e) {
    // TODO Auto-generated method stub
   
  }

  @Override
  public void mouseEntered(MouseEvent e) {
    setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
  }

  @Override
  public void mouseExited(MouseEvent e) {
    // TODO Auto-generated method stub
   
  }

  @Override
  public void mousePressed(MouseEvent e) {
    // TODO Auto-generated method stub
   
  }

  @Override
  public void mouseReleased(MouseEvent e) {
    // TODO Auto-generated method stub
   
  }
}
TOP

Related Classes of GUI.SatedaTextPane

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.