Java:基于socket的聊天实现+文件传输

该工程是基于swing的,需要一些图片。
代码放上来,供参考。
工程源码下载地址:点击下载

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.sql.Date;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.awt.BorderLayout;
import java.awt.Choice;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Caret;

public class MainClass{
	private static void createAndShowGUI()
	{
		new Window();
	}
	public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
	}
}


abstract class Connect{
	Writer writer;
	
	Socket socket;
	
	Thread reader;
	
	Thread executor;
	
	String data;
	
	boolean dataAvailable = false;
	
	Object Lock;
	
	Connect(Socket s){
		socket = s;
		Lock = new Object();
		try {
			connected(s);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	private void connected(Socket socket) throws IOException{
		 writer = new OutputStreamWriter(socket.getOutputStream());
		 reader = new Thread(new Runnable(){
			 	public void run(){readData(socket);}
		 });
		 executor = new Thread(new Runnable(){
			 	public void run(){while(!socket.isClosed()){execute();}}
		 });
		 reader.start();
		 executor.start();
	}
	public void send(String str) {
		 try {
			writer.write(str);
			 writer.flush();
		} catch (IOException e) {
			interrupted();
			return;
		}
		
	}
	abstract void received(String Data);
	private void readData(Socket socket){
		while(!socket.isClosed())
		{
			try {
				BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				StringBuffer sb = new StringBuffer();
				int cLen = 128;
				char cbuf[] = new char[cLen];
				int readLen = br.read(cbuf, 0, cLen);
				if(readLen!=-1)
						sb.append(cbuf, 0, readLen);
				synchronized(Lock){
					if(dataAvailable==true)
						try {
							Lock.wait();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					dataAvailable = true;
					
					
					data =  sb.toString();
					Lock.notifyAll();
				}
			 } catch (IOException e) {
				try {
					socket.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				interrupted();
				return;
			}
		 }
	}
	private void execute(){
		String Data;
 		synchronized(Lock){
 			if(dataAvailable){
 				Data = data;
 				data = "";
 				dataAvailable = false;
 				Lock.notifyAll();
 				received(Data);
 			}else{
 				try {
					Lock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
 			}
 		} 		
	}
	abstract void interrupted();
	
}

class FileConnect {
		FileInputStream fis;
		FileOutputStream fos;
		InputStream sin;
		OutputStream sout;
		String filePath;
		File file;
		Socket socket;

		long length=0;
		FileConnect(Socket s, String FilePath) throws IOException{
			sin = s.getInputStream();
			sout = s.getOutputStream();
			filePath = FilePath;	
			file = new File(filePath);
			socket = s;
		}
		
		void close() throws IOException{
			sin.close();
			sout.close();
			socket.close();
		}
		
		void send() throws IOException {
			try {
				fis = new FileInputStream(file);
				byte[] buf = new byte[1024];
				int len;
				while((len=fis.read(buf))!=-1){
					sout.write(buf);
					sout.flush();
					length+=len;
				}
			} catch (IOException e) {
				sout.close();
				fis.close();
				socket.close();
			}			
		}
		
		void receive() throws IOException {
			try {
				fos = new FileOutputStream(file);
				int len;
				byte[] buf =new byte[1024];
				while((len=sin.read(buf))!=-1	){
					fos.write(buf);
					fos.flush();
					length += len;
				}
				sin.close();
				fos.close();
				socket.close();
			} catch (IOException e) {
				sin.close();
				fos.close();
				socket.close();
			}
		}
		
		boolean isClosed(){
			if( socket.isClosed() && socket.isConnected() )
				return true;
			else 
				return false;
		}
		long getFileSize(){
			return file.length();
		}
		long getDealSize(){
			return length;
		}
	}
class Window extends JFrame implements ActionListener{
	
	JButton sure, wait;
	
	Demo demo = null;
	
	static int port = 3001;
	
	public Window(){
		this.setTitle("开始连接");
		this.setSize(200,80);
		this.setLocationRelativeTo(null);
		this.setVisible(true);
		this.setResizable(false);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		FlowLayout flow = new FlowLayout();
		flow.setAlignment(FlowLayout.CENTER);
		this.setLayout(flow);
		sure = new JButton("发起连接");
		sure.addActionListener(this);
		this.add(sure);
		
		wait = new JButton("等待连接");
		wait.addActionListener(this);
		this.add(wait);
	}
	public void actionPerformed(ActionEvent event) {
		if(event.getSource() == sure){
			String ip;
			ip = JOptionPane.showInputDialog(null, "请输入对方IP地址","");
			if(ip == null)
				JOptionPane.showMessageDialog(null, "IP地址不能为空", "警告", JOptionPane.ERROR_MESSAGE);
			try {
				Socket socket = new Socket();
				socket.connect(new InetSocketAddress(ip,port), 3000);
				if(socket.isConnected())
					demo = new Demo(socket);
			} catch (UnknownHostException e1) {
				JOptionPane.showMessageDialog(null, "未能连接至该IP。", "错误", JOptionPane.ERROR_MESSAGE);
				return;
			} catch (IOException e1) {
				if(e1.getMessage().equals("Connection refused: connect"))
					JOptionPane.showMessageDialog(null, "对方未等待连接。", "错误", JOptionPane.ERROR_MESSAGE);
				else if(e1.getMessage().equals("connect timed out"))
					JOptionPane.showMessageDialog(null, "连接超时,IP不可达或未上线。", "错误", JOptionPane.ERROR_MESSAGE);
				return;
			}
			this.dispose();
		}
		if(event.getSource() == wait){
			sure.setEnabled(false);
			wait.setEnabled(false);
			Thread waitingThread = new Thread(new Runnable(){
				public void run(){
					waiting();
				}
			});
			waitingThread.start();
		}
	}
	void waiting(){
		try{
			ServerSocket server = new ServerSocket(port);
			demo = new Demo(server.accept());
			this.dispose();
			return;
		}catch(IOException e){
			e.printStackTrace();
		}
	}
}

class Demo extends JFrame implements ActionListener,DocumentListener, MouseListener, KeyListener{
	
	JPanel mainpanel = null;
	
	JTextArea inpane = null;
	
	JTextArea outpane = null;
	
	JLabel mainlabel = null;
	
	JToolBar toolbar = null;
	
	JPopupMenu mousemenu = null;                            //鼠标右键显示菜单栏
	
	JPopupMenu mousemenu1 = null;                            //鼠标右键显示菜单栏
	
	JPopupMenu mousemenu2 = null;
	
	JButton lenghan, fanu, zaijian, keai, poqiweixiao, ku, fadai, piezui, weixiao;
	
	JMenuItem  mousecut, mousecopy, mousepaste, mouseselectall, mouseclean, mousesearch;        //右键菜单栏的选项
	
	JMenuItem  mousecut1, mousecopy1, mousepaste1, mouseselectall1, mouseclean1, mousesearch1;        //右键菜单栏的选项
	
	JButton JTBcut, JTBcopy, JTBpaste, JTBfont, JTBfontcolor, JTBbold, JTBitalic, JTBexpression, JTBfile;    // 工具栏选项
	
	JButton send, close;
	
	JPanel fontpanel = null;
	
	JComboBox fontlist, sizelist;
	
	ToDo todo = null;                //作为一个内部类处理文件传输或者消息发送
	
	Socket socket = null;
	
	JFrame me = null;
	
	JFileChooser fileChooser = null;
	
	DataOutputStream output = null;
	
    JButton surecolor;
    
    JButton cancelcolor;
    
    Choice listfont;
    
    Choice listsize;
    
    Choice liststyle;
    
    JDialog fontdialog = new JDialog(this);
    
    JRadioButton chineselabel, englishlabel, numberlabel;
    
    JLabel examplefont;
    
    JButton surefont, cancelfont;
    
    JColorChooser jc = new JColorChooser();
    
    JDialog colordialog = new JDialog();
    
	class ToDo extends Connect
	{
		ToDo(Socket s){
			super(s);
		}
		void received(String Data)
		{
			String Command = Data.substring(0,Data.indexOf("\n"));        //作为标记,发送的是文件还是消息       
			if(Command.equals("TEXT")){
				String data = Data.substring(Data.indexOf("\n")+1);
				
				
				Calendar cal=Calendar.getInstance();
				int year=cal.get(Calendar.YEAR);//得到年
				int month=cal.get(Calendar.MONTH)+1;//得到月,因为从0开始的,所以要加1
				int day=cal.get(Calendar.DAY_OF_MONTH);//得到天
				int hour=cal.get(Calendar.HOUR);//得到小时
				int minute=cal.get(Calendar.MINUTE);//得到分钟
				int second=cal.get(Calendar.SECOND);//得到秒
				
				inpane.append(socket.getInetAddress().toString().substring(1) + ":        "+year+"-"+month+"-"+day+"  "+hour+":"+minute+":"+second + "\n"+ data);
				inpane.setCaretPosition(inpane.getText().length());
			}
			else if(Command.equals("FILE")){
				String[] str = Data.split("\n");
				String fileName = str[1];
				String fileSize = str[2];
				Thread FileThread = new Thread(new Runnable(){
					public void run(){
						try {
							Socket FileSocket = new Socket(socket.getInetAddress(), 3222);
							BufferedWriter writer =new BufferedWriter( new OutputStreamWriter(FileSocket.getOutputStream()));
							Object[] options = {"确定","取消"};
							JFileChooser JFC = new JFileChooser();
							JFC.setSelectedFile(new File(fileName));
							DecimalFormat df = new DecimalFormat("0.000");
							int isAccepted = JOptionPane.showOptionDialog(null, "对方发送文件:"+fileName+"\n大小:"+ df.format(Long.parseLong(fileSize)/(1024.0*1024.0)) +" MB\n是否接收?", "文件接收", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,null, options, options[0]);
							if(isAccepted==1){
								writer.write("Den");
								writer.flush();
								writer.close();
								FileSocket.close();
								return;
							}else if(isAccepted==0){
								if(JFC.showSaveDialog(me)==JFileChooser.CANCEL_OPTION	){
									writer.write("Den");
									writer.flush();
									writer.close();
									FileSocket.close();
									return;
								}
								writer.write("Acc");
								writer.flush();
							}
							String Path  = JFC.getSelectedFile().getAbsolutePath();
							FileConnect ReceiveFile = new FileConnect(FileSocket, Path);
							Thread fileWindowThread =  new Thread(new FileWindow(ReceiveFile, fileName, fileSize));
							fileWindowThread.start();
							ReceiveFile.receive();
							return;
						} catch (IOException e) {
							JOptionPane.showMessageDialog(null, "文件传输中断", "提示", JOptionPane.INFORMATION_MESSAGE);
						}
					}
				});
				FileThread.start();
			}
		}
		void interrupted() {
		}
	}
	
	public Demo(Socket socket)
	{
		this.socket = socket;
		todo = new ToDo(socket);
		me = this;
		
		try{                                                //使窗口更随系统变化而变化
			UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
		}
		catch(Exception e){
			System.err.println(e);
		}

		this.setSize(600,550);                              //对主窗体进行设置
		this.setLocationRelativeTo(null);
		this.setTitle("简易QQ");
		this.validate();
		this.setResizable(false);
		this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         
        mainlabel = new JLabel();                          //对主窗体进行设置
        mainlabel.setText("与"+socket.getInetAddress().toString()+"聊天中");
        JPanel panel1 = new JPanel();
        panel1.add(mainlabel,BorderLayout.CENTER);
        mainlabel.setFont(new Font("Dailog",0,16));
        this.add(panel1,BorderLayout.PAGE_START);
        

        
        Box box1 = new Box(0);                             //增加两个文本框
        
        inpane = new JTextArea();
        inpane.setText("");
        inpane.setFont(new Font("Dialog",0,16));

        
        
        inpane.setEditable(false);
        inpane = new JTextArea();
        inpane.setWrapStyleWord(true);
        inpane.setLineWrap(true);
        box1.setPreferredSize(new Dimension(300,500));
        JScrollPane js1 = new JScrollPane(inpane);
        js1.setPreferredSize(new Dimension(300,500));
        box1.add(js1);
        
        Box box2 = new Box(0);
        outpane = new JTextArea();
        outpane.setWrapStyleWord(true);
        outpane.setLineWrap(true);
        box2.setPreferredSize(new Dimension(100,200));
        JScrollPane js2 = new JScrollPane(outpane);
        js2.setPreferredSize(new Dimension(100,200));
        box2.add(js2);
        
        toolbar = new JToolBar();                          //设置工具栏
        JTBcut = new JButton();
        JTBcut.setToolTipText("剪切");
    	JTBcut.setIcon(new ImageIcon("cut.gif"));
    	JTBcut.setFocusable(false);
    	JTBcut.setEnabled(false);
    	JTBcut.addActionListener(this);
    	
    	JTBcopy = new JButton();
    	JTBcopy.setToolTipText("复制");
    	JTBcopy.setIcon(new ImageIcon("copy.gif"));
    	JTBcopy.setFocusable(false);
    	JTBcopy.setEnabled(false);
    	JTBcopy.addActionListener(this);
    	
    	JTBpaste = new JButton();
    	JTBpaste.setToolTipText("粘贴");
    	JTBpaste.setIcon(new ImageIcon("paste.gif"));
    	JTBpaste.setFocusable(false);
    	JTBpaste.addActionListener(this);
    	
    	JTBfont = new JButton();
    	JTBfont.setToolTipText("字体");
    	JTBfont.setIcon(new ImageIcon("font.gif"));
    	JTBfont.setFocusable(false);
    	JTBfont.addActionListener(this);
    	
    	JTBfontcolor = new JButton();
    	JTBfontcolor.setToolTipText("字体颜色");
    	JTBfontcolor.setIcon(new ImageIcon("fontcolor.gif"));
    	JTBfontcolor.setFocusable(false);
    	JTBfontcolor.addActionListener(this);
    	
    	JTBexpression = new JButton();
    	JTBexpression.setToolTipText("表情");
    	JTBexpression.setIcon(new ImageIcon("expression.gif"));
    	JTBexpression.setFocusable(false);
    	JTBexpression.addActionListener(this);
    	
    	JTBbold = new JButton();
    	JTBbold.setToolTipText("加粗");
    	JTBbold.setIcon(new ImageIcon("bold.gif"));
    	JTBbold.setFocusable(false);
    	JTBbold.addActionListener(this);
    	
    	JTBitalic = new JButton();
    	JTBitalic.setToolTipText("斜体");
    	JTBitalic.setIcon(new ImageIcon("italic.gif"));
    	JTBitalic.setFocusable(false);
    	JTBitalic.addActionListener(this);
    	
    	JTBfile = new JButton();
    	JTBfile.setToolTipText("发送文件");
    	JTBfile.setIcon(new ImageIcon("file.gif"));
    	JTBfile.setFocusable(false);
    	JTBfile.addActionListener(this);
    	
    	toolbar.setEnabled(false);
       	toolbar.add(JTBcut);
    	toolbar.add(JTBcopy);
    	toolbar.add(JTBpaste);
    	toolbar.add(JTBfont);
    	toolbar.add(JTBfontcolor);
    	toolbar.add(JTBexpression);
    	toolbar.add(JTBbold);
    	toolbar.add(JTBitalic);
    	toolbar.add(JTBfile);
          
        Box boss = new Box(1);
        boss.add(Box.createVerticalBox());
        boss.add(box1);

        JPanel panel2 = new JPanel();
		FlowLayout flow1 = new FlowLayout();
		panel2.setLayout(flow1);	
		flow1.setAlignment(FlowLayout.LEFT);		
        panel2.add(toolbar);
        
        boss.add(panel2);
        boss.add(box2);
        this.add(boss);
         
        mousecut = new JMenuItem("剪切(T)");
    	mousecut.setIcon(new ImageIcon("cut.gif"));
    	mousecut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK));
    	mousecut.addActionListener(this);
    	
    	mousecopy = new JMenuItem("复制(C)");
    	mousecopy.setIcon(new ImageIcon("copy.gif"));
    	mousecopy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK));
    	mousecopy.addActionListener(this);
    	
    	mousepaste = new JMenuItem("粘贴(P)");
    	mousepaste.setIcon(new ImageIcon("paste.gif"));
    	mousepaste.setEnabled(true);
    	mousepaste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK));
    	mousepaste.addActionListener(this);
    	
