参照视频,编写出聊天程序。
知识点分析:
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.推送联系人列表给所有客户端。