JTable使用:TableModel和JScrollPane、Vector
JTable:可以理解為表示數(shù)據(jù)的展現(xiàn)組件
TableModel:用于封裝數(shù)據(jù)組件
Vector: 隊(duì)列
package com.huaxin.server; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.util.ArrayList; import javax.swing.JOptionPane; import com.huaxin.UI.InfoPanel; import com.huaxin.UI.TablePanel; public class MyServer { public static ArrayList<ServerThread> serverList = new ArrayList<ServerThread>(); public int port; public ServerSocket server; private TablePanel tablePanel; private InfoPanel infoPanel; public MyServer(int port, TablePanel tablePanel, InfoPanel infoPanel) { this.port=port; this.tablePanel=tablePanel; this.infoPanel=infoPanel; } //啟動(dòng)服務(wù)器 public void startServer(){ try { //創(chuàng)建服務(wù)器對(duì)象 server = new ServerSocket(port); System.out.println("服務(wù)器已啟動(dòng)......"); while(true){ //服務(wù)器連接客戶(hù)端,阻塞方法 Socket socket=server.accept(); System.out.println("有客戶(hù)端連進(jìn)來(lái)了......"); ServerThread st = new ServerThread(socket,tablePanel,infoPanel); st.start(); serverList.add(st); } } catch (BindException e) { JOptionPane.showMessageDialog(null, "端口號(hào)已占用!請(qǐng)重新啟動(dòng)服務(wù)器并輸入新的端口號(hào)!"); System.exit(0); } catch (SocketException e) { JOptionPane.showMessageDialog(null, "服務(wù)器已關(guān)閉....."); } catch (Exception e) { e.printStackTrace(); } } public void sendMsgToClient(String s) { for (int i = 0; i <serverList.size(); i++) { //群發(fā)系統(tǒng)消息 ServerThread st = MyServer.serverList.get(i); //獲得每一個(gè)客戶(hù)真?zhèn)€輸出流 OutputStream ous; try { ous = st.socket.getOutputStream(); st.sendMsg(ous,"The System send a msg :"+s); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } infoPanel.jta.append("System Msg :"+s+"\r\n"); } }
package com.huaxin.server; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Vector; import com.huaxin.UI.InfoPanel; import com.huaxin.UI.TablePanel; import javafx.scene.control.TabPane; public class ServerThread extends Thread { public Socket socket; public InputStream ins; public OutputStream os; public String str; public String name; public String pwd; private TablePanel tablePanel; private InfoPanel infoPanel; public ServerThread(Socket socket, TablePanel tablePanel, InfoPanel infoPanel) { this.socket = socket; this.tablePanel=tablePanel; this.infoPanel=infoPanel; } public void run() { Vector<String> vs=null; try { // 獲得輸入輸出流 ins = socket.getInputStream(); os = socket.getOutputStream(); str = "welcome to zhou's Server"; // 向客戶(hù)端輸出信息 sendMsg(os, str); os.flush(); /************客戶(hù)端登錄和驗(yàn)證****************/ //獲得客戶(hù)端輸入的賬戶(hù)和密碼 getMsg(); //賬號(hào)和密碼校驗(yàn) boolean falg =loginCheck(); //校驗(yàn)不通過(guò)時(shí),循環(huán)校驗(yàn) while(!falg){ str="Fail to connect server......"; sendMsg(os, str); os.flush(); str="please check your name and password and login again....."; sendMsg(os, str); os.flush(); getMsg(); falg =loginCheck(); } //校驗(yàn)成功后:開(kāi)始聊天 str="successful connected..... you can chat with your friends now ......"; // str="yes"; sendMsg(os, str); os.flush(); //登錄成功后,將用戶(hù)名,ip地址和登錄時(shí)間加到TabelPanel中的Table中 //先獲得到TabelPanel中的Table對(duì)象,1層1層傳遞過(guò)來(lái) String ip =socket.getRemoteSocketAddress().toString(); Date date = new Date(); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String currentTime =sdf.format(date); //封裝用戶(hù)名,ip地址和時(shí)間 vs = new Vector<String>(); vs.add(name); vs.add(ip); vs.add(currentTime); //將封裝好的vs加入到tablePanel面板的table中,并刷新面板 tablePanel.data.add(vs); tablePanel.table.updateUI(); // 接受客戶(hù)真?zhèn)€信息 String s = readMsg(ins); while (!s.equals("bye")) { //在消息框中顯示發(fā)送的信息 infoPanel.jta.append(name+" say:"+s+"\r\n"); for (int i = 0; i < MyServer.serverList.size(); i++) { //群發(fā)消息 ServerThread st = MyServer.serverList.get(i); //不給自己發(fā)消息 if (st == this) continue; OutputStream ous =st.socket.getOutputStream(); sendMsg(ous,name+" say:"+s); os.flush(); } //循環(huán)讀取信息 s = readMsg(ins); } // server.close(); } catch (Exception e) { // e.printStackTrace(); System.out.println("客戶(hù)端不正常退出......"); } //關(guān)閉客戶(hù)端后,將該用戶(hù)的記錄從向量隊(duì)里中移除,并刷新面板 if(vs!=null){ this.tablePanel.data.remove(vs); this.tablePanel.table.updateUI(); } // 關(guān)閉流、服務(wù)器、套接字 try { ins.close(); os.close(); socket.close(); MyServer.serverList.remove(this); } catch (IOException e) { // System.out.println("這個(gè)地方有毛病......"); e.printStackTrace(); } } //發(fā)送消息的函數(shù) public void sendMsg(OutputStream os, String s) throws IOException { // 向客戶(hù)端輸出信息 // byte[] bytes = s.getBytes(); os.write(bytes); os.write(13); os.write(10); os.flush(); } //讀取客戶(hù)端輸入數(shù)據(jù)的函數(shù) public String readMsg(InputStream ins) throws Exception { // 讀取客戶(hù)真?zhèn)€信息 int value = ins.read(); // 讀取整行 讀取到回車(chē)(13)換行(10)時(shí)停止讀 String str = ""; while (value != 10) { //點(diǎn)擊關(guān)閉客戶(hù)端時(shí)會(huì)返回⑴值 if(value ==⑴){ throw new Exception(); } str = str + ((char) value); value = ins.read(); } str = str.trim(); return str; } //獲得客戶(hù)端賬號(hào)和密碼的函數(shù) public void getMsg() throws Exception { str="please enter your name :"; sendMsg(os, str); os.flush(); name =readMsg(ins); str="please enter your password :"; sendMsg(os, str); os.flush(); pwd =readMsg(ins); } //校驗(yàn)客戶(hù)端輸入的賬號(hào)和密碼的函數(shù) public boolean loginCheck() throws Exception{ if(name.equals("zhou") && pwd.equals("zhou") || name.equals("user") && pwd.equals("pwd") || name.equals("huaxinjiaoyu") && pwd.equals("huaxinjiaoyu")){ return true; } return false; } }
package com.huaxin.UI; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import com.huaxin.server.MyServer; import com.huaxin.server.ServerThread; public class StartPanel extends JPanel{ public JTextField jtf; public JButton startBtn; public JButton stoptBtn; public boolean flag=true; public MyServer ms ; public TablePanel tablePanel; public InfoPanel infoPanel; /* * 最上面的面板類(lèi) */ public StartPanel(TablePanel tablePanel, InfoPanel infoPanel) { this.tablePanel=tablePanel; this.infoPanel=infoPanel; //創(chuàng)建相干組件 JLabel label =new JLabel("端口號(hào)"); jtf = new JTextField(10); startBtn = new JButton("啟動(dòng)服務(wù)"); //設(shè)置按鈕不可操作 startBtn.setEnabled(false); stoptBtn = new JButton("關(guān)閉服務(wù)"); stoptBtn.setEnabled(false); //設(shè)置背景色彩 this.setBackground(Color.green); //設(shè)置面板大小 this.setPreferredSize(new Dimension(0,50)); this.setLayout(new FlowLayout()); //組件添加 this.add(label); this.add(jtf); this.add(startBtn); this.add(stoptBtn); //給兩個(gè)按鈕添加監(jiān)聽(tīng)器 startBtn.addActionListener(al); stoptBtn.addActionListener(al); //檢測(cè)輸入框是不是為空 checkText(); } //按鈕監(jiān)聽(tīng)器的具體實(shí)現(xiàn) ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e) { String command =e.getActionCommand(); if(command.equals("啟動(dòng)服務(wù)")){ //啟動(dòng)服務(wù)的相干邏輯操作 flag=false; int port =Integer.parseInt(jtf.getText()); ms = new MyServer(port,tablePanel,infoPanel); infoPanel.ms=ms; stoptBtn.setEnabled(true); startBtn.setEnabled(false); //用線(xiàn)程處理,避免阻塞 new Thread(){ public void run() { ms.startServer(); }; }.start(); }else if(command.equals("關(guān)閉服務(wù)")){ try { // flag=true; //關(guān)閉服務(wù)邏輯實(shí)現(xiàn) //移除所有的客戶(hù)端 while(ms.serverList.size()!=0) { ms.serverList.get(0).socket.close(); ms.serverList.remove(0); } //服務(wù)器關(guān)閉 ms.server.close(); //設(shè)置按鈕可操作屬性 stoptBtn.setEnabled(false); startBtn.setEnabled(true); } catch (IOException e1) { e1.printStackTrace(); } } } }; //線(xiàn)程檢測(cè)文本輸入框是不是有輸入 public void checkText(){ new Thread(){ public void run() { while(flag){ //獲得文本輸入框的信息 String info=jtf.getText(); //信息不為空或"",則可以啟動(dòng)服務(wù)器 if(!(info==null || info.equals(""))){ startBtn.setEnabled(true); } try { this.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } }; }.start(); } }
package com.huaxin.UI; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.util.Vector; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; public class TablePanel extends JPanel { public JTable table; public Vector<Vector<String>> data; public TablePanel() { //設(shè)置面板屬性 this.setPreferredSize(new Dimension(450,0)); this.setBackground(Color.white); this.setLayout(new BorderLayout()); //創(chuàng)建表格 Vector<String> colNames = new Vector<String>(); colNames.add("用戶(hù)名"); colNames.add("IP地址"); colNames.add("登錄時(shí)間"); data =new Vector<Vector<String>>(); Vector<String> vs=new Vector<String>(); //創(chuàng)建表格模型 DefaultTableModel tm =new DefaultTableModel(data, colNames); table = new JTable(tm); //創(chuàng)建轉(zhuǎn)動(dòng)條 JScrollPane jsp =new JScrollPane(table); this.add(jsp); } }
package com.huaxin.UI; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import com.huaxin.server.MyServer; public class InfoPanel extends JPanel{ public MyServer ms ; public JTextArea jta; public JTextField jtf; public InfoPanel() { //設(shè)置信息面板的屬性 this.setPreferredSize(new Dimension(350,0)); this.setBackground(Color.blue); this.setLayout(new BorderLayout()); //文本輸入域 jta = new JTextArea(); //設(shè)置自動(dòng)換行 jta.setLineWrap(true); JScrollPane jsp = new JScrollPane(jta); this.add(jsp); //面板底部的發(fā)送面板 jtf = new JTextField(25); JButton btn = new JButton("發(fā)送"); //發(fā)送按鈕添加監(jiān)聽(tīng)器 btn.addActionListener(al); JPanel panel=new JPanel(); panel.setLayout(new FlowLayout()); this.add(panel,BorderLayout.SOUTH); panel.add(jtf); panel.add(btn); } //監(jiān)聽(tīng)具體實(shí)現(xiàn) ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e) { //獲得內(nèi)容 String s=jtf.getText(); //為空的提示信息 if( s==null || "".equals(s)){ JOptionPane.showMessageDialog(null, "輸入框不能為空!"); } else if(ms.server.isClosed()){ JOptionPane.showMessageDialog(null, "服務(wù)器已關(guān)閉,不能發(fā)送消息!"); }else{ try { //不為空,則將消息發(fā)送給服務(wù)器,服務(wù)器轉(zhuǎn)發(fā)給消息給每一個(gè)客戶(hù)端 ms.sendMsgToClient(s); //清空文本 jtf.setText(""); } catch (Exception e1) { e1.printStackTrace(); } } } }; }
package com.huaxin.UI; import java.awt.BorderLayout; import javax.swing.JFrame; /* * 服務(wù)器后臺(tái)界面類(lèi) */ public class UIFrame extends JFrame { public TablePanel tablePanel; public InfoPanel infoPanel ; public static void main(String[] args) { UIFrame ui = new UIFrame(); ui.initFrame(); } public void initFrame() { // 設(shè)置窗體的相干屬性 this.setSize(800, 600); this.setTitle("服務(wù)器后臺(tái)界面"); this.setDefaultCloseOperation(3); this.setLocationRelativeTo(null); this.setLayout(new BorderLayout()); tablePanel = new TablePanel(); infoPanel = new InfoPanel(); StartPanel startPanel = new StartPanel(tablePanel,infoPanel); //在主頁(yè)面中添加3個(gè)面板 this.add(startPanel,BorderLayout.NORTH); this.add(tablePanel, BorderLayout.CENTER); this.add(infoPanel, BorderLayout.EAST); this.setVisible(true); } }