The client doesn't do the expected operations after the button is pressed.
The server log shows "New client connected" and that's it, nothing happens on the GUI's end.
please help me understand why I've been trying everything.
I tried keeping the socket open, because I thought maybe it's closing right after but it didn't work.
Server code:
public class Server extends Application {
private static final String USERS_FILE = "users.dat";
private static List<User> usersList;
private TextArea logArea;
/**
* Starts the server program with a GUI interface.
*
* @param primaryStage The primary stage for the application
*/
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Server-Log");
logArea = new TextArea();
logArea.setEditable(false);
BorderPane root = new BorderPane();
root.setCenter(logArea);
primaryStage.setScene(new Scene(root, 500, 500));
primaryStage.show();
log("Server started " + new Date() + "\n");
loadUsersFromFile();
new Thread(() -> {
try {
ServerSocket serverSocket = new ServerSocket(8000);
log("Server created.");
System.out.println("Server created");
while (true) {
Socket socket = serverSocket.accept();
new Thread(() -> handleClient(socket)).start();
log("New client connected");
}
} catch (IOException ex) {
log("Error occurred: " + ex.getMessage());
}
}).start();
}
/**
* Loads user information from the data file.
*/
private void loadUsersFromFile() {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(USERS_FILE))) {
usersList = (List<User>) ois.readObject();
log("User data loaded from file.");
} catch (IOException | ClassNotFoundException e) {
log("Error loading user data.");
usersList = new ArrayList<>();
}
}
/**
* Saves user information to the data file.
*/
private void saveUsersToFile() {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(USERS_FILE))) {
oos.writeObject(usersList);
log("User data saved to file.");
} catch (IOException e) {
log("Error saving user data: " + e.getMessage());
}
}
/**
* Logs a message to the server log area.
*
* @param message The message to log
*/
private void log(String message) {
Platform.runLater(() -> {
logArea.appendText(message + "\n");
logArea.appendText("---------------------" + "\n");
});
}
/**
* Handles a client connection to the server.
*
* @param socket The socket representing the client connection
*/
private void handleClient(Socket socket) {
try {
ObjectInputStream inputFromClient = new ObjectInputStream(socket.getInputStream());
DataOutputStream outputToClient = new DataOutputStream(socket.getOutputStream());
String requestType = inputFromClient.readUTF();
if (requestType.equals("login")) {
handleLoginRequest(inputFromClient, outputToClient);
} else if (requestType.equals("register")) {
handleUserRegistration(inputFromClient, outputToClient);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Handles a login request from a client.
*
* @param inputFromClient The input stream from the client
* @param outputToClient The output stream to the client
* @throws IOException If an I/O error occurs
*/
private void handleLoginRequest(ObjectInputStream inputFromClient, DataOutputStream outputToClient) throws IOException {
String username = inputFromClient.readUTF();
String password = inputFromClient.readUTF();
User user = findUserByUsername(username);
if (user != null && user.getPassword().equals(password)) {
// Increment login count and update last login date
user.incrementLoginCount();
user.setLastLogin(new Date());
// Save the updated user information to file
saveUsersToFile();
// Send login successful message to client
outputToClient.writeUTF("Login successful. Welcome, " + user.getFirstName() + "!");
log(username + " logged in successfully.");
} else {
outputToClient.writeUTF("Invalid username or password");
}
}
/**
* Handles a user registration request from a client.
*
* @param inputFromClient The input stream from the client
* @param outputToClient The output stream to the client
* @throws IOException If an I/O error occurs
*/
private void handleUserRegistration(ObjectInputStream inputFromClient, DataOutputStream outputToClient) throws IOException {
String username = inputFromClient.readUTF();
String password = inputFromClient.readUTF();
String firstName = inputFromClient.readUTF();
String lastName = inputFromClient.readUTF();
if (!userExists(username)) {
User newUser = new User(firstName, lastName, username, password);
usersList.add(newUser); // Accessing the usersList directly
saveUsersToFile(); // Saving the user data to file
outputToClient.writeUTF("REGISTRATION_SUCCESSFUL");
} else {
outputToClient.writeUTF("USER_ALREADY_EXISTS");
}
}
/**
* Finds a user by username in the user list.
*
* @param username The username to search for
* @return The user object if found, null otherwise
*/
private User findUserByUsername(String username) {
for (User user : usersList) {
if (user.getUsername().equals(username)) {
return user;
}
}
return null;
}
/**
* Checks if a user with the given username already exists.
*
* @param username The username to check
* @return True if the user exists, false otherwise
*/
private boolean userExists(String username) {
return findUserByUsername(username) != null;
}
/**
* The main entry point for the application.
*
* @param args The command-line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Client code:
public class UserGui extends Application {
private TextField firstNameField;
private TextField lastNameField;
private TextField usernameField;
private PasswordField passwordField;
String host = "localhost";
/**
* Start method for JavaFX application.
*
* @param primaryStage The primary stage of the application.
*/
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("User Sign-up and Log-in Page");
GridPane gridPane = createGridPane();
primaryStage.setResizable(false);
Scene scene = new Scene(gridPane, 1000, 700);
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* Creates the grid pane for the user interface.
*
* @return The grid pane with user interface elements.
*/
private GridPane createGridPane() {
GridPane gridPane = new GridPane();
gridPane.setAlignment(Pos.CENTER);
gridPane.setHgap(15);
gridPane.setVgap(15);
// Header text
Text welcomeText = new Text("Welcome! Please sign up or log in.");
welcomeText.setFont(Font.font("Arial", FontWeight.BOLD, 20));
gridPane.add(welcomeText, 0, 0, 2, 1);
GridPane.setHalignment(welcomeText, HPos.CENTER);
// The fields and formatting
Label firstNameLabel = new Label("First Name:");
gridPane.add(firstNameLabel, 0, 1);
firstNameField = new TextField();
gridPane.add(firstNameField, 1, 1);
Label lastNameLabel = new Label("Last Name:");
gridPane.add(lastNameLabel, 0, 2);
lastNameField = new TextField();
gridPane.add(lastNameField, 1, 2);
Label usernameLabel = new Label("Username:");
gridPane.add(usernameLabel, 0, 3);
usernameField = new TextField();
gridPane.add(usernameField, 1, 3);
Label passwordLabel = new Label("Password:");
gridPane.add(passwordLabel, 0, 4);
passwordField = new PasswordField();
gridPane.add(passwordField, 1, 4);
Button loginButton = new Button("Log In");
loginButton.setOnAction(e -> loginUser());
gridPane.add(loginButton, 0, 5, 2, 1);
GridPane.setHalignment(loginButton, HPos.CENTER);
Button registerButton = new Button("Register");
registerButton.setOnAction(e -> registerUser());
gridPane.add(registerButton, 0, 6, 2, 1);
GridPane.setHalignment(registerButton, HPos.CENTER);
return gridPane;
}
/**
* Handles the login functionality.
*/
private void loginUser() {
String firstName = firstNameField.getText();
String lastName = lastNameField.getText();
String username = usernameField.getText();
String password = passwordField.getText();
if (
!firstName.isEmpty() &&
!lastName.isEmpty() &&
!username.isEmpty() &&
!password.isEmpty()
) {
// Using the Task object because the system kept being unresponsive and the
// Task object is used as a prevention method
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
sendRequest("LOGIN", firstName, lastName, username, password);
return null;
}
};
new Thread(task).start();
}
else {
showAlert("Error", "Please fill in all fields");
return;
}
}
/**
* Handles the registration functionality.
*/
private void registerUser() {
String firstName = firstNameField.getText();
String lastName = lastNameField.getText();
String username = usernameField.getText();
String password = passwordField.getText();
if (
!firstName.isEmpty() &&
!lastName.isEmpty() &&
!username.isEmpty() &&
!password.isEmpty()
) {
// Using the Task object because the system kept being unresponsive and the
// Task object is used as a prevention method
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
sendRequest("REGISTER", firstName, lastName, username, password);
return null;
}
};
new Thread(task).start();
} else {
showAlert("Error", "Please fill in all fields");
}
}
/**
* Sends a request to the server.
*
* @param requestType The type of request.
* @param args The arguments for the request.
*/
private void sendRequest(String requestType, String... args) {
try (
Socket socket = new Socket("localhost", 8000);
ObjectOutputStream outputToServer = new ObjectOutputStream(
socket.getOutputStream()
);
ObjectInputStream inputFromServer = new ObjectInputStream(
socket.getInputStream()
)
) {
StringBuilder requestBuilder = new StringBuilder(requestType);
for (String arg : args) {
requestBuilder.append(" ").append(arg);
}
outputToServer.writeUTF(requestBuilder.toString());
String response = inputFromServer.readUTF();
// Making sure to flush the output stream
outputToServer.flush();
if (requestType.equals("LOGIN")) {
Platform.runLater(() -> handleLoginResponse(response));
} else if (requestType.equals("REGISTER")) {
Platform.runLater(() -> handleRegisterResponse(response));
}
clearFields();
} catch (IOException e) {
Platform.runLater(
() ->
showAlert(
"Error",
"An error occurred while communicating with the server"
)
);
}
}
/**
* Handles the response from the server for login requests.
*
* @param response The response from the server.
*/
private void handleLoginResponse(String response) {
if (response.equals("USER_NOT_FOUND")) {
showAlert("Error", "User doesn't exist. Please register.");
} else if (response.equals("LOGIN_SUCCESSFUL")) {
showAlert("Success", "Logged in successfully.");
// Optionally, perform further actions after successful login
} else {
showAlert("Error", "Invalid response from server.");
}
}
/**
* Handles the response from the server for registration requests.
*
* @param response The response from the server.
*/
private void handleRegisterResponse(String response) {
if (response.equals("USER_ALREADY_EXISTS")) {
showAlert("Error", "User already exists. Please try another username.");
} else if (response.equals("REGISTRATION_SUCCESSFUL")) {
showAlert("Success", "Registration successful. You can now log in.");
// Optionally, perform further actions after successful registration
} else {
showAlert("Error", "Invalid response from server.");
}
}
/**
* Clears all input fields.
*/
private void clearFields() {
firstNameField.clear();
lastNameField.clear();
usernameField.clear();
passwordField.clear();
}
/**
* Shows an alert dialog with the given title and content.
*
* @param title The title of the alert.
* @param content The content of the alert.
*/
protected void showAlert(String title, String content) {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle(title);
alert.setHeaderText(title);
alert.setContentText(content);
alert.showAndWait();
}
/**
* The main method to launch the JavaFX application.
*
* @param args Command line arguments.
*/
public static void main(String[] args) {
launch(args);
}
}