How to fix ioexception stream closed? - java

On start up my program gives me the message java.io.IOException: stream closed. It then opens with limited components.
I understand what a stream closed exception is, I just can't figure out how to fix it, in my case. I would really appreciate some help. (I'm sorry about the big chunk of code, but I am not sure what you need to help me)
try {
//Defines new file reader and buffered reader
FileReader file_to_read = new FileReader(path);
BufferedReader br1 = new BufferedReader(file_to_read);
//action code
try {
//Finds the line number to see the number of cards in each set
lnr2= new LineNumberReader(new FileReader(new File("C:\\Users\\priceadria\\Desktop\\Words_" + strSetName + ".txt")));
lnr2.skip(Long.MAX_VALUE);
strLineNumber2 = String.valueOf(lnr2.getLineNumber());
lineNumber2 = Integer.parseInt(strLineNumber2);
//Closes the file reader and buffered reader
br1.close();
file_to_read.close();
} catch (IOException | NumberFormatException e) {
strLineNumber2 = "0";
}
//Adds the set name to the set name array
lblDeckName[row] = new JLabel (strSetName);
//Adds all buttons that will be used in the layout into a button array
JButton aryOptions [][] = new JButton [3][lineNumber];
//Defines and formats the Add Words button
JButton btnAddWords = new JButton("Add Words");
btnAddWords.setOpaque(false);
btnAddWords.setContentAreaFilled(false);
btnAddWords.setBorder(null);
btnAddWords.setBorderPainted(false);
//Defines and formats the Play button
JButton btnPlay = new JButton("Play");
btnPlay.setOpaque(false);
btnPlay.setContentAreaFilled(false);
btnPlay.setBorder(null);
btnPlay.setBorderPainted(false);
//Defines and formats the Delete Set button
JButton btnDelete = new JButton("Delete Set");
btnDelete.setOpaque(false);
btnDelete.setContentAreaFilled(false);
btnDelete.setBorder(null);
btnDelete.setBorderPainted(false);
//Adds each button to the array based on the number of sets
aryOptions [0][row] = btnAddWords;
aryOptions [1][row] = btnPlay;
aryOptions [2][row] = btnDelete;
//Formats the GridBagLayout (Spaces are for formatting purposes)
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = row;
layoutBackground.add(lblDeckName[row],gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = row;
layoutBackground.add(new JLabel(" "),gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx =2;
gbc.gridy = row;
layoutBackground.add(new JLabel (strSubjectName),gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 3;
gbc.gridy = row;
layoutBackground.add(new JLabel(" "),gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 4;
gbc.gridy = row;
layoutBackground.add(new JLabel(strLineNumber2),gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 5;
gbc.gridy = row;
layoutBackground.add(new JLabel(" | "),gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 6;
gbc.gridy = row;
layoutBackground.add(aryOptions[0][row],gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 7;
gbc.gridy = row;
layoutBackground.add(new JLabel(" | "),gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 8;
gbc.gridy = row;
layoutBackground.add(aryOptions[1][row],gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 9;
gbc.gridy = row;
layoutBackground.add(new JLabel(" | "),gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 10;
gbc.gridy = row;
layoutBackground.add(aryOptions[2][row],gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 11;
gbc.gridy = row;
layoutBackground.add(new JLabel(" |"),gbc);
//Creates an action event for the delete set button
btnDelete.addActionListener((ActionEvent a) -> {
//Finds the source of the button that was clicked
String strSource = String.valueOf(a.getSource());
String strSourceCut1 = strSource.substring(25,30);
//Finds the index of the button that was clicked
String [] aryIndex = strSourceCut1.split(",");
String strIndex = aryIndex[0];
try {
//Defines new file reader and buffered reader
FileReader file_to_read2 = new FileReader(path);
BufferedReader br2 = new BufferedReader(file_to_read2);
//Finds the numerical index of the button that was clicked
int intIndex = Integer.parseInt(strIndex)/16;
//Creates a counter to count line numbers
int counter = 0;
while((br2.readLine()) != null) {
counter ++;
if(intIndex == 0) { //If the index is the first option the normal try/catch returns null pointer, so a new try/catch had to be created
try {
//Finds the name of the set based on what button was clicked
String chosenDeck2 = br2.readLine();
String [] aryDeleteDeck = chosenDeck2.split(",");
deleteDeck = aryDeleteDeck[0];
//Closes the buffered reader and file reader
br2.close();
file_to_read2.close();
//Creates the path to the file that needs to be deleted
Path p2 = Paths.get("C:\\Users\\priceadria\\Desktop\\Words_" + deleteDeck + ".txt");
Files.delete(p2);
} catch (IOException e) {
JOptionPane.showMessageDialog(null, e);
}
} else if ( counter == intIndex) {
//Reads the deck name based on the button that was clicked
String chosenDeck2 = br2.readLine();
//Splits the deck name from the subject
String [] aryDeleteDeck = chosenDeck2.split(",");
deleteDeck = aryDeleteDeck[0];
//Closes the buffered reader and file reader
br2.close();
file_to_read2.close();
//Gets the file that needs to be deleted
Path p1 = Paths.get("C:\\Users\\priceadria\\Desktop\\Words_" + deleteDeck + ".txt");
Files.delete(p1);
}
}
}
catch (HeadlessException | IOException | NumberFormatException e) {
JOptionPane.showMessageDialog(null, e);
}
});
//Creates an action event for the add words button
btnAddWords.addActionListener((ActionEvent a) -> {
//Finds the source of the button that was clicked
String strSource = String.valueOf(a.getSource());
String strSourceCut1 = strSource.substring(25,30);
//Finds the index of the button that was clicked
String [] aryIndex = strSourceCut1.split(",");
String strIndex = aryIndex[0];
try {
//Creates a new file reader and buffered reader
FileReader file_to_read3 = new FileReader(path);
BufferedReader br3 = new BufferedReader(file_to_read3);
//Finds the index value
int intIndex = Integer.parseInt(strIndex)/16;
//Creates a counter to count line numbers
int counter = 0;
while((br3.readLine()) != null) {
//Increases counter value by 1
counter ++;
if(intIndex == 0)
{
try {
//Reads the set and subject for the
String chosenDeck2 = br3.readLine();
//Splits the subject from the set
String [] aryDeck = chosenDeck2.split(",");
chosenDeck = aryDeck[0];
//Closes the buffered reader and file reader
br3.close();
file_to_read3.close();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
} else if ( counter == intIndex) {
String chosenDeck2 = br3.readLine();
String [] aryDeck = chosenDeck2.split(",");
chosenDeck = aryDeck[0];
br3.close();
file_to_read3.close();
}
}
}
catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
//Opens the new words frame
frmWords s = new frmWords(deckName, newXPoint, newYPoint, chosenDeck);
s.setVisible(true);
});
}
} catch (Exception e ) {
JOptionPane.showMessageDialog(null, e);
}
What I am finding is that when I am deleting the br1.close() the stream closed error stops, but I can find any reason why? Nothing is using that reader, that I can see. And when I do delete it I get and error saying that the test files are being used by other processes, which I can only presume is br1.
I know this may seem confusing to look at, probably because it is sloppy code, but I would really appreciate some help. I am a high school student.
Thanks :)

You could use the closable feature from Java 7:
try ( FileReader file_to_read = new FileReader(path);
BufferedReader br1 = new BufferedReader(file_to_read)){
//Finds the line number to see the number of cards in each set
lnr2= new LineNumberReader(new FileReader(new File("C:\\Users\\priceadria\\Desktop\\Words_" + strSetName + ".txt")));
lnr2.skip(Long.MAX_VALUE);
strLineNumber2 = String.valueOf(lnr2.getLineNumber());
lineNumber2 = Integer.parseInt(strLineNumber2);
} catch (IOException | NumberFormatException e) {
strLineNumber2 = "0";
}
Then you don't have to care about closing your stream or file in the right order.
Furthermore you could just use libs for doing the "readFile" job like apache commons or guava.

When you construct nested Readers as you do, for example,
FileReader file_to_read = new FileReader(path);
BufferedReader br1 = new BufferedReader(file_to_read);
, closing the outer one automatically closes the inner one, too. You do not need to close the inner one yourself, and if you try to do so after closing the outer one, as you do, you will find that it is already closed.
The best solution is to close only the outer one (as opposed to your workaround of closing only the inner one). You probably don't even need to retain a reference to the inner one -- a more typical idiom would go something like this:
BufferedReader br1 = new BufferedReader(new FileReader(path));
try {
// ... manipulate br1 ...
} finally {
br1.close();
// no need to explicitly close the inner FileReader
}
You could write that in try-with-resources form if that suits your fancy.
Similar applies to nested Writers, InputStreams, and OutputStreams, too.

Related

Placement of bufferedreader.close()

I am having some trouble in the placement of sections of my code. I am a high school student, and for a project I am making a flashcards app. I am using read/write to store the user's data. I am having trouble on where to close my buffered reader.
This is some of my code:
try {
FileReader file_to_read = new FileReader(path);
BufferedReader br1 = new BufferedReader(file_to_read);
for (int row=0; row < lineNumber; row++) {
try {
//Reads the set and the subject in the text file
String strSetSubjectLine = br1.readLine();
//Splits the string of set and subject by using the comma
String [] names = strSetSubjectLine.split(",");
strSetName = names[0];
strSubjectName = names[1];
//Finds the line number to see the number of cards in each set
lnr2= new LineNumberReader(new FileReader(new File("C:\\Users\\priceadria\\Desktop\\Words_" + strSetName + ".txt")));
lnr2.skip(Long.MAX_VALUE);
strLineNumber2 = String.valueOf(lnr2.getLineNumber());
lineNumber2 = Integer.parseInt(strLineNumber2);
} catch (IOException | NumberFormatException e) {
strLineNumber2 = "0";
}
//Adds the set name to the set name array
lblDeckName[row] = new JLabel (strSetName);
//Adds all buttons that will be used in the layout into a button array
JButton aryOptions [][] = new JButton [3][lineNumber];
//Defines and formats the Add Words button
JButton btnAddWords = new JButton("Add Words");
btnAddWords.setOpaque(false);
btnAddWords.setContentAreaFilled(false);
btnAddWords.setBorder(null);
btnAddWords.setBorderPainted(false);
//Defines and formats the Play button
JButton btnPlay = new JButton("Play");
btnPlay.setOpaque(false);
btnPlay.setContentAreaFilled(false);
btnPlay.setBorder(null);
btnPlay.setBorderPainted(false);
//Defines and formats the Delete Set button
JButton btnDelete = new JButton("Delete Set");
btnDelete.setOpaque(false);
btnDelete.setContentAreaFilled(false);
btnDelete.setBorder(null);
btnDelete.setBorderPainted(false);
//Adds each button to the array based on the number of sets
aryOptions [0][row] = btnAddWords;
aryOptions [1][row] = btnPlay;
aryOptions [2][row] = btnDelete;
//Formats the GridBagLayout (Spaces are for formatting purposes)
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = row;
layoutBackground.add(lblDeckName[row],gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = row;
layoutBackground.add(new JLabel(" "),gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx =2;
gbc.gridy = row;
layoutBackground.add(new JLabel (strSubjectName),gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 3;
gbc.gridy = row;
layoutBackground.add(new JLabel(" "),gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 4;
gbc.gridy = row;
layoutBackground.add(new JLabel(strLineNumber2),gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 5;
gbc.gridy = row;
layoutBackground.add(new JLabel(" | "),gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 6;
gbc.gridy = row;
layoutBackground.add(aryOptions[0][row],gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 7;
gbc.gridy = row;
layoutBackground.add(new JLabel(" | "),gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 8;
gbc.gridy = row;
layoutBackground.add(aryOptions[1][row],gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 9;
gbc.gridy = row;
layoutBackground.add(new JLabel(" | "),gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 10;
gbc.gridy = row;
layoutBackground.add(aryOptions[2][row],gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 11;
gbc.gridy = row;
layoutBackground.add(new JLabel(" |"),gbc);
//Creates an action event for the delete set button
btnDelete.addActionListener((ActionEvent a) -> {
//Finds the source of the button that was clicked
String strSource = String.valueOf(a.getSource());
String strSourceCut1 = strSource.substring(25,30);
//Finds the index of the button that was clicked
String [] aryIndex = strSourceCut1.split(",");
String strIndex = aryIndex[0];
try {
//Defines new file reader and buffered reader
FileReader file_to_read2 = new FileReader(path);
BufferedReader br2 = new BufferedReader(file_to_read2);
//Finds the numerical index of the button that was clicked
int intIndex = Integer.parseInt(strIndex)/16;
//Creates a counter to count line numbers
int counter = 0;
while((br2.readLine()) != null) {
counter ++;
if(intIndex == 0) { //If the index is the first option the normal try/catch returns null pointer, so a new try/catch had to be created
try {
//Finds the name of the set based on what button was clicked
String chosenDeck2 = br2.readLine();
String [] aryDeleteDeck = chosenDeck2.split(",");
deleteDeck = aryDeleteDeck[0];
//Creates the path to the file that needs to be deleted
Path p2 = Paths.get("C:\\Users\\priceadria\\Desktop\\Words_" + deleteDeck + ".txt");
Files.delete(p2);
} catch (IOException e) {
JOptionPane.showMessageDialog(null, e);
}
} else if ( counter == intIndex) {
//Reads the deck name based on the button that was clicked
String chosenDeck2 = br2.readLine();
//Splits the deck name from the subject
String [] aryDeleteDeck = chosenDeck2.split(",");
deleteDeck = aryDeleteDeck[0];
//Closes the buffered reader and file reader
//Gets the file that needs to be deleted
Path p1 = Paths.get("C:\\Users\\priceadria\\Desktop\\Words_" + deleteDeck + ".txt");
Files.delete(p1);
}
}
br2.close();
file_to_read2.close();
}
catch (HeadlessException | IOException | NumberFormatException e) {
JOptionPane.showMessageDialog(null, e);
}
});
//Creates an action event for the add words button
btnAddWords.addActionListener((ActionEvent a) -> {
//Finds the source of the button that was clicked
String strSource = String.valueOf(a.getSource());
String strSourceCut1 = strSource.substring(25,30);
//Finds the index of the button that was clicked
String [] aryIndex = strSourceCut1.split(",");
String strIndex = aryIndex[0];
try {
//Creates a new file reader and buffered reader
FileReader file_to_read3 = new FileReader(path);
BufferedReader br3 = new BufferedReader(file_to_read3);
//Finds the index value
int intIndex = Integer.parseInt(strIndex)/16;
//Creates a counter to count line numbers
int counter = 0;
while((br3.readLine()) != null) {
//Increases counter value by 1
counter ++;
if(intIndex == 0)
{
try {
//Reads the set and subject for the
String chosenDeck2 = br3.readLine();
//Splits the subject from the set
String [] aryDeck = chosenDeck2.split(",");
chosenDeck = aryDeck[0];
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
} else if ( counter == intIndex) {
String chosenDeck2 = br3.readLine();
String [] aryDeck = chosenDeck2.split(",");
chosenDeck = aryDeck[0];
}
}
br3.close();
file_to_read3.close();
}
catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
//Opens the new words frame
frmWords s = new frmWords(deckName, newXPoint, newYPoint, chosenDeck);
s.setVisible(true);
});
}
} catch (Exception e ) {
JOptionPane.showMessageDialog(null, e);
}
}
The problem I am facing is when I close my buffered reader "br1". If I close it in the for loop, I get a stream closed error, if I close it after the for loop, my other readers will not work. If I move the declaration of the reader into the for loop and try a try with resources statement, it will read the same line over and over again. If I try to make them all work off 1 buffered reader I get a stream closed error as well.
I am really stuck, and would really appreciate some help.
Thanks :)
You may rearrange your exception handling to use this properly.
try
{
//trying something
}
catch(SomeException e)
{
//we failed
e.printStackTrace();
}
finally
{
//called when we failed or when we succeeded, even after a return; statement
}
EDIT
This will pre-read the file and store the data in an ArrayList. Afterwards it closes the stream.
try {
FileReader file_to_read = new FileReader(path);
BufferedReader br1 = new BufferedReader(file_to_read);
ArrayList<String> linesRead = new ArrayList<String>();
String line = br1.readLine();
while(line != null)
{
linesRead.add(line);
line = br1.readLine();
}
br1.close();
for (int row=0; row < lineNumber; row++) {
try {
//Reads the set and the subject in the text file
String strSetSubjectLine = linesRead.get(row);

Calculator Can't have Decimal

My code now works for sum, subtract, multiple, divide.
However it doesn't show the decimal when I put 10.0 and 2.0 or 5.4 and 2.
How should I change, then it can be used for decimal??
This is my code now.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Calculator extends JFrame implements ActionListener {
// instance variables
JLabel num1Label = null;
JTextField num1Text = null;
JLabel num2Label = null;
JTextField num2Text = null;
JButton sumButton = null;
JButton multipleButton=null;
JButton divideButton=null;
JButton subtractButton = null;
JLabel ansLabel = null;
// constructor
public Calculator() {
setLayout(new GridBagLayout()); // set layout (how elements are arranged in window)
// **** label: num 1
GridBagConstraints layoutCon = new GridBagConstraints();
layoutCon.gridx = 0;
layoutCon.gridy = 0;
layoutCon.insets = new Insets(10,10,10,10);
num1Label = new JLabel("Num 1:");
add(num1Label,layoutCon); // added label to JFrame
// **** text field: num 1
layoutCon = new GridBagConstraints();
layoutCon.gridx = 1;
layoutCon.gridy = 0;
layoutCon.insets = new Insets(10,10,10,10);
num1Text = new JTextField(20);
add(num1Text, layoutCon);
// **** label: num 2
layoutCon = new GridBagConstraints();
layoutCon.gridx = 0;
layoutCon.gridy = 1;
layoutCon.insets = new Insets(10,10,10,10);
num2Label = new JLabel("Num 2:");
add(num2Label,layoutCon); // added label to JFrame
// **** text field: num 2
layoutCon = new GridBagConstraints();
layoutCon.gridx = 1;
layoutCon.gridy = 1;
layoutCon.insets = new Insets(10,10,10,10);
num2Text = new JTextField(20);
add(num2Text, layoutCon);
// **** Sum Button
layoutCon = new GridBagConstraints();
layoutCon.gridx = 0;
layoutCon.gridy = 2;
layoutCon.insets = new Insets(10,10,10,10);
sumButton = new JButton("Sum");
add(sumButton, layoutCon);
sumButton.addActionListener(this); // register sumButton with the ActionListener in Calculator
// Multiple Button
layoutCon= new GridBagConstraints();
layoutCon.gridx=0;
layoutCon.gridy=4;
layoutCon.insets=new Insets(10,10,10,10);
multipleButton= new JButton("Multiple");
add(multipleButton, layoutCon);
multipleButton.addActionListener(this);
// Divide Button
layoutCon = new GridBagConstraints();
layoutCon.gridx = 0;
layoutCon.gridy = 5;
layoutCon.insets = new Insets(10,10,10,10);
divideButton = new JButton("Divide");
add(divideButton, layoutCon);
divideButton.addActionListener(this);
// **** label: answer
layoutCon = new GridBagConstraints();
layoutCon.gridx = 1;
layoutCon.gridy = 2;
layoutCon.insets = new Insets(10,10,10,10);
ansLabel = new JLabel("Answer");
add(ansLabel,layoutCon); // added label to JFrame
// **** Subtract Button
layoutCon = new GridBagConstraints();
layoutCon.gridx = 0;
layoutCon.gridy = 3;
layoutCon.insets = new Insets(10,10,10,10);
subtractButton = new JButton("Subtract");
add(subtractButton, layoutCon);
subtractButton.addActionListener(this); // register subtractButton with the ActionListener in Calculator
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Sum")) {
ansLabel.setText("" + (Integer.parseInt(num1Text.getText()) + Integer.parseInt(num2Text.getText())));
}
else if (e.getActionCommand().equals("Subtract")) {
ansLabel.setText("" + (Integer.parseInt(num1Text.getText()) - Integer.parseInt(num2Text.getText())));
}
else if (e.getActionCommand().equals("Multiple")){
ansLabel.setText(""+(double)(Integer.parseInt(num1Text.getText())*Integer.parseInt(num2Text.getText())));
}
else if (e.getActionCommand().equals("Divide")){
ansLabel.setText(""+(Integer.parseInt(num1Text.getText())/Integer.parseInt(num2Text.getText())));
}
}
public static void main(String[] args) {
Calculator calc = new Calculator();
calc.pack(); // resizes window (JFrame) so you can see the elements in it
calc.setVisible(true); // make window visible
calc.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //exit program when close window
}
}
actionPerformed is parsing its inputs as int and operating on them as such. If you want to use floating-point numbers, try using double instead.
Parsing as an integer cannot handle double's or any floating point number (decimal) as such change your actionPerformed to parse double's instead or parse int's:
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Sum")) {
ansLabel.setText("" + (Double.parseDouble(num1Text.getText()) + Double.parseDouble(num2Text.getText())));
}
else if (e.getActionCommand().equals("Subtract")) {
ansLabel.setText("" + (Double.parseDouble(num1Text.getText()) - Double.parseDouble(num2Text.getText())));
}
else if (e.getActionCommand().equals("Multiple")){
ansLabel.setText(""+(double)(Double.parseDouble(num1Text.getText())*Double.parseDouble(num2Text.getText())));
}
else if (e.getActionCommand().equals("Divide")){
ansLabel.setText(""+(Double.parseDouble(num1Text.getText())/Double.parseDouble(num2Text.getText())));
}
}
You use
Integer.parseInt(num1Text.getText());
which parses a String to an int.
With
Double.parseDouble(num1Text.getText());
you get a double.
Note that you might want to catch the NumberFormatException, since you most likley don't want your program to stop on malformed user input:
double num1;
try
{
num1 = Double.parseDouble(num1Text.getText());
} catch (NumberFormatException e)
{
// either use a default value or give feedback to the user on what he did wrong
// for example
num1 = 1;
}
If you don't want to print a double value, if only integer values are entered by the user, then you could first try to parse to int, catch the exception (if any) and then parse to double.
Another error in your divison line:
ansLabel.setText(
""+(Integer.parseInt(num1Text.getText())/Integer.parseInt(num2Text.getText())));
You do not check if the second parameter is != 0, otherwise you might divide by 0!
To keep your code more readable you might want to create an extra method for parsing a String to a number:
private static double parseDouble(String s)
{
double num;
try
{
num = Double.parseDouble(num1Text.getText());
} catch (NumberFormatException e)
{
// either use a default value or give feedback to the user on what he did wrong
// for example
num = 1;
}
return num;
}
A possible fix for the division by 0 could be:
double num1 = parseDouble(num1Text.getText());
double num2 = parseDouble(num2Text.getText());
String command = e.getActionCommand();
if (command.equals("Sum"))
{
ansLabel.setText("" + (num1 + num2));
} else if (command.equals("Subtract"))
{
ansLabel.setText("" + (num1 - num2));
} else if (command.equals("Multiple"))
{
ansLabel.setText("" + (num1 * num2));
} else if (command.equals("Divide"))
{
if (num2 == 0)
{
ansLabel.setText("ERROR: Division by zero!");
} else
{
ansLabel.setText("" + (num1 / num2));
}
}
you should use double data type instead of integer for 4 operations
Like this:
public void actionPerformed( ActionEvent e )
{
if( e.getActionCommand().equals( "Sum" ) )
ansLabel.setText( "" + ( Double.
parseDouble(num1Text.getText() ) + Double.parseDouble(
num2Text.getText() ) ) );
// etc.

pressing ENTER key do not work for JTextField in applet

I have a JTextField in a JApplet with a ActionListener. I compiled it using Eclipse and it works fine. But when I try to load it in a .html file using applet, the JTextField does not register/recognize the ENTER key when I press it. It seems like the ActionListener did not work. I used:
public void init() {
textField = new JTextField(20);
textField.setText("Enter your question here.");
textField.selectAll();
textField.addActionListener(this);
textArea = new JTextArea(10, 20);
textArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(textArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
// Add Components to the Applet.
GridBagLayout gridBag = new GridBagLayout();
Container contentPane = getContentPane();
contentPane.setLayout(gridBag);
GridBagConstraints c = new GridBagConstraints();
c.gridwidth = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.HORIZONTAL;
gridBag.setConstraints(textField, c);
contentPane.add(textField);
c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.weighty = 1.0;
gridBag.setConstraints(scrollPane, c);
contentPane.add(scrollPane);
newline = System.getProperty("line.separator");
}
public void actionPerformed(ActionEvent event) {
String text = textField.getText();
String question = "";
String answer = "";
question = textField.getText();
question = ProcessString(question);
answer = Answer(question);
textArea.append(text + newline);
textArea.append(answer + newline);
textField.selectAll();
}
static String noAnswer;
static boolean knowAnswer = true;
// process the question string, take out non-ACSII characters, spaces, to
// lower space
public String ProcessString(String question) {
question = question.toLowerCase();
String[] words = question.split("\\s+");
question = "";
for (int wordCount = 0; wordCount < words.length; wordCount++) {
words[wordCount] = words[wordCount].replaceAll("[^A-Za-z]", "");
if (wordCount != words.length - 1)
question = question + words[wordCount] + " ";
else
question = question + words[wordCount];
// System.out.println(words[wordCount]);
}
return question;
}
public String Answer(String question) {
String answer = "";
/*
if the database know the answer (did not not know), then return the
answer. if the database does not know the answer, then recover the
answer in database.
*/
if (knowAnswer == true) {
// open the database file and search if questions matches any one in
// the
// database
Scanner sc = null;
try {
sc = new Scanner(new File("database.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int answerFrequency = 0;
boolean matchFound = false;
while (sc.hasNext()) {
int questionCount = sc.nextInt();
String line = sc.nextLine();
String[] databaseLine = line.split("\\s+");
String databaseQuestion = "";
String databaseAnswer = "";
// collect words for database questions
for (int wordCount = 1; wordCount <= questionCount; wordCount++) {
if (wordCount != questionCount)
databaseQuestion = databaseQuestion
+ databaseLine[wordCount] + " ";
else
databaseQuestion = databaseQuestion
+ databaseLine[wordCount];
}
// collect words for database answer
for (int wordCount = questionCount + 2; wordCount < databaseLine.length; wordCount++) {
databaseAnswer = databaseAnswer + databaseLine[wordCount]
+ " ";
}
// if the question is found in database, print answer
if (question.equals(databaseQuestion)) {
matchFound = true;
// the current answer is more frequency than the previous
// found
// answer, reassign the current answer the find answer
if (answerFrequency < Integer
.parseInt(databaseLine[questionCount + 1])) {
answerFrequency = Integer
.parseInt(databaseLine[questionCount + 1]);
answer = databaseAnswer;
}
}
}
if (matchFound == true) {
// System.out.println(answer);
knowAnswer = true;
} else {
// System.out.println("I don't know what you mean. How should I answer your question?");
knowAnswer = false;
noAnswer = question;
answer = "I don't know how to respond. How should I answer that?";
}
sc.close();
} else if (knowAnswer == false) {
String[] word = noAnswer.split(" ");
BufferedWriter writer = null;
answer = question;
try {
writer = new BufferedWriter(
new FileWriter("database.txt", true));
writer.newLine();
writer.write(word.length + " " + noAnswer + " 1 " + answer);
} catch (IOException e) {
} finally {
try {
if (writer != null)
writer.close();
} catch (IOException e) {
System.out.println("Cannot write to file");
}
}
answer = "I got that.";
knowAnswer = true;
}
return answer;
}
Really appreciate the help.
This seems to work for me....
public class TestApplet04 extends JApplet implements ActionListener {
private JTextField textField;
private JTextArea textArea;
private String newline;
public void init() {
textField = new JTextField(20);
textField.setText("Enter your question here.");
textField.selectAll();
textField.addActionListener(this);
textArea = new JTextArea(10, 20);
textArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(textArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
// Add Components to the Applet.
GridBagLayout gridBag = new GridBagLayout();
Container contentPane = getContentPane();
contentPane.setLayout(gridBag);
GridBagConstraints c = new GridBagConstraints();
c.gridwidth = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.HORIZONTAL;
gridBag.setConstraints(textField, c);
contentPane.add(textField);
c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.weighty = 1.0;
gridBag.setConstraints(scrollPane, c);
contentPane.add(scrollPane);
newline = System.getProperty("line.separator");
}
public void actionPerformed(ActionEvent event) {
String text = textField.getText();
String question = "";
String answer = "";
question = textField.getText();
// question = ProcessString(question);
// answer = Answer(question);
textArea.append(text + newline);
textArea.append(answer + newline);
textField.selectAll();
}
}
Updated after feedback
Here's you major problem...
sc = new Scanner(new File("database.txt"));
This is going to cause you a number of problems. First of all, the applet isn't likely to have access rights to read from the client machine, so you're likely to run into a security exception. Secondly, as the previous statement may have suggested, the file ins't likely to exist on the client machine.
You need to embed this resource within the Jar of your application and use getClass().getResource("...") to gain access to it. This will return a URL, from which you can use URL#openConnection to gain access to a InputStream, which can use in your scanner.
Try adding an Action to the ActionMap and setting the InputMap up for ENTER key.
textField.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter" );
textField.getActionMap().put("enter", new AbstractAction() {...} );
The field will have to have focus.
I'm also a newbie to Java, but found out that JTextfield is only a single line entry.
If you want a multiline entry, you would need to use a JTextArea instead.
Hope this helps :)

Java JTree freezing when file is re-selected

I have a JTree that I use as a file tree. If I choose a new file, and select the same one as was already selected, the tree freezes up for some reason. It should be removing the old JScrollPane containing the tree and replacing it with a new one, and it works fine if I select a different file, but not with the same one. The rest of the GUI still works, it's just the tree that freezes. Here is the relevant code:
if ("browse".equals(e.getActionCommand())) {
returnVal = fc.showOpenDialog(DSAuto.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
filename = file.getAbsolutePath();
l1.setText("Job Location: " + filename);
c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 10;
c.gridheight = 9;
c.ipady = 0;
if (rm)
pane.remove(ft1);
else
pane.remove(sp1);
if (rm2) {
pane.remove(l3);
rm2 = false;
}
if (!(file.isDirectory() || file.isFile())) {
l3 = new JLabel("404 File Not Found");
pane.add(l3, c);
rm2 = true;
} else {
ft1 = new FileTree(file);
ft1.all = allB;
pane.add(ft1, c);
rm = true;
}
}
}
I can supply the code for the FileTree class, as well, if that is needed.
It should be removing the old frame and replacing it with a new one
You can't add/remove a JFrame from a JFrame so I don't know what that comment means.
Don't remove/add components? If you want to update an existing component then change the model. That is:
tree.setModel(...);
Or if you do remove/add components, then you need to use:
panel.revalidate();
panel.repaint();

Why does this code work in Vista but not 7?

For some reason every time I have someone run this program in Vista it works flawlessly but as soon as I move it over to a Windows 7 PC it stops in the middle of the ActionListener's Action Performed Method meaning I can click my choices but it will never say size selected.
Is there any way to fix this?
import java.io.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class SizerFrame extends JFrame {
ButtonGroup buttons = new ButtonGroup();
JTextField width = new JTextField(2);
JTextField height = new JTextField(2);
double inchesPerTimeline = 2.1;
public SizerFrame()
{
super("Timeline Application");
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
setBounds(screen.width/2-125,screen.height/2-90,250,180);
getContentPane().setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
int[] gridX = new int[]{0,0,0,0};
int[] gridY = new int[]{0,1,2,3};
int[] gridW = new int[]{1,1,2,5};
String[] titles = new String[]{"6\"","9\"","10\"","Custom"};
String[] actions = new String[]{"6","9","10","C"};
for (int a = 0; a < 4; a++)
{
JRadioButton current = new JRadioButton(titles[a]);
current.setActionCommand(actions[a]);
c.gridx = gridX[a];
c.gridy = gridY[a];
c.gridwidth = gridW[a];
buttons.add(current);
getContentPane().add(current,c);
}
c.gridwidth = 1;
String[] title = new String[]{" ","Width","Height"};
gridX = new int[]{9,10,12};
for (int a = 0; a< 3; a++)
{
c.gridx = gridX[a];
getContentPane().add(new JLabel(title[a]),c);
}
c.gridx = 11;
getContentPane().add(width,c);
c.gridx = 13;
getContentPane().add(height,c);
c.gridx = 11;
c.gridy = 0;
c.gridwidth = 2;
JButton button = new JButton("Done");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ButtonModel x = buttons.getSelection();
String size = "XXX";
System.out.println("Getting screen resolution");
int screenRes = Toolkit.getDefaultToolkit().getScreenResolution();
System.out.println("Successfully got screen resolution");
if (x!=null)
size = x.getActionCommand();
try{
TimeTable.width = new Integer(size)*screenRes;
TimeTable.height = (int)((TimeTable.titleCount+1)*inchesPerTimeline*screenRes);
}
catch(NumberFormatException ex)
{
try{
TimeTable.width = (int)(new Double(width.getText().trim())*screenRes);
TimeTable.height = (int)(new Double(height.getText().trim())*screenRes);
}
catch (NumberFormatException except)
{
return;
}
}
TimeTable.ready = true;
System.out.println("Size selected");
dispose();
}
});
getContentPane().add(button,c);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent winEvt){
System.exit(0);
}
});
setVisible(true);
}
}
Concise explanation :
I have a macro that runs out of Excel in Windows Vista and I tried to distribute it to a Computer running Windows 7. Upon execution the code failed to continue executing after this point i.e. it never printed out the words "Size selected". The rest of the program brings in a csv file from a C:\Users\?\AppData\TimeLineMacroProgram folder and later creates an image in the same directory. But this is the portion of the code that is currently broken. Whenever the GUI pops up I select the option for 9" and click done which should pass in 9 as a parameter and then print out "Size Selected" but it doesn't it only disposes the window. Please help.
Longshot guess:
There is an exit from your action listener if width and height text fields don't have content: you return after two NumberFormatExceptions. This would prevent "Size selected" from being displayed, and not dispose the frame. If you got the output "Successfully got screen resolution" and then it appeared to stop working, this could possibly be why. But if you experience that, and then click something else and then Done, it would print size selected.

Categories