Coverage Summary for Class: LoginFXMLController (it.polimi.ingsw.gc14.View.GUI)
| Class |
Class, %
|
Method, %
|
Branch, %
|
Line, %
|
| LoginFXMLController |
0%
(0/1)
|
0%
(0/14)
|
0%
(0/14)
|
0%
(0/63)
|
package it.polimi.ingsw.gc14.View.GUI;
import it.polimi.ingsw.gc14.Controller.ClientController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Network.NetworkConfig;
import it.polimi.ingsw.gc14.Network.InterfaceResolver;
import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient;
import it.polimi.ingsw.gc14.Network.TCP.Client.TCPClient;
import javafx.animation.*;
import javafx.application.Platform;
import javafx.css.PseudoClass;
import javafx.fxml.FXML;
import javafx.geometry.Rectangle2D;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Screen;
import javafx.util.Duration;
import java.net.*;
import java.util.Enumeration;
/**
* FXML controller for the login scene.
*
* <p>Handles username/IP/player-count input, protocol selection (TCP/RMI),
* and initiates the connection to the server.
*/
public class LoginFXMLController {
//TODO
@FXML private ImageView backgroundImage;
//TODO
@FXML private TextField campoNome;
//TODO
@FXML private TextField campoNumPlayers;
//TODO
@FXML private TextField campoIP;
//TODO
@FXML private Button btnAccedi;
//TODO
@FXML private Label labelErrore;
//TODO
@FXML private VBox formPanel;
//TODO
@FXML private StackPane protocolToggle;
//TODO
@FXML private Region toggleThumb;
//TODO
@FXML private Label labelRMI;
//TODO
@FXML private Label labelTCP;
//TODO
private boolean isRMI = true;
//TODO
private ClientController controller;
//TODO
private final PseudoClass activeProtocolPseudo = PseudoClass.getPseudoClass("active-protocol");
/**
* Injects the client controller into this FXML controller.
*
* @param controller the client controller to use.
*/
public void setController(ClientController controller) {
this.controller = controller;
}
/** Initializes the scene: loads background, sets up animations, and binds input listeners. */
@FXML
public void initialize() {
// Background setup
Image img = new Image(getClass().getResourceAsStream("/GUIImages/BackgroundLogin.png"));
backgroundImage.setImage(img);
Rectangle2D screenBounds = Screen.getPrimary().getBounds();
backgroundImage.setFitWidth(screenBounds.getWidth());
backgroundImage.setFitHeight(screenBounds.getHeight());
// Protocol toggle configuration
protocolToggle.setOnMouseClicked(e -> switchProtocol());
protocolToggle.setStyle(protocolToggle.getStyle() + " -fx-cursor: hand;");
labelRMI.pseudoClassStateChanged(activeProtocolPseudo, true);
labelTCP.pseudoClassStateChanged(activeProtocolPseudo, false);
// Login Action
btnAccedi.setOnAction(e -> onAccediClick());
}
/** Toggles the selected protocol between RMI and TCP, animating the toggle thumb and updating label styles. */
private void switchProtocol() {
isRMI = !isRMI;
TranslateTransition tt = new TranslateTransition(Duration.millis(200), toggleThumb);
tt.setToX(isRMI ? 0 : 110);
tt.play();
// pseudoClassStateChanged preserves layout properties unlike direct style mutation
labelRMI.pseudoClassStateChanged(activeProtocolPseudo, isRMI);
labelTCP.pseudoClassStateChanged(activeProtocolPseudo, !isRMI);
}
/** Validates form input and starts a background thread to connect to the server. */
@FXML
private void onAccediClick() {
String name = campoNome.getText().trim();
String ip = campoIP.getText().trim();
if (name.isEmpty()) {
showError("Please select a name.");
return;
}
int numPlayers;
try {
numPlayers = Integer.parseInt(campoNumPlayers.getText().trim());
} catch (NumberFormatException e) {
showError("Invalid number of players.");
return;
}
updateLoginButton(false);
controller.setMyUsername(name);
new Thread(() -> {
try {
String localInterface = InterfaceResolver.resolveLocalInterface(ip);
System.setProperty("java.rmi.server.hostname", localInterface);
connect(name, ip, numPlayers, localInterface);
} catch (Exception ex) {
Platform.runLater(() -> {
showError("Network error: " + ex.getMessage());
updateLoginButton(true);
});
}
}).start();
}
/**
* Enables or disables the login button and updates its visual style.
*
* @param enabled {@code true} to enable the button, {@code false} to disable it.
*/
public void updateLoginButton(boolean enabled) {
btnAccedi.setDisable(!enabled);
btnAccedi.setStyle(
"-fx-font-family: 'Cinzel'; -fx-font-size: 12; -fx-font-weight: bold;" +
"-fx-letter-spacing: 4; -fx-text-fill: #0c0601;" +
"-fx-background-color: linear-gradient(to right, #f4c05a, #c8791a, #f4c05a);" +
"-fx-padding: 13 48 13 48; -fx-background-radius: 2;" +
"-fx-opacity: " + (enabled ? "1.0" : "0.3") + ";" +
"-fx-cursor: " + (enabled ? "hand" : "default") + ";"
);
}
/** Connects to the server using the selected protocol and transitions to the waiting state on success. */
private void connect(String nome, String ip, int numPlayers, String localInterface) {
if (isRMI) {
RMIClient client = new RMIClient(controller, ip, NetworkConfig.RMI_PORT, localInterface);
ErrorType serverResponse = client.connect(nome, numPlayers);
if (serverResponse == null) {
controller.setClient(client);
Platform.runLater(() -> showSuccess("Connected! Waiting for other players…"));
} else {
Platform.runLater(() -> {
showError(serverResponse);
updateLoginButton(true);
});
}
} else {
TCPClient client = new TCPClient(controller, ip, NetworkConfig.TCP_PORT, NetworkConfig.HEARTBEAT_PORT);
ErrorType serverResponse = client.connect(nome, numPlayers);
if (serverResponse == null) {
controller.setClient(client);
Platform.runLater(() -> showSuccess("Connected! Waiting for other players…"));
} else {
Platform.runLater(() -> {
showError(serverResponse);
updateLoginButton(true);
});
}
}
}
/**
* Displays an error from an {@link ErrorType} constant in the login form label.
*
* @param errorType the error to display.
*/
public void showError(ErrorType errorType) {
labelErrore.setTextFill(Color.web("#e05050"));
labelErrore.setText(errorType.toString());
}
/**
* Displays an arbitrary error message in the login form label.
*
* @param msg the error message to display.
*/
public void showError(String msg) {
labelErrore.setTextFill(Color.web("#e05050"));
labelErrore.setText(msg);
}
/** Displays a success message in green in the login form label. */
private void showSuccess(String msg) {
labelErrore.setTextFill(Color.web("#6fcf8a"));
labelErrore.setText(msg);
}
}