Browse Source

Merge branch 'main' into client-handler

remotes/origin/client-handler
Valentin Spiroski 11 months ago
parent
commit
0936bcd83e
  1. 4
      .gitignore
  2. 18
      pom.xml
  3. 112
      src/main/java/ChatClient.java
  4. 60
      src/main/java/ChatServer.java
  5. 65
      src/main/java/ClientHandler.java
  6. 5
      src/main/java/Constants.java
  7. 155
      src/main/java/CreateUser.java
  8. 122
      src/main/java/LoginGUI.java
  9. 103
      src/main/java/SignUpGUI.java
  10. 0
      src/main/java/test
  11. 23
      user.json

4
.gitignore

@ -0,0 +1,4 @@
/target/
/.idea/
/.settings/
java-chat.iml

18
pom.xml

@ -3,4 +3,22 @@
<groupId>org.progmethoden</groupId> <groupId>org.progmethoden</groupId>
<artifactId>java-chat</artifactId> <artifactId>java-chat</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.1.10</version>
<scope>test</scope>
</dependency>
</dependencies>
</project> </project>

112
src/main/java/ChatClient.java

@ -0,0 +1,112 @@
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.*;
import java.net.Socket;
public class ChatClient extends JFrame implements KeyListener {
private String address;
private String connectionFailedMessage;
private Socket connectionToServer;
private BufferedReader fromServerReader;
private PrintWriter toServerWriter;
// GUI
private JTextArea outputTextArea;
private JTextField inputTextField;
private JScrollPane outputScrollPane;
public ChatClient() {
super("Chat");
address = JOptionPane.showInputDialog("bitte IP-Adresse");
if (null != address) {
connectionFailedMessage = "Verbindung zum Server " + (address.isEmpty() ? "" : ("\"" + address + "\"")) + " fehlgeschlagen.";
receiveMessages();
}
}
private void initGui() {
outputTextArea = new JTextArea();
outputTextArea.setEditable(false);
outputTextArea.setBorder(BorderFactory.createTitledBorder("Chat"));
outputScrollPane = new JScrollPane(outputTextArea);
inputTextField = new JTextField();
inputTextField.setBorder(BorderFactory.createTitledBorder("Nachricht eingeben"));
inputTextField.addKeyListener(this);
add(outputScrollPane, BorderLayout.CENTER);
add(inputTextField, BorderLayout.SOUTH);
setVisible(true);
setSize(Constants.WINDOW_WIDTH, Constants.WINDOW_HEIGHT);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void receiveMessages() {
try {
connectionToServer = new Socket(address, Constants.PORT);
fromServerReader = new BufferedReader(new InputStreamReader(connectionToServer.getInputStream()));
toServerWriter = new PrintWriter(new OutputStreamWriter(connectionToServer.getOutputStream()));
initGui();
while (true) {
String message = fromServerReader.readLine();
outputTextArea.append(message + "\n");
outputScrollPane.getVerticalScrollBar().setValue(outputScrollPane.getVerticalScrollBar().getMaximum());
}
} catch (IOException e) {
JOptionPane.showMessageDialog(null, connectionFailedMessage);
dispose();
} finally {
if (null != connectionToServer) {
try {
connectionToServer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != fromServerReader) {
try {
fromServerReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != toServerWriter) {
toServerWriter.close();
}
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
String message = inputTextField.getText();
if (!message.isEmpty()) {
toServerWriter.println(message);
toServerWriter.flush();
inputTextField.setText("");
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
public static void main(String[] args) {
new ChatClient();
}
}

60
src/main/java/ChatServer.java

@ -0,0 +1,60 @@
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class ChatServer {
private ServerSocket serverSocket;
private List<ClientHandler> clients; // Liste, um alle verbundenen Clients zu verwalten
public ChatServer(int port) {
clients = new CopyOnWriteArrayList<>(); // Verwende CopyOnWriteArrayList für die Thread-Sicherheit
try {
serverSocket = new ServerSocket(port);
System.out.println("Started ChatServer on port " + port);
while (true) {
System.out.println("waiting for new Client...");
Socket connectionToClient = serverSocket.accept(); // Auf Verbindungen von Clients warten
ClientHandler client = new ClientHandler(this, connectionToClient);
clients.add(client); // Neuen Client zur Liste hinzufügen
System.out.println("Accepted new Client");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// Methode, um eine Nachricht an alle verbundenen Clients zu senden
public void broadcastMessage(String message) {
System.out.println(message);
if (message != null) {
for (ClientHandler client : clients) {
client.sendMessage(message); // Nachricht an jeden Client senden
}
}
}
public static void main(String[] args) {
new ChatServer(3141); // ChatServer auf Port 3141 starten (eventuell den Port flexibler noch wählen? falls belegt)
}
// Methode, um einen Client aus der Liste der verbundenen Clients zu entfernen
public void removeClient(ClientHandler client) {
clients.remove(client);
}
}

65
src/main/java/ClientHandler.java

@ -0,0 +1,65 @@
import java.io.*;
import java.net.Socket;
public class ClientHandler implements Runnable {
private ChatServer chatServer;
private Socket connectionToClient;
private String name;
private BufferedReader fromClientReader;
private PrintWriter toClientWriter;
// Constructor for ClientHandler
public ClientHandler(ChatServer chatServer, Socket connectionToClient) {
this.chatServer = chatServer;
this.connectionToClient = connectionToClient;
name = connectionToClient.getInetAddress().getHostAddress(); // Use the client's IP address as their name for simplicity
new Thread(this).start();} // Start a new thread for this client handler
@Override
public void run() {
try {
// Set up input and output streams for communication with the client
fromClientReader = new BufferedReader (new InputStreamReader(connectionToClient.getInputStream()));
toClientWriter = new PrintWriter (new OutputStreamWriter(connectionToClient.getOutputStream()));
chatServer.broadcastMessage(name + " connected."); // Broadcast a message when the client is connected
// Read messages from the client and broadcast them to all clients
String message = fromClientReader.readLine();
while (message!=null) {
// Broadcast the client's message to all connected clients
chatServer.broadcastMessage(name + ": " + message);
message = fromClientReader.readLine();
}
}
catch (IOException e) {
throw new RuntimeException(e); // Handle exceptions by throwing a runtime exception
}
finally {
chatServer.removeClient(this);
chatServer.broadcastMessage(name + " disconnected."); // Broadcast a message when the client is disconnected
// Close resources in the finally block
if (fromClientReader != null) {
try {
fromClientReader.close();
}
catch (IOException e){
e.printStackTrace();
}
}
if (toClientWriter != null) {
toClientWriter.close();
}
}
}
//Method to send a message to the client
public void sendMessage(String message) {
toClientWriter.println(message); // Send the message to the client
toClientWriter.flush(); // Flush the stream
}
}

5
src/main/java/Constants.java

@ -0,0 +1,5 @@
public class Constants {
public static final int WINDOW_WIDTH = 800;
public static final int WINDOW_HEIGHT = 600;
public static final int PORT = 3141;
}

155
src/main/java/CreateUser.java

@ -0,0 +1,155 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.io.*;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.io.FileWriter;
import java.io.IOException;
import java.util.UUID;
class CreateUser {
private String id;
private String userName;
private String password;
private String birthday;
private boolean stayLoggedIn;
// Constructor
public CreateUser(String id, String name, String password, String birthday) {
this.id = id;
this.userName = name;
this.password = password;
this.birthday = birthday;
}
// Getters and Setters
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public boolean isStayLoggedIn() {
return stayLoggedIn;
}
public void setStayLoggedIn(boolean stayLoggedIn) {
this.stayLoggedIn = stayLoggedIn;
}
// Function to create user with validation
public static CreateUser createUser(String id, String userName, String password, String birthday) {
if (userName == null || userName.isEmpty()) {
throw new IllegalArgumentException("Username cannot be empty");
}
if (password == null || password.isEmpty()) {
throw new IllegalArgumentException("Password cannot be empty");
}
if (password.length() < 6) {
throw new IllegalArgumentException("Password must be at least 6 characters long");
} return new CreateUser(id, userName, password, birthday);
}
// Function to save to JSON file, replace with database call later
public void saveToJsonFile(String filename) {
List<CreateUser> userList = readUserListFromJsonFile(filename);
userList.add(this);
try (FileWriter fileWriter = new FileWriter(filename)) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
gson.toJson(userList, fileWriter);
System.out.println("User information appended to " + filename);
} catch (IOException e) {
System.out.println("Error occurred while saving user information to JSON file: " + e.getMessage());
}
}
// Function to read user information from a JSON file
public static List<CreateUser> readUserListFromJsonFile(String filename) {
List<CreateUser> userList = new ArrayList<>();
try (Reader reader = new FileReader(filename)) {
Type userListType = new TypeToken<List<CreateUser>>() {}.getType();
Gson gson = new Gson();
userList = gson.fromJson(reader, userListType);
} catch (FileNotFoundException e) {
// File does not exist yet, so return an empty list
} catch (IOException e) {
System.out.println("Error occurred while reading user information from JSON file: " + e.getMessage());
}
return userList;
}
// Function to update stayLoggedIn variable in the JSON file
public static void updateStayLoggedIn(String filename, String username, boolean stayLoggedIn) {
List<CreateUser> userList = readUserListFromJsonFile(filename);
for (CreateUser user : userList) {
if (user.getUserName().equals(username)) {
user.setStayLoggedIn(stayLoggedIn);
break;
}
}
try (FileWriter fileWriter = new FileWriter(filename)) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
gson.toJson(userList, fileWriter);
System.out.println("StayLoggedIn updated in " + filename);
} catch (IOException e) {
System.out.println("Error occurred while updating StayLoggedIn in JSON file: " + e.getMessage());
}
}
public static void main(String[] args) {
try {
// Example usage
UUID randomUUID = UUID.randomUUID();
CreateUser user = createUser(randomUUID.toString(), "Test User", "TestPasswort123", "01.01.2000");
// Example of accessing properties
System.out.println("UserID: " + user.getId());
System.out.println("User Name: " + user.getUserName());
System.out.println("User Password: " + user.getPassword());
System.out.println("User Birthday: " + user.getBirthday());
// Save user information to a JSON file
user.saveToJsonFile("user.json");
updateStayLoggedIn("user.json", "Test User", true);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
}
}

122
src/main/java/LoginGUI.java

@ -0,0 +1,122 @@
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class LoginGUI extends JFrame implements ActionListener {
private JTextField usernameField;
private JPasswordField passwordField;
private JButton loginButton;
private JCheckBox stayLoggedInCheckbox;
public LoginGUI() {
setTitle("Login");
setSize(300, 180);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(null);
JLabel usernameLabel = new JLabel("Username:");
usernameLabel.setBounds(20, 20, 80, 25);
add(usernameLabel);
usernameField = new JTextField();
usernameField.setBounds(100, 20, 160, 25);
add(usernameField);
JLabel passwordLabel = new JLabel("Password:");
passwordLabel.setBounds(20, 50, 80, 25);
add(passwordLabel);
passwordField = new JPasswordField();
passwordField.setBounds(100, 50, 160, 25);
add(passwordField);
stayLoggedInCheckbox = new JCheckBox("Stay Logged In");
stayLoggedInCheckbox.setBounds(20, 80, 150, 25);
add(stayLoggedInCheckbox);
loginButton = new JButton("Login");
loginButton.setBounds(100, 110, 100, 25);
loginButton.addActionListener(this);
add(loginButton);
getRootPane().setDefaultButton(loginButton);
passwordField.addKeyListener(new EnterKeyListener());
stayLoggedInCheckbox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
boolean stayLoggedIn = stayLoggedInCheckbox.isSelected();
String username = usernameField.getText();
updateStayLoggedIn(username, stayLoggedIn);
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == loginButton) {
login();
}
}
private void login() {
String username = usernameField.getText();
String password = new String(passwordField.getPassword());
boolean stayLoggedIn = stayLoggedInCheckbox.isSelected(); // Get checkbox state
if (authenticateUser(username, password)) {
JOptionPane.showMessageDialog(this, "Login successful!");
// Perform actions after successful login
dispose();
} else {
JOptionPane.showMessageDialog(this, "Invalid username or password", "Login Error", JOptionPane.ERROR_MESSAGE);
}
}
private void updateStayLoggedIn(String username, boolean stayLoggedIn) {
// Update stayLoggedIn in the JSON file for the user
CreateUser.updateStayLoggedIn("user.json", username, stayLoggedIn);
}
// Function to authenticate the user by comparing the entered username and password with the saved user data
private boolean authenticateUser(String username, String password) {
List<CreateUser> userList = CreateUser.readUserListFromJsonFile("user.json");
if (userList != null) {
for (CreateUser user : userList) {
if (user.getUserName().equals(username) && user.getPassword().equals(password)) {
return true; //Success
}
}
}
return false; // Fail
}
private class EnterKeyListener implements KeyListener {
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
login();
}
}
@Override
public void keyReleased(KeyEvent e) {}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
LoginGUI loginGUI = new LoginGUI();
loginGUI.setVisible(true);
});
}
}

103
src/main/java/SignUpGUI.java

@ -0,0 +1,103 @@
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.UUID;
public class SignUpGUI extends JFrame implements ActionListener {
private JTextField usernameField, passwordField, confirmPasswordField, birthdayField;
private JButton signUpButton;
public SignUpGUI() {
setTitle("Sign Up");
setSize(300, 250);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(null);
JLabel usernameLabel = new JLabel("Username:");
usernameLabel.setBounds(20, 20, 80, 25);
add(usernameLabel);
usernameField = new JTextField();
usernameField.setBounds(100, 20, 160, 25);
add(usernameField);
JLabel passwordLabel = new JLabel("Password:");
passwordLabel.setBounds(20, 50, 80, 25);
add(passwordLabel);
passwordField = new JPasswordField();
passwordField.setBounds(100, 50, 160, 25);
add(passwordField);
JLabel confirmPasswordLabel = new JLabel("Confirm Password:");
confirmPasswordLabel.setBounds(20, 80, 120, 25);
add(confirmPasswordLabel);
confirmPasswordField = new JPasswordField();
confirmPasswordField.setBounds(140, 80, 120, 25);
add(confirmPasswordField);
JLabel birthdayLabel = new JLabel("Birthday:");
birthdayLabel.setBounds(20, 110, 80, 25);
add(birthdayLabel);
birthdayField = new JTextField();
birthdayField.setBounds(100, 110, 160, 25);
add(birthdayField);
signUpButton = new JButton("Sign Up");
signUpButton.setBounds(100, 150, 100, 25);
signUpButton.addActionListener(this);
add(signUpButton);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == signUpButton) {
String username = usernameField.getText();
String password = passwordField.getText();
String confirmPassword = confirmPasswordField.getText();
String birthday = birthdayField.getText();
if (!password.equals(confirmPassword)) {
JOptionPane.showMessageDialog(this, "Passwords do not match!", "Sign Up Error", JOptionPane.ERROR_MESSAGE);
return;
}
if (!isUsernameAvailable("user.json", username)) {
JOptionPane.showMessageDialog(this, "Username already exists!", "Sign Up Error", JOptionPane.ERROR_MESSAGE);
return;
}
try {
UUID randomUUID = UUID.randomUUID();
CreateUser user = CreateUser.createUser(randomUUID.toString(), username, password, birthday);
user.saveToJsonFile("user.json");
JOptionPane.showMessageDialog(this, "User signed up successfully!");
dispose();
} catch (IllegalArgumentException ex) {
JOptionPane.showMessageDialog(this, "Error: " + ex.getMessage(), "Sign Up Error", JOptionPane.ERROR_MESSAGE);
}
}
}
// Function to check if the input username doesn't already exist in the JSON file
private boolean isUsernameAvailable(String filename, String username) {
List<CreateUser> userList = CreateUser.readUserListFromJsonFile(filename);
if (userList != null) {
for (CreateUser user : userList) {
if (user.getUserName().equals(username)) {
return false; // Username already exists
}
}
}
return true; // Username is available
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
SignUpGUI signUpGUI = new SignUpGUI();
signUpGUI.setVisible(true);
});
}
}

0
src/main/java/test

23
user.json

@ -0,0 +1,23 @@
[
{
"id": "a2864d79-1079-4cbb-8d77-f5f84995580d",
"userName": "Another Test User",
"password": "TestPasswort123",
"birthday": "01.01.2000",
"stayLoggedIn": false
},
{
"id": "3690702d-9c7e-48fb-8a01-ef89b3b76268",
"userName": "TestUser2",
"password": "123456",
"birthday": "01.01.2000",
"stayLoggedIn": false
},
{
"id": "685bc3a6-e706-4214-a5e1-8443d1a5258e",
"userName": "Test User",
"password": "Test",
"birthday": "01.01.2000",
"stayLoggedIn": true
}
]
Loading…
Cancel
Save