先放效果圖:java
登錄:服務器
/**在本類109行附近調用了ChatClient類 * */ import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.Toolkit; import java.io.File; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; 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; public class ClientLogin extends JFrame { private JTextField nametext ; private JPasswordField passwordtetx ; //private Object bPanel; public ClientLogin() { this.init() ; //init方法初始化 this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true); } public void init() { this.setTitle("呆萌聊天室登錄"); this.setSize(330,230); //借用成熟美觀尺寸 int y = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight() ; int x = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth() ; /**以上的方法要是不借助Eclipse實在是很難記住,尼瑪! * */ this.setLocation( (x-this.getWidth() )/2, ( y-this.getHeight() )/2 ); this.setResizable(false); //不容許用戶自行更改大小 Icon icon = new ImageIcon("d:"+File.separator+"login.jpg") ; JLabel label = new JLabel(icon) ; //設置登錄界面上邊框 this.add(label,BorderLayout.NORTH) ; JPanel mainPanel = new JPanel() ; Border border = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED) ; mainPanel.setBorder(BorderFactory.createTitledBorder(border,"輸入登錄信息",TitledBorder.CENTER,TitledBorder.TOP)) ; this.add(mainPanel,BorderLayout.CENTER) ; //將主面板加入frame mainPanel.setLayout(null) ; JLabel namelabel = new JLabel("請輸入暱稱") ; namelabel.setBounds(30,30,80,22) ; mainPanel.add(namelabel) ; nametext = new JTextField() ; nametext.setBounds(115,30,120,22); mainPanel.add(nametext) ; JLabel passwordlabel = new JLabel("請輸入密碼") ; passwordlabel.setBounds(30,60,80,22); mainPanel.add(passwordlabel) ; passwordtetx = new JPasswordField() ; passwordtetx.setBounds(115,60,120,22) ; mainPanel.add(passwordtetx) ; //接下來按鈕位置排放 JPanel bPanel = new JPanel() ; bPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)) ; this.add(bPanel,BorderLayout.SOUTH) ; JButton reset = new JButton("重置") ; reset.addActionListener(new ActionListener() { //爲「重置」按鈕添加事件監聽 public void actionPerformed(ActionEvent e) { nametext.setText(""); passwordtetx.setText(""); } }); bPanel.add(reset) ; /**下面開始實現提交按鈕 * */ JButton submit = new JButton("登錄") ; submit.addActionListener(new LoginAction(this) ); //由於登錄相對複雜,從新爲登錄寫一個類 bPanel.add(submit) ; } /**下面開始寫登錄類 * */ class LoginAction implements ActionListener { private JFrame self ; public LoginAction(JFrame self) { this.self = self ; } public void actionPerformed(ActionEvent e) { //System.out.println("用戶名是:"+nametext.getText()+" 密碼是:"+new String(passwordtext.getPassword())) ; try { //開始鏈接到服務器 Socket socket = new Socket("127.0.0.1",8888) ; new ChatClient(socket,nametext.getText()) ; //調用dispose方法關閉登錄框 self.dispose(); }catch(UnknownHostException e1) { e1.printStackTrace(); JOptionPane.showConfirmDialog(self, "找不到指定服務器!~","鏈接失敗",JOptionPane.OK_OPTION,JOptionPane.ERROR_MESSAGE) ; }catch(IOException e1) { e1.printStackTrace() ; JOptionPane.showConfirmDialog(self, "鏈接服務器出錯,請重試!","鏈接失敗",JOptionPane.OK_OPTION,JOptionPane.ERROR_MESSAGE) ; } } } public static void main(String args[]) { new ClientLogin() ; } }
客戶端:app
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.util.Date; import java.text.SimpleDateFormat; 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; public class ChatClient extends JFrame { private Socket socket ; //負責和服務器通訊 private JTextArea sendArea ; //消息編輯區域 private JTextArea contentArea ; //羣聊消息顯示框 private String name ; //當前用戶名稱 public ChatClient(Socket socket,String name) { this.socket = socket ; this.name = name ; 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.setResizable(false); //不容許用戶改變大小 contentArea = new JTextArea() ; contentArea.setLineWrap(true); //換行方法 JScrollPane logPanel = new JScrollPane(contentArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER ) ; sendArea = new JTextArea() ; sendArea.setLineWrap(true); //控制每行顯示長度最大不超過界面長度 JScrollPane sendPanel = new JScrollPane(sendArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER ) ; //建立一個分隔窗格 JSplitPane splitpane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,logPanel,sendPanel) ; splitpane.setDividerLocation(250); this.add(splitpane,BorderLayout.CENTER) ; //按鈕面板 JPanel bPanel = new JPanel() ; bPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)) ; this.add(bPanel,BorderLayout.SOUTH) ; JLabel namelabel = new JLabel("暱稱: "+this.name+" ") ; bPanel.add(namelabel) ; JButton closeButton = new JButton("關閉") ; closeButton.addActionListener( new ActionListener( ) { public void actionPerformed(ActionEvent e) { } }); bPanel.add(closeButton) ; JButton sendButton = new JButton("發送") ; sendButton.addActionListener(new ActionListener() { //@Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub 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(Exception e1) { e1.printStackTrace(); } sendArea.setText(""); } }); bPanel.add(sendButton) ; } } //客戶端與服務器端通訊的線程類 class ClientThread extends Thread { private Socket socket ; private JTextArea contentArea ; public ClientThread(Socket socket, JTextArea conteArea) { this.socket = socket ; this.contentArea = conteArea ; } public void run() { BufferedReader br = null ; try { br = new BufferedReader(new InputStreamReader( socket.getInputStream())) ; String str = null ; while( (str = br.readLine()) != null) { System.out.println(str) ; contentArea.append(str); contentArea.append("\n"); } } catch(IOException e) { e.printStackTrace(); } finally { if(br != null) { try { br.close () ; }catch(IOException e) { e.printStackTrace(); } } } }}
服務器端:socket
import java.util.List; 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 { private List<Socket> sockets = new ArrayList<Socket>() ; //類集的應用 public ChatServer() 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[]) { try { new ChatServer() ; } catch(Exception e) { e.printStackTrace(); } } } class ServerRunner implements Runnable { private List<Socket> sockets ; private Socket currentSocket ; //當前socket public ServerRunner (List<Socket> sockets,Socket currentSocket) { this.sockets = sockets ; this.currentSocket = currentSocket ; } public void run() { String ip = currentSocket.getInetAddress().getHostAddress() ; BufferedReader br = null ; try { br = new BufferedReader(new InputStreamReader(currentSocket.getInputStream())) ; String str = null ; while((str = br.readLine()) != null) { System.out.println(ip+"說"+str) ; //往全部的客戶端寫入信息 for(Socket temp : sockets) { PrintWriter pw = new PrintWriter(new OutputStreamWriter(temp.getOutputStream())) ; pw.println(str) ; pw.flush(); } } }catch(IOException e) { e.printStackTrace(); } } }