参照视频,编写出聊天程序。

知识点分析:

Socket + GUI  + IO =  简版QQ

------------------------------

1.GUI

package com.it18zhang16;


import java.awt.event.MouseAdapter;


public class GUIDemo extends MouseAdapter{


/**

* @param args

*/

public static void main(String[] args) {

MyWindows mw=new MyWindows();

}


}

package com.it18zhang16;


import java.awt.Component;

import java.awt.FileDialog;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.io.BufferedReader;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.FileReader;

import java.io.IOException;

import java.io.InputStreamReader;


import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;


public class MyWindows extends JFrame {


private static final long serialVersionUID = -4229766929291837335L;

private JButton btnSave;

private JButton btnClose;

private JButton btnOpen;

//文本域

private JTextArea textArea;

//滚动面板

private JScrollPane scrollPane;

/**

* 设置一个窗口类

*/

//构造函数

public MyWindows(){

iniWindows();

}

public void iniWindows(){


//设置大小

this.setSize(600, 400);

//设置位置

this.setLocation(500, 200);


//不设置布局管理器

this.setLayout(null);

//设置文本域

textArea=new JTextArea();

//this.add(textArea);

textArea.setBounds(0, 0, 550, 300);

//增加滚动面板

scrollPane=new JScrollPane(textArea);

scrollPane.setBounds(0, 0, 550, 300);

this.add(scrollPane);

//设置按钮

btnOpen = new JButton("打开");

this.add(btnOpen);

btnSave = new JButton("保存");

this.add(btnSave);

btnClose = new JButton("关闭");

this.add(btnClose);

//设置按钮的边界

btnOpen.setBounds(140, 320, 100, 50);

btnSave.setBounds(250, 320, 100, 50);

btnClose.setBounds(360, 320, 100, 50);

//鼠标点击事件

MyButtonAdapter mba=new MyButtonAdapter();

btnSave.addMouseListener(mba);

btnClose.addMouseListener(mba);

btnOpen.addMouseListener(mba);

//设置可见性

this.setVisible(true);

}

class MyButtonAdapter extends MouseAdapter{

public void mouseClicked(MouseEvent e){

Component comp=e.getComponent();

FileDialog fd=new FileDialog(MyWindows.this);

if(comp==btnSave){

//System.out.println("点击了保存按钮");

String cont=textArea.getText();

//获取文件位置

//FileDialog fd=new FileDialog(MyWindows.this);

String dictionary=fd.getDirectory();

String fileName=fd.getFile();

String file=dictionary+"/"+fileName;

try {

//FileOutputStream fos=new FileOutputStream("E:/51cto/test/11.txt");

FileOutputStream fos=new FileOutputStream(file);

fos.write(cont.getBytes("gbk"));

fos.close();

textArea.setText("");

} catch (Exception e1) {

e1.printStackTrace();

}

}else if(comp==btnClose){

//System.out.println("点击了关闭按钮");

System.exit(-1);

}else if(comp==btnOpen){

//System.out.println("点击了打开按钮");

//FileDialog fd=new FileDialog(MyWindows.this);

fd.setVisible(true);

//获取文件绝对路径

String dictionary=fd.getDirectory();

String fileName=fd.getFile();

String file=dictionary+"/"+fileName;

BufferedReader br=null;

if(file!=null){

try {

br=new BufferedReader(new InputStreamReader(new FileInputStream(file), "gbk"));

String line=null;

while((line=br.readLine())!=null){

String old=textArea.getText();

old=old==null?"":old;

textArea.setText(old+"\r\n"+line);

}

} catch (Exception e1) {

e1.printStackTrace();

}

finally{

try {

if(br==null){

br.close();

}

} catch (IOException e1) {

e1.printStackTrace();

}

}

}

}

}

}

}

2.Socket

ServerSocket : port + accept 


Socket sock  = accept();

//更新窗口


//接收client的数据

new Thread(){

run(){

sock..getInputStream();

....

//更新窗口

}

}.start()

//消息服务

package com.it18zhang16;


import java.net.InetAddress;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.ArrayList;

