Bonjour a tous!
J'ai un problème de rafraichissement de ma fenêtre lorsque j'appuie sur le bouton 'play' de mon projet, la fenêtre ne se rafraichit pas avant que l'action soit terminée (fonction paintComponents pas appelée). Quelqu'un aurait-il une idée?


Je poste un peu de code pour vous montrer.
Ma classe main:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
public class Simulator extends Thread {
    private int step;
    volatile boolean isPaused;
    volatile int delay;
    private Ocean ocean;
    private Ocean updatedOcean;
    private List<Fish>  fishes;
    private List<Fish>  newFishes;
    private SimulatorView simView;
    private static final int DEFAULT_HEIGHT = 50;
    private static final int DEFAULT_WIDTH = 50;
    private static Simulator sim;
 
 
    public static void main(String[] args) 
    {
        sim = new Simulator(50, 50);
        sim.run(20); // test fonctionne bien
    }
 
    public static Simulator getInstance() {
        synchronized (sim) {
            if (sim == null)
                sim = new Simulator();
            return sim;
        }
    }
 
    public Simulator() {
        this(Simulator.DEFAULT_HEIGHT, Simulator.DEFAULT_WIDTH);
    }
 
    public Simulator(int height, int width)
    {
        if (height <= 0 || width <= 0) {
            System.out.println("The dimensions must be greater than zero.");
            System.out.println("Using default values.");
            height = DEFAULT_HEIGHT;
            width = DEFAULT_WIDTH;
        }
        isPaused = false;
        delay = 300;
        ocean = new Ocean(height, width);
        updatedOcean = new Ocean(height, width);
        fishes = new LinkedList<Fish>();
        newFishes = new LinkedList<Fish>();
        simView = new SimulatorView(height, width);
 
        simView.setColor(Herring.class, Herring.getColor());
        simView.setColor(Groper.class, Groper.getColor());
        simView.setColor(Shark.class, Shark.getColor());
        simView.setColor(Rock.class, Rock.getColor());
        reset();
    }
 
    /**
     * Reset and clear all variables of the class
     */
    public void reset() {
        step = 1;
        fishes.clear();
        newFishes.clear();
        ocean.clear();
        updatedOcean.clear();
        populate();
        simView.showStatus(step, ocean);
    }
 
    /**
     * Populate the ocean for the first time.
     */
    public void populate() {
         ...
    }
 
    /**
     * Simulate one step of the simulation
     */
    public void simulateOneStep() {
        .....
        simView.showStatus(step, ocean);
    }
 
    /**
     * Main loop of the simulation
     *
     * @param steps The maximum number of steps to go through
     */
    public void run(int steps)
    {
        for (step = 1 ; step <= steps && simView.isViable(ocean) ; step++) {
            synchronized(this) {
                while (isPaused) {
                    try {
                        wait();
                    }
                    catch (InterruptedException e) {
                        System.err.println("Error : " + e);
                    }
                }
            }
            try {
                sleep(delay);
            } catch (InterruptedException e) {
            }
            simulateOneStep();
        }
    }
 
    public synchronized void paused(boolean p) {
        isPaused = p;
        notifyAll();
    }
 
    public synchronized void setDelay(int delay) {
        this.delay = delay;
    }
 
}
Les classes du GUI
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
package Simulation;
 
import Ocean.Ocean;
import Ocean.Animals.Fish;
import Ocean.BlockingEntity.BlockingEntity;
import Ocean.OceanSlot;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.util.List;
import javax.swing.*;
import java.util.HashMap;
import java.util.Map.Entry;
 
/**
 * A graphical view of the simulation grid.
 * The view displays a colored rectangle for each location 
 * representing its contents. It uses a default background color.
 * Colors for each type of species can be defined using the
 * setColor method.
 * 
 * @author David J. Barnes and Michael Kolling
 * @author Geoffrey Brier
 * @version 2003.12.22
 */
public class SimulatorView extends JFrame {
 
