2017-03-21 2 views
2

J'essaie de faire afficher mon programme (en testant dans la console d'abord) le nombre de comptage à chaque étape où la cellule change de forme. Donc, le nombre devrait commencer à partir de 0 et augmenter chaque fois que la cellule change de forme. J'ai essayé ceci, en utilisant count ++ mais il ne s'incrémente pas de 1 mais me donne des nombres aléatoires. Toute aide sera très appréciée.Comment est-ce que j'ajoute une fonctionnalité où je peux obtenir la génération dans mon programme de jeu de la vie?

import java.awt.Color; 
import java.util.Timer; 
import java.util.TimerTask; 
import java.awt.Image; 
import java.awt.Graphics; 
import javax.swing.SwingUtilities; 

public class GameOfLife extends javax.swing.JFrame { 

final int wid = 100, hei = 50; 
public static int count; 
boolean[][] currentMove = new boolean[hei][wid], nextMove = new boolean[hei][wid]; 
boolean play; 
Image offScrImg; 
Graphics offScrGraph; 

public GameOfLife() { 
    initComponents(); 
    offScrImg = createImage(jPanel1.getWidth(), jPanel1.getHeight()); 
    offScrGraph = offScrImg.getGraphics(); 
    Timer time = new Timer(); 
    TimerTask task = new TimerTask(){ 
     public void run(){ 
      if(play){ 
       System.out.println(count); 
       for(int i = 0; i < hei; i++){ 
        for(int j = 0; j < wid; j++){ 
         nextMove[i][j] = decide(i,j); 

        } 
       } 
       for(int i = 0; i < hei; i++){ 
        for(int j = 0; j < wid; j++){ 
         currentMove[i][j] = nextMove[i][j]; 

        } 
       } 
       repain(); 
      } 
     } 
    }; 
    time.scheduleAtFixedRate(task, 0, 100); 
    repain(); 
} 

private boolean decide(int i, int j){ 
    int neighbors = 0; 

    // top-left row-1,col-1 

    if (currentMove[getTopRow(i - 1)][getLeftCol(j - 1)]) neighbors++; //Uses getTopRow and getLeftCol methods to determine the indices of the top left cell 

    // left row,col-1 
    if (currentMove[i][getLeftCol(j - 1)]) neighbors++; 

    // bottom left row+1,col-1 
    if (currentMove[getBottomRow(i + 1)][getLeftCol(j - 1)]) neighbors++; 

    // bottom row+1,col 
    if (currentMove[getBottomRow(i + 1)][j]) neighbors++; 

    // bottom right row+1,col+1 
    if (currentMove[getBottomRow(i + 1)][getRightCol(j + 1)]) neighbors++; 

    // right row,col+1 
    if (currentMove[i][getRightCol(j + 1)]) neighbors++; 

    // top-right row-1,col+1 
    if (currentMove[getTopRow(i - 1)][getRightCol(j + 1)])neighbors++; 

    // top row-1, col 
    if(currentMove[getTopRow(i - 1)][j]) neighbors++; 


    if(neighbors == 3) {  
     count++; 
     return true;     
    } 
    if(currentMove[i][j] && neighbors == 2){ 
     count++; 
     return true;   
    } 
    return false; 
} 
private int getLeftCol(int neighbourCol) { 
    return neighbourCol < 0 ? (wid-1) : neighbourCol; //If the index of leftCol is less than 0, it uses the right most col (columns - 1) 
} 

private int getRightCol(int neighbourCol) { 
    return neighbourCol > (wid-1) ? 0 : neighbourCol; 
} 

private int getTopRow(int neighbourRow) { 
    return neighbourRow < 0 ? (hei - 1) : neighbourRow; //If the index of topRow is less than 0, it uses the bottom last row (rows - 1) 
} 

private int getBottomRow(int neighbourRow) { 
    return neighbourRow > (hei - 1) ? 0 : neighbourRow; 
} 

private void repain(){ 
    offScrGraph.setColor(Color.RED); 
    offScrGraph.fillRect(0, 0, jPanel1.getWidth(), jPanel1.getHeight()); 
    for(int i = 0 ; i < hei ; i++){ 
     for(int j = 0 ; j < wid; j++){ 
      if(currentMove[i][j]){ 
       offScrGraph.setColor(Color.GREEN); 
       int x = j * jPanel1.getWidth()/wid; 
       int y = i * jPanel1.getHeight()/hei; 
       offScrGraph.fillRect(x, y, jPanel1.getWidth()/wid, jPanel1.getHeight()/hei); 
      } 
     } 
    } 
    offScrGraph.setColor(Color.BLACK); 
    for(int i = 1; i < hei;i++){ 
     int y = i * jPanel1.getHeight()/hei; 
     offScrGraph.drawLine(0, y, jPanel1.getWidth(), y); 
    } 
    for(int j = 1; j < wid;j++){ 
     int x = j * jPanel1.getWidth()/wid; 
     offScrGraph.drawLine(x, 0, x, jPanel1.getHeight()); 
    } 
    jPanel1.getGraphics().drawImage(offScrImg, 0, 0, jPanel1); 
} 

@SuppressWarnings("unchecked") 
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents 
private void initComponents() { 

    jPanel1 = new javax.swing.JPanel(); 
    jButton1 = new javax.swing.JButton(); 
    jButton2 = new javax.swing.JButton(); 

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

    jPanel1.setBackground(new java.awt.Color(102, 102, 102)); 
    jPanel1.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() { 
     public void mouseDragged(java.awt.event.MouseEvent evt) { 
      jPanel1MouseDragged(evt); 
     } 
    }); 
    jPanel1.addMouseListener(new java.awt.event.MouseAdapter() { 
     public void mouseClicked(java.awt.event.MouseEvent evt) { 
      jPanel1MouseClicked(evt); 
     } 
    }); 
    jPanel1.addComponentListener(new java.awt.event.ComponentAdapter() { 
     public void componentResized(java.awt.event.ComponentEvent evt) { 
      jPanel1ComponentResized(evt); 
     } 
    }); 

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); 
    jPanel1.setLayout(jPanel1Layout); 
    jPanel1Layout.setHorizontalGroup(
      jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGap(0, 0, Short.MAX_VALUE) 
      ); 
    jPanel1Layout.setVerticalGroup(
      jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGap(0, 293, Short.MAX_VALUE) 
      ); 

    jButton1.setText("Play"); 
    jButton1.addActionListener(new java.awt.event.ActionListener() { 
     public void actionPerformed(java.awt.event.ActionEvent evt) { 
      jButton1ActionPerformed(evt); 
     } 
    }); 

    jButton2.setText("Reset"); 
    jButton2.addActionListener(new java.awt.event.ActionListener() { 
     public void actionPerformed(java.awt.event.ActionEvent evt) { 
      jButton2ActionPerformed(evt); 
     } 
    }); 

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
    getContentPane().setLayout(layout); 
    layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
        .addContainerGap() 
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
          .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 
          .addGroup(layout.createSequentialGroup() 
            .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE) 
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 323, Short.MAX_VALUE) 
            .addComponent(jButton2, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE))) 
        .addContainerGap()) 
      ); 
    layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
        .addContainerGap() 
        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 
          .addComponent(jButton1) 
          .addComponent(jButton2)) 
        .addContainerGap()) 
      ); 

    pack(); 
}// </editor-fold>//GEN-END:initComponents 

