BufferedReader causing Java GUI to hang - java

I am currently working on an add-on to a rhythm game called osu! using Java. There are multiple windows involved, but after the actionPerformed event listener is invoked for one of them, it creates another window that creates an object the constructor of which calls two methods that each use a BufferedReader. However, once I click the button for the actionPerformed, the program hangs and freezes until it is terminated from task manager. Here is the actionPerformed code for the GUI window:
private void btnCreateActionPerformed(ActionEvent evt) throws IOException {
String text = textBeats.getText();
if (text == null) {
JOptionPane.showMessageDialog(contentPane, "Please enter a positive number.");
}
boolean isNumber = true;
for (char c : text.toCharArray()) {
if (!Character.isDigit(c)) {
isNumber = false;
} else if (c == '-') {
isNumber = false;
}
}
if (isNumber) {
double beats = Double.parseDouble(text);
WindowCode window = new WindowCode(drawArea, file, beats);
window.setVisible(true);
this.dispose();
} else {
JOptionPane.showMessageDialog(contentPane, "Please enter a positive number.");
}
}
And here are the two methods called when creating WindowCode:
public double[] getLastTimingPoint() {
String line;
String timings[] = new String[8];
double pointElements[] = new double[8];
boolean isTiming = false;
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(osuFile), "UTF-8"))){
while ((line = reader.readLine()) != null) {
if (line.contains("[TimingPoints]")) {
isTiming = true;
} else if (line.contains("[Colours]") || line.contains("[HitObjects]")) {
isTiming = false;
}
if (isTiming) {
if (!line.contains("[TimingPoints]") && !line.contains("[Colours]") && !line.contains("[HitObjects]") && line.length() > 0) {
timings = line.split(",");
}
}
}
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < timings.length; i++) {
pointElements[i] = Double.parseDouble(timings[i]);
}
System.out.println("1");
return pointElements;
}
public double[] getLastInheritedPoint() {
String line;
String timings[] = new String[8];
double pointElements[] = new double[8];
boolean isTiming = false;
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(osuFile), "UTF-8"))) {
while ((line = reader.readLine()) != null) {
if (line.contains("[TimingPoints]")) {
isTiming = true;
}
while (isTiming) {
if (!line.contains("[TimingPoints]") && !line.contains("[Colours]") && !line.contains("-")) {
timings = line.split(",");
}
}
}
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < timings.length; i++) {
pointElements[i] = Double.parseDouble(timings[i]);
}
System.out.println("2");
return pointElements;
}
I have tried to print out checkpoint numbers and it only prints "1" to the console, leading me to believe that it is the second method that is causing this. My question is if the BufferedReader affects the EDT somehow and if it does, how I should get around it.

On the second method you have this inner loop:
while (isTiming) {
if (!line.contains("[TimingPoints]") && !line.contains("[Colours]") && !line.contains("-")) {
timings = line.split(",");
}
}
If the file being read contains this string "[TimingPoints]" then variable isTiming will be set to true, and no one else resets it back to false, being trapped into an infinite loop.
You should revise that loop logic.

Related

How can I change this to just array?

I have written this code but I have to change this from saving in list to saving in array. So that every animal in my txt file should have its position in the array. There is 10 animals. Anyone can help?
public class Main {
public static void main(String[] args) {
String line = "";
int count = 0;
List<String> arrayList = new ArrayList<>();
try {
BufferedReader br = new BufferedReader(new FileReader("Zoo.txt"));
while (line != null) {
count++;
line = br.readLine();
if (line == null)
break;
if (count == 3 || count % 3 == 1 && !line.equals("1") &&
!line.equals("5") && !line.equals("10"));
arrayList.add(line);
}
System.out.println(Arrays.toString(arrayList.toArray()));
br.close();
} catch (FileNotFoundException e) {
System.err.println("File not found.");
}catch (IOException e) {
System.err.println("Cannot read this file.");
}
}
}
With Java8+, you could do :
Path path = Paths.get("Zoo.txt");
String[] animals = Files.lines(path, Charset.defaultCharset()).toArray(String[]::new);
Based on #Ryan suggestion :
public static void main(String[] args) {
// TODO Auto-generated method stub
String line = "";
int count = 0;
int countLineNumber=0; //to count line numbers
List<String> arrayList = new ArrayList();
try {
BufferedReader br = new BufferedReader(new FileReader("Zoo.txt"));
while (line != null) {
count++;
line = br.readLine();
if (line == null)
break;
if (count == 3 || count % 3 == 1 && !line.equals("1") &&
!line.equals("5") && !line.equals("10"));
arrayList.add(line);
countLineNumber++;
}
//System.out.println(countLineNumber);
br.close();
} catch (FileNotFoundException e) {
System.err.println("File not found.");
}catch (IOException e) {
System.err.println("Cannot read this file.");
}
//getting elements from arayList saving them into a array
String[] array=new String[countLineNumber];
for(int i=0;i<countLineNumber;i++){
array[i]=arrayList.get(i);
}
//display element in array
for(int k=0;k<array.length;k++){
System.out.println(array[k]);
}
}

