Java初学者,用GUI做了一个经典的轮渡系统。我的思路是利用三个排队队列和两个轮渡队列(分别代表两趟船)实现功能。由于每次切界面时会更新对象,输入的内容无法保存,因此需要使用IO流存储信息。大体思路是这样的:
1.先在文件里读取内容到一个6*6的二维数组
2.判断输入内容,如果符合条件的话会存进第1——3行中的某一行;
3.将数组的前1——5行分别存进五个队列里,再进行操作;
4.队列再存进数组里,然后数组再存进文件里
通过这种操作进行数据存储,这里把出问题的软件包给出来:
package src.GroupTest2_1;
import java.time.*;
import java.awt.event.ActionEvent;
import java.io.*;
import java.util.Scanner;
public class Implement implements java.awt.event.ActionListener{
linkQueue L1=new linkQueue();//五个队列
linkQueue L2=new linkQueue();
linkQueue L3=new linkQueue();
linkQueue L4=new linkQueue();
linkQueue L5=new linkQueue();
Scanner reader=new Scanner(System.in);
Panel P;
String S,ST;
String[][] SI1=new String[6][6],SI2=new String[6][6];
int i=0,j=0,k=0;
public Implement(Panel P){
this.P=P;
}
public void actionPerformed(ActionEvent event){
Object O=event.getSource();
switch (event.getActionCommand()){
case"进行检票":
new Panel().TicketChecking();
P.JF1.setVisible(false);
break;
case"时 间 表":
new Panel().TimeTable();
P.JF1.setVisible(false);
break;
case"车辆状态":
new Panel().VehicleStatus();
P.JF1.setVisible(false);
break;
case"确 定(检票)":
File file=new File("D:\\JavaSC-Code\\src\\queue.txt");//读取
BufferedReader bufferedReader=null;
try{
InputStreamReader inputStreamReader=new InputStreamReader(new FileInputStream(new File("D:\\JavaSC-Code\\src\\queue.txt")));
bufferedReader=new BufferedReader(inputStreamReader);
String line=null;
int i=0;
while((line=bufferedReader.readLine())!=null){
if(null!=line){
String[] strings=line.split("\\t");
for(int k=0;k[i][k]=strings[k];
}
i++;
}
}
}catch(Exception e){
e.printStackTrace();
}
if(Time()==-1||Time()==2){
S=P.JTF.getText();
if(P.JRB1.isSelected()&&!P.JRB2.isSelected()&&!P.JRB3.isSelected()){//插入
for(int i=0;i<6;i++){
if(SI1[0][i]==null){
SI1[1][i]=S;
break;
}
}
}else if(!P.JRB1.isSelected()&&P.JRB2.isSelected()&&!P.JRB3.isSelected()){
for(int i=0;i<6;i++){
if(SI1[1][i]==null){
SI1[1][i]=S;
break;
}
}
}else if(!P.JRB1.isSelected()&&!P.JRB2.isSelected()&&P.JRB3.isSelected()){
for(int i=0;i<6;i++){
if(SI1[2][i]==null){
SI1[2][i]=S;
break;
}
}
}else
System.out.println("error");
}
for(int i=0;i<6;i++){
if(!SI1[0][i].equals(null))
L1.EnQueue(SI1[0][i].substring(0,1),SI1[0][i].substring(1));
if(!SI1[1][i].equals(null))
L2.EnQueue(SI1[1][i].substring(0,1),SI1[1][i].substring(1));
if(!SI1[2][i].equals(null))
L3.EnQueue(SI1[2][i].substring(0,1),SI1[2][i].substring(1));
if(!SI1[3][i].equals(null))
L4.EnQueue(SI1[3][i].substring(0,1),SI1[3][i].substring(1));
if(!SI1[4][i].equals(null))
L5.EnQueue(SI1[4][i].substring(0,1),SI1[4][i].substring(1));
}
EnQueueB();//判断归类
for(int i=0;i<6;i++){//复存
if(!L1.isEmpty())
SI2[0][i]=L1.DeQueue().getNumble()+L1.DeQueue().getName();
if(!L2.isEmpty())
SI2[1][i]=L2.DeQueue().getNumble()+L2.DeQueue().getName();
if(!L3.isEmpty())
SI2[2][i]=L3.DeQueue().getNumble()+L3.DeQueue().getName();
if(!L4.isEmpty())
SI2[3][i]=L4.DeQueue().getNumble()+L4.DeQueue().getName();
if(!L5.isEmpty())
SI2[4][i]=L5.DeQueue().getNumble()+L5.DeQueue().getName();
}
FileWriter out=null;
try{
out=new FileWriter("D:\\JavaSC-Code\\src\\queue.txt");
for(int i=0;i<6;i++){
for(int j=0;j<6;j++){
String S=String.valueOf(SI2[i][j]+"");
out.write(S+"\t");
}
out.write("\r\n");
}
out.close();
}catch(IOException e){
e.printStackTrace();
}
new Panel().Menu();
new Panel().Confirm1();
P.JF2.setVisible(false);
break;
case"确 定(车状)":
BufferedReader bufferedReader2=null;
try{
InputStreamReader inputStreamReader=new InputStreamReader(new FileInputStream(new File("D:\\JavaSC-Code\\src\\queue.txt")));
bufferedReader2=new BufferedReader(inputStreamReader);
String line=null;
int i=0;
while((line=bufferedReader2.readLine())!=null){
if(null!=line){
String[] strings=line.split("\\t");
for(int k=0;k++ ){
SI1[i][k]=strings[k];
}
i++;
}
}
}catch(Exception e){
e.printStackTrace();
}
for(int i=0;i<6;i++){
if(SI1[0][i]!=null)
L1.EnQueue(SI1[0][i].substring(0,1),SI1[0][i].substring(1));
if(SI1[1][i]!=null)
L2.EnQueue(SI1[1][i].substring(0,1),SI1[1][i].substring(1));
if(SI1[2][i]!=null)
L3.EnQueue(SI1[2][i].substring(0,1),SI1[2][i].substring(1));
if(SI1[3][i]!=null)
L4.EnQueue(SI1[3][i].substring(0,1),SI1[3][i].substring(1));
if(SI1[4][i]!=null)
L5.EnQueue(SI1[4][i].substring(0,1),SI1[4][i].substring(1));
}
ST=VehicleStatus(S);
new Panel().Menu();
new Panel().Confirm2(ST);
P.JF4.setVisible(false);
break;
case"返 回(检票)":
new Panel().Menu();
P.JF2.setVisible(false);
break;
case"返 回(时表)":
new Panel().Menu();
P.JF3.setVisible(false);
break;
case"返 回(车状)":
new Panel().Menu();
P.JF4.setVisible(false);
break;
case"退 出":
System.exit(1);
}
}
public String VehicleStatus(String S1){
if(L1.find(S1)||L2.find(S1)||L3.find(S1))
return S1+" 正在候车区,请耐心等待";
else if(L4.find(S1)){
if(Time()==-1||Time()==0)
return S1+"正在搭乘 湛江湾———特呈岛 8.15 次轮渡";
else
return S1+" 已到达特呈岛";
}else if(L5.find(S1)){
if(Time()==2||Time()==3)
return S1+"正在搭乘 湛江湾———特呈岛 13.05 次轮渡";
else
return S1+" 已到达特呈岛";
}else
return " 未找到车辆信息!";
}
public void EnQueueB(){
if(Time()==-2){
;
}else if(Time()==0){
if(!L1.isEmpty()&&i<3){
L4.EnQueue(L1.DeQueue());
i++;
}else if(!L2.isEmpty()&&i==3&&j<2){
L4.EnQueue(L2.DeQueue());
j++;
}else if(!L3.isEmpty()&&i==3&&j==2&&k==0){
L4.EnQueue(L3.DeQueue());
k++;
}
}else if(Time()==2){
if(L4.size()<6){
while(i<3&& !L2.isEmpty()&&L4.size()<6)
L4.EnQueue(L2.DeQueue());
while(j<2&&(!L1.isEmpty()||!L3.isEmpty())&&L4.size()<6){
if(!L1.isEmpty()&& !L3.isEmpty())
L4.EnQueue(L1.DeQueue());
else if(!L1.isEmpty()&&L3.isEmpty())
L4.EnQueue(L1.DeQueue());
else if(L1.isEmpty()&&!L3.isEmpty())
L4.EnQueue(L3.DeQueue());
}while(k==0&&(!L1.isEmpty()||!L2.isEmpty())&&L4.size()<6){
if(!L1.isEmpty()&& !L2.isEmpty())
L4.EnQueue(L1.DeQueue());
else if(!L1.isEmpty()&&L2.isEmpty())
L4.EnQueue(L1.DeQueue());
else if(L1.isEmpty()&&!L2.isEmpty())
L4.EnQueue(L2.DeQueue());
}
}
}
}
public int Time(){
LocalTime time1=LocalTime.now();
LocalTime time2=LocalTime.of(8,10,0,0);
LocalTime time3=LocalTime.of(8,15,0,0);
LocalTime time4=LocalTime.of(8,20,0,0);
LocalTime time5=LocalTime.of(13,0,0,0);
LocalTime time6=LocalTime.of(13,05,0,0);
LocalTime time7=LocalTime.of(13,10,0,0);
if(time1.isBefore(time2))//未检票
return -2;
else if(time1.isAfter(time2)&&time1.isBefore(time3))//检票未发
return -1;
else if(time1.isAfter(time3)&&time1.isBefore(time4))//已发未到
return 0;
else if(time1.isAfter(time4)&&time1.isBefore(time5))//已到未检
return 1;
else if(time1.isAfter(time5)&&time1.isBefore(time6))//检票未发
return 2;
else if(time1.isAfter(time6)&&time1.isBefore(time7))//已发未到
return 3;
else
return 4;
}
}
报错如下:
从84行来看 SI1[0][i].substring(0,1) 出现了越界错误,可以得出SI1[0][i]没有两个字符。因此我们要去检查你给SI1[0][i]赋值的地方。也就是44~42行读取文件的地方,,最好打印出来这个二维数组看一下每个值是否正确,。有时候程序上没问题,而BUG是由于测试数据不当引起
这是数组越界异常了,84行。
解决方法如图,可以打断点调试
对SI1[0][i]加一个非空判断兼容处理一下
原因 : 程序中的变量是 null,就意味着它没有引用指向或者说没有指针。这时,我们对这个变量进行任何操作,都必然会引发空指针异常
空指针异常虽然恼人但好在容易定位,更麻烦的是要弄清楚 null 的含义。比如,客户端给服务端的一个数据是 null,那么其意图到底是给一个空值,还是没提供值呢?再比如,数据库中字段的 NULL 值,是否有特殊的含义呢,针对数据库中的 NULL 值,写 SQL 需要特别注意什么呢?
解决方法:
对于 Integer 的判空,可以使用 Optional.ofNullable 来构造一个 Optional,然后使用 orElse(0) 把 null 替换为默认值再进行 +1 操作。对于 String 和字面量的比较,可以把字面量放在前面,比如"OK".equals(s),这样即使 s 是 null 也不会出现空指针异常;而对于两个可能为 null 的字符串变量的 equals 比较,可以使用 Objects.equals,它会做判空处理。
对于 ConcurrentHashMap,既然其 Key 和 Value 都不支持 null,修复方式就是不要把 null 存进去。HashMap 的 Key 和 Value 可以存入 null,而 ConcurrentHashMap 看似是 HashMap 的线程安全版本,却不支持 null 值的 Key 和 Value,这是容易产生误区的一个地方。
对于类似 fooService.getBarService().bar().equals(“OK”) 的级联调用,需要判空的地方有很多,包括 fooService、getBarService() 方法的返回值,以及 bar 方法返回的字符串。如果使用 if-else 来判空的话可能需要好几行代码,但使用 Optional 的话一行代码就够了。
对于 rightMethod 返回的 List,由于不能确认其是否为 null,所以在调用 size 方法获得列表大小之前,同样可以使用 Optional.ofNullable 包装一下返回值,然后通过.orElse(Collections.emptyList()) 实现在 List 为 null 的时候获得一个空的 List,最后再调用 size 方法。
如有帮助,望采纳
你这只给了部分代码,没法调
String index out of range: -1 这是越界了,应是str.indexOf("+")出错.String 的indexOf方法返回查找字符在字符串中的位置,
但是没找到的话就会返回-1(详细看JDK API文档)。所以当找不到指定字符时救会出错了。
字符串下标从0到str.length(),来个-1自然越界(substring()方法),
最好在处理前做个判断int index = str.indexOf("+")if(index!=-1) op2=Double.parseDouble((str.substring(index,str.length())))else System.out.println("找不到指定字符!")
在这里加一行代码, 打印下:
System.out.println(SI1[0][i]);