private void jPanel1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanel1MouseClicked 

}//GEN-LAST:event_jPanel1MouseClicked 

private void jPanel1ComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_jPanel1ComponentResized 
    offScrImg = createImage(jPanel1.getWidth(), jPanel1.getHeight()); 
    offScrGraph = offScrImg.getGraphics(); 
    repain(); 
}//GEN-LAST:event_jPanel1ComponentResized 

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed 
    play = !play; 
    if(play) jButton1.setText("Pause"); 
    else jButton1.setText("Play"); 
    repain(); 
}//GEN-LAST:event_jButton1ActionPerformed 

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed 
    currentMove = new boolean[hei][wid]; 
    repain(); 
}//GEN-LAST:event_jButton2ActionPerformed 

private void jPanel1MouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanel1MouseDragged 
    int j = wid * evt.getX()/jPanel1.getWidth(); 
    int i = hei * evt.getY()/jPanel1.getHeight(); 
    if(SwingUtilities.isLeftMouseButton(evt)){ 
     currentMove[i][j] = true; 
    }else currentMove[i][j] = false; 
    repain(); 
}//GEN-LAST:event_jPanel1MouseDragged 

public static void main(String args[]) { 
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> 
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. 
    * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
    */ 
    try { 
     for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
      if ("Nimbus".equals(info.getName())) { 
       javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
       break; 
      } 
     } 
    } catch (ClassNotFoundException ex) { 
     java.util.logging.Logger.getLogger(GameOfLife.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } catch (InstantiationException ex) { 
     java.util.logging.Logger.getLogger(GameOfLife.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } catch (IllegalAccessException ex) { 
     java.util.logging.Logger.getLogger(GameOfLife.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } catch (javax.swing.UnsupportedLookAndFeelException ex) { 
     java.util.logging.Logger.getLogger(GameOfLife.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } 
    //</editor-fold> 

    java.awt.EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      new GameOfLife().setVisible(true); 
     } 
    }); 
} 

