chatroom.java
来自「开源项目openfire的完整源程序」· Java 代码 · 共 1,006 行 · 第 1/3 页
JAVA
1,006 行
/**
* $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.resource.Res;
import org.jivesoftware.resource.SparkRes;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.spark.ChatAreaSendField;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.component.BackgroundPanel;
import org.jivesoftware.spark.component.RolloverButton;
import org.jivesoftware.spark.plugin.ContextMenuListener;
import org.jivesoftware.spark.util.GraphicUtils;
import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.settings.local.LocalPreferences;
import org.jivesoftware.sparkimpl.settings.local.SettingsManager;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* The base implementation of all ChatRoom conversations. You would implement this class to have most types of Chat.
*/
public abstract class ChatRoom extends BackgroundPanel implements ActionListener, PacketListener, DocumentListener, ConnectionListener, FocusListener, ContextMenuListener {
private final JPanel chatPanel;
private final JSplitPane splitPane;
private JSplitPane verticalSplit;
private final JLabel notificationLabel;
private final TranscriptWindow transcriptWindow;
private final ChatAreaSendField chatAreaButton;
private final ChatToolBar toolbar;
private final JScrollPane textScroller;
private final JPanel bottomPanel;
private final JPanel editorBar;
private JPanel chatWindowPanel;
private int unreadMessageCount;
private boolean mousePressed;
private List<ChatRoomClosingListener> closingListeners = new CopyOnWriteArrayList<ChatRoomClosingListener>();
private ChatRoomTransferHandler transferHandler;
private final List<String> packetIDList;
private final List<MessageListener> messageListeners;
private List<Message> transcript;
private List<FileDropListener> fileDropListeners;
private MouseAdapter transcriptWindowMouseListener;
private KeyAdapter chatEditorKeyListener;
/**
* Initializes the base layout and base background color.
*/
protected ChatRoom() {
chatPanel = new JPanel(new GridBagLayout());
transcriptWindow = new TranscriptWindow();
splitPane = new JSplitPane();
packetIDList = new ArrayList<String>();
notificationLabel = new JLabel();
toolbar = new ChatToolBar();
bottomPanel = new JPanel();
messageListeners = new ArrayList<MessageListener>();
transcript = new ArrayList<Message>();
editorBar = new JPanel(new FlowLayout(FlowLayout.LEFT, 1, 1));
fileDropListeners = new ArrayList<FileDropListener>();
transcriptWindowMouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
getChatInputEditor().requestFocus();
}
public void mouseReleased(MouseEvent e) {
if (transcriptWindow.getSelectedText() == null) {
getChatInputEditor().requestFocus();
}
}
};
transcriptWindow.addMouseListener(transcriptWindowMouseListener);
chatAreaButton = new ChatAreaSendField(SparkRes.getString(SparkRes.SEND));
/*{
public Dimension getPreferredSize() {
Dimension dim = super.getPreferredSize();
int windowHeight = getChatRoom().getHeight();
if (dim.getHeight() > windowHeight - 200) {
dim.height = windowHeight - 200;
}
return dim;
}
};
*/
textScroller = new JScrollPane(transcriptWindow);
textScroller.setBackground(transcriptWindow.getBackground());
textScroller.getViewport().setBackground(Color.white);
transcriptWindow.setBackground(Color.white);
getChatInputEditor().setSelectedTextColor((Color)UIManager.get("ChatInput.SelectedTextColor"));
getChatInputEditor().setSelectionColor((Color)UIManager.get("ChatInput.SelectionColor"));
init();
// Initally, set the right pane to null to keep it empty.
getSplitPane().setRightComponent(null);
notificationLabel.setIcon(SparkRes.getImageIcon(SparkRes.BLANK_IMAGE));
getTranscriptWindow().addContextMenuListener(this);
transferHandler = new ChatRoomTransferHandler(this);
getTranscriptWindow().setTransferHandler(transferHandler);
getChatInputEditor().setTransferHandler(transferHandler);
add(toolbar, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
// Add Connection Listener
SparkManager.getConnection().addConnectionListener(this);
// Add Focus Listener
addFocusListener(this);
}
// Setup base layout.
private void init() {
setLayout(new GridBagLayout());
// Remove Default Beveled Borders
splitPane.setBorder(null);
splitPane.setOneTouchExpandable(false);
// Add Vertical Split Pane
verticalSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
add(verticalSplit, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
verticalSplit.setBorder(null);
verticalSplit.setOneTouchExpandable(false);
verticalSplit.setTopComponent(splitPane);
textScroller.setAutoscrolls(true);
// Speed up scrolling. It was way too slow.
textScroller.getVerticalScrollBar().setBlockIncrement(50);
textScroller.getVerticalScrollBar().setUnitIncrement(20);
chatWindowPanel = new JPanel();
chatWindowPanel.setLayout(new GridBagLayout());
chatWindowPanel.add(textScroller, new GridBagConstraints(0, 10, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
chatWindowPanel.setOpaque(false);
// Layout Components
chatPanel.add(chatWindowPanel, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 5, 0, 5), 0, 0));
// Add Chat Panel to Split Pane
splitPane.setLeftComponent(chatPanel);
// Add edit buttons to Chat Room
editorBar.setOpaque(false);
chatPanel.setOpaque(false);
editorBar.add(new JSeparator(JSeparator.VERTICAL));
bottomPanel.setOpaque(false);
splitPane.setOpaque(false);
bottomPanel.setLayout(new GridBagLayout());
bottomPanel.add(chatAreaButton, new GridBagConstraints(0, 1, 5, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 5, 5, 5), 0, 15));
bottomPanel.add(editorBar, new GridBagConstraints(0, 0, 5, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
// Set bottom panel border
bottomPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(197, 213, 230)));
verticalSplit.setOpaque(false);
verticalSplit.setBottomComponent(bottomPanel);
verticalSplit.setResizeWeight(1.0);
verticalSplit.setDividerSize(2);
// Add listener to send button
chatAreaButton.getButton().addActionListener(this);
// Add Key Listener to Send Field
getChatInputEditor().getDocument().addDocumentListener(this);
// Add Key Listener to Send Field
chatEditorKeyListener = new KeyAdapter() {
public void keyPressed(KeyEvent e) {
checkForEnter(e);
}
};
getChatInputEditor().addKeyListener(chatEditorKeyListener);
getChatInputEditor().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("ctrl F4"), "closeTheRoom");
getChatInputEditor().getActionMap().put("closeTheRoom", new AbstractAction("closeTheRoom") {
public void actionPerformed(ActionEvent evt) {
// Leave this chat.
closeChatRoom();
}
});
}
// I would normally use the command pattern, but
// have no real use when dealing with just a couple options.
public void actionPerformed(ActionEvent e) {
sendMessage();
// Clear send field and disable send button
getChatInputEditor().clear();
chatAreaButton.getButton().setEnabled(false);
}
/**
* Creates and sends a message object from the text in
* the Send Field, using the default nickname specified in your
* Chat Preferences.
*/
protected abstract void sendMessage();
/**
* Creates a Message object from the given text and delegates to the room
* for sending.
*
* @param text the text to send.
*/
protected abstract void sendMessage(String text);
/**
* Sends the current message.
*
* @param message - the message to send.
*/
public abstract void sendMessage(Message message);
/**
* Returns the nickname of the current agent as specified in Chat
* Preferences.
*
* @return the nickname of the agent.
*/
public String getNickname() {
LocalPreferences pref = SettingsManager.getLocalPreferences();
return pref.getNickname();
}
/**
* The main entry point when receiving any messages. This will
* either handle a message from a customer or delegate itself
* as an agent handler.
*
* @param message - the message receieved.
*/
public void insertMessage(Message message) {
// Fire Message Filters
SparkManager.getChatManager().filterIncomingMessage(this, message);
SparkManager.getChatManager().fireGlobalMessageReceievedListeners(this, message);
addToTranscript(message, true);
fireMessageReceived(message);
}
/**
* Add a <code>ChatResponse</chat> to the current discussion chat area.
*
* @param message the message to add to the transcript list
* @param updateDate true if you wish the date label to be updated with the
* date and time the message was received.
*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?