Compiler thinks final instance variable not initialised

My compiler is warning me that that an instance variable, a 2d int[][] array, might not have been initialised when I go to assign it.
I understand why the compiler might think that, because it is initialised in a double if statement. However the first if is on a boolean that is initialised to true, and the second if throws an exception on the else. I am confident of the logic of the program but the compiler obviously is not.
Does anyone have any tips for overcoming this kind of problem? I don't want to otherwise initialise the variable because it is meant to be final.
The variable of concern is the board variable. The below is part of a constructor for the object which contains the variable.
try {
FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);
boolean first = true;
int lineCount = 0;
String line;
while ((line = br.readLine()) != null) {
String lineParts[] = line.split(" ");
if (first) {
if (lineParts.length == 2) {
this.xSize = Integer.parseInt(lineParts[0]);
this.ySize = Integer.parseInt(lineParts[1]);
board = new int[this.ySize][this.xSize];
first = false;
} else { throw new RuntimeException(); }
} else {
lineCount++;
if (lineParts.length == this.xSize) {
for (int i = 0; i < this.xSize; i++) {
board[lineCount][i] = Integer.parseInt(lineParts[i]);
}
} else throw new RuntimeException();
}
}
br.close();
if (lineCount != this.ySize) throw new RuntimeException();
}
Indeed, the compiler can't unravel the loop logic enough to know the final variable is initialized before use.
You'll need to move handling of the first line out of the loop — which is reasonable anyway, since the content of the loop is almost completely different for the first line and subsequent lines:
try {
FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);
int lineCount = 0;
String line;
line = br.readLine();
if (line != null) {
String lineParts[] = line.split(" ");
if (lineParts.length == 2) {
this.xSize = Integer.parseInt(lineParts[0]);
this.ySize = Integer.parseInt(lineParts[1]);
board = new int[this.ySize][this.xSize];
} else {
throw new RuntimeException();
}
while ((line = br.readLine()) != null) {
String lineParts[] = line.split(" ");
lineCount++;
if (lineParts.length == this.xSize) {
for (int i = 0; i < this.xSize; i++) {
board[lineCount][i] = Integer.parseInt(lineParts[i]);
}
} else {
throw new RuntimeException();
}
}
}
br.close();
if (lineCount != this.ySize) throw new RuntimeException();
}
Note: This code preserves the previous code's behavior that it doesn't count the first line. I'm guessing the fact it's special includes not counting it. :-)
Side note: I'd strongly recommend using try-with-resources in that code, not only for best practices, but because you're not closing the file when you throw your exceptions:
try (
FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);
) {
int lineCount = 0;
String line;
line = br.readLine();
if (line != null) {
String lineParts[] = line.split(" ");
if (lineParts.length == 2) {
this.xSize = Integer.parseInt(lineParts[0]);
this.ySize = Integer.parseInt(lineParts[1]);
board = new int[this.ySize][this.xSize];
} else {
throw new RuntimeException();
}
while ((line = br.readLine()) != null) {
String lineParts[] = line.split(" ");
lineCount++;
if (lineParts.length == this.xSize) {
for (int i = 0; i < this.xSize; i++) {
board[lineCount][i] = Integer.parseInt(lineParts[i]);
}
} else {
throw new RuntimeException();
}
}
}
if (lineCount != this.ySize) throw new RuntimeException();
}

Creating file and writing to it (null pointer)