// Variables declaration - do not modify//GEN-BEGIN:variables 
private javax.swing.JButton jButton1; 
private javax.swing.JButton jButton2; 
private javax.swing.JPanel jPanel1; 
// End of variables declaration//GEN-END:variables 
} 
+0

@AndrewThompson Done –

+0

J'ai utilisé repain car il existe déjà une méthode intégrée appelée repaint. Donc je ne voulais pas entrer en conflit. –

+0

Nice edit. :) BTW - N'a pas examiné de près votre code, mais vérifié que [ce code] (http://stackoverflow.com/a/8200046/418556) pourrait implémenter un compteur de génération dans une poignée de lignes de code. Serait-il utile que vous voyiez cela? –

Répondre

0

Je pense que vous devez obtenir une erreur. Vous n'initialisez jamais votre compteur. Changer

public static int count; 

à

public static int count = 0; 

et essayer ce qui se passe

+0

J'ai essayé ceci et voici la sortie: 12 –

1

Voici comment cela peut être fait en utilisant un related code example.

enter image description here

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import java.util.Random; 

public class GameOfLife extends JPanel { 

    private int row, col; 
    private boolean isLiving; 
    private static int generation = 0; 

    public static Random random = new Random(); 

    public GameOfLife(int r, int c) { 
     this.row = r; 
     this.col = c; 
     MouseListener listener = new MouseAdapter() { 
      public void mouseClicked(MouseEvent e) { 
       isLiving = !isLiving; 
       repaint(); 
      } 
     }; 
     this.addMouseListener(listener); 
     isLiving = random.nextBoolean(); 
    } 

    public boolean isAlive(int neighbors) { 
     boolean alive = false; 
     if (this.isLiving) { 
      if (neighbors < 2) { 
       alive = false; 
      } else if (neighbors == 2 || neighbors == 3) { 
       alive = true; 
      } else if (neighbors > 3) { 
       alive = false; 
      } 
     } else { 
      if (neighbors == 3) { 
       alive = true; 
      } 
     } 
     return alive; 
    } 

    public void setAlive(boolean alive) { 
     isLiving = alive; 
    } 

