Action à la fermeture d'une fenêtre
Bonjour à tous !
par avance, un grand merci pour votre aide sur le sujet suivant, qui est un sujet de débutant. Je vais essayer de l'expliquer le plus simplement possible si j'y arrive.
J'ai donc fait une petite application minimaliste "to do liste" sur javafx qui marche parfaitement.
Au tout début du développement j'ai fait toute l'application dans une seule et unique classe, histoire de m'assurer que tout fonctionnait. et tout fonctionne !
après avoir constaté que tout marchait très bien, j'ai décidé de recommencer mais avec une structure d'organisation plus propre à savoir : une classe ListViewDemo.java (ma classe main )qui va charger un MainApp.fxml ( qui contient la structure graphique de l'application ), puis ce MainApp.fxml va être controlé par un MainController.java.
tout marche très bien, mon seul et unique souci : à la fermeture de ma fenêtre, au niveau du primary stage qui est déclaré au niveau de mon ListViewDemo.java, je veux enregistrer les données de ma todoliste pour qu'à la réouverture de cette todoliste les taches enregistrées apparaisent à nouveau.
le problème, c'est que je dois faire référence dans le main à mon ObservableList, qui est déclaré dans mon MainController.java, et je n'y ai pas accès. à l'inverse, il m'est impossible d'observer la fermeture de mon primary stage depuis le MainController.java.
voici mon code :
ListViewDemo.java
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package ListViewDemo;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class ListViewDemo extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/ressources/fxml/MainApp.fxml"));
stage.setTitle("ToDoliste");
Scene scene = new Scene(root, 350, 200);
stage.setScene(scene);
stage.show();
stage.setResizable(false);
// stage.addEventFilter(javafx.stage.WindowEvent.WINDOW_CLOSE_REQUEST, e -> {
// try {
// Utils.DataLoadSave.writeToTextFile(books);
// } catch (IOException e1) {
//
// e1.printStackTrace();
// }
// });
}
public static void main(String[] args) {
launch(args);
}
} |
on notera que la partie avec des quotes, est celle qui déclenche la sauvegarde des données de mon observable liste "books" en appelant la méthode Utils.DataLoadSave.writeToTextFile(books); et tout marchait tres bien au moment ou je déclarais mon Observable liste dans cette même classe ListViewDemo.java
voici maintenant ma classe MainApp.fxml qui est appelée depuis ListViewDemo.java :
MainApp.fxml
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.Cursor?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ListViewDemo.MainController">
<children>
<TextField id="textField" fx:id="textField" />
<HBox prefHeight="55.0" prefWidth="600.0">
<children>
<Button mnemonicParsing="false" onAction="#HandleAddTaskButtonAction" text="ajouter une tache">
<opaqueInsets>
<Insets bottom="30.0" left="30.0" right="30.0" top="30.0" />
</opaqueInsets>
<cursor>
<Cursor fx:constant="HAND" />
</cursor>
<HBox.margin>
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
</HBox.margin>
</Button>
<Button mnemonicParsing="false" onAction="#HandleRemoveTaskButtonAction" text="supprimer une tache">
<opaqueInsets>
<Insets bottom="30.0" left="30.0" right="30.0" top="30.0" />
</opaqueInsets>
<cursor>
<Cursor fx:constant="HAND" />
</cursor>
<HBox.margin>
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
</HBox.margin>
</Button>
<Button mnemonicParsing="false" onAction="#HandleSaveButtonAction" text="SAVE">
<HBox.margin>
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
</HBox.margin>
</Button>
</children>
<opaqueInsets>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</opaqueInsets>
<VBox.margin>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</VBox.margin>
</HBox>
<ListView id="listView" fx:id="listView" prefHeight="400.0" prefWidth="600.0" />
</children>
</VBox> |
je met cette classe juste pour info car le problème je pense ne se situe pas là.
voici maintenant ma classe MainController.java, qui va controller les éléments définis dans le MainApp.fxml.
c'est dans cette classe que je déclare mon ObservableList avec laquelle je tente de communiquer depuis ma classe ListViewDemo qui est ma classe main
MainController.java
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
package ListViewDemo;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.scene.control.TextField;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ListView;
public class MainController implements Initializable{
//Creat an Observable List
public ObservableList<Book> books = Utils.DataLoadSave.intializeObservable();
// Create a ListView
@FXML
private ListView<Book> listView ;
@FXML
private TextField textField ;
@FXML
protected void HandleAddTaskButtonAction( ActionEvent e) {
String monTexte = textField.getText();
if (!monTexte.isEmpty()) {
Book bookNext = new Book(monTexte);
books.add(books.size(), bookNext);
textField.clear();
System.out.println(books);
}
}
@FXML
protected void HandleRemoveTaskButtonAction( ActionEvent e) {
System.out.println("ok remove");
if (!listView.getSelectionModel().isEmpty()) {
int index = listView.getSelectionModel().getSelectedIndex();
books.remove(index);
}
}
@FXML
protected void HandleSaveButtonAction ( ActionEvent e ) throws IOException {
Utils.DataLoadSave.writeToTextFile(books);
}
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
listView.setItems(books);
}
} |
et aussi juste pour info voici la classe qui me permet de sauver et de charger les infos déclarées dans mon ObservableList :
DataLoadSave.java
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| package Utils;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import ListViewDemo.Book;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
public class DataLoadSave {
//write the list to text file
public static void writeToTextFile( ObservableList<Book> books)
throws IOException {
System.out.println("ok on sauve dans dataload save" + books);
FileWriter writer = new FileWriter("students.txt");
for (Book book : books) {
writer.write(book.getName() +"\n");
}
writer.close();
}
public static ObservableList<Book> intializeObservable() {
ObservableList<Book> books = FXCollections.observableArrayList();
BufferedReader reader = null;
try {
reader = Files.newBufferedReader(Paths.get("students.txt"));
} catch (IOException e) {
e.printStackTrace();
}
String line;
try {
while((line = reader.readLine()) != null) {
//myArray.add(line);
books.add(new Book(line));
}
} catch (IOException e) {
e.printStackTrace();
}
return books;
}
} |
voilà j'espère que tout ca n'est pas trop compliqué à comprendre...le problème ultime : je ne parviens pas à passer mon observableList en argument depuis mon main. Le coeur du problème est dans la partie en QUOTE dans ma classe 'main' qui se nomme ListViewDemo.java
un grand merci !!