reglage du bug save
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -30,8 +30,9 @@ all: \
|
||||
|
||||
# Compilation des classes main
|
||||
$(BIN)/$(PKG_PATH)/Convertisseur.class: $(BIN) \
|
||||
$(BIN)/$(PKG_PATH)/vconverter/ConverterWindow.class \
|
||||
$(BIN)/$(PKG_PATH)/ConverterController.class \
|
||||
$(BIN)/$(PKG_PATH)/vconverter/ConverterWindow.class \
|
||||
$(BIN)/$(PKG_PATH)/ExportButtonListener.class \
|
||||
$(SRC)/$(PKG_PATH)/Convertisseur.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/Convertisseur.java
|
||||
|
||||
@@ -46,86 +47,103 @@ $(BIN):
|
||||
$(DOC):
|
||||
mkdir -p $(DOC)
|
||||
|
||||
#Compilation des classe de mhuffman
|
||||
|
||||
# Compilation des classes util
|
||||
$(BIN)/$(PKG_PATH)/util/ByteUtils.class: $(BIN) \
|
||||
$(SRC)/$(PKG_PATH)/util/ByteUtils.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/util/ByteUtils.java
|
||||
|
||||
$(BIN)/$(PKG_PATH)/util/BitInputStream.class: $(BIN) \
|
||||
$(SRC)/$(PKG_PATH)/util/BitInputStream.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/util/BitInputStream.java
|
||||
|
||||
$(BIN)/$(PKG_PATH)/util/BitOutputStream.class: $(BIN) \
|
||||
$(SRC)/$(PKG_PATH)/util/BitOutputStream.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/util/BitOutputStream.java
|
||||
|
||||
|
||||
# Compilation des classes mhuffman
|
||||
$(BIN)/$(PKG_PATH)/mhuffman/CanonicalCode.class: $(BIN) \
|
||||
$(SRC)/$(PKG_PATH)/mhuffman/CanonicalCode.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mhuffman/CanonicalCode.java
|
||||
|
||||
|
||||
$(BIN)/$(PKG_PATH)/mhuffman/FrequencyTable.class: $(BIN) \
|
||||
$(BIN)/$(PKG_PATH)/mimage/RGBImage.class \
|
||||
$(SRC)/$(PKG_PATH)/mhuffman/FrequencyTable.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mhuffman/FrequencyTable.java
|
||||
|
||||
$(BIN)/$(PKG_PATH)/mhuffman/HuffmanTree.class: $(BIN) \
|
||||
$(BIN)/$(PKG_PATH)/mhuffman/HuffmanNode.class \
|
||||
$(BIN)/$(PKG_PATH)/mhuffman/HuffmanTree.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mhuffman/HuffmanTree.java
|
||||
|
||||
$(BIN)/$(PKG_PATH)/mhuffman/HuffmanNode.class: $(BIN) \
|
||||
$(SRC)/$(PKG_PATH)/mhuffman/HuffmanNode.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mhuffman/HuffmanNode.java
|
||||
|
||||
$(BIN)/$(PKG_PATH)/mhuffman/HuffmanTree.class: $(BIN) \
|
||||
$(BIN)/$(PKG_PATH)/mhuffman/HuffmanNode.class \
|
||||
$(SRC)/$(PKG_PATH)/mhuffman/HuffmanTree.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mhuffman/HuffmanTree.java
|
||||
|
||||
|
||||
# Compilation des classes mimage
|
||||
$(BIN)/$(PKG_PATH)/mimage/Pixel.class: $(BIN) \
|
||||
$(SRC)/$(PKG_PATH)/mimage/Pixel.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mimage/Pixel.java
|
||||
|
||||
# Compilation des classe mimages
|
||||
$(BIN)/$(PKG_PATH)/mimage/RGBImage.class: $(BIN) \
|
||||
$(BIN)/$(PKG_PATH)/mimage/Pixel.class \
|
||||
$(SRC)/$(PKG_PATH)/mimage/RGBImage.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mimage/RGBImage.java
|
||||
|
||||
$(BIN)/$(PKG_PATH)/mimage/Pixel.class: $(BIN) \
|
||||
$(SRC)/$(PKG_PATH)/mimage/Pixel.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mimage/Pixel.java
|
||||
|
||||
#Compilation de l'interface graphique je compile converterWindow
|
||||
$(BIN)/$(PKG_PATH)/vconverter/ConverterWindow.class: $(BIN) \
|
||||
$(BIN)/$(PKG_PATH)/vconverter/ImagePreviewPanel.class \
|
||||
$(BIN)/$(PKG_PATH)/vconverter/FrequencyTablePanel.class \
|
||||
$(BIN)/$(PKG_PATH)/vconverter/CodeTablePanel.class \
|
||||
$(SRC)/$(PKG_PATH)/vconverter/ConverterWindow.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/vconverter/ConverterWindow.java
|
||||
|
||||
# ConverterWindow dépend des autres classes je les compile aussi
|
||||
# Interface graphique
|
||||
$(BIN)/$(PKG_PATH)/vconverter/ImagePreviewPanel.class: $(BIN) \
|
||||
$(SRC)/$(PKG_PATH)/vconverter/ImagePreviewPanel.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/vconverter/ImagePreviewPanel.java
|
||||
|
||||
$(BIN)/$(PKG_PATH)/vconverter/FrequencyTablePanel.class: $(BIN) \
|
||||
$(SRC)/$(PKG_PATH)/vconverter/FrequencyTablePanel.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/vconverter/FrequencyTablePanel.java
|
||||
|
||||
$(BIN)/$(PKG_PATH)/vconverter/CodeTablePanel.class: $(BIN) \
|
||||
$(SRC)/$(PKG_PATH)/vconverter/CodeTablePanel.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/vconverter/CodeTablePanel.java
|
||||
|
||||
# $(BIN)/$(PKG_PATH)/vconverter/ConverterWindow.class: $(BIN) \
|
||||
# $(BIN)/$(PKG_PATH)/ConverterController.class \
|
||||
# $(BIN)/$(PKG_PATH)/vconverter/ImagePreviewPanel.class \
|
||||
# $(BIN)/$(PKG_PATH)/vconverter/FrequencyTablePanel.class \
|
||||
# $(BIN)/$(PKG_PATH)/vconverter/CodeTablePanel.class \
|
||||
# $(SRC)/$(PKG_PATH)/vconverter/ConverterWindow.java
|
||||
# $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/vconverter/ConverterWindow.java
|
||||
|
||||
# Compilation des classes mpif
|
||||
|
||||
|
||||
# Compilation PIFWriter
|
||||
$(BIN)/$(PKG_PATH)/mpif/PIFWriter.class: $(BIN) \
|
||||
$(BIN)/$(PKG_PATH)/mimage/RGBImage.class \
|
||||
$(SRC)/$(PKG_PATH)/util/BitOutputStream.class \
|
||||
$(BIN)/$(PKG_PATH)/util/BitOutputStream.class \
|
||||
$(SRC)/$(PKG_PATH)/mpif/PIFWriter.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mpif/PIFWriter.java
|
||||
|
||||
|
||||
# Compilation du controleur
|
||||
$(BIN)/$(PKG_PATH)/ConverterController.class: $(BIN) \
|
||||
$(BIN)/$(PKG_PATH)/mimage/Pixel.class \
|
||||
$(BIN)/$(PKG_PATH)/mimage/RGBImage.class \
|
||||
$(BIN)/$(PKG_PATH)/mhuffman/FrequencyTable.class \
|
||||
$(BIN)/$(PKG_PATH)/mhuffman/CanonicalCode.class \
|
||||
$(BIN)/$(PKG_PATH)/vconverter/ConverterWindow.class \
|
||||
$(SRC)/$(PKG_PATH)/ConverterController.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/ConverterController.java
|
||||
|
||||
|
||||
#Compilation des classes util
|
||||
$(BIN)/$(PKG_PATH)/util/ByteUtils.class: $(BIN) \
|
||||
$(SRC)/$(PKG_PATH)/util/ByteUtils.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/util/ByteUtils.java
|
||||
$(BIN)/$(PKG_PATH)/util/BitInputStream.class: $(BIN) \
|
||||
$(SRC)/$(PKG_PATH)/util/BitInputStream.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/util/BitInputStream.java
|
||||
$(BIN)/$(PKG_PATH)/util/BitOutputStream.class: $(BIN) \
|
||||
$(SRC)/$(PKG_PATH)/util/BitOutputStream.java
|
||||
$(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/util/BitOutputStream.java
|
||||
|
||||
# GROSSE compilation du listener + ConvertController + ConvertWindow car il y a une dependance cirulaire
|
||||
$(BIN)/$(PKG_PATH)/ConverterController.class \
|
||||
$(BIN)/$(PKG_PATH)/ExportButtonListener.class \
|
||||
$(BIN)/$(PKG_PATH)/vconverter/ConverterWindow.class: \
|
||||
$(SRC)/$(PKG_PATH)/ConverterController.java \
|
||||
$(SRC)/$(PKG_PATH)/ExportButtonListener.java \
|
||||
$(SRC)/$(PKG_PATH)/vconverter/ConverterWindow.java \
|
||||
$(BIN)/$(PKG_PATH)/mimage/Pixel.class \
|
||||
$(BIN)/$(PKG_PATH)/mimage/RGBImage.class \
|
||||
$(BIN)/$(PKG_PATH)/mhuffman/FrequencyTable.class \
|
||||
$(BIN)/$(PKG_PATH)/mhuffman/HuffmanTree.class \
|
||||
$(BIN)/$(PKG_PATH)/mhuffman/CanonicalCode.class \
|
||||
$(BIN)/$(PKG_PATH)/vconverter/ImagePreviewPanel.class \
|
||||
$(BIN)/$(PKG_PATH)/vconverter/FrequencyTablePanel.class \
|
||||
$(BIN)/$(PKG_PATH)/vconverter/CodeTablePanel.class \
|
||||
$(BIN)/$(PKG_PATH)/mpif/PIFWriter.class | $(BIN)
|
||||
@$(JAVAC) -cp $(BIN) -d $(BIN) \
|
||||
$(SRC)/$(PKG_PATH)/ConverterController.java \
|
||||
$(SRC)/$(PKG_PATH)/ExportButtonListener.java \
|
||||
$(SRC)/$(PKG_PATH)/vconverter/ConverterWindow.java
|
||||
|
||||
|
||||
# Exécution
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package fr.iutfbleau.sae;
|
||||
import fr.iutfbleau.sae.mhuffman.CanonicalCode;
|
||||
import fr.iutfbleau.sae.mhuffman.FrequencyTable;
|
||||
import fr.iutfbleau.sae.mhuffman.HuffmanTree;
|
||||
import fr.iutfbleau.sae.mimage.Pixel;
|
||||
import fr.iutfbleau.sae.mimage.RGBImage;
|
||||
import fr.iutfbleau.sae.mhuffman.*;
|
||||
import fr.iutfbleau.sae.mimage.*;
|
||||
import fr.iutfbleau.sae.mpif.PIFWriter;
|
||||
import fr.iutfbleau.sae.vconverter.ConverterWindow;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
/**
|
||||
* Contrôleur pour la conversion d'images.
|
||||
@@ -39,17 +38,21 @@ public class ConverterController {
|
||||
// La fenêtre du convertisseur
|
||||
private ConverterWindow fen;
|
||||
|
||||
public ConverterController(ConverterWindow fen) {
|
||||
String outputPath;
|
||||
String inputPath;
|
||||
|
||||
public ConverterController(ConverterWindow fen, String in, String out) {
|
||||
this.fen = fen;
|
||||
this.outputPath = out;
|
||||
this.inputPath = in;
|
||||
}
|
||||
|
||||
|
||||
// charger une image depuis un fichier avec bufferedImage et la convertir en RGBImage
|
||||
public void loadImage(String filepath) {
|
||||
File FI = new File(filepath);
|
||||
public void loadImage(File file) {
|
||||
try{
|
||||
// Lire l'image avec BufferedImage
|
||||
BufferedImage buffimage = ImageIO.read(FI);
|
||||
BufferedImage buffimage = ImageIO.read(file);
|
||||
if (buffimage == null) {
|
||||
throw new IllegalArgumentException("Le fichier spécifié n'est pas une image valide.");
|
||||
}
|
||||
@@ -134,9 +137,7 @@ public class ConverterController {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void saveAsPIF(String pathfile) {
|
||||
|
||||
// je Vérifie que l'image et les codes canoniques sont disponibles
|
||||
if(this.image == null || this.canonRED == null){
|
||||
System.err.println("Impossible d'ecrire le fichier PIF : données manquantes.");
|
||||
@@ -151,6 +152,69 @@ public class ConverterController {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void saveViaBtn() {
|
||||
try {
|
||||
if (outputPath != null) {
|
||||
saveAsPIF(outputPath);
|
||||
System.out.println("Sauvegarde dans : " + outputPath);
|
||||
return;
|
||||
}
|
||||
|
||||
// Sinon JFileChooser
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.setDialogTitle("Enregistrer le fichier .pif");
|
||||
|
||||
if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
|
||||
saveAsPIF(chooser.getSelectedFile().getAbsolutePath());
|
||||
System.out.println("Fichier sauvegardé : " + chooser.getSelectedFile().getAbsolutePath());
|
||||
JOptionPane.showMessageDialog(null, "Fichier sauvegardé avec succès : " + chooser.getSelectedFile().getName());
|
||||
}
|
||||
|
||||
System.out.println("Via BTN Sauvegarde terminée.");
|
||||
|
||||
} catch (Exception ex) {
|
||||
System.out.println("Erreur lors de la sauvegarde : " + ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void StartconvessionProcess(){
|
||||
// chragement
|
||||
if (this.inputPath != null) {
|
||||
// Chargement direct depuis les arguments
|
||||
File file = new File(inputPath);
|
||||
this.loadImage(file);
|
||||
}else{
|
||||
// Sinon JFileChooser pour choisir l'image
|
||||
JFileChooser choosser =new JFileChooser();
|
||||
choosser.setDialogTitle("Choisissez une image");
|
||||
if (choosser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
|
||||
this.loadImage(choosser.getSelectedFile());
|
||||
}else {
|
||||
System.err.println("Aucune image choisie. Arrêt du programme.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// je place la logique de conversion dans lordre
|
||||
computeFrequencies();
|
||||
computeHuffman();
|
||||
computeCanonical();
|
||||
|
||||
// Sauvegarder: un second argument est donné sauvegarde automatique
|
||||
if (this.outputPath != null) {
|
||||
this.saveAsPIF(this.outputPath);
|
||||
System.out.println("Fichier sauvegardé automatiquement : " + this.outputPath);
|
||||
}else{
|
||||
// pas de deuxième argument j'ajoute un boutton pour choisir avec un jfilechoser
|
||||
fen.addSaveButton(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public RGBImage getImage(){
|
||||
return this.image;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
package fr.iutfbleau.sae;
|
||||
|
||||
import fr.iutfbleau.sae.vconverter.ConverterWindow;
|
||||
|
||||
public class Convertisseur {
|
||||
public static void main(String[] args) {
|
||||
// Créer et stocker la référence à la fenêtre
|
||||
ConverterWindow window = new ConverterWindow();
|
||||
// je la passe au controleur
|
||||
ConverterController controller = new ConverterController(window);
|
||||
|
||||
|
||||
// chemins de l'image
|
||||
String inpuPath;
|
||||
String outputPath;
|
||||
String inpuPath = null;
|
||||
String outputPath = null;
|
||||
if (args.length >= 1) {
|
||||
inpuPath = args[0];
|
||||
}
|
||||
@@ -17,17 +15,11 @@ public class Convertisseur {
|
||||
outputPath = args[1];
|
||||
}
|
||||
|
||||
// je charge l'image
|
||||
controller.loadImage(testIMG);
|
||||
|
||||
// je place la logique de conversion dans lordre
|
||||
controller.computeFrequencies();
|
||||
controller.computeHuffman();
|
||||
controller.computeCanonical();
|
||||
|
||||
if (condition) {
|
||||
|
||||
}
|
||||
// Créer et stocker la référence à la fenêtre
|
||||
ConverterWindow window = new ConverterWindow();
|
||||
// je la passe au controleur
|
||||
ConverterController controller = new ConverterController(window, inpuPath, outputPath);
|
||||
|
||||
controller.StartconvessionProcess();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package fr.iutfbleau.sae;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
public class ExportButtonListener implements ActionListener {
|
||||
private ConverterController controller;
|
||||
|
||||
public ExportButtonListener(ConverterController controller){
|
||||
this.controller = controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e){
|
||||
controller.saveViaBtn();
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
// test
|
||||
|
||||
/**
|
||||
* Implémente un arbre de Huffman utilisé pour la compression de données.
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package fr.iutfbleau.sae.vconverter;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Map;
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
import fr.iutfbleau.sae.ConverterController;
|
||||
import fr.iutfbleau.sae.ExportButtonListener;
|
||||
|
||||
/**
|
||||
* Fenêtre principale du convertisseur.
|
||||
*
|
||||
@@ -41,7 +44,9 @@ public class ConverterWindow extends JFrame {
|
||||
this.setSize(900, 600);
|
||||
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
this.setLocationRelativeTo(null); // Centre la fenêtre
|
||||
this.setResizable(true); // on autorise le resize
|
||||
this.setResizable(true); // on autorise le
|
||||
this.setLayout(new BorderLayout());
|
||||
|
||||
|
||||
|
||||
// Initialisation des panels
|
||||
@@ -78,8 +83,8 @@ public class ConverterWindow extends JFrame {
|
||||
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
scrollPane.getVerticalScrollBar().setUnitIncrement(16); // scroll plus adouci fluide
|
||||
|
||||
this.add(scrollPane);
|
||||
this.setVisible(true); // toi meme tu sais
|
||||
this.add(scrollPane, BorderLayout.CENTER);
|
||||
this.setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -133,4 +138,24 @@ public class ConverterWindow extends JFrame {
|
||||
Map<Integer, String> codesBleu) {
|
||||
codeTablePanel.updateCanonicalCodes(codesRouge, codesVert, codesBleu);
|
||||
}
|
||||
|
||||
public void addSaveButton(ConverterController controller) {
|
||||
JButton saveBtn = new JButton("Exporter en .pif");
|
||||
ExportButtonListener ecouteur =new ExportButtonListener(controller);
|
||||
saveBtn.addActionListener(ecouteur);
|
||||
|
||||
// panneau du bas
|
||||
JPanel bottomPanel = new JPanel();
|
||||
bottomPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
|
||||
bottomPanel.add(saveBtn);
|
||||
|
||||
// ajoute au bas de la fenêtre
|
||||
this.add(bottomPanel, BorderLayout.SOUTH);
|
||||
|
||||
// rafraîchir l'affichage
|
||||
this.revalidate();
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
Learning log – Problème de blocage de la fenêtre après la sauvegarde:
|
||||
|
||||
Après avoir implémenté la fonctionnalité d’export au format PIF depuis l’interface du convertisseur,
|
||||
j’ai rencontré un problème important : une fois que je cliquais sur le bouton d’exportation,
|
||||
la fenêtre se figeait complètement. Elle restait visible, mais impossible à fermer ou à interagir avec.
|
||||
Le programme semblait bloqué.
|
||||
|
||||
En analysant le comportement et en utilisant des impressions de debug, j’ai constaté que le blocage n’était pas lié à l’écriture du
|
||||
fichier ni à la logique du convertisseur, mais bien à un problème de gestion des threads dans Swing.
|
||||
|
||||
Swing repose sur un fonctionnement particulier : toute l’interface graphique est gérée par un seul thread dédié,
|
||||
appelé l’Event Dispatch Thread (EDT). Ce thread est responsable de tout ce qui concerne l’interface utilisateur :
|
||||
la gestion des clics, le rafraîchissement de la fenêtre, la fermeture, le dessin et l’affichage en général.
|
||||
Tant que ce thread tourne correctement, l’application reste réactive.
|
||||
|
||||
L’EDT ne démarre réellement qu’après l’appel à la méthode permettant d’afficher la fenêtre. À partir de ce moment,
|
||||
toutes les opérations qui modifient l’interface devraient strictement être exécutées sur ce thread.
|
||||
C’est une règle fondamentale pour éviter les blocages.
|
||||
|
||||
En examinant mon programme, je me suis rendu compte que le problème venait de la manière dont j’avais structuré mon point d’entrée.
|
||||
Mon programme principal créait la fenêtre, le contrôleur, puis lançait immédiatement tout le processus de conversion,
|
||||
qui incluait le chargement du fichier image, le calcul des fréquences, la construction des arbres de Huffman,
|
||||
la génération des codes canoniques, et éventuellement l’écriture du fichier PIF.
|
||||
Ce sont des opérations potentiellement longues et qui se déroulaient sur le thread principal,
|
||||
avant même que l’EDT ne prenne le relais pour gérer l’interface.
|
||||
|
||||
Cela avait deux conséquences. D'abord, la fenêtre pouvait parfois être affichée trop tard ou de manière irrégulière.
|
||||
Ensuite, après l’export, Swing se retrouvait dans un état instable, puisque certaines opérations graphiques avaient été réalisées
|
||||
hors du thread dédié.
|
||||
C’est exactement ce qui provoquait le gel de l’interface : une fois le fichier enregistré, la fenêtre ne répondait plus car
|
||||
l’EDT était bloqué ou interrompu, empêchant toute interaction, y compris la fermeture de la fenêtre.
|
||||
|
||||
Une fois le problème identifié, les solutions étaient claires. Il fallait s’assurer que toutes les opérations qui touchent
|
||||
a l’interface graphique soient exécutées sur l’Event Dispatch Thread. Cela signifie que toute interaction, y compris l’ouverture
|
||||
d’un sélecteur de fichiers, doit obligatoirement être déclenchée dans ce contexte. De plus, il fallait veiller à ne pas exécuter
|
||||
de longues opérations synchrones avant le démarrage complet de l’EDT.
|
||||
|
||||
La solution consiste donc à déléguer l’appel du processus de conversion au thread graphique, en utilisant le mécanisme fourni par
|
||||
Swing pour garantir que le code s’exécute sur l’EDT. Une autre possibilité serait d’exécuter les opérations lourdes dans un thread en
|
||||
arrière-plan pour éviter de bloquer l’interface, mais dans tous les cas le respect strict de la séparation entre traitements et interface
|
||||
est essentiel.
|
||||
|
||||
Grâce à cette analyse, j’ai mieux compris la manière dont Swing gère les threads et j’ai pu corriger la structure de mon programme
|
||||
afin qu’il reste totalement réactif, même après l’export. Cette expérience m’a rappelé l’importance de maîtriser les principes fondamentaux
|
||||
des bibliothèques graphiques et leurs contraintes en matière de multithreading.
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user