    public boolean isLiving() { 
     return this.isLiving; 
    } 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     if (this.isLiving) { 
      g.fillRect(0, 0, getWidth() - 1, getHeight() - 1); 
     } else { 
      g.drawRect(0, 0, getWidth() - 1, getHeight() - 1); 
     } 
    } 

    public static void main(String[] args) { 
     final int s = 40; 
     JPanel ui = new JPanel(new BorderLayout(4, 4)); 
     final JLabel generationLabel = new JLabel("0", JLabel.CENTER); 
     ui.add(generationLabel, BorderLayout.PAGE_START); 

     final GameOfLife[][] biosphere = new GameOfLife[s][s]; 
     final JPanel gui = new JPanel(new GridLayout(s, s, 2, 2)); 
     ui.add(gui); 
     for (int ii = 0; ii < s; ii++) { 
      for (int jj = 0; jj < s; jj++) { 
       GameOfLife cell = new GameOfLife(ii, jj); 
       cell.setPreferredSize(new Dimension(10, 10)); 
       gui.add(cell); 
       biosphere[ii][jj] = cell; 
      } 
     } 

     ActionListener al = new ActionListener() { 
      public void actionPerformed(ActionEvent ae) { 
       boolean[][] living = new boolean[s][s]; 
       for (int ii = 0; ii < s; ii++) { 
        for (int jj = 0; jj < s; jj++) { 
         int top = (jj > 0 ? jj - 1 : s - 1); 
         int btm = (jj < s - 1 ? jj + 1 : 0); 
         int lft = (ii > 0 ? ii - 1 : s - 1); 
         int rgt = (ii < s - 1 ? ii + 1 : 0); 
         int neighbors = 0; 
         if (biosphere[ii][top].isLiving()) { 
          neighbors++; 
         } 
         if (biosphere[ii][btm].isLiving()) { 
          neighbors++; 
         } 
         if (biosphere[lft][top].isLiving()) { 
          neighbors++; 
         } 
         if (biosphere[lft][btm].isLiving()) { 
          neighbors++; 
         } 
         if (biosphere[lft][jj].isLiving()) { 
          neighbors++; 
         } 
         if (biosphere[rgt][jj].isLiving()) { 
          neighbors++; 
         } 
         if (biosphere[rgt][top].isLiving()) { 
          neighbors++; 
         } 
         if (biosphere[rgt][btm].isLiving()) { 
          neighbors++; 
         } 
         living[ii][jj] = biosphere[ii][jj].isAlive(neighbors); 
        } 
       } 
       for (int ii = 0; ii < s; ii++) { 
        for (int jj = 0; jj < s; jj++) { 
         biosphere[ii][jj].setAlive(living[ii][jj]); 
        } 
       } 
       generationLabel.setText("Generation: " + generation++); 
       gui.repaint(); 
      } 
     }; 

     Timer timer = new Timer(50, al); 
     timer.start(); 

     JOptionPane.showMessageDialog(null, ui); 
     timer.stop(); 
    } 
} 
0

est ici la façon dont j'ai mis en avant, je l'utilise 2 tableaux booléens pour vérifier l'état actuel de la carte et l'enregistrer dans un nouveau tableau, puis copiez les nouvelles valeurs de tableau à le tableau de l'état actuel et repeindre la carte:

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.util.Random; 

import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JSlider; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

public class GameOfLife { 

    public static final int ROWS = 30; 
    public static final int COLS = 30; 

    private JFrame frame; 
    private JPanel pane; 
    private Cell[][] cells; 
    private boolean[][] currentState; 
    private boolean[][] newState; 
    private boolean isAlive = false; 
    private JButton startButton; 
    private JButton stopButton; 
    private Timer timer; 
    private JSlider slider; 
    private JLabel label; 
    private int interations; 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> new GameOfLife().createAndShowGui()); 
    } 

    public void randomGeneration() { 
     Random r = new Random(); 
     for (int i = 0; i < ROWS; i++) { 
      for (int j = 0; j < COLS; j++) { 
       currentState[i][j] = r.nextBoolean(); 
       cells[i][j].setAlive(currentState[i][j]); 
      } 
     } 
    } 

    public void createAndShowGui() { 
     frame = new JFrame(getClass().getSimpleName());  

     slider = new JSlider(JSlider.HORIZONTAL, 0, 1000, 500); 

     slider.addChangeListener(new ChangeListener() { 
      @Override 
      public void stateChanged(ChangeEvent e) { 
       timer.setDelay(slider.getValue()); 
      } 
     }); 

     label = new JLabel("Number of iterations: " + interations); 

     timer = new Timer(slider.getValue(), listener); 
     timer.setInitialDelay(slider.getValue()); 

     pane = new JPanel(new GridLayout(ROWS, COLS)); 

     cells = new Cell[ROWS][COLS]; 
     currentState = new boolean[ROWS][COLS]; 
     newState = new boolean[ROWS][COLS]; 

     startButton = new JButton("Start"); 
     stopButton = new JButton("Stop"); 

     for (int i = 0; i < ROWS; i++) { 
      for (int j = 0; j < COLS; j++) { 
       currentState[i][j] = false; 
       newState[i][j] = false; 

       isAlive = currentState[i][j]; 
       cells[i][j] = new Cell(isAlive); 

       cells[i][j].setBorder(BorderFactory.createLineBorder(Color.BLACK)); 
       cells[i][j].addMouseListener(mouseListener); 
       pane.add(cells[i][j]); 
      } 
     } 

     startButton.addActionListener(listener); 
     stopButton.addActionListener(listener); 

     frame.add(slider, BorderLayout.NORTH); 
     frame.add(pane); 
     frame.add(startButton, BorderLayout.WEST); 
     frame.add(stopButton, BorderLayout.EAST); 
     frame.add(label, BorderLayout.SOUTH); 

     randomGeneration(); 

     frame.pack(); 
     frame.setVisible(true); 

     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocationRelativeTo(null); 
    } 

    public void updateState(int i, int j) { 
     currentState[i][j] = !currentState[i][j]; 

     cells[i][j].setAlive(currentState[i][j]); 
     cells[i][j].repaint(); 
    } 

    ActionListener listener = new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      if (e.getSource().equals(startButton)) { 
       if (!timer.isRunning()) { 
        timer.start(); 
       } else { 
        timer.restart(); 
       } 
      } else if (e.getSource().equals(stopButton)) { 
       timer.stop(); 
      } else { 
       for (int i = 0; i < ROWS; i++) { 
        for (int j = 0; j < COLS; j++) { 
         int neighbors = 0; 

         if (i - 1 > 0) { 
          if (j - 1 > 0) { 
           if (currentState[i - 1][j - 1]) { 
            neighbors++; 
           } 
          } 
          if (j + 1 < COLS) { 
           if (currentState[i - 1][j + 1]) { 
            neighbors++; 
           } 
          } 
          if (currentState[i - 1][j]) { 
           neighbors++; 
          } 
         } 
         if (i + 1 < ROWS) { 
          if (j - 1 > 0) { 
           if (currentState[i + 1][j - 1]) { 
            neighbors++; 
           } 
          } 
          if (j + 1 < COLS) { 
           if (currentState[i + 1][j + 1]) { 
            neighbors++; 
           } 
          } 
          if (currentState[i + 1][j]) { 
           neighbors++; 
          } 
         } 
         if (j - 1 > 0) { 
          if (currentState[i][j - 1]) { 
           neighbors++; 
          } 
         } 
         if (j + 1 < COLS) { 
          if (currentState[i][j + 1]) { 
           neighbors++; 
          } 
         } 

         if (currentState[i][j]) { 
          if (neighbors < 2 || neighbors >= 4) { 
           newState[i][j] = false; 
          } else { 
           newState[i][j] = true; 
          } 
         } else { 
          if (neighbors == 3) { 
           newState[i][j] = true; 
          } 
         } 
        } 
       } 

       for (int i = 0; i < ROWS; i++) { 
        for (int j = 0; j < COLS; j++) { 
         currentState[i][j] = newState[i][j]; 
         cells[i][j].setAlive(currentState[i][j]); 
         cells[i][j].revalidate(); 
         cells[i][j].repaint(); 
        } 
       } 

       interations++; 
       label.setText("Number of iterations: " + interations); 
       pane.revalidate(); 
       pane.repaint(); 
      } 
     } 
    }; 

    MouseListener mouseListener = new MouseListener() { 



     @Override 
     public void mouseReleased(MouseEvent e) { 

     } 

     @Override 
     public void mousePressed(MouseEvent e) { 

     } 

     @Override 
     public void mouseExited(MouseEvent e) { 

     } 

     @Override 
     public void mouseEntered(MouseEvent e) { 

     } 

     @Override 
     public void mouseClicked(MouseEvent e) { 
      for (int i = 0; i < ROWS; i++) { 
       for (int j = 0; j < COLS; j++) { 
        if (e.getSource().equals(cells[i][j])) { 
         updateState(i, j); 
         break; 
        } 
       } 
      } 
     } 
    }; 
} 

@SuppressWarnings("serial") 
class Cell extends JPanel { 
    private boolean isAlive; 

    public Cell(boolean isAlive) { 
     this.isAlive = isAlive; 
    } 

    public boolean isAlive() { 
     return isAlive; 
    } 

    public void setAlive(boolean isAlive) { 
     this.isAlive = isAlive; 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(20, 20); 
    } 

    @Override 
    public Color getBackground() { 
     return isAlive ? Color.GREEN : Color.GRAY; 
    } 
} 

Il comprend également un JSlider pour gérer la vitesse de traitement:

enter image description here

Amusez-vous et notez que j'ai utilisé un Swing Timer au lieu du Util Timer que vous utilisez.