    	mouseclean = new JMenuItem("清屏(L)");
    	mouseclean.setIcon(new ImageIcon("delete.gif"));
    	mouseclean.setEnabled(true);
    	mouseclean.addActionListener(this);
    	
    	mousesearch = new JMenuItem("搜索");
    	mousesearch.setIcon(new ImageIcon("search.gif"));
    	mousesearch.setEnabled(true);
    	mousesearch.addActionListener(this);
    	
    	mousecut1 = new JMenuItem("剪切(T)");
    	mousecut1.setIcon(new ImageIcon("cut.gif"));
    	mousecut1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK));
    	mousecut1.addActionListener(this);
    	
    	mousecopy1 = new JMenuItem("复制(C)");
    	mousecopy1.setIcon(new ImageIcon("copy.gif"));
    	mousecopy1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK));
    	mousecopy1.addActionListener(this);
    	
    	mousepaste1 = new JMenuItem("粘贴(P)");
    	mousepaste1.setIcon(new ImageIcon("paste.gif"));
    	mousepaste1.setEnabled(true);
    	mousepaste1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK));
    	mousepaste1.addActionListener(this);
    	
    	mouseclean1 = new JMenuItem("清屏(L)");
    	mouseclean1.setIcon(new ImageIcon("delete.gif"));
    	mouseclean1.setEnabled(true);
    	mouseclean1.addActionListener(this);
    	
    	mousesearch1 = new JMenuItem("搜索");
    	mousesearch1.setIcon(new ImageIcon("search.gif"));
    	mousesearch1.setEnabled(true);
    	mousesearch1.addActionListener(this);
        
    	mousemenu = new JPopupMenu();
    	mousemenu.add(mousecopy);
    	mousemenu.add(mousepaste);
    	mousemenu.add(mouseclean);
    	mousemenu.addSeparator();
    	mousemenu.add(mousesearch);
    	
    	mousemenu1 = new JPopupMenu();
    	mousemenu1.add(mousecut1);
    	mousemenu1.add(mousecopy1);
    	mousemenu1.add(mousepaste1);
    	mousemenu1.addSeparator();
    	mousemenu1.add(mouseclean1);
    	mousemenu1.addSeparator();
    	mousemenu1.add(mousesearch1);
    	
    	inpane.addMouseListener(new MouseAdapter(){                //实现鼠标右击弹出菜单    
			public void mousePressed(MouseEvent e){
			if(e.getModifiers() == InputEvent.BUTTON3_MASK)
				mousemenu.show(inpane,e.getX(),e.getY());
			}
			public void mouseReleased(MouseEvent e)
			{
				if (inpane.getSelectedText() == null )
				{
					mousecopy.setEnabled(false);
					mousepaste.setEnabled(false);
					mousesearch.setEnabled(false);
				}
				else
				{
					mousecopy.setEnabled(true);
					mousepaste.setEnabled(true);
					mousesearch.setEnabled(true);
				}
				if ( inpane.getText().equals(""))
				{
					mouseclean.setEnabled(false);
				}
				else
					mouseclean.setEnabled(true);
			}
		}); 
    	inpane.addMouseListener(this);
    	
    	outpane.addMouseListener(new MouseAdapter(){                //实现鼠标右击弹出菜单    
			public void mouseReleased(MouseEvent e)
			{
				if ( outpane.getSelectedText() == null )
				{
					mousesearch1.setEnabled(false);
					mousecopy1.setEnabled(false);
					mousecut1.setEnabled(false);
					JTBcopy.setEnabled(false);
					JTBcut.setEnabled(false);
				}
				else
				{
					mousesearch1.setEnabled(true);
					mousecut1.setEnabled(true);
					mousecopy1.setEnabled(true);
					JTBcopy.setEnabled(true);
					JTBcut.setEnabled(true);
				}
				if ( outpane.getText().equals("") )
					mouseclean1.setEnabled(false);
				else
					mouseclean1.setEnabled(true);
			}
			public void mousePressed(MouseEvent e){
				if(e.getModifiers() == InputEvent.BUTTON3_MASK )
					mousemenu1.show(outpane,e.getX(),e.getY());
			}
		}); 
    	
    	outpane.addMouseListener(this);
    	outpane.addKeyListener(new KeyAdapter(){
    		@SuppressWarnings("static-access")
			public void keyPressed(KeyEvent ke)
    		{
    			if ( ke.getKeyChar() == ke.VK_ENTER)
    			{
    			}
    		}
    	});
    	
    	close = new JButton("关闭");
    	close.addActionListener(this);
    	close.setToolTipText("关闭");
    	send = new JButton("发送");
    	send.addActionListener(this);
    	send.setToolTipText("发送(按ENTER可发送)消息");
    	
    	
    	JLabel timelabel = new JLabel();
    	this.setTimer(timelabel);
    	
    	JPanel panel3 = new JPanel();
    	FlowLayout flow = new FlowLayout();	
		flow.setAlignment(FlowLayout.RIGHT);
		panel3.add(timelabel);
    	panel3.add(close);
    	panel3.add(send);
    	panel3.setLayout(flow);
    	panel3.validate();
    	this.add(panel3,BorderLayout.PAGE_END); 
    	
    	
    	lenghan = new JButton();
    	lenghan.setToolTipText("冷汗");
    	lenghan.setPreferredSize(new Dimension(32,32));
    	lenghan.setIcon(new ImageIcon("lenghan.gif"));
    	lenghan.addActionListener(this);
    	
    	fanu = new JButton();
    	fanu.setToolTipText("发怒");
    	fanu.setPreferredSize(new Dimension(32,32));
    	fanu.setIcon(new ImageIcon("fanu.gif"));
    	fanu.addActionListener(this);
    	
    	zaijian = new JButton();
    	zaijian.setToolTipText("再见");
    	zaijian.setPreferredSize(new Dimension(32,32));
    	zaijian.setIcon(new ImageIcon("zaijian.gif"));
    	zaijian.addActionListener(this);
    	
    	poqiweixiao = new JButton();
    	poqiweixiao.setToolTipText("破泣为笑");
    	poqiweixiao.setPreferredSize(new Dimension(32,32));
    	poqiweixiao.setIcon(new ImageIcon("poqiweixiao.gif"));
    	poqiweixiao.addActionListener(this);
    	
    	keai = new JButton();
    	keai.setToolTipText("可爱");
    	keai.setPreferredSize(new Dimension(32,32));
    	keai.setIcon(new ImageIcon("keai.gif"));
    	keai.addActionListener(this);
    	
    	ku = new JButton();
    	ku.setToolTipText("哭");
    	ku.setPreferredSize(new Dimension(32,32));
    	ku.setIcon(new ImageIcon("ku.gif"));
    	ku.addActionListener(this);
    	
    	fadai = new JButton();
    	fadai.setToolTipText("发呆");
    	fadai.setPreferredSize(new Dimension(32,32));
    	fadai.setIcon(new ImageIcon("fadai.gif"));
    	fadai.addActionListener(this);
    	
    	piezui = new JButton();
    	piezui.setToolTipText("撇嘴");
    	piezui.setPreferredSize(new Dimension(32,32));
    	piezui.setIcon(new ImageIcon("piezui.gif"));
    	piezui.addActionListener(this);
    	
    	weixiao = new JButton();
    	weixiao.setToolTipText("微笑");
    	weixiao.setPreferredSize(new Dimension(32,32));
    	weixiao.setIcon(new ImageIcon("weixiao.gif"));
    	weixiao.addActionListener(this);
    	
    	mousemenu2 = new JPopupMenu();
    	JPanel[] panel = new JPanel[3];
    	panel[0] = new JPanel();
    	panel[1] = new JPanel();
    	panel[2] = new JPanel();
    	panel[0].add(lenghan);
    	panel[0].add(fanu);
    	panel[0].add(zaijian);
    	panel[1].add(keai);
    	panel[1].add(poqiweixiao);
    	panel[1].add(ku);
    	panel[2].add(fadai);
    	panel[2].add(piezui);
    	panel[2].add(weixiao);
    	mousemenu2.add(panel[0]);
    	mousemenu2.add(panel[1]);
    	mousemenu2.add(panel[2]);
    	
    	JTBexpression.addMouseListener(new MouseAdapter(){                //实现鼠标左击弹出菜单    
			public void mousePressed(MouseEvent e){
				if(e.getModifiers() == InputEvent.BUTTON1_MASK )
					mousemenu2.show(JTBexpression,e.getX(),e.getY());
			}
    	});
    	this.validate();
    	outpane.addKeyListener(new KeyAdapter(){
    		public void keyReleased(KeyEvent e) {
    			if(e.getKeyCode() == KeyEvent.VK_ENTER){
    				outpane.setText(outpane.getText().substring(0, outpane.getText().length()));
    				if(outpane.getText().length()==0)
    					return;
    				todo.send("TEXT\n"+outpane.getText().toString());
    				SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
    				Calendar cal=Calendar.getInstance();
    				int year=cal.get(Calendar.YEAR);//得到年
    				int month=cal.get(Calendar.MONTH)+1;//得到月,因为从0开始的,所以要加1
    				int day=cal.get(Calendar.DAY_OF_MONTH);//得到天
    				int hour=cal.get(Calendar.HOUR);//得到小时
    				int minute=cal.get(Calendar.MINUTE);//得到分钟
    				int second=cal.get(Calendar.SECOND);//得到秒
    				
    				inpane.append("我:        "+year+"-"+month+"-"+day+"  "+hour+":"+minute+":"+second+"\n"+outpane.getText().toString());
    				inpane.setCaretPosition(inpane.getText().length());
    				outpane.setText("");
    			}
    		}
    	});
    	
	}


	@Override
	public void changedUpdate(DocumentEvent arg0) {
		// TODO 自动生成的方法存根
		
	}

	@Override
	public void insertUpdate(DocumentEvent arg0) {
		// TODO 自动生成的方法存根
		
	}

	@Override
	public void removeUpdate(DocumentEvent e) {
		// TODO 自动生成的方法存根
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO 自动生成的方法存根	
		if (e.getSource() == mouseclean)
			inpane.setText("");
		if (e.getSource() == mouseclean1)
			outpane.setText("");
		if ( e.getSource() == JTBcut)
			outpane.cut();
		if ( e.getSource() == JTBcopy )
			outpane.copy();
		if ( e.getSource() == JTBpaste )
			outpane.paste();
		if ( e.getSource() == JTBfont )
		{
			fontdialog = new JDialog(this);
			fontdialog.setTitle("字体设置");
			fontdialog.setVisible(true);
			fontdialog.setLocationRelativeTo(this);
			fontdialog.setResizable(false);
			fontdialog.setSize(700,250);
			
			
			GraphicsEnvironment eg = GraphicsEnvironment.getLocalGraphicsEnvironment();  
            String[] fontName = eg.getAvailableFontFamilyNames(); 
            listfont = new Choice();
            for ( int i = 0 ; i < fontName.length; i ++)
            	listfont.addItem(fontName[i]);
            listfont.select(inpane.getFont().getFamily());
            
            liststyle = new Choice();
            liststyle.addItem("常规");
            liststyle.addItem("粗体");            
            liststyle.addItem("斜体");            
            liststyle.addItem("粗偏斜体");
            if ( inpane.getFont().getStyle() == 0 )
            	liststyle.select("常规");
            if ( inpane.getFont().getStyle() == 1 )
            	liststyle.select("粗体");
            if ( inpane.getFont().getStyle() == 2)
            	liststyle.select("斜体");
            if ( inpane.getFont().getStyle() == 3)
            	liststyle.select("粗偏斜体");
            
            listsize = new Choice();
            for ( int i = 0; i <= 72 ;)
            {
            	if ( i <= 17 )
            	{
            		listsize.addItem(""+i);
            		i ++;
            	}
            	if ( i > 17 && i < 30 )
            	{
            		listsize.addItem(""+i);
            		i += 2;
            	}
            	if ( i >= 30 && i <= 72 )
            	{
            		listsize.addItem(""+i);
            		i += 5;
            	}
            }
            listsize.select(inpane.getFont().getSize()+"");
            
            JLabel fontlabel = new JLabel();
            fontlabel.setText("字体(F):");
            JPanel fontpanel = new JPanel();
            fontpanel.add(fontlabel,BorderLayout.NORTH);
            fontpanel.add(listfont,BorderLayout.SOUTH);
            
            JLabel stylelabel = new JLabel();
            stylelabel.setText("字形(Y):");
            JPanel stylepanel = new JPanel();
            stylepanel.add(stylelabel,BorderLayout.NORTH);
            stylepanel.add(liststyle,BorderLayout.SOUTH);
            
            JLabel sizelabel = new JLabel();
            sizelabel.setText("大小(S)");
            JPanel sizepanel = new JPanel();
            sizepanel.add(sizelabel,BorderLayout.NORTH);
            sizepanel.add(listsize,BorderLayout.SOUTH);
            
            
            chineselabel = new JRadioButton("中文示例");
            chineselabel.addActionListener(this);
            englishlabel = new JRadioButton("英文示例");
            englishlabel.addActionListener(this);
            numberlabel = new JRadioButton("数字示例");
            numberlabel.addActionListener(this);
            ButtonGroup group = new ButtonGroup();
            group.add(chineselabel);
            group.add(englishlabel);
            group.add(numberlabel);
            chineselabel.setSelected(true);
            
            
            Box b1 = new Box(0);
            b1.add(fontpanel);
            b1.add(Box.createHorizontalStrut(5));   
            b1.add(Box.createVerticalBox());
            b1.add(Box.createVerticalStrut(5));
  
            Box b2 = new Box(0);
            b2.add(stylepanel);
            b2.add(Box.createHorizontalStrut(5));
            b2.add(Box.createVerticalBox());
            b2.add(Box.createVerticalStrut(5));
            
            Box b3 = new Box(0);
            b3.add(sizepanel);
            b3.add(Box.createHorizontalStrut(5));
            b3.add(Box.createVerticalBox());
            b3.add(Box.createVerticalStrut(5));
            

            Box boss1 = new Box(2);
            boss1.add(b1);
            boss1.add(b2);
            boss1.add(b3);
            
            Box b4 = new Box(0);
            b4.add(chineselabel);
            b4.add(Box.createHorizontalStrut(150));
            
            Box b5 = new Box(0);
            b5.add(englishlabel);
            b5.add(Box.createHorizontalStrut(150));
            
            Box b6 = new Box(0);
            b6.add(numberlabel);
            b6.add(Box.createHorizontalStrut(0));
            
            Box boss2 = new Box(2);
            boss2.add(Box.createVerticalBox());
            boss2.add(b4);
            boss2.add(b5);
            boss2.add(b6);
            
            Box boss3 = new Box(1);
            boss3.add(boss1,BorderLayout.NORTH);
            JLabel fontlabel3 = new JLabel();
            fontlabel3.setText("                                   ");
            boss3.add(fontlabel3,BorderLayout.CENTER);
            boss3.add(boss2,BorderLayout.SOUTH);
            fontdialog.add(boss3,BorderLayout.NORTH);
            
            examplefont = new JLabel();
            examplefont.setText("范例字体");
            examplefont.setFont(inpane.getFont());
            JPanel sonpanel = new JPanel();
            sonpanel.add(examplefont,BorderLayout.CENTER);
            fontdialog.add(sonpanel,BorderLayout.CENTER);
            
            surefont = new JButton("确定");
            surefont.addActionListener(this);
            cancelfont = new JButton("取消");
            cancelfont.addActionListener(this);
            JPanel daughtpanel = new JPanel();
            daughtpanel.add(surefont,BorderLayout.AFTER_LAST_LINE);
            daughtpanel.add(cancelfont,BorderLayout.AFTER_LAST_LINE);
            fontdialog.add(daughtpanel,BorderLayout.PAGE_END);
		}
		if ( e.getSource() == chineselabel)
		{
			String s1, s2, s3;
			int a2 = 0, a3 = 0;
            s1 = listfont.getSelectedItem();
            s2 = liststyle.getSelectedItem();
            s3 = listsize.getSelectedItem();
            if ( s2 == "常规")
           	 a2 = 0;
            if ( s2 == "粗体")
           	 a2 = 1;
            if ( s2 == "粗偏斜体")
           	 a2 = 3;
            if ( s2 == "倾斜")
           	 a2 = 2;
            a3 =  Integer.parseInt(s3);

            examplefont.setText("中文字体");
            examplefont.setFont(new Font(s1,a2,a3));
            JPanel p = new JPanel();
            p.add(examplefont,BorderLayout.SOUTH);
            fontdialog.add(p,BorderLayout.CENTER);
            fontdialog.validate();
		}
		if ( e.getSource() == englishlabel)
		{
			String s1,s2,s3;
            int a2=0,a3=0;
            s1 = listfont.getSelectedItem();
            s2 = liststyle.getSelectedItem();
            s3 = listsize.getSelectedItem();
            if ( s2 == "常规")
           	 a2 = 0;
            if ( s2 == "粗体")
           	 a2 = 1;
            if ( s2 == "粗偏斜体")
           	 a2 = 3;
            if ( s2 == "倾斜")
           	 a2 = 2;
            a3 =  Integer.parseInt(s3);

            examplefont.setText("AaBbCc");
            examplefont.setFont(new Font(s1,a2,a3));
            JPanel p = new JPanel();
            p.add(examplefont,BorderLayout.SOUTH);
            fontdialog.add(p,BorderLayout.CENTER);
            fontdialog.validate();
		}
		if ( e.getSource() == numberlabel)
		{
			String s1,s2,s3;
            int a2=0,a3=0;
            s1 = listfont.getSelectedItem();
            s2 = liststyle.getSelectedItem();
            s3 = listsize.getSelectedItem();
            if ( s2 == "常规")
           	 a2 = 0;
            if ( s2 == "粗体")
           	 a2 = 1;
            if ( s2 == "粗偏斜体")
           	 a2 = 3;
            if ( s2 == "倾斜")
           	 a2 = 2;
            a3 =  Integer.parseInt(s3);

            examplefont.setText("1234567890");
            examplefont.setFont(new Font(s1,a2,a3));
            JPanel p = new JPanel();
            p.add(examplefont,BorderLayout.SOUTH);
            fontdialog.add(p,BorderLayout.CENTER);
            fontdialog.validate();
		}
		if ( e.getSource() == surefont )
		{
			String s1,s2,s3;
            int a2=0,a3=0;
            s1 = listfont.getSelectedItem();
            s2 = liststyle.getSelectedItem();
            s3 = listsize.getSelectedItem();
            if ( s2 == "常规")
           	 a2 = 0;
            if ( s2 == "粗体")
           	 a2 = 1;
            if ( s2 == "粗偏斜体")
           	 a2 = 3;
            if ( s2 == "倾斜")
           	 a2 = 2;
            a3 =  Integer.parseInt(s3);
           inpane.setFont(new Font(s1,a2,a3));
           outpane.setFont(new Font(s1,a2,a3));
            if ( inpane.getFont().getStyle() == 2 || inpane.getFont().getStyle() == 3 )
            	JTBitalic.setSelected(true);
            else
            	JTBitalic.setSelected(false);
            if (inpane.getFont().getStyle() == 1 || inpane.getFont().getStyle() == 3 )
            	JTBbold.setSelected(true);
            else
            	JTBbold.setSelected(false);
            fontdialog.dispose();
		}
		if ( e.getSource() == cancelfont )
			fontdialog.dispose();
		if ( e.getSource() == JTBfontcolor )
		{
			jc = new JColorChooser();
    		jc.setSize(300, 300);
    		colordialog = new JDialog(this);
    		colordialog.setTitle("颜色选择");
    		colordialog.setSize(600,430);
    		colordialog.setLocation(250,100);
    		colordialog.show();
    		colordialog.add(jc,BorderLayout.NORTH);
    		colordialog.setResizable(false);
			FlowLayout flow = new FlowLayout();	
    		flow.setAlignment(FlowLayout.CENTER);	
    		flow.setHgap(10);	
    		flow.setVgap(10);
    		
    		colordialog.setLayout(flow);
    		surecolor = new JButton("确定");
    		surecolor.addActionListener(this);
    		cancelcolor = new JButton("取消");
    		cancelcolor.addActionListener(this);
    		
    		colordialog.add(surecolor);
    		colordialog.add(cancelcolor);
		}
		if ( e.getSource() == surecolor)
		{
			inpane.setForeground(jc.getColor());
			outpane.setForeground(jc.getColor());
			colordialog.dispose();
		}
		if ( e.getSource() == cancelcolor)
			colordialog.dispose();
		
		if ( e.getSource() == JTBbold )
		{
			if ( outpane.getFont().getStyle() == 0 )
			{
				JTBbold.setSelected(true);
				outpane.setFont(new Font(outpane.getFont().getFamily(),1,outpane.getFont().getSize()));
			}
			else if ( outpane.getFont().getStyle() == 1 )
			{
				JTBbold.setSelected(false);
				outpane.setFont(new Font(outpane.getFont().getFamily(),0,outpane.getFont().getSize()));
			}
			else if ( outpane.getFont().getStyle() == 2 )
			{
				JTBbold.setSelected(true);
				outpane.setFont(new Font(outpane.getFont().getFamily(),3,outpane.getFont().getSize()));
			}
			else if ( outpane.getFont().getStyle() == 3 )
			{
				JTBbold.setSelected(false);
				outpane.setFont(new Font(outpane.getFont().getFamily(),2,outpane.getFont().getSize()));
			}
		}
		if ( e.getSource() == JTBitalic )
		{
			if ( outpane.getFont().getStyle() == 0 )
			{
				JTBitalic.setSelected(true);
				outpane.setFont(new Font(outpane.getFont().getFamily(),2,outpane.getFont().getSize()));
			}
			else if ( outpane.getFont().getStyle() == 1 )
			{
				JTBitalic.setSelected(true);
				outpane.setFont(new Font(outpane.getFont().getFamily(),3,outpane.getFont().getSize()));
			}
			else if ( outpane.getFont().getStyle() == 2 )
			{
				JTBitalic.setSelected(false);
				outpane.setFont(new Font(outpane.getFont().getFamily(),0,outpane.getFont().getSize()));
			}
			else if ( outpane.getFont().getStyle() == 3 )
			{
				JTBitalic.setSelected(false);
				outpane.setFont(new Font(outpane.getFont().getFamily(),1,outpane.getFont().getSize()));
			}
		}
		if (e.getSource() == close )
			this.dispose();
		if (e.getSource() == send)
		{
			outpane.setText(outpane.getText().substring(0, outpane.getText().length()));
			if(outpane.getText().length()==0)
				return;
			todo.send("TEXT\n"+outpane.getText().toString());
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

			Calendar cal=Calendar.getInstance();
			int year=cal.get(Calendar.YEAR);//得到年
			int month=cal.get(Calendar.MONTH)+1;//得到月,因为从0开始的,所以要加1
			int day=cal.get(Calendar.DAY_OF_MONTH);//得到天
			int hour=cal.get(Calendar.HOUR);//得到小时
			int minute=cal.get(Calendar.MINUTE);//得到分钟
			int second=cal.get(Calendar.SECOND);//得到秒
			
			inpane.append("我:        "+year+"-"+month+"-"+day+"  "+hour+":"+minute+":"+second+"\n"+outpane.getText().toString());
			
			Caret c1 = inpane.getCaret();
			int x = c1.getDot();
			inpane.setCaretPosition(x);
			
			outpane.setText("");
		}

		if(e.getSource() == JTBfile)
		{
			fileChooser = new JFileChooser();
			if(fileChooser.showOpenDialog(this)==JFileChooser.APPROVE_OPTION){	
				Thread sendFileThread = new Thread(new Runnable(){
					public void run(){
						byte[] data = new byte[1024];
						todo.send("FILE\n"+fileChooser.getSelectedFile().getName()+"\n"+fileChooser.getSelectedFile().length());
						try {
							ServerSocket FileAcceptListen = new ServerSocket(3222);
							Socket FileSocket = FileAcceptListen.accept();
							FileAcceptListen.close();
							BufferedReader reader = new BufferedReader(new InputStreamReader(FileSocket.getInputStream()));
							int len;
							char[] tmp = new char[3];
							String reply="";
							if((len=reader.read(tmp))!=-1){
								reply = new String(tmp);
							}
							if(!reply.equals("Acc")){
								JOptionPane.showMessageDialog(null, "对方拒绝接收该文件", "提示", JOptionPane.INFORMATION_MESSAGE);
								reader.close();
								FileSocket.close();
								
								return;
							}
							
							FileConnect SendFile = new FileConnect(FileSocket, fileChooser.getSelectedFile().getAbsolutePath());
							Thread fileWindowThread =  new Thread(new FileWindow(SendFile, fileChooser.getSelectedFile().getName(), ""+fileChooser.getSelectedFile().length()));
							fileWindowThread.start();
							SendFile.send();
							return;
						} catch (IOException e) {
							JOptionPane.showMessageDialog(null, "对方取消传输", "提示", JOptionPane.INFORMATION_MESSAGE);
						}
					}
				});
				sendFileThread.start();
		}
		
	}
			
		}
		
	@Override
	public void mouseClicked(MouseEvent arg0) {
		// TODO 自动生成的方法存根
		
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO 自动生成的方法存根
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO 自动生成的方法存根

	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO 自动生成的方法存根

	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO 自动生成的方法存根
	}
	public void KeyPressed(KeyEvent e )
	{
	}

	@Override
	public void keyPressed(KeyEvent arg0) {
		// TODO 自动生成的方法存根
		
	}
	
	private void setTimer(JLabel time){               //利用线程动态获取当前时间
		final JLabel varTime = time;
		Timer timeAction = new Timer(1000,new ActionListener(){
			public void actionPerformed(ActionEvent e) { 
				 long timemillis = System.currentTimeMillis(); 
				 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				 varTime.setText("当前时间:" + df.format(new Date(timemillis)));
			}
		});
		timeAction.start();
	}

	@Override
	public void keyReleased(KeyEvent e) {
		if(e.getKeyCode() == KeyEvent.VK_ENTER){
			outpane.setText(outpane.getText().substring(0, outpane.getText().length()));
			if(outpane.getText().length() == 0)
				return;
			todo.send("TEXT\n"+outpane.getText().toString());
			inpane.append("我:"+outpane.getText().toString());
			inpane.setCaretPosition(inpane.getText().length());
			outpane.setText("");
		}
	}
	private void toSendText(){
		if(outpane.getText().length() == 0)
			return;
		todo.send("TEXT\n"+outpane.getText().toString());
		inpane.append("我:"+outpane.getText().toString()+"\n");
		inpane.setCaretPosition(inpane.getText().length());
		outpane.setText("");
	}

	@Override
	public void keyTyped(KeyEvent arg0) {
	}
}