import java.util.List;


public class MessageServer {


public List<String> clients=new ArrayList<String>();

private MyWindow window;

public MessageServer(MyWindow window) {

super();

this.window = window;

}

public void start(int port){

try {

ServerSocket ss=new ServerSocket(port);

System.out.println("服务器启动了");

InetAddress remAddr;

int remPort;

while(true){

final Socket socket=ss.accept();

new MessageReceiverThread(window,socket).start();

remAddr=socket.getInetAddress();

remPort=socket.getPort();

clients.add(SocketUtil.getAddr(socket));

//刷新列表

window.refreshContacts(clients);

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

//消息接收

package com.it18zhang16;


import java.io.BufferedReader;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.net.Socket;


public class MessageReceiverThread extends Thread{

//消息接收线程

private MyWindow window;

private Socket sock;

public MessageReceiverThread(MyWindow window, Socket sock) {

super();

this.window = window;

this.sock = sock;

}

public void run(){

while(true){

try {

InputStream ss=sock.getInputStream();

BufferedReader br=new BufferedReader(new InputStreamReader(ss,"gbk"));

String line=null;

while((line=br.readLine())!=null){

window.updateHistory(SocketUtil.getAddr(sock), line);

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

//界面设置

package com.it18zhang16;


import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import java.util.ArrayList;

import java.util.HashSet;

import java.util.List;

import java.util.Set;


import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JTable;

import javax.swing.JTextArea;

import javax.swing.table.AbstractTableModel;

import javax.swing.table.TableModel;


public class MyWindow extends JFrame{


/**

*/

private static final long serialVersionUID = -7279041927148205095L;

//界面四块 

private JTextArea taHistory;

private JTextArea taContent;

private JButton btnSend;

private JTable table;

public MyWindow(){

ini();

}

private void ini(){

//布局

this.setLayout(null);

this.setSize(600, 400);

this.setLocation(500, 200);

//联系人列表

table =new JTable();

table.setBounds(450, 0, 150, 400);

this.add(table);

//文本域

taHistory =new JTextArea();

taHistory.setBounds(0, 0, 440, 280);

this.add(taHistory);

//输入区

taContent=new JTextArea();

taContent.setBounds(0, 290, 385, 110);

this.add(taContent);

//按钮

btnSend=new JButton("发送");

btnSend.setBounds(390,290, 60, 110);

this.add(btnSend);

//设置界面可见

this.setVisible(true);

//设置界面关闭程序关闭事件

this.addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e){

System.exit(-1);

}

});

}

//刷新联系人

public void refreshContacts(List<String> clients){

Set<String> set=new HashSet<String>(clients);

final List<String> newclients=new ArrayList<String>(set);

TableModel dataModel=new AbstractTableModel() {

public Object getValueAt(int rowIndex, int columnIndex) {

return newclients.get(rowIndex);

}

public int getRowCount() {

return newclients.size();

}

public int getColumnCount() {

return 1;

}

};

table.setModel(dataModel);

}

//更新聊天记录

public void updateHistory(String addr,String line){

//原文

String old=taHistory.getText();

StringBuilder sb=new StringBuilder();

sb.append(old);

sb.append("\r\n");

sb.append(addr);

sb.append("\r\n");

sb.append(line);

//更新聊天区域

taHistory.setText(sb.toString());

}

}

//获取ip串

package com.it18zhang16;


import java.net.Socket;


public class SocketUtil {

//返回地址串

public static String getAddr(Socket socket){

String ip=socket.getInetAddress().getHostAddress();

//只取ip最后一位

String ip0=ip.substring(ip.lastIndexOf(".")+1);

return ip0+":"+socket.getPort();

}

}

package com.it18zhang16;


public class App {


/**

* @param args

*/

public static void main(String[] args) {

MyWindow mw=new MyWindow();

MessageServer  ms=new MessageServer(mw);

ms.start(1234);

}


}

3.在分线程中完成ServerSocket推送消息给所有客户端。

List<OutputStream> ... = ;

4.推送联系人列表给所有客户端。