用户登录
ClientLogin.java
package QQDome;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
@SuppressWarnings("serial")
public class ClientLogin extends JFrame {
private JTextField nameTxt;
private JPasswordField jPasswordField;
public ClientLogin() {
// TODO 自动生成的构造函数存根
this.init();
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
public void init(){
this.setTitle("聊天登录界面");
//this.setSize(330, 230);
this.setBounds(200, 500, 340, 230);
int x = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth();
int y = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight();
this.setLocation(x-this.getWidth() / 2, y-this.getHeight() / 2);
this.setResizable(false);
this.setVisible(true);
//登录信息面板
JPanel mainPanel = new JPanel();
Border border = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
mainPanel.setBorder(BorderFactory.createTitledBorder(border, "输入登录信息", TitledBorder.CENTER, TitledBorder.TOP));
this.add(mainPanel,BorderLayout.CENTER);
mainPanel.setLayout(null);
JLabel nameLbl = new JLabel("请输入昵称: ");
nameLbl.setBounds(30,30,80,22);
mainPanel.add(nameLbl);
nameTxt = new JTextField();
nameTxt.setBounds(115,30,120,22);
mainPanel.add(nameTxt);
JLabel pwdLbl = new JLabel("请输入密码: ");
pwdLbl.setBounds(30,60,80,22);
mainPanel.add(pwdLbl);
jPasswordField = new JPasswordField();
jPasswordField.setBounds(115, 60, 120, 22);
mainPanel.add(jPasswordField);
//按钮面板放置在JFrame的南边
JPanel btnPanel = new JPanel();
btnPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
this.add(btnPanel, BorderLayout.SOUTH);
JButton resetBtn = new JButton("重置");
resetBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO 自动生成的方法存根
nameTxt.setText("");
jPasswordField.setText("");
}
});
btnPanel.add(resetBtn);
JButton submitBtn = new JButton("登录");
submitBtn.addActionListener(new LoginAction(this));
btnPanel.add(submitBtn);
}
//登录时间处理类
class LoginAction implements ActionListener{
private JFrame self;
public LoginAction(JFrame self) {
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO 自动生成的方法存根
System.out.println("用户名是" + nameTxt.getText() + ",密码是" + new String(jPasswordField.getPassword()));
try {
//链接服务器
Socket socket = new Socket("127.0.0.1", 8888);
//连接上之后,显示聊天窗口
new ChatClient(socket, nameTxt.getText());
//本窗口销毁
self.dispose();
}catch (UnknownHostException e1) {
// TODO: handle exception
e1.printStackTrace();
JOptionPane.showConfirmDialog(self, "找不到指定的服务器!","链接失败", JOptionPane.OK_OPTION,JOptionPane.ERROR_MESSAGE);
}catch (IOException e1) {
// TODO: handle exception
e1.printStackTrace();
JOptionPane.showConfirmDialog(self, "找不到指定的服务器!","链接失败", JOptionPane.OK_OPTION,JOptionPane.ERROR_MESSAGE);
}
}
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
JFrame.setDefaultLookAndFeelDecorated(true);
JDialog.setDefaultLookAndFeelDecorated(true);
new ClientLogin();
}
}
聊天室的客户端
ChatClient.java
package QQDome;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
@SuppressWarnings("serial")
public class ChatClient extends JFrame{
//负责跟服务器通讯的Socket
private Socket socket;
//要发送的内容区域
private JTextArea sendArea;
//聊天记录区域
private JTextArea contentArea;
//当前用户的昵称
private String name;
public ChatClient(Socket socket,String name) {
// TODO 自动生成的构造函数存根
this.name = name;
this.socket = socket;
this.init();
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
//启动一个单独的线程关门从服务器中读取数据
ClientThread thread = new ClientThread(socket, contentArea);
thread.start();
}
public void init() {
this.setTitle("我的聊天室");
this.setSize(300,400);
int x = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth();
int y = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight();
this.setLocation(x-this.getWidth()/2, y-this.getHeight()/2);
this.setVisible(false);
contentArea = new JTextArea();
contentArea.setLineWrap(true);
JScrollPane logPane = new JScrollPane(contentArea,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
sendArea = new JTextArea();
sendArea.setLineWrap(true);
JScrollPane sendPane = new JScrollPane(sendArea,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
//创建一个分割窗口
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,logPane,sendPane);
splitPane.setDividerSize(10);
this.add(splitPane,BorderLayout.CENTER);
//按钮面板
JPanel btnPanel = new JPanel();
btnPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
this.add(btnPanel, BorderLayout.SOUTH);
JLabel nameLbl = new JLabel("昵称: " + this.name + " ");
btnPanel.add(nameLbl);
JButton resetBtn = new JButton("关闭");
resetBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO 自动生成的方法存根
}
});
btnPanel.add(resetBtn);
JButton submitBtn = new JButton("发送");
//发送数据到服务器
submitBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO 自动生成的方法存根
//要发送的内容
String str = sendArea.getText();
SimpleDateFormat formater = new SimpleDateFormat("HH:mm:ss"); //设定时间格式
String time = formater.format(new Date());
String sendStr = name + " " + time + "说: " + str;
//往服务器发送
PrintWriter out = null;
try {
out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
out.println(sendStr);
out.flush();
}catch (IOException e1) {
// TODO: handle exception
e1.printStackTrace();
}
sendArea.setText("");
}
});
btnPanel.add(submitBtn);
}
//客户端跟服务器通讯的线程类
class ClientThread extends Thread{
//客户端跟服务器连接上的Socket
private Socket socket;
//聊天记录区域
private JTextArea contentArea;
public ClientThread(Socket socket,JTextArea contentArea) {
this.socket = socket;
this.contentArea = contentArea;
}
public void run() {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//从输入流中读取数据添加到聊天记录区域中
String str = null;
while((str = bufferedReader.readLine()) != null) {
contentArea.append(str);
contentArea.append("\n");
}
}catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}finally {
if (bufferedReader!=null) {
try {
bufferedReader.close();
}catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
Socket socket = null;
String name = null;
new ChatClient(socket,name);
}
}
聊天室的服务器端
ChatServer.java
package QQServer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class ChatServer {
//用来保存所有客户端的socket信息
private ArrayList<Socket> sockets = new ArrayList<Socket>();
public ChatServer() throws IOException{
this.init();
}
public void init() throws IOException {
ServerSocket ss =new ServerSocket(8888);
System.out.println("服务器已经开始监听8888端口了...");
//监听并接受客户端
while(true) {
Socket socket = ss.accept();
sockets.add(socket);
String ip = socket.getInetAddress().getHostAddress();
System.out.println("有一个客户端来了他的IP地址是: " + ip);
//针对每一个客户端都启动一个线程单独跟他通信
Thread thread = new Thread(new ServerRunner(sockets,socket));
thread.start();
}
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
try {
new ChatServer();
}catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
//服务器跟客户端通信的线程类
//把某个客户端发过来的数据转发给所有客户端
class ServerRunner implements Runnable{
private ArrayList<Socket> sockets;
private Socket currentsocket;
public ServerRunner(ArrayList<Socket> sockets,Socket currentsocket) {
// TODO 自动生成的构造函数存根
this.sockets = sockets;
this.currentsocket = currentsocket;
}
@Override
public void run() {
// TODO 自动生成的方法存根
String ip = currentsocket.getInetAddress().getHostAddress();
BufferedReader bReader = null;
try {
bReader = new BufferedReader(new InputStreamReader(currentsocket.getInputStream()));
String str = null;
while((str = bReader.readLine()) != null){
System.out.println(ip + "说:" + str);
//往所有客户端socket写信息
for(Socket temp:sockets) {
PrintWriter pw = new PrintWriter(new OutputStreamWriter(temp.getOutputStream()));
pw.println(str);
pw.flush();
}
}
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}