    private static final long serialVersionUID = 1L;
    // Colors used for empty locations.
    private static final Color EMPTY_COLOR = Color.white;
    // Color used for objects that have no defined color.
    private static final Color UNKNOWN_COLOR = Color.gray;
    private final String STEP_PREFIX = "Step: ";
    private final String POPULATION_PREFIX = "Population: ";
    private JLabel stepLabel, population;
    private OceanActions oceanActions;
    private OceanView oceanView;
    // A map for storing colors for entities in the simulation
    private HashMap<Class<?>, Color> colors;
    // A statistics object computing and storing simulation information
    private OceanStats stats;
 
    /**
     * Create a view of the given width and height.
     * @param height The simulation height.
     * @param width The simulation width.
     */
    public SimulatorView(int height, int width) {
        stats = new OceanStats();
        colors = new HashMap<Class<?>, Color>();
 
        setTitle("Ocean simulation");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Exit when clicking on the close button
        stepLabel = new JLabel(STEP_PREFIX, JLabel.CENTER);
        population = new JLabel(POPULATION_PREFIX, JLabel.CENTER);
 
        setLocation(100, 50);
 
        oceanView = new OceanView(height, width);
 
        Container contents = getContentPane();
        contents.add(stepLabel, BorderLayout.NORTH);
        contents.validate();
        contents.add(oceanView, BorderLayout.CENTER);
        contents.validate();
 
        // Add the tool bar
        setJMenuBar(new OceanMenuBar());
        validate();
        // Add buttons at the bottom of the window
        //contents.add(population, BorderLayout.SOUTH);
        //contents.validate();
        contents.add(new OceanActions(population), BorderLayout.SOUTH);
        contents.validate();
        pack();
        setVisible(true);
    }
 
    /**
     * Define a color to be used for a given class of fish.
     */
    public void setColor(Class<?> clazz, Color color) {
        if (Fish.class.isAssignableFrom(clazz) || BlockingEntity.class.isAssignableFrom(clazz)) {
            colors.put(clazz, color);
        } else {
            System.out.println("Class " + clazz.getName() + " not handled");
        }
    }
 
    /**
     * @return The color to be used for a given class.
     */
    private Color getColor(Class<?> clazz) {
        Color col = colors.get(clazz);
        if (col == null) {
            // no color defined for this class
            return UNKNOWN_COLOR;
        } else {
            return col;
        }
    }
 
    /**
     * Show the current status of the ocean.
     * @param step Which iteration step it is.
     * @param ocean The ocean whose status is to be displayed.
     */
    public synchronized void showStatus(int step, Ocean ocean) {
        if (!isVisible()) {
            setVisible(true);
        }
 
        stepLabel.setText(STEP_PREFIX + step);
        stats.reset();
        oceanView.preparePaint();
 
        // Go through all slots of the ocean
        ....
        stats.countFinished();
        population.setText(POPULATION_PREFIX + stats.getPopulationDetails(ocean));
        oceanView.repaint(); // Probleme ici, le REPAINT ne repaint pas :)
    }
 
    /**
     * Determine whether the simulation should continue to run.
     * @return true If there is more than one species alive.
     */
    public boolean isViable(Ocean ocean) {
        return stats.isViable(ocean);
    }
 
    /**
     * Provide a graphical view of a rectangular ocean. This is 
     * a nested class (a class defined inside a class) which
     * defines a custom component for the user interface. This
     * component displays the ocean.
     * This is rather advanced GUI stuff - you can ignore this 
     * for your project if you like.
     */
    private class OceanView extends JPanel {
 
        private static final long serialVersionUID = 1L;
        private final int GRID_VIEW_SCALING_FACTOR = 10;
        private int gridWidth, gridHeight;
        private int xScale, yScale;
        Dimension size;
        private Graphics g;
        private Image oceanImage;
 
        /**
         * Create a new OceanView component.
         */
        public OceanView(int height, int width) {
            gridHeight = height;
            gridWidth = width;
            size = new Dimension(0, 0);
        }
 
