本不想使用swing这种过时技术,只不过学校实验要求。。。。
最后结果如图:
附上代码:
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Client extends JFrame implements Runnable {
Socket socket;
ServerSocket server;
private static JPanel contentPane;
private static JTextField inputArea;
protected static JTextArea recordPane;
private JFrame frame;
public Client() {
try {
frame=new JFrame("客户端");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 420, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
frame.setContentPane(contentPane);
contentPane.setLayout(null);
//发送按钮
JButton btnSend = new JButton("发送");
JButton btnExit = new JButton("退出");
btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
new sendThread().start();
}
});
btnExit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
frame.dispatchEvent(new WindowEvent(frame,WindowEvent.WINDOW_CLOSING) );
}
});
btnSend.setBounds(270, 210, 60, 50);
btnExit.setBounds(340, 210, 60, 50);
contentPane.add(btnSend);
contentPane.add(btnExit);
//聊天记录面板
recordPane = new JTextArea();
recordPane.setBounds(9, 9, 400, 190);
contentPane.add(recordPane);
//输入框
inputArea = new JTextField();
inputArea.setBounds(2, 210, 250, 75);
contentPane.add(inputArea);
inputArea.setColumns(10);
frame.setVisible(true);
try {
socket = new Socket("127.0.0.1",8080);
server=new ServerSocket(8081);
recordPane.append("客户已启动!\n");
} catch (Exception e){
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
while (true) {
InputStream in = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(in,"UTF-8");
BufferedReader br = new BufferedReader(isr);
String line = null;
while((line = br.readLine())!=null) {
recordPane.append("蛋蛋说:"+line+"\n");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
class sendThread extends Thread{
@Override
public void run() {
super.run();
try {
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw,true);
String line=inputArea.getText();
if(!line.equals("")) {
inputArea.setText("");
pw.println(line);
recordPane.append("我说:"+line+"\n");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Client client = new Client();
new Thread(client).start();
}
}
下面是Server类
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server extends JFrame implements Runnable {
ServerSocket server;
Socket socket;
private static JPanel contentPane;
private static JTextField inputArea;
protected static JTextArea recordPane;
private JFrame frame;
public Server() {
frame=new JFrame("服务端");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 420, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
frame.setContentPane(contentPane);
contentPane.setLayout(null);
//发送按钮
JButton btnSend = new JButton("发送");
JButton btnExit = new JButton("退出");
btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
new sendThread().start();
}
});
btnExit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
frame.dispatchEvent(new WindowEvent(frame,WindowEvent.WINDOW_CLOSING) );
}
});
btnSend.setBounds(270, 210, 60, 50);
btnExit.setBounds(340, 210, 60, 50);
contentPane.add(btnSend);
contentPane.add(btnExit);
//聊天记录面板
recordPane = new JTextArea();
recordPane.setBounds(9, 9, 400, 190);
contentPane.add(recordPane);
//输入框
inputArea = new JTextField();
inputArea.setBounds(2, 210, 250, 75);
contentPane.add(inputArea);
inputArea.setColumns(10);
frame.setVisible(true);
try {
System.out.println("正在启动服务端...");
server = new ServerSocket(8080);
System.out.println("服务端启动完毕!");
} catch (Exception e){
e.printStackTrace();
}
}
@Override
public void run() {
try {
while(true){
socket = server.accept();
recordPane.append("服务器已启动!\n");
InputStream in = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(in,"UTF-8");
BufferedReader br = new BufferedReader(isr);
String line = null;
while((line = br.readLine())!=null){
recordPane.append("狗狗说:"+line+"\n");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
class sendThread extends Thread{
@Override
public void run() {
super.run();
try {
if(socket!=null){
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw;
BufferedWriter bw;
PrintWriter pw;
osw = new OutputStreamWriter(out,"UTF-8");
bw = new BufferedWriter(osw);
pw = new PrintWriter(bw,true);
String line=inputArea.getText();
if(!line.equals("")) {
inputArea.setText("");
pw.println(line);
recordPane.append("我说:"+line+"\n");
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Server server = new Server();
new Thread(server).start();
}
}
这个聊天室其实就服务端使用两个线程,一个线程让Java swing里响应触发(也就是点击发送,获取到了你在文本框输入的值,然后发送)。客户端的两个线程也是类似,一个无限循环获取服务端来的值,一个点击发送响应得到你写的值,使用outputstream 写回到服务端