Skip to content
Snippets Groups Projects
Commit cd0f0cd3 authored by Francesco Fontana's avatar Francesco Fontana
Browse files

Inizializzazione

parent 9c959477
Branches main
No related tags found
No related merge requests found
Pipeline #3233 failed
# bagnini con prof
# CORSO INGEGNERIA DEL SOFTWARE A.A. 2022/23
# Esame del 6 luglio 2023
* `<Cognome> <Nome> <matricola>`
## Getting started
Dopo avere effettuato il **fork** su `gitlab.di.unimi.it` e il **clone** in
locale, modificate questo README
inserendo i vostri dati seguendo lo schema sopra riportato.
Concedete quindi i permessi di lettura (livello **reporter**) al vostro progetto su gitlab ai
docenti (`carlo.bellettini` e `mattia.monga`).
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
## Processo
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
Il progetto va implementato secondo la *metodologia TDD*, utilizzando `git flow`, quindi occorre iniziare con un `git flow init`.
Poi ripetere i passi seguenti fino ad aver implementato tutte le funzionalità richieste:
## Add your files
* creare un nuovo *branch* per la funzionalità corrente attraverso l'esecuzione del comando `git flow feature start`,
* implementare un test per le funzionalità volute;
* verificare che **il codice compili correttamente**, ma l'**esecuzione del test fallisca**;
solo a questo punto effettuare un *commit* iniziando il messaggio di commit con la stringa `ROSSO:`,
* aggiungere la minima implementazione necessaria a realizzare la funzionalità, in modo che **il
test esegua con successo**; solo a questo punto
effettua un *commit* iniziando il messaggio di commit con la stringa `VERDE:`,
* procedere, se necessario, al **refactoring** del codice, accertandosi che le modifiche non
comportino il fallimento di alcun test; solo in questo caso fa seguire a ogni
passo un *commit* iniziando il messaggio di commit con la stringa `REFACTORING:`,
* eseguire il *merge* del *branch* per la funzionalità sviluppata all'interno del *branch develop*
attraverso il comando `git flow feature finish`,
* **solo in fase di rilascio**, esegue una *release* all'interno del *branch master* attraverso il comando `git flow release start` e successivamente `git flow release finish`,
* effettua un *push* (di tutti i *branch*) con `git push origin --all` e poi `git push origin --tags`.
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
# SAPORE DI SALE
```
cd existing_repo
git remote add origin https://gitlab.di.unimi.it/francesco.fontana4/bagnini-con-prof.git
git branch -M main
git push -uf origin main
```
Obiettivo dell'esercizio è progettare e realizzare un insieme di classi atte a
produrre un programma Java che per la gestione di una spiaggia con zone
presidiate da bagnini.
## Integrate with your tools
Ogni bagnino segnala la propria presenza nella zona di competenza: ciò avviene
inviando un messaggio all'arrivo e all'abbandono della zona. Durante la
permanenza il bagnino può inviare messaggi che informano sullo stato della
balneabilità, indicando il colore convenzionale della bandiera corrispondente:
ROSSA (pericolo elevato), GIALLA (rischio medio, solo nuotatori esperti), VERDE
(nuoto sicuro), VIOLA (presenza di meduse).
- [ ] [Set up project integrations](https://gitlab.di.unimi.it/francesco.fontana4/bagnini-con-prof/-/settings/integrations)
- All'arrivo il bagnino indica il proprio nome cioè una stringa alfabetica:
- UNIVOCA (cioè non ci possono essere due bagnini attivi con lo stesso nome)
- NON VUOTA
- di non più di 30 caratteri;
- La segnalazione di abbandono della postazione non prevede indicazioni nel campo di testo e chiaramente ha successo solo se la postazione era presidiata ;
- Le segnalazioni sullo stato di balneabilità
sono permesse solo dopo una segnalazione di arrivo e consistono nella indicazione del colore della bandiera esposta;
- I colori della bandiera devono essere indicati esclusivamente con le stringhe
dell'insieme ROSSA, GIALLA, VERDE, VIOLA.
## Collaborate with your team
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
Nell'esempio ci sono 4 zone di presidio con i bottoni per svolgere le operazioni sopra indicate
e 2 display.
Quello a sinistra indica lo
stato della 4 zone della nostra spiaggia, mentre quello a destra la postazione in cui si trovano i agnini attivi.
## Test and Deploy
In particolare nella vista display a sinistra per ogni zona/postazione verrà scritto a secondo del caso:
- **postazione non presidiata**
- **\[** _numpostazione_ **\]** _nome bagnino_ **segnala** _messaggio di stato dipendente dall'ultima bandiera segnalata_
Use the built-in continuous integration in GitLab.
ad esempio: [2] Carlo segnala presenza di meduse
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
***
Nella vista display a destra verrà invece scritto per ogni bagnino attivo (e in ordine alfabetico:
- _nome bagnino_ **è alla postazione** _numero postazione_
# Editing this README
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template.
## Suggestions for a good README
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
## TRACCIA
## Name
Choose a self-explaining name for your project.
Completare, in modo da realizzare un'organizzazione del sistema di tipo
*Model-View-Presenter*.
## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
## Badges
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
## Visuals
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
Vi vengono fornite già due classi *Viste* del sistema:
## Installation
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
- `PostazioneView`: la vista che permette (vedi metodo `addHandlers`) di:
- Comunicare arrivo di un bagnino in una zona;
- Comunicare abbandono di un bagnino da una zona;
- Comunicare il colore della bandiera scelto dal bagnino per una zona;
- `DisplayView`: un display generale che permette di visualizzare alcune righe
di testo e può essere usato per visualizzare sia la situazione delle zone, che la posizione dei bagnini.
## Usage
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
## Support
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
Viene fornita anche una prima versione della classe `Main`, e una classe (`GUITest`) contenente solo alcuni test d'integrazione/validazione.
## Roadmap
If you have ideas for releases in the future, it is a good idea to list them in the README.
**TUTTE LE CLASSI DATE POSSONO ESSERE MODIFICATE (CANCELLATE, COMPLETATE) PER
ADERIRE A DIFFERENTI IDEE DI
PROGETTAZIONE**
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
Lanciando il codice attuale (tramite il task **run** di gradle) si ottiene inizialmente una
interfaccia come quella nella figura sottostante.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
![start](img_0.png)
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
Ad esempio partendo dalla seguente situazione iniziale
## License
For open source projects, say how it is licensed.
![start](img_1.png)
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
la sequenza di operazioni (con l'ultima che causerà errore):
- Arrivo alla postazione 1 del bagnino "Mario"
- che segnala la bandiera ROSSA;
- Arrivo alla postazione 0 del bagnino "Luigi"
- che segnala la bandiera GIALLA;
- Arrivo alla postazione 3 del bagnino "Giovanni"
- che segnala la bandiera GRIGIA;
porterebbe alla situazione:
![start](img_2.png)
### Suggerimenti
Oltre all'uso del pattern _Model-View-Presenter_, vi consigliamo di considerare
lo sfruttamento
al fine di scrivere un codice migliore anche di altri pattern (ad es. il pattern
_Strategy_, o il pattern _Template_) e in
ogni caso di prestare grande attenzione al rispetto dei principi **SOLID** di
buona progettazione Object Oriented.
Prestare estrema attenzione anche a garantire una corretta encapsulation dello
stato da parte delle varie classi (ad
esempio del Model) in modo da garantire l'assenza di **escaping references** anche di
solo parte dello stato.
### Testing
Mano a mano che si sviluppa il progetto, si deve controllare di mantenere una
copertura, sia dei comandi che delle
decisioni, soddisfacente (se inferiore al 100% inserire un commento che spieghi
perché non è possibile raggiungerlo).
Sono presenti anche alcuni test di integrazione.
Vi dovrebbero essere di aiuto anche per capire cosa serve fare (cioè come
specifiche).
Può essere utile oltre ai test di unità che scrivete durante il TDD prevedere di aggiungere anche qualche test di
integrazione per verificare che il sistema funzioni correttamente anche facendo interagire le diverse classi reali.
### Consegna
Al termine del laboratorio dovete impacchettare l'ultima versione stabile (non ci possono essere test di unità che
falliscono) a cui siete arrivati come una _release_ di gitflow chiamata
"consegna" ed effettuare un ultimo *push* anche di tutti i rami locali (comprese quindi eventuali feature aperte ma non
completate e non presenti nella realease "consegna"):
`git push origin --all` e poi `git push origin --tags`
## **Verificate su `gitlab.di.unimi.it`** che ci sia la completa traccia dei *commit* effettuati e di averne dato visibilità ai docenti.
plugins {
id 'java'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.13'
id "org.unbroken-dome.test-sets" version "4.0.0"
}
application.mainClass = 'it.unimi.di.sweng.esame.Main'
javafx {
version = '17'
modules = [ 'javafx.controls']
}
repositories {
mavenCentral()
}
testSets {
integrationTest
}
dependencies {
implementation 'org.jetbrains:annotations:24.0.1'
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'
testImplementation 'org.assertj:assertj-core:3.24.2'
testImplementation 'org.hamcrest:hamcrest-core:2.2'
testImplementation 'org.mockito:mockito-core:5.2.0'
integrationTestImplementation "org.testfx:testfx-junit5:4.0.16-alpha"
integrationTestImplementation 'org.testfx:testfx-core:4.0.16-alpha'
}
test {
useJUnitPlatform()
}
integrationTest {
useJUnitPlatform();
}
check.dependsOn integrationTest
integrationTest.mustRunAfter test
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
img_0.png 0 → 100644
img_0.png

91.7 KiB

img_1.png 0 → 100644
img_1.png

163 KiB

img_2.png 0 → 100644
img_2.png

124 KiB

package it.unimi.di.sweng.esame;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.matchesPattern;
import static org.hamcrest.Matchers.startsWith;
import static org.testfx.api.FxAssert.verifyThat;
import static org.testfx.matcher.control.LabeledMatchers.hasText;
import it.unimi.di.sweng.esame.views.DisplayView;
import it.unimi.di.sweng.esame.views.PostazioneView;
import javafx.collections.ObservableList;
import javafx.scene.Node;
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 org.assertj.core.util.introspection.FieldSupport;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.testfx.api.FxRobot;
import org.testfx.framework.junit5.ApplicationExtension;
import org.testfx.framework.junit5.Start;
@ExtendWith(ApplicationExtension.class)
@TestMethodOrder(MethodOrderer.MethodName.class)
public class GUITest {
private Label[] elencoPostazioni;
private Label[] elencoBagnini;
private final TextField[] inputMessage = new TextField[Main.NUMPOSTAZIONI];
private final Button[][] bottoni = new Button[Main.NUMPOSTAZIONI][];
private final Label[] errorMessage = new Label[Main.NUMPOSTAZIONI];
private final Label[] bagniniNomi = new Label[Main.NUMPOSTAZIONI];
@Start
public void start(Stage primaryStage) {
Main m = new Main();
m.start(primaryStage);
GridPane gp = (GridPane) primaryStage.getScene().getRoot();
ObservableList<Node> view = gp.getChildren();
PostazioneView[] postazioniView = new PostazioneView[Main.NUMPOSTAZIONI];
for (int i = 0; i < Main.NUMPOSTAZIONI; i++) {
postazioniView[i] = (PostazioneView) view.get(i);
bottoni[i] = FieldSupport.EXTRACTION.fieldValue("button", Button[].class, postazioniView[i]);
inputMessage[i] = FieldSupport.EXTRACTION.fieldValue("textField", TextField.class, postazioniView[i]);
errorMessage[i] = FieldSupport.EXTRACTION.fieldValue("error", Label.class, postazioniView[i]);
bagniniNomi[i] = FieldSupport.EXTRACTION.fieldValue("bagnino", Label.class, postazioniView[i]);
}
DisplayView leftView = (DisplayView) view.get(Main.NUMPOSTAZIONI);
DisplayView rightView = (DisplayView) view.get(Main.NUMPOSTAZIONI + 1);
elencoPostazioni = FieldSupport.EXTRACTION.fieldValue("rows", Label[].class, leftView);
elencoBagnini = FieldSupport.EXTRACTION.fieldValue("rows", Label[].class, rightView);
}
void selezioneContenutoCasellaTesto(FxRobot robot, TextField field) {
robot.doubleClickOn(field).clickOn(field); //triplo click per selezionare tutto
}
@Test
public void testArrivaOK(FxRobot robot) {
selezioneContenutoCasellaTesto(robot, inputMessage[2]);
robot.write("Carlo");
robot.clickOn(bottoni[2][0]);
verifyThat(errorMessage[2], hasText(""));
verifyThat(elencoPostazioni[2], hasText("[2] Carlo segnala ancora nulla"));
verifyThat(elencoBagnini[0], hasText("Carlo è alla postazione 2"));
verifyThat(bagniniNomi[2] , hasText("Carlo"));
}
@Test
public void testArrivaNomeVuotoFail(FxRobot robot) {
selezioneContenutoCasellaTesto(robot, inputMessage[2]);
robot.write("");
robot.clickOn(bottoni[2][0]);
verifyThat(errorMessage[2], hasText("nome vuoto"));
verifyThat(elencoPostazioni[2], hasText("postazione non presidiata"));
}
@Test
public void testArrivaNomeLungoFail(FxRobot robot) {
selezioneContenutoCasellaTesto(robot, inputMessage[2]);
robot.write("Nometroppolungomapropriopropriopriprio");
robot.clickOn(bottoni[2][0]);
verifyThat(errorMessage[2], hasText("nome troppo lungo"));
verifyThat(elencoPostazioni[2], hasText("postazione non presidiata"));
}
@Test
public void testVaViaNonpresenteFail(FxRobot robot) {
selezioneContenutoCasellaTesto(robot, inputMessage[2]);
robot.write("");
robot.clickOn(bottoni[2][2]);
verifyThat(errorMessage[2], hasText("Bagnino non presente"));
verifyThat(elencoPostazioni[2], hasText("postazione non presidiata"));
}
@Test
public void testSegnalaBandieraVuota(FxRobot robot) {
selezioneContenutoCasellaTesto(robot, inputMessage[1]);
robot.write("");
robot.clickOn(bottoni[1][1]);
verifyThat(errorMessage[1], hasText("Indicare colore bandiera"));
}
@Test
public void testSegnalaBandieraSbagliata(FxRobot robot) {
selezioneContenutoCasellaTesto(robot, inputMessage[1]);
robot.write("TURCHESE");
robot.clickOn(bottoni[1][1]);
verifyThat(errorMessage[1], hasText("Bandiera non valida"));
}
@Test
public void testSegnalaBandieraDaPostazioneVuota(FxRobot robot) {
selezioneContenutoCasellaTesto(robot, inputMessage[1]);
robot.write("ROSSA");
robot.clickOn(bottoni[1][1]);
verifyThat(errorMessage[1], hasText("postazione non presidiata"));
}
@Test
public void testSegnalaBandieraOK(FxRobot robot) {
selezioneContenutoCasellaTesto(robot, inputMessage[2]);
robot.write("Carlo");
robot.clickOn(bottoni[2][0]);
selezioneContenutoCasellaTesto(robot, inputMessage[2]);
robot.write("ROSSA");
robot.clickOn(bottoni[2][1]);
verifyThat(errorMessage[2], hasText(""));
verifyThat(elencoPostazioni[2], hasText("[2] Carlo segnala pericolo elevato"));
}
@Test
public void testArrivaBagninoFail(FxRobot robot) {
selezioneContenutoCasellaTesto(robot, inputMessage[2]);
robot.write("Carlo");
robot.clickOn(bottoni[2][0]);
selezioneContenutoCasellaTesto(robot, inputMessage[2]);
robot.write("Mattia");
robot.clickOn(bottoni[2][0]);
verifyThat(errorMessage[2], hasText("postazione già occupata"));
}
@Test
public void testArrivaBagninoFail2(FxRobot robot) {
selezioneContenutoCasellaTesto(robot, inputMessage[2]);
robot.write("Carlo");
robot.clickOn(bottoni[2][0]);
selezioneContenutoCasellaTesto(robot, inputMessage[0]);
robot.write("Carlo");
robot.clickOn(bottoni[0][0]);
verifyThat(errorMessage[0], hasText("bagnino già presente in altra postazione"));
}
@Test
public void testOrdinamentoListaBagnini(FxRobot robot) {
selezioneContenutoCasellaTesto(robot, inputMessage[0]);
robot.write("Violetta");
selezioneContenutoCasellaTesto(robot, inputMessage[2]);
robot.write("Mattia");
selezioneContenutoCasellaTesto(robot, inputMessage[1]);
robot.write("Carlo");
selezioneContenutoCasellaTesto(robot, inputMessage[3]);
robot.write("Anna");
robot.clickOn(bottoni[2][0]);
robot.clickOn(bottoni[1][0]);
robot.clickOn(bottoni[3][0]);
robot.clickOn(bottoni[0][0]);
verifyThat(elencoBagnini[0], hasText("Anna è alla postazione 3"));
verifyThat(elencoBagnini[1], hasText(startsWith("Carlo è alla postazione 1")));
verifyThat(elencoBagnini[2], hasText(startsWith("Mattia è alla postazione 2")));
verifyThat(elencoBagnini[3], hasText(startsWith("Violetta è alla postazione 0")));
robot.clickOn(bottoni[1][2]);
verifyThat(elencoBagnini[0], hasText("Anna è alla postazione 3"));
verifyThat(elencoBagnini[1], hasText(startsWith("Mattia è alla postazione 2")));
verifyThat(elencoBagnini[2], hasText(startsWith("Violetta è alla postazione 0")));
}
}
package it.unimi.di.sweng.esame;
import it.unimi.di.sweng.esame.views.DisplayView;
import it.unimi.di.sweng.esame.views.PostazioneView;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Main extends Application {
public static final int NUMPOSTAZIONI = 4;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Baywatch");
PostazioneView[] postazioneView = new PostazioneView[NUMPOSTAZIONI];
for (int i = 0; i < NUMPOSTAZIONI; i++) {
postazioneView[i] = new PostazioneView();
}
DisplayView leftSideView = new DisplayView("Elenco postazioni", NUMPOSTAZIONI);
DisplayView rightSideView = new DisplayView("Elenco Bagnini", NUMPOSTAZIONI);
GridPane gridPane = new GridPane();
gridPane.setBackground(new Background(new BackgroundFill(Color.DARKOLIVEGREEN, CornerRadii.EMPTY, Insets.EMPTY)));
gridPane.setPadding(new Insets(10, 10, 10, 10));
for (int i = 0; i < NUMPOSTAZIONI; i++) {
gridPane.add(postazioneView[i], i % 2, i / 2);
}
gridPane.add(leftSideView, 0, 2);
gridPane.add(rightSideView, 1, 2);
//TODO creare presenters e connettere model e view
//model.notifyObservers();
Scene scene = new Scene(gridPane);
primaryStage.setScene(scene);
primaryStage.show();
}
}
package it.unimi.di.sweng.esame.presenters;
public interface Presenter {
void action(String text1, String text2);
}
package it.unimi.di.sweng.esame.views;
import javafx.geometry.Insets;
import javafx.scene.control.Label;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import org.jetbrains.annotations.NotNull;
public class DisplayView extends Region {
@NotNull private final Label[] rows;
public DisplayView(@NotNull String title, int rows) {
this.rows = new Label[rows];
setBackground(new Background(
new BackgroundFill(Color.LIGHTBLUE, new CornerRadii(5.0), Insets.EMPTY)));
setBorder(new Border(
new BorderStroke(null, BorderStrokeStyle.SOLID, new CornerRadii(5.0), new BorderWidths(2))));
GridPane grid = new GridPane();
grid.setPadding(new Insets(10, 10, 10, 10));
Label title1 = new Label(title);
title1.setFont(Font.font("sans", 20));
grid.add(title1, 0, 0);
for (int i = 0; i < rows; i++) {
this.rows[i] = new Label(String.format("%-35s","Row #" + i));
this.rows[i].setPadding(new Insets(10, 10, 10, 10));
this.rows[i].setFont(Font.font("monospace", 14));
grid.add(this.rows[i], 0, i + 1);
}
this.getChildren().add(grid);
}
public void set(int i, @NotNull String s) {
rows[i].setText(s);
}
public int size() {
return rows.length;
}
}
package it.unimi.di.sweng.esame.views;
import it.unimi.di.sweng.esame.presenters.Presenter;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class PostazioneView extends Region {
@NotNull
private final TextField textField;
@NotNull
private final Label error;
@NotNull
private final Button[] button = new Button[3];
@NotNull
private final Label bagnino;
public PostazioneView() {
bagnino = new Label("postazione non presidiata");
bagnino.setFont(Font.font("sans", 24));
button[0] = new Button("Arriva");
button[1] = new Button("Segnala");
button[2] = new Button("Va via");
textField = new TextField();
error = new Label("");
textField.setFont(Font.font("sans", 20));
setBackground(new Background(
new BackgroundFill(Color.LIGHTGRAY, new CornerRadii(5.0), Insets.EMPTY)));
setBorder(new Border(
new BorderStroke(null, BorderStrokeStyle.SOLID, new CornerRadii(5.0), new BorderWidths(2))));
GridPane grid = new GridPane();
grid.setPadding(new Insets(10, 10, 10, 10));
grid.add(bagnino, 0, 0, 3, 1);
grid.add(textField, 0, 2, 3, 1);
for (int i = 0; i < 3; i++) {
grid.add(button[i], i, 1);
button[i].setFont(Font.font("sans", 20));
}
grid.add(error, 0, 3, 3, 1);
this.getChildren().add(grid);
}
public void addHandlers(@NotNull Presenter presenter) {
/*Arriva */
button[0].setOnAction(eh -> presenter.action(button[0].getText(), textField.getText()));
/*Segnala*/
button[1].setOnAction(eh -> presenter.action(button[1].getText(), bagnino.getText() + "," + textField.getText()));
/*Va via */
button[2].setOnAction(eh -> presenter.action(button[2].getText(), bagnino.getText()));
}
public void showError(@NotNull String s) {
error.setText(s);
setBackground(new Background(
new BackgroundFill(Color.YELLOW, new CornerRadii(5.0), Insets.EMPTY)));
}
public void showSuccess() {
error.setText("");
textField.clear();
setBackground(new Background(
new BackgroundFill(Color.LIGHTGRAY, new CornerRadii(5.0), Insets.EMPTY)));
}
public void setBagnino(@Nullable String s) {
bagnino.setText(s);
}
}
package it.unimi.di.sweng.esame;
import static org.assertj.core.api.Assertions.assertThat;
import org.assertj.core.api.Assertions;
class VariTest {
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment