JavaFX - JSON file bind to observable list

Maven pom.xml org.json

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>fr.ronanlefichant</groupId>
	<artifactId>javafxlistjson</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>11</maven.compiler.source>
		<maven.compiler.target>11</maven.compiler.target>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.openjfx</groupId>
			<artifactId>javafx-controls</artifactId>
			<version>17.0.0.1</version>
		</dependency>
		<dependency>
			<groupId>org.json</groupId>
			<artifactId>json</artifactId>
			<version>20211205</version>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.0</version>
				<configuration>
					<release>11</release>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.openjfx</groupId>
				<artifactId>javafx-maven-plugin</artifactId>
				<version>0.0.6</version>
				<executions>
					<execution>
						<!-- Default configuration for running -->
						<!-- Usage: mvn clean javafx:run -->
						<id>default-cli</id>
						<configuration>
							<mainClass>fr.ronanlefichant.javafxlistjson.App</mainClass>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

Liaison entre fichier / ObservableList

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

import org.json.JSONArray;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 * JavaFX App
 */
public class App extends Application {

  @Override
  public void start(Stage stage) {

    // La vue de la liste et la liste
    ListView < Object > listView = new ListView < Object > ();
    ObservableList < Object > observableList = FXCollections.observableArrayList();
    listView.setItems(observableList);

    // Liaison entre le fichier JSON et la liste
    try {
      new ArrayJSONFileObservableListBinder(Path.of("array.json"), observableList);
    } catch (IOException e) {
      e.printStackTrace();
    }

    // Création de la fenêtre et de la scène
    Scene scene = new Scene(new StackPane(listView), 640, 480);
    stage.setScene(scene);
    stage.show();
  }

  public static void main(String[] args) {
    launch();
  }

  class ArrayJSONFileObservableListBinder {

    private ObservableList < Object > items;
    private Path path;

    public ArrayJSONFileObservableListBinder(Path path, ObservableList < Object > items) throws IOException {
      this.path = path;
      this.items = items;
      startBinding(path);
    }

    private void startBinding(Path path) throws IOException {
      addAllFileArrayToObservableList();
      Thread thread = new Thread(() -> {
        try {
          createWatchServiceAndPoll(path);
        } catch (IOException | InterruptedException e) {
          e.printStackTrace();
        }
      });
      // Stop le thread si l'application est quittée
      thread.setDaemon(true);
      thread.start();
    }

    private void createWatchServiceAndPoll(Path path) throws IOException, InterruptedException {
      WatchService watchService = createWatchService();
      poll(watchService);
    }

    private void poll(WatchService watchService) throws InterruptedException, IOException {
      boolean poll = true;
      while (poll) {
        WatchKey key = watchService.take();
        // Pour tous les événements
        for (WatchEvent < ? > event : key.pollEvents()) {
          String fileName = event.context().toString();
          /*
           * Si le nom du fichier concerné par l'événement est le même que le fichier du
           * chemin
           */
          if (path.getFileName().toString().equals(fileName)) {
            addAllFileArrayToObservableList();
          }
        }
        poll = key.reset();
      }
    }

    private WatchService createWatchService() throws IOException {
      WatchService watchService = FileSystems.getDefault().newWatchService();
      // Watch service pour modification de fichier
      path.toAbsolutePath().getParent().register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
      return watchService;
    }

    private void addAllFileArrayToObservableList() throws IOException {
      // Lecture du fichier JSON
      String jsonString = Files.readString(path);
      // Récupération du tableau JSON
      JSONArray jsonArray = new JSONArray(jsonString);
      Platform.runLater(() -> {
        // Vide la liste
        items.clear();
        // Ajoute tous les éléments
        items.addAll(jsonArray.toList());
      });

    }
  }

}

Vous pouvez aussi consulter l'article sur l'API WatchService Java

Commentaires