Issue
I need to create a JavaFX project that creates a gui to input a name and password. I have created the panes, and set the stage. The items show correctly, however I cant upon button click get the info to write to the file. It creates the file but will not store the data. I need to be able to several names and passwords so I can create a reader login program to check the .txt file. Here is the code I have. Thanks.
import javax.swing.JOptionPane;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.geometry.HPos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import java.io.*;
public class AddUser extends Application {
private TextField tfUsername = new TextField();
private TextField tfPassword = new TextField();
private Button btAddUser = new Button("Add User");
private Button btClear = new Button("Clear");
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
// Create UI
GridPane gridPane = new GridPane();
gridPane.setHgap(5);
gridPane.setVgap(5);
gridPane.add(new Label("Username:"), 0, 0);
gridPane.add(tfUsername, 1, 0);
gridPane.add(new Label("Password:"), 0, 1);
gridPane.add(tfPassword, 1, 1);
gridPane.add(btAddUser, 1, 3);
gridPane.add(btClear, 1, 3);
// Set properties for UI
gridPane.setAlignment(Pos.CENTER);
tfUsername.setAlignment(Pos.BOTTOM_RIGHT);
tfPassword.setAlignment(Pos.BOTTOM_RIGHT);
GridPane.setHalignment(btAddUser, HPos.LEFT);
GridPane.setHalignment(btClear, HPos.RIGHT);
// Process events
btAddUser.setOnAction(e -> writeNewUser());
btClear.setOnAction(e -> {
tfUsername.clear();
tfPassword.clear();
});
// Create a scene and place it in the stage
Scene scene = new Scene(gridPane, 300, 150);
primaryStage.setTitle("Add User"); // Set title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
public void writeNewUser() {
PrintWriter fw = null;
try {
fw = new PrintWriter("users.txt");
BufferedWriter bw = new BufferedWriter(fw);
bw.write(tfUsername.getText());
bw.newLine();
bw.write(tfPassword.getText());
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* The main method is only needed for the IDE with limited
* JavaFX support. Not needed for running from the command line.
*/
public static void main(String[] args) {
launch(args);
}
}
Solution
You're "original" had the fw.close
method within the catch
block of the try-catch
in your writeNewUser
method...
public void writeNewUser() {
PrintWriter fw = null;
try {
fw = new PrintWriter("users.txt");
BufferedWriter bw = new BufferedWriter(fw);
bw.write(tfUsername.getText());
bw.newLine();
bw.write(tfPassword.getText());
} catch (IOException e) {
e.printStackTrace();
fw.close();
}
}
As has been pointed out, this will only be called if something goes wrong. Also, PrintWriter#close
will throw an IOException
and fw
could be null
, causing more issues...
The modified code is only marginally better...
public void writeNewUser() {
PrintWriter fw = null;
try {
//....
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Placing the close
call in within the try
section means that it will only be called if all goes well. If an exception occurs for some reason, the resource will never be closed
You should also be closing the outer resource, the BufferedWriter
in this case, this will chain the close call to each enclosing resource.
Instead, you should use a try-with-resources
, which will close the resources automatically, for example...
public void writeNewUser() {
try (BufferedWriter bw = new BufferedWriter(new PrintWriter("users.txt"))) {
bw.write(tfUsername.getText());
bw.newLine();
bw.write(tfPassword.getText());
} catch (IOException e) {
e.printStackTrace();
}
}
Take a look at The try-with-resources Statement for more details
Updated
To append to the file, you might need to use FileWriter
instead, for example...
public void writeNewUser() {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("users.txt", true))) {
bw.write(tfUsername.getText());
bw.newLine();
bw.write(tfPassword.getText());
bw.newLine();
} catch (IOException e) {
e.printStackTrace();
}
}
Answered By - MadProgrammer
Answer Checked By - Marie Seifert (JavaFixing Admin)