JTable使用:TableModel和JScrollPane、Vector
JTable:可以理解为表示数据的展现组件
TableModel:用于封装数据组件
Vector: 队列
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; } //启动服务器 public void startServer(){ try { //创建服务器对象 server = new ServerSocket(port); System.out.println("服务器已启动......"); while(true){ //服务器连接客户端,阻塞方法 Socket socket=server.accept(); System.out.println("有客户端连进来了......"); ServerThread st = new ServerThread(socket,tablePanel,infoPanel); st.start(); serverList.add(st); } } catch (BindException e) { JOptionPane.showMessageDialog(null, "端口号已占用!请重新启动服务器并输入新的端口号!"); System.exit(0); } catch (SocketException e) { JOptionPane.showMessageDialog(null, "服务器已关闭....."); } catch (Exception e) { e.printStackTrace(); } } public void sendMsgToClient(String s) { for (int i = 0; i <serverList.size(); i++) { //群发系统消息 ServerThread st = MyServer.serverList.get(i); //获得每一个客户真个输出流 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"; // 向客户端输出信息 sendMsg(os, str); os.flush(); /************客户端登录和验证****************/ //获得客户端输入的账户和密码 getMsg(); //账号和密码校验 boolean falg =loginCheck(); //校验不通过时,循环校验 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(); } //校验成功后:开始聊天 str="successful connected..... you can chat with your friends now ......"; // str="yes"; sendMsg(os, str); os.flush(); //登录成功后,将用户名,ip地址和登录时间加到TabelPanel中的Table中 //先获得到TabelPanel中的Table对象,1层1层传递过来 String ip =socket.getRemoteSocketAddress().toString(); Date date = new Date(); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String currentTime =sdf.format(date); //封装用户名,ip地址和时间 vs = new Vector<String>(); vs.add(name); vs.add(ip); vs.add(currentTime); //将封装好的vs加入到tablePanel面板的table中,并刷新面板 tablePanel.data.add(vs); tablePanel.table.updateUI(); // 接受客户真个信息 String s = readMsg(ins); while (!s.equals("bye")) { //在消息框中显示发送的信息 infoPanel.jta.append(name+" say:"+s+"\r\n"); for (int i = 0; i < MyServer.serverList.size(); i++) { //群发消息 ServerThread st = MyServer.serverList.get(i); //不给自己发消息 if (st == this) continue; OutputStream ous =st.socket.getOutputStream(); sendMsg(ous,name+" say:"+s); os.flush(); } //循环读取信息 s = readMsg(ins); } // server.close(); } catch (Exception e) { // e.printStackTrace(); System.out.println("客户端不正常退出......"); } //关闭客户端后,将该用户的记录从向量队里中移除,并刷新面板 if(vs!=null){ this.tablePanel.data.remove(vs); this.tablePanel.table.updateUI(); } // 关闭流、服务器、套接字 try { ins.close(); os.close(); socket.close(); MyServer.serverList.remove(this); } catch (IOException e) { // System.out.println("这个地方有毛病......"); e.printStackTrace(); } } //发送消息的函数 public void sendMsg(OutputStream os, String s) throws IOException { // 向客户端输出信息 // byte[] bytes = s.getBytes(); os.write(bytes); os.write(13); os.write(10); os.flush(); } //读取客户端输入数据的函数 public String readMsg(InputStream ins) throws Exception { // 读取客户真个信息 int value = ins.read(); // 读取整行 读取到回车(13)换行(10)时停止读 String str = ""; while (value != 10) { //点击关闭客户端时会返回⑴值 if(value ==⑴){ throw new Exception(); } str = str + ((char) value); value = ins.read(); } str = str.trim(); return str; } //获得客户端账号和密码的函数 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); } //校验客户端输入的账号和密码的函数 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; /* * 最上面的面板类 */ public StartPanel(TablePanel tablePanel, InfoPanel infoPanel) { this.tablePanel=tablePanel; this.infoPanel=infoPanel; //创建相干组件 JLabel label =new JLabel("端口号"); jtf = new JTextField(10); startBtn = new JButton("启动服务"); //设置按钮不可操作 startBtn.setEnabled(false); stoptBtn = new JButton("关闭服务"); stoptBtn.setEnabled(false); //设置背景色彩 this.setBackground(Color.green); //设置面板大小 this.setPreferredSize(new Dimension(0,50)); this.setLayout(new FlowLayout()); //组件添加 this.add(label); this.add(jtf); this.add(startBtn); this.add(stoptBtn); //给两个按钮添加监听器 startBtn.addActionListener(al); stoptBtn.addActionListener(al); //检测输入框是不是为空 checkText(); } //按钮监听器的具体实现 ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e) { String command =e.getActionCommand(); if(command.equals("启动服务")){ //启动服务的相干逻辑操作 flag=false; int port =Integer.parseInt(jtf.getText()); ms = new MyServer(port,tablePanel,infoPanel); infoPanel.ms=ms; stoptBtn.setEnabled(true); startBtn.setEnabled(false); //用线程处理,避免阻塞 new Thread(){ public void run() { ms.startServer(); }; }.start(); }else if(command.equals("关闭服务")){ try { // flag=true; //关闭服务逻辑实现 //移除所有的客户端 while(ms.serverList.size()!=0) { ms.serverList.get(0).socket.close(); ms.serverList.remove(0); } //服务器关闭 ms.server.close(); //设置按钮可操作属性 stoptBtn.setEnabled(false); startBtn.setEnabled(true); } catch (IOException e1) { e1.printStackTrace(); } } } }; //线程检测文本输入框是不是有输入 public void checkText(){ new Thread(){ public void run() { while(flag){ //获得文本输入框的信息 String info=jtf.getText(); //信息不为空或"",则可以启动服务器 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() { //设置面板属性 this.setPreferredSize(new Dimension(450,0)); this.setBackground(Color.white); this.setLayout(new BorderLayout()); //创建表格 Vector<String> colNames = new Vector<String>(); colNames.add("用户名"); colNames.add("IP地址"); colNames.add("登录时间"); data =new Vector<Vector<String>>(); Vector<String> vs=new Vector<String>(); //创建表格模型 DefaultTableModel tm =new DefaultTableModel(data, colNames); table = new JTable(tm); //创建转动条 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() { //设置信息面板的属性 this.setPreferredSize(new Dimension(350,0)); this.setBackground(Color.blue); this.setLayout(new BorderLayout()); //文本输入域 jta = new JTextArea(); //设置自动换行 jta.setLineWrap(true); JScrollPane jsp = new JScrollPane(jta); this.add(jsp); //面板底部的发送面板 jtf = new JTextField(25); JButton btn = new JButton("发送"); //发送按钮添加监听器 btn.addActionListener(al); JPanel panel=new JPanel(); panel.setLayout(new FlowLayout()); this.add(panel,BorderLayout.SOUTH); panel.add(jtf); panel.add(btn); } //监听具体实现 ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e) { //获得内容 String s=jtf.getText(); //为空的提示信息 if( s==null || "".equals(s)){ JOptionPane.showMessageDialog(null, "输入框不能为空!"); } else if(ms.server.isClosed()){ JOptionPane.showMessageDialog(null, "服务器已关闭,不能发送消息!"); }else{ try { //不为空,则将消息发送给服务器,服务器转发给消息给每一个客户端 ms.sendMsgToClient(s); //清空文本 jtf.setText(""); } catch (Exception e1) { e1.printStackTrace(); } } } }; }
package com.huaxin.UI; import java.awt.BorderLayout; import javax.swing.JFrame; /* * 服务器后台界面类 */ 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() { // 设置窗体的相干属性 this.setSize(800, 600); this.setTitle("服务器后台界面"); this.setDefaultCloseOperation(3); this.setLocationRelativeTo(null); this.setLayout(new BorderLayout()); tablePanel = new TablePanel(); infoPanel = new InfoPanel(); StartPanel startPanel = new StartPanel(tablePanel,infoPanel); //在主页面中添加3个面板 this.add(startPanel,BorderLayout.NORTH); this.add(tablePanel, BorderLayout.CENTER); this.add(infoPanel, BorderLayout.EAST); this.setVisible(true); } }