I want to create a method that reads from a file, then creates a file which will then write a certain subset of what was read from but I keep getting a null pointer exception at output.write(line) and I am not sure why?
public void readCreateThenWriteTo(String file, String startRowCount, String totalRowCount) {
BufferedReader br = null;
File newFile = null;
BufferedWriter output = null;
StringBuilder sb = null;
int startRowCountInt = Integer.parseInt(startRowCount);
int totalRowCountInt = Integer.parseInt(totalRowCount);
try {
br = new BufferedReader(new FileReader(file));
sb = new StringBuilder();
newFile = new File("hiya.txt");
output = new BufferedWriter(new FileWriter(newFile));
String line = "";
int counter = 0;
while (line != null) {
line = br.readLine();
if (startRowCountInt <= counter && counter <= totalRowCountInt) {
System.out.println(line);
output.write(line);
}
counter++;
}
} catch (IOException e) {
// TODO Auto-generated catch block
LOGGER.info("File was not found.");
e.printStackTrace();
} finally {
// Should update to Java 7 in order to use try with resources and then this whole finally block can be removed.
try {
if ( br != null ) {
br.close();
}
if ( output != null ) {
output.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
LOGGER.info("Couldn't close BufferReader.");
e.printStackTrace();
}
}
}
You need to check the result of readLine() before you enter the loop:
while ((line = br.readLine()) != null) {
if (startRowCountInt <= counter && counter <= totalRowCountInt) {
System.out.println(line);
output.write(line);
}
counter++;
}

FileInputStream returns null

I have two methods, both using FileInputStream Objects.
The First one returns expected value. This method works fine.
But the Second method returns nothing. The value passed to the second method is not null.
I need to get the hexadecimal format of the files passed to methods.
Why is it so? Kindly Explain.
Here is my code
public String binaryFile1(File file1){
try{
stringBuilder1=new StringBuilder();
is1=new FileInputStream(file1);
while(b!=-1){
counter++;
b=is1.read();
String s = Integer.toHexString(b).toUpperCase();
if (s.length() == 1) {
stringBuilder1.append('0');
}
if(counter%5==0){
stringBuilder1.append(s).append("\n");
counter=0;
}else
stringBuilder1.append(s).append(' ');
}
is1.close();
}catch(Exception e){
e.printStackTrace();
}
return stringBuilder1.toString();
}
public String binaryFile2(File file2){
try{
stringBuilder2=new StringBuilder();
is2=new FileInputStream(file2);
while(b!=-1){
counter++;
b=is2.read(); //Here b does not get any content assigned.
String s = Integer.toHexString(b).toUpperCase();
if (s.length() == 1) {
stringBuilder2.append('0');
}
if(counter%5==0){
stringBuilder2.append(s).append("\n");
counter=0;
}else
stringBuilder2.append(s).append(' ');
}
is2.close();
}catch(Exception e){
e.printStackTrace();
}
return stringBuilder2.toString(); //Here stringBuilder2 is null
}
Since b is shared and you don't reset it after binaryFile1 it's still -1 at the start of binaryFile2. I suggest you use,
int b;
while ((b = is2.read()) != -1) {
// ...
}
Edit
It is important to close your resources when you're done. I also suggest you try and limit variable scope as much as possible. Using try-with-resources you could write binaryFile2 like
public String binaryFile2(File file) {
StringBuilder sb = new StringBuilder();
int counter = 0;
try (InputStream is = new FileInputStream(file)) {
int b;
while ((b = is.read()) != -1) {
counter++;
String s = Integer.toHexString(b).toUpperCase();
if (s.length() == 1) {
sb.append('0');
}
sb.append(s);
if (counter % 5 == 0) {
sb.append(System.lineSeparator());
counter = 0;
} else {
sb.append(' ');
}
}
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}

Importing a file using the Java FileChooser

I'm having trouble using the Java JFileChooser and was wondering if anyone could help me out. It's probably something really simple but I just can't spot what's wrong.
The JFileChooser window opens fine when I click my import button and I can navigate to any field but I just cant read them into my JTextFields.
Heres my JFileChooser method:
public void importFile() {
JFileChooser chooser = new JFileChooser();//A
if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { //a
try {
BufferedReader file_in = new BufferedReader(
new FileReader(chooser.getSelectedFile().getPath()));
int i = 0;
String name = "",hnumber = "", mnumber = "", address = "";
while (((fileLines = file_in.readLine()) != null)) {
if (fileLines.length() > 0) {
i++;
if (i == 1) {
name = fileLines;
} else if (i == 2) {
hnumber = fileLines;
} else if (i == 3) {
mnumber = fileLines;
} else if (i == 4) {
address = fileLines;
String[] nameArray = name.split(" ");
Contact c = new Contact (nameArray[1], nameArray[0],
hnumber, mnumber, address);
contactList.add(c);
index = 0;
}
}
}
for (int j = 0; j < contactList.size(); j++) {
System.out.print(contactList.get(j).getname());
System.out.print(" ");
System.out.println(contactList.get(j).getmnumber());
System.out.println(contactList.get(j).gethnumber());
System.out.println(contactList.get(j).getaddress());
System.out.println(contactList.get(j).getsurname());
System.out.println(" ");
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
You should use a List or a StringBuilder for ease of getting the lines. And do you get any error(s) as result? Debugging would really help to see where your program is breaking.
Here is something I put together for you real quick:
public void importFile() {
JFileChooser chooser = new JFileChooser();//A
if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { //a
try {
FileReader fr = new FileReader(chooser.getSelectedFile().getPath());
BufferedReader file_in = new BufferedReader(fr);
List lines = new List();
String line = new String("");
while ((line = file_in.readLine()) != null) {
list.add(line);
if (list.size() >= 3) {
String[] nameArray = ((String)list.get(0)).split(" ");
Contact c = new Contact (nameArray[1], nameArray[0],
(String)list.get(1), (String)list.get(2),
(String)list.get(3));
contactList.add(c);
}
System.out.println(list.get(list.size()-1)); // Debug
}
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
I didn't compile it so may have some typos or of such...
It imports into a array list called "contactList" which you can see is on the 5th line from the bottom. So it doesn't go straight into the JTextFields but either way I can't get it to work.

Categories

Resources