📄 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.25 2002/09/01 11:19:16 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.25 2002/09/01 11:19:16 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), "", "奔覆眉");
}
/**
* 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" : a2 );
StyleConstants.setFontFamily(style, a2 );
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 + -