feat(host): gestion de l'ajout de nouveaux hôtes/adresses serveur, fix du logger

This commit is contained in:
Emi Boucly 2025-01-28 14:22:51 +01:00
parent 8cea05bb7b
commit ab0e49f2f0
6 changed files with 165 additions and 11 deletions

View file

@ -16,15 +16,13 @@ import java.util.logging.Logger;
public class ChatApplication extends Application {
public static final Logger LOGGER = Logger.getLogger(ChatApplication.class.getCanonicalName());
public class EssaiLogger {
static {
try {
InputStream is = EssaiLogger.class.getClassLoader()
.getResource("logging.properties").openStream();
LogManager.getLogManager().readConfiguration(is);
} catch (Exception e) {
LOGGER.log(Level.INFO, "Cannot read configuration file", e);
}
static {
try {
InputStream is = ChatApplication.class
.getResource("logging.properties").openStream();
LogManager.getLogManager().readConfiguration(is);
} catch (Exception e) {
LOGGER.log(Level.INFO, "Cannot read configuration file", e);
}
}

View file

@ -10,7 +10,9 @@ import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
@ -19,6 +21,7 @@ import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Modality;
import javafx.stage.Stage;
import net.synedra.validatorfx.Check;
import net.synedra.validatorfx.TooltipWrapper;
@ -98,6 +101,7 @@ public class ChatController implements Initializable {
loginTextField.disableProperty().bind(connectionButton.selectedProperty());
hostComboBox.disableProperty().bind(connectionButton.selectedProperty());
hostAddMenuItem.setOnAction(this::handleHostAdd);
avatarMenuItem.setOnAction(this::handleAvatarChange);
avatarImageView.setOnMouseClicked(this::handleAvatarChange);
sendButton.setOnAction(this::onActionSend);
@ -128,6 +132,39 @@ public class ChatController implements Initializable {
}
private void handleHostAdd(ActionEvent actionEvent) {
try {
ChatHostAddController controller = showNewStage("Add host", "chathostadd-view.fxml");
if (controller.isOk()) {
hostComboBox.getItems().add(controller.hostTextField.getText());
hostComboBox.setValue(controller.hostTextField.getText());
}
} catch (IOException e) {
LOGGER.warning("Impossible d'ouvrir la fenêtre de dialogue: fxml introuvable \n" + e.getMessage());
e.printStackTrace();
}
}
/**
* Ouvre une fenêtre modale et attend qu'elle se ferme.
*
* @param title titre de la fenêtre
* @param fxmlFileName nom du fichier FXML décrivant l'interface graphique
* @return l'objet contrôleur associé à la fenêtre
* @throws IOException si le fichier FXML n'est pas trouvé dans les ressources
*/
public <T> T showNewStage(String title, String fxmlFileName) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(ChatApplication.class.getResource(fxmlFileName));
Scene scene = new Scene(fxmlLoader.load());
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle(title);
stage.setResizable(false);
stage.setScene(scene);
stage.showAndWait();
return fxmlLoader.getController();
}
private void initRoomListView() {
try {
roomsListView.setCellFactory(roomListView -> new RoomListViewCell());

View file

@ -0,0 +1,70 @@
package rtgre.chat;
import javafx.beans.binding.Bindings;
import javafx.event.ActionEvent;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import net.synedra.validatorfx.Check;
import net.synedra.validatorfx.TooltipWrapper;
import net.synedra.validatorfx.Validator;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ChatHostAddController implements Initializable {
public TextField hostTextField;
public Button resetButton;
public HBox submitWrapper;
public Button submitButton;
private boolean ok = false;
public static final Pattern HOST_PORT_REGEX = Pattern.compile("^([-.a-zA-Z0-9]+)(?::([0-9]{1,5}))?$");
private Validator validatorHost = new Validator();
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
submitButton.setOnAction(this::onActionSubmit);
resetButton.setOnAction(this::onActionReset);
submitButton.disableProperty().bind(validatorHost.containsErrorsProperty());
TooltipWrapper<Button> submitWrapper = new TooltipWrapper<>(
submitButton,
validatorHost.containsErrorsProperty(),
Bindings.concat("Cannot submit:\n", validatorHost.createStringBinding())
);
this.submitWrapper.getChildren().add(submitWrapper);
validatorHost.createCheck()
.dependsOn("host", hostTextField.textProperty())
.withMethod(this::checkHost)
.decorates(hostTextField)
.immediate();
}
private void checkHost(Check.Context context) {
String host = context.get("host");
if (!HOST_PORT_REGEX.matcher(host).matches()) {
context.error("Host should be a valid IP address or name with potentially port number");
}
}
private void onActionReset(ActionEvent actionEvent) {
hostTextField.setText("");
}
private void onActionSubmit(ActionEvent actionEvent) {
ok = true;
((Stage) submitButton.getScene().getWindow()).close();
}
public boolean isOk() {
return ok;
}
}

View file

@ -2,6 +2,7 @@ package rtgre.server;
import org.json.JSONException;
import org.json.JSONObject;
import rtgre.chat.ChatController;
import rtgre.chat.net.ChatClient;
import rtgre.modeles.*;
@ -28,7 +29,7 @@ public class ChatServer {
static {
try {
InputStream is = ChatServer.class.getClassLoader()
InputStream is = ChatController.class
.getResource("logging.properties").openStream();
LogManager.getLogManager().readConfiguration(is);
} catch (Exception e) {