class FileWindow extends JFrame implements Runnable, WindowListener{
	int value;
	
	JButton cancel;
	
	JLabel FileNameLB, FileSizeLB,SpeedLB;
	
	FileConnect fc;
	
	JProgressBar progressbar;
	
	long FileSize;
	
	FileWindow( FileConnect FileConn, String fileName, String fileSize ){      //进行 
		fc = FileConn; 
		FileSize = Long.parseLong(fileSize);
		this.setTitle("发送文件");
		this.setSize(335, 200);
		this.setLayout(null);
		this.setLocationRelativeTo(null);
		///进度条
		progressbar = new JProgressBar();
		progressbar.setMinimum(0);
		progressbar.setMaximum(100);
		progressbar.setValue(0);
		progressbar.setStringPainted(true);
		progressbar.setBounds(10, 70, 300 , 30);
		progressbar.setBorderPainted(true);

		cancel =new JButton("取消");
		cancel.setBounds(130,110,60,30);

		SpeedLB = new JLabel();
		SpeedLB.setBounds(10,100,300,20);
		FileNameLB = new JLabel("文件名:"+fileName);
		FileNameLB.setBounds(10, 10, 300, 20);
		DecimalFormat df = new DecimalFormat("0.00");
		FileSizeLB = new JLabel("文件大小:"+df.format(FileSize/(1024.0*1024.0)) + " MB");
		FileSizeLB.setBounds(10, 30, 300, 20);
		this.add(SpeedLB);
		this.add(FileSizeLB);
		this.add(FileNameLB);
		this.add(cancel);
		this.add(progressbar);
		this.setVisible(true);
		this.addWindowListener(this);
		this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
		
		
		cancel.addActionListener(new ActionListener(){
			  public void actionPerformed(ActionEvent e){
				  closeWindow();
			  }
		  });
	}
	
