📄 chatpanel.java
字号:
/* * Copyright (C) 2003 Adam Olsen * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 1, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */package com.valhalla.jbother;import java.awt.Component;import java.awt.Dimension;import java.awt.Font;import java.awt.GridLayout;import java.awt.Toolkit;import java.awt.event.*;import java.beans.PropertyChangeEvent;import java.beans.PropertyChangeListener;import java.net.URL;import java.util.ArrayList;import java.util.Date;import java.util.Hashtable;import java.util.Iterator;import java.util.Locale;import java.util.ResourceBundle;import java.util.Set;import javax.swing.AbstractAction;import javax.swing.Action;import javax.swing.BorderFactory;import javax.swing.Box;import javax.swing.BoxLayout;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JComboBox;import javax.swing.JComponent;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JList;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JSplitPane;import javax.swing.KeyStroke;import javax.swing.ListCellRenderer;import javax.swing.SwingUtilities;import javax.swing.text.JTextComponent;import org.jivesoftware.smack.Chat;import org.jivesoftware.smack.XMPPException;import org.jivesoftware.smack.packet.Message;import org.jivesoftware.smack.packet.Presence;import org.jivesoftware.smackx.MessageEventManager;import org.jivesoftware.smackx.muc.MultiUserChat;import com.valhalla.gui.*;import com.valhalla.jbother.jabber.BuddyStatus;import com.valhalla.jbother.jabber.MUCBuddyStatus;import com.valhalla.jbother.jabber.smack.SecureExtension;import com.valhalla.jbother.menus.ConversationPopupMenu;import com.valhalla.jbother.plugins.events.*;import com.valhalla.misc.GnuPG;import com.valhalla.settings.Settings;/** * Handles conversations between two users. It is usually associated with a * BuddyStatus. * *@author Adam Olsen *@author Andrey Zakirov *@created September 9, 2005 *@version 1.1 *@see com.valhalla.jbother.jabber.BuddyStatus */public class ChatPanel extends ConversationPanel { private ResourceBundle resources = ResourceBundle.getBundle( "JBotherBundle", Locale.getDefault()); //private StringBuffer conversationText = new StringBuffer(); private boolean offlineMessage = false; private ConversationPopupMenu popMenu = new ConversationPopupMenu(this, conversationArea); //private HTMLDocument document = // (HTMLDocument)conversationArea.getDocument(); private JSplitPane container; private JPanel buttonPanel = new JPanel(); private JPanel scrollPanel = new JPanel(new GridLayout(1, 0)); //private JCheckBox useHTML = new JCheckBox( "Use HTML" ); // for logging private JComboBox resourceBox = new JComboBox(); private JLabel typingLabel = new JLabel(Standard.getIcon("images/nottyping.png")); private JButton clearButton = new JButton(Standard.getIcon("images/buttons/New24.gif")); private JButton emoteButton = new JButton(Standard.getIcon("images/buttons/smiley.gif")); private boolean divSetUp = false; private DividerListener dividerListener = new DividerListener(); private Hashtable chats = new Hashtable(); private boolean isTyping = false; private javax.swing.Timer typingTimer = new javax.swing.Timer(13000, new TypingHandler()); private JButton encryptButton = new JButton(); private String selected = null; private JScrollPane scroll = new JScrollPane(textEntryArea); /** * Sets up the ChatPanel - creates all visual components and adds event * listeners * *@param buddy the buddy to associate with */ public ChatPanel(final BuddyStatus buddy) { super(buddy); setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); // create two fields, one for where you type your message to be sent, // and the other where you see the conversation that has already happened. textEntryArea.setLineWrap(true); textEntryArea.setWrapStyleWord(true); conversationArea.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); container = new JSplitPane(JSplitPane.VERTICAL_SPLIT, conversationArea, scroll); container.setResizeWeight(1); JPanel containerPanel = new JPanel(); containerPanel.setLayout(new BoxLayout(containerPanel, BoxLayout.X_AXIS)); containerPanel.add(container); JPanel bottomPanel = new JPanel(); bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS)); if (buddy.getUser().indexOf("/") >= 0) { resourceBox.setEnabled(false); } resourceBox.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { selected = (String) resourceBox.getSelectedItem(); } }); resourceBox.setRenderer(new PresenceComboBoxRenderer()); buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS)); JPanel resourcePanel = new JPanel(); resourcePanel.setLayout(new BoxLayout(resourcePanel, BoxLayout.Y_AXIS)); resourcePanel.add(Box.createVerticalGlue()); resourcePanel.add(resourceBox); buttonPanel.add(resourcePanel); typingLabel.setPreferredSize(new Dimension(26, 26)); buttonPanel.add(typingLabel); typingLabel.setToolTipText(resources.getString("notTypingReply")); emoteButton.setPreferredSize(new Dimension(26, 26)); buttonPanel.add(emoteButton); if (!buddy.isEncrypting()) { encryptButton.setIcon(Standard.getIcon("images/buttons/ssl_no.png")); } else { encryptButton.setIcon(Standard.getIcon("images/buttons/ssl_yes.png")); } encryptButton.setPreferredSize(new Dimension(26, 26)); if (JBotherLoader.isGPGEnabled() && BuddyList.getInstance().getGnuPGPassword() != null) { buttonPanel.add(encryptButton); } String gnupgSecretKey = Settings.getInstance().getProperty( "gnupgSecretKeyID"); if (gnupgSecretKey == null) { encryptButton.setEnabled(false); } clearButton.setPreferredSize(new Dimension(26, 26)); buttonPanel.add(clearButton); bottomPanel.add(buttonPanel); add(containerPanel); add(Box.createRigidArea(new Dimension(0, 5))); add(bottomPanel); textEntryArea.grabFocus(); textEntryArea.addKeyListener( new KeyAdapter() { public void keyTyped(KeyEvent e) { if (lastReceived != null && !isTyping && e.getKeyChar() != KeyEvent.VK_ENTER) { if (Settings.getInstance().getBoolean( "sendTypingNotification") && buddy.getComposingID() != null && buddy.getComposingID().equals( lastReceived.getPacketID())) { ConnectorThread.getInstance().getMessageEventManager() .sendComposingNotification( lastReceived.getFrom(), lastReceived.getPacketID()); isTyping = true; if (typingTimer.isRunning()) { typingTimer.restart(); } else { typingTimer.start(); } } } } }); addListeners(); updateResources(); } public void removeScroll() { scroll.setViewportView(null); } /** * Description of the Method */ public void enableEncrypt() { encryptButton.setEnabled(true); } /** * Description of the Method */ public void disableEncrypt() { encryptButton.setEnabled(true); } /** * Description of the Class * *@author synic *@created September 9, 2005 */ private class TypingHandler implements ActionListener { /** * Description of the Method * *@param e Description of the Parameter */ public void actionPerformed(ActionEvent e) { if (lastReceived != null && buddy.getComposingID() != null && buddy.getComposingID() .equals(lastReceived.getPacketID())) { ConnectorThread.getInstance().getMessageEventManager() .sendCancelledNotification(lastReceived.getFrom(), lastReceived.getPacketID()); } typingTimer.stop(); isTyping = false; } } /** * Sets the isTyping attribute of the ChatPanel object * *@param typing The new isTyping value */ public void setIsTyping(boolean typing) { if (buddy.size() <= 0) { return; } String s = "images/typing.png"; if (!typing) { s = "images/nottyping.png"; } typingLabel.setIcon(Standard.getIcon(s)); if (typing) { typingLabel.setToolTipText(resources.getString("typingReply")); } else { typingLabel.setToolTipText(resources.getString("notTypingReply")); } typingLabel.validate(); } /** * Description of the Method */ public void removeDividerListener() { container.removePropertyChangeListener(dividerListener); } /** *@return the input area of this panel */ public JComponent getInputComponent() { return textEntryArea; } /** * Sets up the Divider */ public void setUpDivider() { String modifier = ""; if (Settings.getInstance().getBoolean("useTabbedWindow")) { modifier = "tabbed_"; } String stringHeight = Settings.getInstance().getProperty( "conversationWindowHeight"); // set up the divider location from settings String divLocString = Settings.getInstance().getProperty( modifier + "conversationWindowDividerLocation"); int divLoc = 30; try { if (divLocString != null) { divLoc = Integer.parseInt(divLocString); } else { divLoc = Integer.parseInt(stringHeight) - 117; } } catch (NumberFormatException ex) { ex.printStackTrace(); } container.setDividerLocation(divLoc); if (!divSetUp) { container.addPropertyChangeListener("lastDividerLocation", dividerListener); divSetUp = true; } } /** *@return the ChatPanel's JSPlitPane */ public JSplitPane getSplitPane() { return container; } /** * Listens for the user to move the divider, and saves it's location * *@author Adam Olsen *@created September 9, 2005 *@version 1.0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -