📄 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.CopyPasteContextMenu;import com.valhalla.gui.MJTextArea;import com.valhalla.gui.Standard;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.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 * @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 JScrollPane conversationScroll; private JPanel buttonPanel = new JPanel(); private JPanel scrollPanel = new JPanel(new GridLayout(1, 0)); private MJTextArea textEntryArea = new MJTextArea(); //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 JButton eventButton = new JButton (Standard .getIcon("images/buttons/bell.gif")); private ChatPanel thisPointer = this; private boolean divSetUp = false; private DividerListener dividerListener = new DividerListener(); private Hashtable chats = new Hashtable(); private Message lastReceived = null; 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; /** * Sets up the ChatPanel - creates all visual components and adds event * listeners * * @param buddy * the buddy to associate with * @param userId * the buddy's userId * @param buddyName * the buddy's alias */ 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); conversationScroll = new JScrollPane(conversationArea); conversationScroll .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); conversationArea.setScroll(conversationScroll); scrollPanel.add(conversationScroll); container = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollPanel, new JScrollPane(textEntryArea)); 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); eventButton.setPreferredSize(new Dimension(26, 26)); buttonPanel.add(eventButton); 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 enableEncrypt() { encryptButton.setEnabled(true); } public void disableEncrypt() { encryptButton.setEnabled(true); } private class TypingHandler implements ActionListener { 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; } } public void setLastReceivedMessage(Message message) { this.lastReceived = message; } 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(); } 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -