多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁(yè) > php開(kāi)源 > php教程 > Java小程序之服務(wù)器的UI實(shí)現(xiàn)

Java小程序之服務(wù)器的UI實(shí)現(xiàn)

來(lái)源:程序員人生   發(fā)布時(shí)間:2017-01-23 20:56:52 閱讀次數(shù):4180次

Java小程序之服務(wù)器的UI實(shí)現(xiàn)
1、前言:
前面我們做的服務(wù)器都是沒(méi)有界面的,只是利用簡(jiǎn)單的輸入輸出語(yǔ)句在控制臺(tái)中打印語(yǔ)句;今天,我們要讓服務(wù)器有界面,可視化操作;

2、UI功能需求:
3、知識(shí)點(diǎn)分析

JTable使用:TableModelJScrollPaneVector

JTable:可以理解為表示數(shù)據(jù)的展現(xiàn)組件

TableModel:用于封裝數(shù)據(jù)組件

Vector: 隊(duì)列

代碼框架

4、具體實(shí)現(xiàn)思路
1、先實(shí)現(xiàn)全部界面UI(功能暫時(shí)不著急)這里主要是JTable的使用,剛開(kāi)始啟動(dòng)按鈕和關(guān)閉按鈕都不能操作
2、最上方功能按鈕的實(shí)現(xiàn),當(dāng)界面初始化的時(shí)候,用1個(gè)線(xiàn)程開(kāi)始不斷檢測(cè)輸入框中是不是有內(nèi)容,有內(nèi)容則啟動(dòng)按鈕可操作;啟動(dòng)按鈕啟動(dòng)后,創(chuàng)建服務(wù)器對(duì)象,等待客戶(hù)真?zhèn)€連接,并將啟動(dòng)按鈕再次設(shè)置為不可操作,而關(guān)閉按鈕設(shè)置為可操作;
3、獲得客戶(hù)端輸入的賬戶(hù)和密碼,服務(wù)器校驗(yàn)成功后,將該賬號(hào)的相干信息進(jìn)行封裝,將封裝好的信息加到Table中顯示
4、顯示聊天功能,消息內(nèi)容昨天實(shí)在控制臺(tái)中打印的,這次,我們這要將從客戶(hù)端接收到的消息放在服務(wù)器界面UI中顯示便可;

5、源代碼:
源代碼結(jié)構(gòu)圖:
com.huaxin.server包:
MyServer類(lèi):(甚么時(shí)候啟動(dòng)服務(wù)器?當(dāng)點(diǎn)擊啟動(dòng)按鈕時(shí),履行者下面的代碼)
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");
	}
}

ServerThread類(lèi):
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;
 }
}

com.huaxin.UI包:
(該包分為將全部面板的3個(gè)區(qū)域分出了3個(gè)類(lèi),在UIFrame中創(chuàng)建該3個(gè)類(lèi),并整合3個(gè)類(lèi),到達(dá)上圖的整體效果)

StartPanel類(lèi):(最上面的面板類(lèi))
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();
	}
	

}


TablePanel類(lèi):登錄用戶(hù)信息顯示面板
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);
	}
	
	

}


InfoPanel類(lèi):聊天信息顯示面板
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();
				}
			}
		}
	};
}



UIFrame類(lèi):程序入口和面板整合類(lèi):
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);
	}	

}



6、運(yùn)行結(jié)果:

先啟動(dòng)界面UI類(lèi),輸入9090點(diǎn)擊啟動(dòng)服務(wù),開(kāi)啟服務(wù)器服務(wù)器1定要先打開(kāi),否則客戶(hù)端沒(méi)法連接





利用系統(tǒng)自帶的telnet客戶(hù)端,啟動(dòng)客戶(hù)端





輸入正確的密碼進(jìn)行登錄:





當(dāng)有用戶(hù)登錄進(jìn)來(lái)后的界面顯示效果:




以一樣的方法開(kāi)啟另外客戶(hù)端



界面UI小時(shí)效果:




在3個(gè)客戶(hù)端分別輸入聊天消息:




界面UI顯示效果:



測(cè)試系統(tǒng)發(fā)送功能:(在信息面板中的發(fā)送按鈕添加監(jiān)聽(tīng))








7、總結(jié):
1、不要著急,1步1步實(shí)現(xiàn)
2、服務(wù)那邊的代碼可以參看昨天的博客;
3、把界面的單個(gè)部份分成3個(gè)類(lèi)出去實(shí)現(xiàn),最后在1個(gè)類(lèi)中創(chuàng)建3個(gè)類(lèi)的對(duì)象,并將3個(gè)對(duì)象在該類(lèi)中整合
4、1定依照思路來(lái),越急躁的人越回1通亂來(lái)
個(gè)人經(jīng)驗(yàn)分享:之前我也嘗試照著書(shū)中的代碼1句1句去敲,先把1個(gè)類(lèi)的代碼敲完,再去敲另外一個(gè)了類(lèi)的代碼,其實(shí)這樣是非常不好的,我們寫(xiě)代碼的時(shí)候也不是1口氣就把1個(gè)類(lèi)的代碼全部寫(xiě)完,同時(shí),定義的變量也不是1下就可以想到要那末多的變量,只是在我們需要的時(shí)候去定義某個(gè)變量;所以,寫(xiě)程序,思路真的非常非常重要;我把源代碼都貼上來(lái),也不是讓某些人直接copy拿去交作業(yè)(固然,有部份人肯定是直接copy的),更重要的是幫助那些自學(xué)的朋友在某個(gè)地方卡殼的時(shí)候,參看1下的代碼,能順時(shí)頓悟;而浪費(fèi)太多沒(méi)必要要的時(shí)間;最最重要的是能和大家1起學(xué)習(xí)討論和交換;嗯,相信我的意思大家都明白!
共勉!
生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線(xiàn)----------------------------
分享到:
------分隔線(xiàn)----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 男人久久 | 国产在线永久视频 | 国产午夜影院 | 色自拍偷拍 | 最近最新日本中文免费 | 国产一区二区福利 | 最好免费高清视频在线看 | www.日本xxxx | 中文字幕在线观看2022 | 亚洲黄色毛片 | 伊人久久大香线蕉 | 日韩一区二区三区视频 | 亚洲日本在线免费观看 | 天天天天鲁天天拍一拍 | 色偷偷亚洲女人天堂观看欧 | 国产极品粉嫩交性大片 | 小说图片亚洲 | 在线播放免费一级毛片欧美 | 亚洲第一视频在线播放 | 欧美片欧美日韩国产综合片 | 久久免费久久 | 波多野结衣免费一区二区三区香蕉 | 五月婷婷在线观看视频 | 亚洲 欧美 国产 中文 | 可以免费看黄色的网站 | 美国一级免费 | 中文字幕www | 亚洲国产成人麻豆精品 | 青青青青手机在线视频观看国产 | 伊人影院在线播放 | 精品国产91久久久久久久 | 毛片破处 | 最近高清中文国语视频 | 国产a级午夜毛片 | 国内自拍在线视频高清 | xxxxxx国产对白 | 日本视频一区二区三区 | 综合网站 | 2019国内精品久久久久久 | 亚洲成年网站 | 精品欧美一区二区三区四区 |