问题遇到的现象和发生背景
使用Swing制作游戏,想用单选框控制文件路径后读取文件并显示游戏得分,完成后第一次点击单选框会提示找不到文件并清除单选框组的选择状态,第二次再次点击却又可以正确读取文件并显示得分了
问题相关代码
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.util.ArrayList;
import javax.swing.*;
public class ScoreFrame extends JFrame implements ItemListener {
private static String[] filenames = {"text/m1paraiso.txt","text/m1terra.txt","text/m1inferno.txt",
"text/m2paraiso.txt","text/m2terra.txt","text/m2inferno.txt"};
public static File getFile() {
return file;
}
private static File file;
private JPanel jpNorth = new JPanel();
private JLabel jl = new JLabel("História");
private static JTextArea jta =new JTextArea(11,34);
private JScrollPane jspCenter = new JScrollPane(jta);
private ButtonGroup dificuldadeGrp = new ButtonGroup();
private ButtonGroup mapGrp = new ButtonGroup();
private JRadioButton r1,r2,r3,r4,r5;
public ScoreFrame() throws IOException {
int i;
for (i=0;i<filenames.length;i++) {
file = new File(filenames[i]);
if(!file.exists()) { // 文本被删除后可以重新生成
file.createNewFile();
}
}
setLayout(new BorderLayout());
r1 = new JRadioButton("Paraíso");
r2 = new JRadioButton("Terra");
r3 = new JRadioButton("Inferno");
dificuldadeGrp.add(r1);
dificuldadeGrp.add(r2);
dificuldadeGrp.add(r3);
r1.setSelected(true);
jpNorth.add(r1);
jpNorth.add(r2);
jpNorth.add(r3);
jpNorth.add(jl);
jl.setFont(new Font("Arial",1,25));
jpNorth.setLayout(new FlowLayout());
r4 = new JRadioButton("Map 1");
r5 = new JRadioButton("Map 2");
mapGrp.add(r4);
mapGrp.add(r5);
r4.setSelected(true);
jpNorth.add(r4);
jpNorth.add(r5);
r1.addItemListener(this);
r2.addItemListener(this);
r3.addItemListener(this);
r4.addItemListener(this);
r5.addItemListener(this);
jta.setEditable(false);
add(jpNorth,BorderLayout.NORTH);
add(jspCenter,BorderLayout.CENTER);
readFile();
setSize(450, 300);
setVisible(true);
setResizable(false);
setTitle("Score");
this.setLocationRelativeTo(null);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
setVisible(false);
jta.setText("");
}
});
}
// 按钮事件的监听,被按下后读取指定文件
public void itemStateChanged(ItemEvent e){
if (e.getSource()==r1) {
try {
readFile();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} else if (e.getSource()==r2) {
try {
readFile();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} else if (e.getSource()==r3) {
try {
readFile();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} else if (e.getSource()==r4) {
try {
readFile();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} else if (e.getSource()==r5) {
try {
readFile();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
// 读取文件的方法
public void readFile() throws IOException {
jta.setText("");
file = new File(getFileName());
FileReader fReader =new FileReader(getFileName());
BufferedReader bReader =new BufferedReader(fReader);
ArrayList<String> scoreList = new ArrayList<>();
String string;
while((string=bReader.readLine())!=null){
scoreList.add(string);
}
for (int i = 0; i <scoreList.size(); i++) {
jta.append(scoreList.get(i)+"\n");
}
}
//根据单选框的选择从filenames里获取文件地址
// r1,r2,r3和r4,r5分别是游戏难度和地图,通过这两组单选框的选项读取不同的文件来获得得分
public String getFileName() {
String f = "";
if (r4.isSelected()) {
if (r1.isSelected()) {
f = filenames[0];
} else if (r2.isSelected()) {
f = filenames[1];
} else if (r3.isSelected()) {
f = filenames[2];
}
} else if (r5.isSelected()) {
if (r1.isSelected()) {
f = filenames[3];
} else if (r2.isSelected()) {
f = filenames[4];
} else if (r3.isSelected()) {
f = filenames[5];
}
}
return f;
}
}
运行结果及报错内容
只有当第二次点击同一个单选框后才可以正确显示文本内容,之后如果点击另一个单选框也要点击两次才可以,第一次报错并清空单选框状态,第二次正确读取文件
以下是报错内容
Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: java.io.FileNotFoundException: (绯荤粺鎵句笉鍒版寚瀹氱殑鏂囦欢銆�)
at ScoreFrame.itemStateChanged(ScoreFrame.java:111)
at java.desktop/javax.swing.AbstractButton.fireItemStateChanged(AbstractButton.java:2000)
at java.desktop/javax.swing.AbstractButton$Handler.itemStateChanged(AbstractButton.java:2320)
at java.desktop/javax.swing.DefaultButtonModel.fireItemStateChanged(DefaultButtonModel.java:458)
at java.desktop/javax.swing.JToggleButton$ToggleButtonModel.setSelected(JToggleButton.java:374)
at java.desktop/javax.swing.ButtonGroup.setSelected(ButtonGroup.java:166)
at java.desktop/javax.swing.JToggleButton$ToggleButtonModel.setSelected(JToggleButton.java:356)
at java.desktop/javax.swing.JToggleButton$ToggleButtonModel.setPressed(JToggleButton.java:392)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626)
at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3389)
at java.desktop/java.awt.Component.processEvent(Component.java:6391)
at java.desktop/java.awt.Container.processEvent(Container.java:2266)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:746)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:744)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: java.io.FileNotFoundException: (绯荤粺鎵句笉鍒版寚瀹氱殑鏂囦欢銆�)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:216)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:111)
at java.base/java.io.FileReader.<init>(FileReader.java:60)
at ScoreFrame.readFile(ScoreFrame.java:125)
at ScoreFrame.itemStateChanged(ScoreFrame.java:109)
... 38 more
进程已结束,退出代码0
我的解答思路和尝试过的方法
一开始是在readFile()方法中的file = new File(getFileName());上报错,后来尝试过用File f = new File(getFileName())把它变成了file = new File(f); File和FileReaer是不报错了,但是BufferedReader又开始报错,也都是需要再次选择同一个单选框才可以读取文本,感觉这方法治标不治本也不知道BufferedReader这要怎么改。是不是我的读取方式有问题
我想要达到的结果
在单选框选择一次后就能正确找到并读取文件