在Java中有一個叫做集合類的概念,用它可以擴展引用數據類型的使用。這跟以前我寫的醫院排隊系統很相似,但由于功能需求有所改變,使之整體的設計思路也不一樣。在介紹程序之前,先給大家介紹一下銀行排隊的需求。眾所周之,銀行排隊系統是平時大家經常接觸的東西。該系統分成兩部分,當用戶需要辦理業務時首先在客戶端領取票號,票號中顯示該用戶當前的流水賬號,前面還有多少用戶等待,另外各個銀行為鼓勵用戶到自己的銀行存款又新加了一項金卡業務。所謂金卡業務其實就是當用戶在該銀行存款金額達到一定的數額時(如100000元),該用戶就會升級為金卡客戶。當金卡客戶辦理業務時,不管前面有多少普通用戶在等待,排隊系統自動把該用戶排到最前端,并顯示相應信息,等業務員處理完一位普通用戶的業務叫下一位時,大屏幕會顯示金卡用戶,金卡用戶就會在普通用戶前面提前辦理業務。
好了下面給大家介紹一下整個程序的設計過程及代碼。
首先編寫一個客戶信息的類,代碼如下:
package com.bank.waiter;
public class BankWaiter {
private int num;//用戶排隊號
private int type;//用戶類型,0為普通用戶,1為金卡用戶。
private int former;//該用戶前面還有多少人
public int getFormer() {
return former;
}
public void setFormer(int former) {
this.former = former;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
用戶領去號碼端的UI設計,代碼如下:
package com.bank.ui;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import com.bank.network.EchoClient;
public class WaiterUI {
public static void main(String[] args) {
final Display display = Display.getDefault();
final Shell shell = new Shell();
shell.setSize(400, 500);
shell.setText("銀行排隊系統客戶端");
// ------------------新插入的界面核心代碼------------------------
shell.setLayout(new FillLayout()); // shell應用充滿式布局
// 因為comp1容器使用stackLayout布局,所以comp1中的兩個Text框是重疊在一起的
final Composite comp1 = new Composite(shell, SWT.NONE);
final StackLayout stackLayout = new StackLayout();
comp1.setLayout(stackLayout);
// 在comp1中創建兩個Text框
final Text text1 = new Text(comp1, SWT.BORDER|SWT.WRAP);
text1.setText("普通用戶");
final Text text2 = new Text(comp1, SWT.BORDER|SWT.WRAP);
text2.setText("金卡用戶");
// 在一個新容器中建立兩個按鈕用來控制上面兩個text框的顯示
Composite comp2 = new Composite(shell, SWT.NONE);
comp2.setLayout(new RowLayout());
// 按鈕button1。它控制Text1的顯示
Button button1 = new Button(comp2, SWT.NONE);
button1.setText("普通用戶");
button1.addSelectionListener(new SelectionAdapter() { // 單擊事件
public void widgetSelected(SelectionEvent e) {
EchoClient client = new EchoClient("0");
try {
String str = client.send();
text1.setText(str);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
stackLayout.topControl = text1; // 將t1框顯示
comp1.layout(); // 將界面刷新一下,否則顯示上會沒任何反映的
}
});
// 按鈕button2。它控制Text2的顯示
Button button2 = new Button(comp2, SWT.NONE);
button2.setText("金卡用戶");
button2.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
EchoClient client = new EchoClient("1");
try {
String str = client.send();
text2.setText(str);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
stackLayout.topControl = text2;
comp1.layout();
}
});
// ------------------END---------------------------------------------
shell.layout();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
}
工作人員處理業務端UI設計,代碼如下:
package com.bank.ui;
import com.bank.network.*;
import java.util.Timer;
import java.util.TimerTask;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
public class ClientUI {
public static void main(String args[])
{
final Display display=new Display();
Shell shell=new Shell(display);
//初始化界面
shell.setText("銀行排隊系統前端");
//創建一個面板用來盛放滾動條
Composite composite=new Composite(shell,0);
composite.setBounds(50,50,830,80);
composite.setBackground(new Color(display,SWT.COLOR_BLUE,0,0));
//建立廣告顯示標簽
final Label label=new Label(composite,SWT.CENTER);
label.setBounds(0,20,830,80);
label.setBackground(new Color(display,SWT.COLOR_BLUE,0,0));
label.setForeground(new Color(display,255,0,0));
label.setFont(new Font(display,"宋體",20,SWT.BOLD));
//一號窗口顯示標簽
Label label1=new Label(shell,SWT.CENTER);
label1.setBounds(100,200,230,80);
label1.setText("一號窗口");
label1.setFont(new Font(display,"宋體",20,SWT.BOLD));
//二號窗口顯示標簽
Label label2=new Label(shell,SWT.CENTER);
label2.setBounds(400,200,230,80);
label2.setText("二號窗口");
label2.setFont(new Font(display,"宋體",20,SWT.BOLD));
//三號窗口顯示標簽
Label label3=new Label(shell,SWT.CENTER);
label3.setBounds(700,200,230,80);
label3.setText("三號窗口");
label3.setFont(new Font(display,"宋體",20,SWT.BOLD));
//一號窗口按鈕
Button button1=new Button(shell,SWT.Activate);
button1.setBounds(150,300,120,60);
button1.setText("下一個");
//二號窗口按鈕
Button button2=new Button(shell,SWT.Activate);
button2.setBounds(450,300,120,60);
button2.setText("下一個");
//三號窗口按鈕
Button button3=new Button(shell,SWT.Activate);
button3.setBounds(750,300,120,60);
button3.setText("下一個");
Timer timer = new Timer(true);
class myTask extends TimerTask {
public void run() {//Display.asyncExec()來解決,該方法會新開一個線程
display.asyncExec(new Runnable() {
public void run() {
//循環播放
int mx=label.getLocation().x; //獲取橫坐標
int my=label.getLocation().y;
if(mx==770){
mx=-300;
}
label.setLocation(mx+5, my); //橫坐標每次移動1像素
}
});
}
}
timer.schedule(new myTask(), 0, 50);
//一號窗口按鈕添加事件處理
button1.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e)
{
EchoClient client=new EchoClient("next");
String str;
try {
str = client.send();
if(!"0".equals(str)){
label.setText(str+"一號窗口辦理業務");
}else{
label.setText("目前沒有用戶信息");
}
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
//二號窗口按鈕添加事件處理
button2.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e)
{
EchoClient client=new EchoClient("next");
try {
String str = client.send();
if(!"0".equals(str)){
label.setText(str+"二號窗口辦理業務");
}else{
label.setText("目前沒有用戶信息");
}
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
//三號窗口按鈕添加事件處理
button3.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e)
{
EchoClient client=new EchoClient("next");
String str;
try {
str = client.send();
if(!"0".equals(str)){
label.setText(str+"三號窗口辦理業務");
}else{
label.setText("目前沒有用戶信息");
}
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
// shell.pack();
shell.open();
while(!shell.isDisposed())
{
if(!display.readAndDispatch()){
display.sleep();
}
}
}
}
網絡通信Client端設計,代碼如下:
package com.bank.network;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
public class EchoClient {
private String str;
public EchoClient(String str){
this.str = str;
}
public String send()throws Exception{
Socket socket = null;//連接服務器
socket = new Socket("192.168.1.28",9999);
BufferedReader dis = new BufferedReader(new InputStreamReader(socket.getInputStream()));//接收服務器端信息
PrintStream dos = new PrintStream(socket.getOutputStream());
dos.println(str);
String msg = null;
msg=dis.readLine();
dos.flush();//收尾處理
dos.close();
socket.close();
return msg;
}
}
網絡通信server端設計,代碼如下:
package com.bank.network;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;
import com.bank.waiter.BankWaiter;
public class EchoServer {
private static String str;
private static int num=1;
public static void main(String[] args)throws Exception{
LinkedList<BankWaiter> bw = new LinkedList<BankWaiter>();
ServerSocket server = new ServerSocket(9999);
Socket client = null;
while(true){
client = server.accept();
BufferedReader dis = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintStream dos = new PrintStream(client.getOutputStream());
str = dis.readLine();
if("0".equals(str)){
//1新建一個客戶,并添加到用戶集合對象的尾部。
BankWaiter waiter = new BankWaiter();
waiter.setNum(num++);
waiter.setType(0);
waiter.setFormer(bw.size());
bw.offer(waiter);
//2在大屏幕上面顯示
dos.println("流水賬號:"+waiter.getNum()+"前面還有"+waiter.getFormer()+"名客戶");
}else if("1".equals(str)){
//1新建一個客戶,并放到用戶集合對象的首位。
BankWaiter waiter = new BankWaiter();
waiter.setNum(num++);
waiter.setType(1);
waiter.setFormer(bw.size());
bw.offerFirst(waiter);
//2在大屏幕上顯示
dos.println("尊敬的金卡用戶您前面還有"+waiter.getFormer()+"名客戶,我們將把您排在第一位");
}else
if("next".equals(str)){
BankWaiter waiter = bw.poll();
if(waiter!=null){
if(waiter.getType()==0){
dos.println("請"+waiter.getNum()+"號顧客");
}
else if(waiter.getType()==1){
dos.println("尊敬的"+waiter.getNum()+"號金卡用戶請到");
}}else {
dos.println("0");
}
}
}
}
}
該系統整個代碼完畢。該系統運行時,首先要先開啟服務器端,然后再打開工作人員端和客戶端。當沒有用戶時,大屏幕滾動顯示用戶信息,運行結果如下圖:
當第五名客戶排隊時,客戶端的界面如圖:
假如第七名用戶為金卡用戶,當他領取號碼時,屏幕顯示如圖:
假如此時工作人員才開始工作,大屏幕滾動顯示如下:
當金卡客戶業務辦理完了,下一位普通用戶辦理業務時,界面如下:
工作人員的UI設計時,為了易于演示一共開了三個端口,當然這個跟實際不太一樣。哈哈,,,
好了,有關銀行排隊系統的初步設計完成,本次設計有很多的不足,例如當有多個金卡用戶等待時,總是把最后那名客戶放到首位,這與實際不符。要修改這個不足可以在設計程序時建立兩個用戶等待的集合對象分別存取普通用戶和金卡用戶,工作人員端調取用戶時首先判斷金卡用戶集合對象是否為空。當為空是再去除了普通用戶,而金卡用戶的添加就和普通用戶的添加一樣了。當然我設計的這個系統還有很多的不足以及需要改進的地方,希望大家多多批評指正。