	void setProgress(int value){
		if(progressbar!=null){
			progressbar.setValue(value);
		}
	}
	
	public void run(){
		value=0;
		while(value <= 100){
			long tempSize = fc.getDealSize();
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			value = (int)(((double)fc.getDealSize()/(double)FileSize)*100.0);
			setProgress(value);
			DecimalFormat df = new DecimalFormat("0.00");
			SpeedLB.setText(""+df.format(((fc.getDealSize()-tempSize)/1024.0)*2.0)+"KB/s");
			if(value == 100||fc.isClosed()){
				this.dispose();
				if(value < 100){
					JOptionPane.showMessageDialog(null, "文件传输被取消", "提示", JOptionPane.INFORMATION_MESSAGE);
				}
				return;
			}
		}
		if(value == 100)
			this.dispose();
	}
	
	private void closeWindow(){
		int option = JOptionPane.showConfirmDialog(null, "取消文件发送?", "取消?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
		  if(option==JOptionPane.YES_OPTION){
			  try {
				fc.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			  this.dispose();
		  }
	}
	
	public void windowClosing(WindowEvent e	){
		  closeWindow();
	  }

	@Override
	public void windowOpened(WindowEvent e) {
		
	}

	@Override
	public void windowClosed(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowIconified(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowDeiconified(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowActivated(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowDeactivated(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}
	
}


上一篇:重启winform程序代码


下一篇:2022/1/24