上文提到,建立了OrderUI,因为餐馆数增加,所以选择参观时,用number表示选择的餐馆编号,在Mypanel类绘制送给哪个餐馆时,只要向那家餐馆方向移动就行。
run方法修改成
while(xg.flag0==0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//改成number
xg.delivey(rest[number].x, rest[number].y);
repaint();
}
接下来就进行比较重要的一步:给XiaoGe类建立服务端,OrderUI类建立客户端。
先给XiaoGe类添加窗口与文本域,定义多个属性
//自带缓冲区的输入流
public BufferedReader reader;
//输出流
public PrintWriter writer;
//发送的信息
public String sendmessage;
public transient JFrame frame1=new JFrame("风里雨里的小哥");
public transient JTextArea text=new JTextArea(20,20);
public transient JPanel panel1=new JPanel();
//两个按钮 一个发送消息 一个清空文本域
public transient JButton button1=new JButton("send");
public transient JButton button2=new JButton("clear");
//滚动带
public transient JScrollPane roll;
在构造方法中添加
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//改变窗口的布局方式
frame1.setLayout(new FlowLayout());
frame1.setSize(400,400);
frame1.setVisible(true);
frame1.setBounds(50, 100, 400, 400);
//自动换行
text.setLineWrap(true);
//构造方法的参数为文本域类
roll=new JScrollPane(text);
//定义垂直滚动
roll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
roll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
//面板添加的是滚动带
panel1.add(roll);
//以内部类的方式给按钮注册监听
button2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
//清空消息栏
text.setText("");
}
});
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
//将文本域中的内容发送出去
writer.println(text.getText());
//清空输出流
writer.flush();
text.setText("");
text.requestFocus();
}
});
frame1.add(panel1);
frame1.add(button2);
frame1.add(button1);
启动服务端方法
//开始服务端
public void StartKH() {
try {
//服务端套节字
//端口为5056
ServerSocket serversock=new ServerSocket(5056);
//接受客户端信息
while(true) {
//有客户才会往下进行 不然会阻塞
Socket socket=serversock.accept();
System.out.println("连接成功");
//输出向客户端
writer=new PrintWriter(socket.getOutputStream());
//读取客户的线程
Thread t=new Thread(new readerCient(socket));
t.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
不断读取信息的线程(以内部类的方式建立)
//客户端信息要不断读取
//所以要建立一个线程实时读取客户端信息
class readerCient implements Runnable{
//套节子类型
Socket socket;
boolean volog=true;//判断是否送餐
public readerCient(Socket UIsocket) {
super();
try {
socket = UIsocket;
//装饰模式读取信息
reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
// TODO Auto-generated method stub
String str;
//读取信息
try {
//有信息开始读取 每次读取一行
while((str=reader.readLine())!=null) {
// System.out.println("开始读取");
text.append(str+"\n");
//收到消息 向客户端反馈
if(volog) {
writer.println("我已收到,开始送餐");
volog=false;
}
//必须要加这条语句 不然可能消息发送不成功
writer.flush();
// System.out.println("服务器发送");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
由于服务端要独立运行,也就是要有自己的main方法,而在Mypanel类中又要获取XiaoGe的位置等信息。所以我想到的解决办法是将XiaoGe类对象序列化,然后在Mypanel类中解序列化(有些不能序列化的类要加transient)。
public static void main(String[] args) {
try {
//将对象序列化
XiaoGe x1=new XiaoGe(50, 60);
ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream("ObjectXiaoGe.txt"));
os.writeObject(x1);
os.close();
//开始客户端线程
x1.StartKH();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
相应的在Mypanel类中解序列化
//读取对象
try {
FileInputStream file=new FileInputStream("ObjectXiaoGe.txt");
ObjectInputStream is = null;
if(file.available()!=0) {
is=new ObjectInputStream(file);
xg=(XiaoGe)is.readObject();
}
is.close();
给OrderUI搭建客户端
private void KehuStart() {
try {
//ip地址与端口 端口要和服务端相同
//"127.0.0.1"代表本机地址
socket=new Socket("127.0.0.1",5056);
System.out.println("客户端连接");
//装饰模式 接收服务器消息
reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
//发送消息到服务端
writer=new PrintWriter(socket.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
同时给客户端不断读取的线程
//不断读取线程
class InReader implements Runnable{
String str;
@Override
public void run() {
// TODO Auto-generated method stub
try {
//System.out.println("wohuizhixing");
//System.out.println(reader.readLine().isEmpty());
while((str=reader.readLine())!=null) {
//System.out.println("客服端读取");
text.setText(str);
//System.out.println("sufferful");
}
//while语句后的不运行
System.out.println("真的会?");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
先启动服务端,再启动客户端,顺序反了会报异常。
如果成功了就会显示下图
来源:码农迪迪,本文观点不代表自营销立场,网址:https://www.zyxiao.com/p/87587