        /**
         * Tell the GUI manager how big we would like to be.
         */
        public Dimension getPreferredSize() {
            return new Dimension(gridWidth * GRID_VIEW_SCALING_FACTOR,
                    gridHeight * GRID_VIEW_SCALING_FACTOR);
        }
 
        /**
         * Prepare for a new round of painting. Since the component
         * may be resized, compute the scaling factor again.
         */
        public void preparePaint() {
            if (!size.equals(getSize())) {  // if the size has changed...
                size = getSize();
                oceanImage = oceanView.createImage(size.width, size.height);
                g = oceanImage.getGraphics();
 
                xScale = size.width / gridWidth;
                if (xScale < 1) {
                    xScale = GRID_VIEW_SCALING_FACTOR;
                }
                yScale = size.height / gridHeight;
                if (yScale < 1) {
                    yScale = GRID_VIEW_SCALING_FACTOR;
                }
            }
        }
 
        /**
         * Paint on grid location on this ocean in a given color.
         */
        public void drawMark(int x, int y, Color color) {
            g.setColor(color);
            g.fillRect(x * xScale, y * yScale, xScale - 1, yScale - 1);
        }
 
        /**
         * The ocean view component needs to be redisplayed. Copy the
         * internal image to screen.
         */
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (oceanImage != null) {
                Dimension currentSize = getSize();
                if (size.equals(currentSize)) {
                    g.drawImage(oceanImage, 0, 0, null);
                } else {
                    // Rescale the previous image.
                    g.drawImage(oceanImage, 0, 0, currentSize.width, currentSize.height, null);
                }
            }
        }
    }
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Simulation;
 
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
 
/**
 * This class is used to add the main buttons (play/pause/stop), and main
 * fields (time between steps, number of steps, plankton refresh rate)
 *
 * @author Geoffrey Brier
 */
public class OceanActions extends JPanel implements ActionListener {
 
    private final String PLAY = "Play";
    private final String PAUSE = "Pause";
    private final String STOP = "Stop";
    private final String RESTART = "Restart";
    private boolean isStarted = false;
    private JButton play, pause, stop, restart;
    private JLabel pop;
 
    public OceanActions(JLabel population) {
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        // Creating buttons
        play = new JButton(PLAY);
        pause = new JButton(PAUSE);
        restart = new JButton(RESTART);
        pop = population;
 
        // "Customizing"
        play.setEnabled(true);
        pause.setEnabled(false);
        pop.setAlignmentX(CENTER_ALIGNMENT);
 
 
        // Adding buttons in another panel with a flow layout
        JPanel p = new JPanel();
        p.setLayout(new FlowLayout());
 
        p.add(play);
        p.validate();
        p.add(pause);
        p.validate();
        p.add(restart);
        p.validate();
 
        // Adding the panel & population
        add(pop);
        validate();
        add(p);
        validate();
 
        // Setting action listener
        play.addActionListener(this);
        pause.addActionListener(this);
        restart.addActionListener(this);
 
        setPreferredSize(new Dimension(100, 50));
        p.setPreferredSize(new Dimension(100, 20));
    }
 
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals(PLAY)) {
            play.setEnabled(false);
            pause.setEnabled(true);
           // Lorsque j'appuie sur le bouton play, je lance la méthode
           // a ce niveau et ce n'est qu'après le traitement que tout est
           // bien afficher
            if (!isStarted)
                Simulator.getInstance().run(10);
            else
                Simulator.getInstance().paused(false);
            isStarted = true;
        } else if (e.getActionCommand().equals(PAUSE)) {
            play.setEnabled(true);
            pause.setEnabled(false);
            Simulator.getInstance().paused(true);
        } else if (e.getActionCommand().equals(RESTART)) {
            play.setEnabled(false);
            pause.setEnabled(true);
            isStarted = false;
            Simulator.getInstance().run(50);
        } else {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
}
Merci d'avance