在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设计时,为了易于演示一共开了三个端口,当然这个跟实际不太一样。哈哈,,,
好了,有关银行排队系统的初步设计完成,本次设计有很多的不足,例如当有多个金卡用户等待时,总是把最后那名客户放到首位,这与实际不符。要修改这个不足可以在设计程序时建立两个用户等待的集合对象分别存取普通用户和金卡用户,工作人员端调取用户时首先判断金卡用户集合对象是否为空。当为空是再去除了普通用户,而金卡用户的添加就和普通用户的添加一样了。当然我设计的这个系统还有很多的不足以及需要改进的地方,希望大家多多批评指正。