2013-06-28 4 views
-1

J'essaie de remplacer Thread.sleep() par une minuterie swing java car j'entends que c'est beaucoup mieux pour les graphiques. Avant, j'avais quelque chose de configuré comme ça, mais cela interférait avec les graphismes.Timer en Java swing

while(counter < array.size){ 
Thread.sleep(array.get(counter).startTime); 
//do first task 
Thread.sleep(array.get(counter).secondTime); 
//do second task 
Thread.sleep(array.get(counter).thirdTime); 
//do third task 
counter++ 
} 

Maintenant, je suis en train de remplacer chaque Thread.sleep() avec l'un de ces puis-je les événements réels qui se produisent après cela, mais il ne semble pas attendre du tout.

int test = array.get(counter).time; 
ActionListener taskPerformer = new ActionListener(){ 
public void actionPerformed(ActionEvent evt){ 
} 
}; 
Timer t = new Timer(test, taskPerformer); 
t.setRepeats(false); 
t.start(); 

En gros, comment puis-je faire en sorte que le programme attendra sans lui donner un code à exécuter à l'intérieur de la minuterie? Je vous remercie!

+2

C'est ... pas ce que font les minuteries. –

+0

D'accord, merci. Si vous savez comment, alors pouvez-vous répondre comment ai-je 3 tâches séquentielles se produisent dans une boucle avec le temps entre eux l'un après l'autre? – Yesha

+3

Vous ne voulez pas que le programme attende. L'idée est que chaque fois qu'une minuterie tic-tac va changer l'état du programme est d'une certaine façon, qui est ensuite peint et la minuterie suivante commence ... – MadProgrammer

Répondre

5

La réponse se résume à ce que vous voulez réaliser ...

Les choses à l'importation à retenir sont, Swing est simple environnement fileté, qui est, il est prévu que toutes les interactions, les changements, les modifications, Les mises à jour et les créations de l'interface utilisateur sont effectuées dans le contexte du fil d'envoi des événements.

Toute action qui bloque l'EDT (telle que sleep, wait, etc.) empêchera l'EDT de repeindre l'interface utilisateur ou de répondre à de nouveaux événements.

Une façon d'y parvenir est par l'utilisation de javax.swing.Timer

Ceci est par exemple très simple en utilisant 3 minuteries enchaînées ensemble. Personnellement, j'utiliser une minuterie unique configurée pour une courte durée cocher et vérifier si le délai requis est survenu et puis changer l'état en conséquence, mais cela devient le point à travers ...

enter image description here

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class SimpleTimer { 

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

    public SimpleTimer() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private Timer red; 
     private Timer green; 
     private Timer yellow; 
     private Color color = Color.GREEN; 

     private Point spot; 

     public TestPane() { 
      red = new Timer(500, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        color = Color.RED; 
        green.start(); 
        repaint(); 
       } 
      }); 
      green = new Timer(2000, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        color = Color.GREEN; 
        yellow.start(); 
        repaint(); 
       } 
      }); 
      yellow = new Timer(1000, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        color = Color.YELLOW; 
        red.start(); 
        repaint(); 
       } 
      }); 
      red.setRepeats(false); 
      green.setRepeats(false); 
      yellow.setRepeats(false); 
      green.start(); 

      addMouseMotionListener(new MouseAdapter() { 
       @Override 
       public void mouseMoved(MouseEvent e) { 
        spot = e.getPoint(); 
        repaint(); 
       } 
      }); 

     } 

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

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      int radius = 20; 
      int x = (getWidth() - radius)/2; 
      int y = (getHeight() - radius)/2; 
      g2d.setColor(color); 
      g2d.fillOval(x, y, radius, radius); 

      if (spot != null) { 

       x = spot.x - 5; 
       y = spot.y - 5; 
       g2d.setColor(Color.RED); 
       g2d.drawOval(x, y, 10, 10); 
       g2d.setColor(Color.YELLOW); 
       g2d.fillOval(x, y, 10, 10); 

      } 

      g2d.dispose(); 
     } 
    } 
} 

Une autre option serait d'utiliser un SwingWorker, cela permet de faire une sorte de traitement dans un thread d'arrière-plan (en laissant l'EDT en cours d'exécution), mais fournit des méthodes par lesquelles vous pouvez simplement synchroniser les résultats avec l'EDT.

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.List; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingWorker; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class SimpleTimer { 

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

    public SimpleTimer() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private Color color = Color.GREEN; 

     private Point spot; 

     public TestPane() { 

      new Switcher().execute(); 

      addMouseMotionListener(new MouseAdapter() { 
       @Override 
       public void mouseMoved(MouseEvent e) { 
        spot = e.getPoint(); 
        repaint(); 
       } 
      }); 

     } 

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

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      int radius = 20; 
      int x = (getWidth() - radius)/2; 
      int y = (getHeight() - radius)/2; 
      g2d.setColor(color); 
      g2d.fillOval(x, y, radius, radius); 

      if (spot != null) { 

       x = spot.x - 5; 
       y = spot.y - 5; 
       g2d.setColor(Color.RED); 
       g2d.drawOval(x, y, 10, 10); 
       g2d.setColor(Color.YELLOW); 
       g2d.fillOval(x, y, 10, 10); 

      } 

      g2d.dispose(); 
     } 

     public class Switcher extends SwingWorker<Void, Color> { 

      @Override 
      protected void process(List<Color> chunks) { 
       color = chunks.get(chunks.size() - 1); 
       repaint(); 
      } 

      @Override 
      protected Void doInBackground() throws Exception { 

       while (true) { 

        publish(Color.GREEN); 
        Thread.sleep(2000); 
        publish(Color.YELLOW); 
        Thread.sleep(500); 
        publish(Color.RED); 
        Thread.sleep(2000); 

       } 

      } 

     } 

    } 
} 

Découvrez Concurrency in Swing pour plus de détails

+0

Wow, c'est génial! Merci beaucoup! – Yesha

+0

Espérons que cela vous aide dans tout ce que vous essayez d'atteindre – MadProgrammer

+0

Oh, ce sera certainement.C'est une application de sous-titrage qui ira sur toute vidéo qui a un fichier SRT (sous-titre) disponible sur le web. – Yesha