chatarea.java.svn-base

来自「开源项目openfire的完整源程序」· SVN-BASE 代码 · 共 703 行 · 第 1/2 页

SVN-BASE
703
字号
/**
 * $Revision: $
 * $Date: $
 *
 * Copyright (C) 2006 Jive Software. All rights reserved.
 *
 * This software is published under the terms of the GNU Lesser Public License (LGPL),
 * a copy of which is included in this distribution.
 */

package org.jivesoftware.spark.ui;

import org.jivesoftware.Spark;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.plugin.ContextMenuListener;
import org.jivesoftware.spark.util.BrowserLauncher;
import org.jivesoftware.spark.util.ModelUtil;
import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.plugin.emoticons.EmoticonManager;
import org.jivesoftware.sparkimpl.settings.local.LocalPreferences;
import org.jivesoftware.sparkimpl.settings.local.SettingsManager;

import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

/**
 * The ChatArea class handles proper chat text formatting such as url handling. Use ChatArea for proper
 * formatting of bold, italics, underlined and urls.
 */
public class ChatArea extends JTextPane implements MouseListener, MouseMotionListener, ActionListener {
    /**
     * The SimpleAttributeSet used within this instance of JTextPane.
     */
    public final SimpleAttributeSet styles = new SimpleAttributeSet();

    /**
     * The default Hand cursor.
     */
    public static final Cursor HAND_CURSOR = new Cursor(Cursor.HAND_CURSOR);

    /**
     * The default Text Cursor.
     */
    public static final Cursor DEFAULT_CURSOR = new Cursor(Cursor.DEFAULT_CURSOR);

    /**
     * The currently selected Font Family to use.
     */
    private String fontFamily;

    /**
     * The currently selected Font Size to use.
     */
    private int fontSize;

    private List contextMenuListener = new ArrayList();

    private JPopupMenu popup;


    private JMenuItem cutMenu;
    private JMenuItem copyMenu;
    private JMenuItem pasteMenu;
    private JMenuItem selectAll;

    private List interceptors = new ArrayList();

    private EmoticonManager emoticonManager;

    /**
     * ChatArea Constructor.
     */
    public ChatArea() {
        emoticonManager = EmoticonManager.getInstance();

        // Set Default Font
        final LocalPreferences pref = SettingsManager.getLocalPreferences();
        int fs = pref.getChatRoomFontSize();
        fontSize = fs;
        setFontSize(fs);


        cutMenu = new JMenuItem("Cut");
        cutMenu.addActionListener(this);

        copyMenu = new JMenuItem("Copy");
        copyMenu.addActionListener(this);

        pasteMenu = new JMenuItem("Paste");
        pasteMenu.addActionListener(this);

        selectAll = new JMenuItem("Select All");
        selectAll.addActionListener(this);

        // Set Default Font
        setFont(new Font("Dialog", Font.PLAIN, 12));


        getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("Ctrl x"), "cut");

        getActionMap().put("cut", new AbstractAction("cut") {
            public void actionPerformed(ActionEvent evt) {
                cutAction();
            }
        });

        getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("Ctrl c"), "copy");

        getActionMap().put("copy", new AbstractAction("copy") {
            public void actionPerformed(ActionEvent evt) {
                SparkManager.setClipboard(getSelectedText());
            }
        });

        getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("Ctrl v"), "paste");

        getActionMap().put("paste", new AbstractAction("paste") {
            public void actionPerformed(ActionEvent evt) {
                pasteAction();
            }
        });

    }

    /**
     * Set the current text of the ChatArea.
     *
     * @param message inserts the text directly into the ChatArea
     */
    public void setText(String message) {
        // By default, use the hand cursor for link selection
        // and scrolling.
        setCursor(HAND_CURSOR);

        // Make sure the message is not null.
        //  message = message.trim();
        message = message.replaceAll("/\"", "");
        if (ModelUtil.hasLength(message)) {
            try {
                insert(message);
            }
            catch (BadLocationException e) {
                Log.error(e);
            }
        }
    }

    /**
     * Clear the current document. This will remove all text and element
     * attributes such as bold, italics, and underlining. Note that the font family  and
     * font size will be persisted.
     */
    public void clear() {
        super.setText("");
        if (fontFamily != null) {
            setFont(fontFamily);
        }

        if (fontSize != 0) {
            setFontSize(fontSize);
        }

        StyleConstants.setUnderline(styles, false);
        StyleConstants.setBold(styles, false);
        StyleConstants.setItalic(styles, false);
        setCharacterAttributes(styles, false);
    }


    /**
     * Does the actual insertion of text, adhering to the styles
     * specified during message creation in either the thin or thick client.
     *
     * @param text - the text to insert.
     * @throws BadLocationException
     */
    public void insert(String text) throws BadLocationException {
        boolean bold = false;
        boolean italic = false;
        boolean underlined = false;


        final StringTokenizer tokenizer = new StringTokenizer(text, " \n \t,", true);
        while (tokenizer.hasMoreTokens()) {
            String textFound = tokenizer.nextToken();
            if (textFound.startsWith("http://") || textFound.startsWith("ftp://")
                    || textFound.startsWith("https://") || textFound.startsWith("www.") ||
                    textFound.startsWith("\\") || textFound.indexOf("://") != -1) {
                insertLink(textFound);
            }
            else if (!insertImage(textFound)) {
                insertText(textFound);
            }
        }

        // By default, always have decorations off.
        StyleConstants.setBold(styles, bold);
        StyleConstants.setItalic(styles, italic);
        StyleConstants.setUnderline(styles, underlined);
    }

    /**
     * Inserts text into the current document.
     *
     * @param text the text to insert
     * @throws BadLocationException
     */
    public void insertText(String text) throws BadLocationException {
        final Document doc = getDocument();
        styles.removeAttribute("link");
        doc.insertString(doc.getLength(), text, styles);
    }

    /**
     * Inserts text into the current document.
     *
     * @param text  the text to insert
     * @param color the color of the text
     * @throws BadLocationException
     */
    public void insertText(String text, Color color) throws BadLocationException {
        final Document doc = getDocument();
        StyleConstants.setForeground(styles, color);
        doc.insertString(doc.getLength(), text, styles);
    }

    /**
     * Inserts a link into the current document.
     *
     * @param link - the link to insert( ex. http://www.javasoft.com )
     * @throws BadLocationException
     */
    public void insertLink(String link) throws BadLocationException {
        final Document doc = getDocument();
        styles.addAttribute("link", link);

        StyleConstants.setForeground(styles, (Color)UIManager.get("Link.foreground"));
        StyleConstants.setUnderline(styles, true);
        doc.insertString(doc.getLength(), link, styles);
        StyleConstants.setUnderline(styles, false);
        StyleConstants.setForeground(styles, (Color)UIManager.get("TextPane.foreground"));
        styles.removeAttribute("link");
        setCharacterAttributes(styles, false);

    }

    /**
     * Inserts an emotion icon into the current document.
     *
     * @param imageKey - the smiley representation of the image.( ex. :) )
     * @return true if the image was found, otherwise false.
     */
    public boolean insertImage(String imageKey) {
        final Document doc = getDocument();
        Icon emotion = emoticonManager.getEmoticonImage(imageKey.toLowerCase());
        if (emotion == null) {
            return false;
        }

        setEditable(true);
        select(doc.getLength(), doc.getLength());
        insertIcon(emotion);
        setEditable(false);

        return true;
    }

    /**
     * Sets the current element to be either bold or not depending
     * on the current state. If the element is currently set as bold,
     * it will be set to false, and vice-versa.
     */
    public void setBold() {
        final Element element = getStyledDocument().getCharacterElement(getCaretPosition() - 1);
        if (element != null) {
            AttributeSet as = element.getAttributes();
            boolean isBold = StyleConstants.isBold(as);
            StyleConstants.setBold(styles, !isBold);
            try {
                setCharacterAttributes(styles, true);
            }
            catch (Exception ex) {
                Log.error("Error settings bold:", ex);
            }
        }
    }

    /**
     * Sets the current element to be either italicized or not depending
     * on the current state. If the element is currently set as italic,
     * it will be set to false, and vice-versa.
     */
    public void setItalics() {
        final Element element = getStyledDocument().getCharacterElement(getCaretPosition() - 1);
        if (element != null) {
            AttributeSet as = element.getAttributes();
            boolean isItalic = StyleConstants.isItalic(as);
            StyleConstants.setItalic(styles, !isItalic);
            try {
                setCharacterAttributes(styles, true);
            }
            catch (Exception fontException) {
                Log.error("Error settings italics:", fontException);
            }
        }
    }

    /**
     * Sets the current document to be either underlined or not depending
     * on the current state. If the element is currently set as underlined,
     * it will be set to false, and vice-versa.
     */
    public void setUnderlined() {
        final Element element = getStyledDocument().getCharacterElement(getCaretPosition() - 1);
        if (element != null) {
            AttributeSet as = element.getAttributes();
            boolean isUnderlined = StyleConstants.isUnderline(as);
            StyleConstants.setUnderline(styles, !isUnderlined);
            try {
                setCharacterAttributes(styles, true);
            }
            catch (Exception underlineException) {
                Log.error("Error settings underline:", underlineException);
            }
        }
    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?