2014-10-26 1 views
0

Я пытаюсь реализовать программу, где хочу, чтобы разные компоненты мигали на разных скоростях. Я использую потоки. Но это не работает. Как это реализовать.Реализация JComponent мигает в Java с помощью потоков

Это функция аннулируются работать в классе, который реализует работоспособный

public void run() 
{ 
    try 
    { 
     while(true) 
     { 
      Thread.sleep(1000); 
      if(isVisible()==true) 
      { 
       setVisible(false); 
      } 
      else 
      { 
       setVisible(true); 
      } 
      repaint(); 
     } 


    } 

    catch(InterruptedException e) 
    { 

    } 
} 

} и это класс (его в краске составляющей главного JPanel), где я называю threads-

{ 
    cars[i]=new Car(color, xLocation, yLocation, speed, type, i, widthController, heightController); 
    cars[i].setBounds(widthController+(xLocation*50)+10, heightController+(yLocation*50)+10, 30, 30); 
    add(cars[i]); 

    threads[i]=new Thread(cars[i]); 
    threads[i].start(); 
} 

cars - это массив JComponents, частью которого является void run.

Благодаря

+0

В чем проблема? – Radiodef

+0

Умм. Его не моргают. Но void run() определенно выполняется, хотя причина, когда я вставляю в него System.out.println, его печатает бесконечно. – rkat

ответ

0

С Качели, все операции, которые влияют на видимые компоненты должны работать на АВТ-EventQueue. Это выделенный поток для операций ввода/вывода, а также операций рисования и компонентов. Моя рекомендация - использовать таймер качания для вашей работы. Вызванный вами перерисовывание вызовет метод paintCompnent на AWT-EventQueue. Однако вы меняете состояние видимости на отдельном потоке. Это означает, что к тому времени, когда будет сделан вызов перерисовки, возможно, что состояние уже изменилось на предыдущее значение.

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
//Rest of code above... 
    //This will execute the timer every 500 milliseconds 
    Timer aTimer = new Timer(500, new ActionListener() { 

    @Override 
    public void actionPerformed(ActionEvent pE) { 
     aComponent.setVisible(!aComponent.isVisible()); 

    } 
    }); 
    aTimer.start(); 

Другой вариант заключается в том, что на каждом потоке добавить этот вызов: // Это должно быть добавлено внутри вашей нити

SwingUtilities.invokeLater(new Runnable() { 

    @Override 
    public void run() { 
    aComponent.setVisible(!aComponent.isVisible()); 
    } 
}); 

Вот ответ, который я имел в виду в своих комментариях:

public void run() 
{ 
    try 
    { 
     while(true) 
     { 
      Thread.sleep(1000); 
      SwingUtilities.invokeLater(new Runnable() { 

       @Override 
       public void run() { 
       setVisible(!isVisible()); 
      } 

     } 
    }); 


    } 

    catch(InterruptedException e) 
    { 

    } 
+0

Умм, спасибо, но я должен использовать для этого темы. Например, вы запускаете нить для каждого компонента, и они мигают с разной скоростью по всему JPanel. – rkat

+0

Затем вы остаетесь с двумя вариантами: 1) Блокируйте EDT каждый раз, когда вы меняете состояние (состояние является видимостью), если вы делаете это вне потока или 2) Имейте поток, представляющий runnable type для EDT с помощью SwingUtilties. invokeLater внутри вашего метода потока. Проблема с многопоточным состоит в том, что нет ничего, чтобы остановить потоки от изменения состояния друг от друга. Это вызвано условием гонки, так как результат двух потоков, изменяющих/получающих доступ к одному и тому же состоянию в одном и том же состоянии, не может быть определен. – lordoku

+0

Я пошел вперед и добавил свое второе предложение к моему ответу. – lordoku