📄 chatarea.java
字号:
/* * @(#)ChatArea.java * * Copyright (c) 2002, Jang-Ho Hwang * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Jang-Ho Hwang nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $Id: ChatArea.java,v 1.26 2004/06/28 08:43:39 xrath Exp $ */package rath.jmsn.ui;import java.awt.*;import java.awt.dnd.*;import java.awt.datatransfer.*;import java.awt.event.*;import javax.swing.*;import javax.swing.text.Document;import javax.swing.text.DefaultStyledDocument;import javax.swing.text.SimpleAttributeSet;import javax.swing.text.StyleConstants;import javax.swing.text.html.HTMLEditorKit;import javax.swing.text.rtf.RTFEditorKit;import java.io.IOException;import java.util.List;import java.util.Vector;import java.util.Enumeration;import rath.jmsn.MainFrame;import rath.jmsn.util.Emoticon;/** * 盲泼 措拳芒 哪器惩飘 * <p> * Special thank to pistos (Min-Jong Kim) * * @author Jangho Hwang, rath@linuxkorea.co.kr * @version $Id: ChatArea.java,v 1.26 2004/06/28 08:43:39 xrath Exp $ */public abstract class ChatArea extends JTextPane implements ActionListener, MouseListener, MouseMotionListener{ private Emoticon emoticon = Emoticon.getInstance(); private SimpleAttributeSet style; private Vector startIndex = new Vector(); private Vector endIndex = new Vector(); private Vector linkURL = new Vector(); private JTextArea tempArea = new JTextArea(); private boolean isViewEmoticon = MainFrame.LOCALCOPY.getPropertyBoolean(MainFrame.EMOTICON_DISPLAY, true); private boolean useFixedFont = MainFrame.LOCALCOPY.getPropertyBoolean(MainFrame.USE_FIXED_CHAT_FONT, false); public ChatArea() { style = new SimpleAttributeSet(); StyleConstants.setForeground(style, Color.black); StyleConstants.setFontSize(style, 12); StyleConstants.setBold(style, false); StyleConstants.setItalic(style, false); this.registerKeyboardAction(this, KeyStroke.getKeyStroke(KeyEvent.VK_C, 2), WHEN_FOCUSED ); this.setContentType("text/rtf"); this.setEditorKit(new RTFEditorKit()); this.addMouseListener(this); this.addMouseMotionListener(this); this.setEditable(false); setBorder( BorderFactory.createEmptyBorder(5,5,5,5) ); new DropTarget( this, new DropListener() ); } /** * 靛贰弊 矩 靛酚阑 烹秦 input等 java.io.File 按眉甸狼 List甫 逞咯霖促. * * @param files DND甫 烹秦 档馒茄 颇老按眉甸狼 府胶飘 */ public abstract void acceptFiles( List files ); /** * DND甫 烹秦 BuddyTree肺何磐 模备甫 檬措沁澜阑 舅妨霖促. * * @param loginName 檬措窍绊磊窍绰 模备赤籍狼 捞抚 */ public abstract void inviteFriend( String loginName ); /** * Message甫 罐酒 钎矫秦霖促. * * @param msg 钎矫且 message */ public void append(String msg) { append(msg, new Color(0,0,0), "", "Dialog"); } /** * Message甫 罐酒 钎矫秦霖促. * * @param msg 钎矫且 message * @param co 钎矫且 臂磊祸 * @param ef 钎矫且 臂裁鸥蕾 * @param fn 钎矫且 臂裁捞抚 */ public void append(String msg, Color co, String ef, String fn) { Color a3 = StyleConstants.getForeground(style); StyleConstants.setForeground(style, co); String a2 = StyleConstants.getFontFamily(style); StyleConstants.setFontFamily(style, useFixedFont ? "Dialog" : fn ); boolean fi = false; boolean fu = false; boolean fb = false; boolean fs = false; if(ef.indexOf('B')!=-1) { fb = StyleConstants.isBold(style); StyleConstants.setBold(style, true); } if(ef.indexOf('I')!=-1) { fi = StyleConstants.isItalic(style); StyleConstants.setItalic(style, true); } if(ef.indexOf('S')!=-1) { fs = StyleConstants.isStrikeThrough(style); StyleConstants.setStrikeThrough(style, true); } if(ef.indexOf('U')!=-1) { fu = StyleConstants.isUnderline(style); StyleConstants.setUnderline(style, true); } try { String s = this.getDocument().getText(0,getDocument().getLength()); int d1 = s.length(); this.getDocument().insertString(this.getDocument().getLength(), msg, style); this.setEditable(true); if( isViewEmoticon ) replaceEmoticon(msg, d1); replaceURL(msg, d1); this.setEditable(false); // Temporary patch code. this.getDocument().insertString(this.getDocument().getLength(), "", style); } catch(Exception e) { System.out.println(e.getMessage()); } StyleConstants.setFontFamily(style, a2); StyleConstants.setForeground(style, a3); StyleConstants.setBold(style, fb); StyleConstants.setItalic(style, fi); StyleConstants.setStrikeThrough(style, fs); StyleConstants.setUnderline(style, fu); } /** * Message俊辑 捞葛萍能阑 摹券茄促. * */ protected void replaceEmoticon(String msg, int d1) { try { boolean hasMoreEmoticons = true; int lid = -1; while(hasMoreEmoticons) { Enumeration e = emoticon.getEmoticons(); boolean a = false; while(e.hasMoreElements()) { String key = e.nextElement().toString(); int index = -1; if((index=msg.indexOf(key.toUpperCase(),lid))!=-1 || (index=msg.indexOf(key.toLowerCase(),lid))!=-1){ lid = index; this.getDocument().remove( (d1+index), key.length() ); this.setCaretPosition(d1+index); insertIcon(emoticon.get(key)); msg = this.getDocument().getText(d1, getDocument().getLength()-d1); a = true; break; } } hasMoreEmoticons = a; } } catch(Exception e) { System.err.println(e.getMessage()); } } /** * Message俊辑 URL阑 摹券茄促. * */ protected void replaceURL(String msg, int d1) { try { Document doc = this.getDocument(); int lid = -1; boolean a1 = StyleConstants.isUnderline(style); boolean a2 = StyleConstants.isItalic(style); Color a3 = StyleConstants.getForeground(style); StyleConstants.setUnderline(style, true); StyleConstants.setForeground(style, Color.blue); while(true) { int index= -1; msg = doc.getText(d1, doc.getLength()-d1); if((index = msg.indexOf("http://", lid+1))!=-1) { lid = index; int endPoint=msg.indexOf(" ",lid+1); int te1 = msg.indexOf("http://", lid+1); int te2 = msg.indexOf("\n", lid+1); //System.out.println(te1+","+te2+","+endPoint); if(te1!=-1) { endPoint = Math.min(te1, endPoint); if(endPoint == -1) endPoint = te1; } if(te2!=-1) { endPoint = Math.min(te2, endPoint); if(endPoint == -1) endPoint = te2; } if(endPoint == -1) endPoint = msg.length()-1; String anchor = doc.getText(d1+lid, endPoint-lid); doc.remove(d1+lid, endPoint-lid); doc.insertString(d1+lid, anchor, style); doc.insertString(d1+lid+anchor.length(), " ", new SimpleAttributeSet()); startIndex.add(new Integer(d1+lid)); endIndex.add(new Integer(d1+endPoint)); linkURL.add(anchor); } else break; } StyleConstants.setUnderline(style, a1); StyleConstants.setForeground(style, a3); } catch(Exception e) { System.out.println(e.getMessage()); } } /** * Ctrl+C 啊 力措肺 冈洒瘤 臼绰 包拌肺 流立备泅 * */ public void actionPerformed(ActionEvent e) { tempArea.setText(this.getSelectedText()); tempArea.selectAll(); tempArea.copy(); } /** * URL阑 努腐窍搁 秦寸 URL肺 官肺啊扁 * * @param msg 钎矫且 message */ public void mouseClicked(MouseEvent e) { int idx = viewToModel(e.getPoint()); for(int i=0;i<startIndex.size();i++) { int sp = ((Integer)startIndex.elementAt(i)).intValue(); int ep = ((Integer)endIndex.elementAt(i)).intValue(); if(idx>=sp & idx<=ep) { String url = (String)linkURL.elementAt(i); //System.out.println(url); showURL( url ); break; } } } public void mousePressed(MouseEvent e){} public void mouseReleased(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} private void showURL( String urls ) { try { String[] cmd = new String[2]; /* * currently support only win32 and netscape navigator. * the browser to open will change to customize. */ cmd[0] = System.getProperty("os.name").startsWith("Windows") ? "explorer" : "netscape"; cmd[1] = "\"" + urls + "\""; Runtime.getRuntime().exec( cmd ); } catch( Exception e ) { System.err.println( e ); } } /** * URL困俊 付快胶啊 棵扼啊搁 目辑葛剧 官操扁 * * @param msg 钎矫且 message */ public void mouseMoved(MouseEvent e) { int idx = viewToModel(e.getPoint()); int a =0; for(int i=0;i<startIndex.size();i++) { int sp = ((Integer)startIndex.elementAt(i)).intValue(); int ep = ((Integer)endIndex.elementAt(i)).intValue(); if(idx>=sp & idx<=ep) { setCursor(new Cursor(Cursor.HAND_CURSOR)); a++; break; } } if(a==0) setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } public void mouseDragged(MouseEvent e){} /** * 模备格废俊辑 Drag and drop窍看阑锭, Invite action阑 秒且 荐 乐档废 * Drop event甫 荐脚窍绰 event listener 努贰胶捞促. */ private class DropListener implements DropTargetListener { public void dragEnter( DropTargetDragEvent e ) {} public void dragExit( DropTargetEvent e ) {} public void dragOver( DropTargetDragEvent e ) {} public void dropActionChanged( DropTargetDragEvent e ) {} public void drop( DropTargetDropEvent event ) { try { Transferable t = event.getTransferable(); if( t.isDataFlavorSupported(DataFlavor.javaFileListFlavor) ) { event.acceptDrop( DnDConstants.ACTION_MOVE ); List filelist = (List)t.getTransferData( DataFlavor.javaFileListFlavor ); event.getDropTargetContext().dropComplete( true ); acceptFiles( filelist ); } else if( t.isDataFlavorSupported(DataFlavor.stringFlavor) ) { event.acceptDrop( DnDConstants.ACTION_MOVE ); String loginName = (String)t.getTransferData( DataFlavor.stringFlavor ); event.getDropTargetContext().dropComplete( true ); inviteFriend( loginName ); } else event.rejectDrop(); } catch( IOException e ) { event.rejectDrop(); } catch( UnsupportedFlavorException e ) { event.rejectDrop(); } } } public void dispose() { this.setText( "" ); startIndex.removeAllElements(); endIndex.removeAllElements(); linkURL.removeAllElements(); tempArea.setText( "" ); startIndex = null; endIndex = null; linkURL = null; tempArea = null; }};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -