2013-06-28 2 views
-1

Я пытаюсь заменить Thread.sleep() таймером качания java, поскольку я слышу, что это намного лучше для графики.Таймер в 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++ 
} 

Теперь я пытаюсь заменить каждый Thread.sleep() с одним из них, а затем у меня есть реальные события, которые происходят после этого, но это, кажется, не будет ждать вообще.

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(); 

В принципе, как я могу гарантировать, что программа будет ждать, не указывая на выполнение какого-либо кода внутри таймера? Спасибо!

+2

Это ... не то, что делают таймеры. –

+0

Хорошо, спасибо. Если вы знаете, как это сделать, тогда вы можете ответить, как я могу сделать 3 последовательных задания в цикле со временем между ними один за другим? – Yesha

+3

Вы не хотите, чтобы программа ждала. Идея состоит в том, что каждый раз, когда таймер тикает, он изменит состояние программы, будет каким-то образом, который затем будет окрашен, а следующий таймер запустится ... – MadProgrammer

ответ

5

Ответ сводится к тому, что именно вы хотите достичь ...

Импортные вещи, чтобы помнить это, Swing однопоточен среда, то есть предполагается, что все взаимодействия, изменения, модификации, обновления и создания пользовательского интерфейса выполняются из контекста потока Dispatching Event.

Любое действие, которое блокирует EDT (например, sleep, wait и т. Д.), Не позволит EDT перекрасить пользовательский интерфейс или отвечать на новые события.

Одним из способов достижения этой цели является использование javax.swing.Timer

Это очень простой пример использования 3 таймера прикованного вместе. Лично я хотел бы использовать один таймер, выполненный в течение короткого периода клещевого и проверить, если требуемая задержка произошла, а затем изменить состояние соответственно, но это получает через точку ...

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(); 
     } 
    } 
} 

Другим вариантом будет использование SwingWorker, что позволяет выполнять некоторую обработку в фоновом потоке (оставляя работу EDT), но предоставляет методы, с помощью которых вы можете просто синхронизировать результаты с 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); 

       } 

      } 

     } 

    } 
} 

Заканчивать Concurrency in Swing для более подробной информации

+0

Wow, это потрясающе! Спасибо огромное! – Yesha

+0

Надеюсь, это поможет вам в чем бы то ни было, вы пытаетесь достичь – MadProgrammer

+0

О, это определенно будет.Это приложение субтитров, которое перейдет на любое видео, имеющее доступный файл SRT (субтитров) в Интернете. – Yesha