Multithreading 使用线程在Java中实现JComponent闪烁

Multithreading 使用线程在Java中实现JComponent闪烁,multithreading,graphics,jcomponent,Multithreading,Graphics,Jcomponent,我试图实现一个程序,我希望不同的组件以不同的速度闪烁。我正在使用线程。但它不起作用。 我如何实现这一点 这是实现runnable的类中的void run函数 public void run() { try { while(true) { Thread.sleep(1000); if(isVisible()==true) { setVisible(

我试图实现一个程序,我希望不同的组件以不同的速度闪烁。我正在使用线程。但它不起作用。 我如何实现这一点

这是实现runnable的类中的void run函数

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


    }

    catch(InterruptedException e)
    {

    }   
}
} 这是主JPanelwhere的一个绘画组件中的类,我称之为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是一系列JC组件,void run是其中的一部分


感谢使用Swing,所有影响可见组件的操作都应该在AWT事件队列上运行。这是用于输入/输出操作以及图形和组件操作的专用线程。我的建议是在跑步时使用摆动计时器。您所做的重新绘制调用将调用AWT EventQueue上的PaintCompent方法。但是,您正在更改单独线程上的可见性状态。这意味着在进行重新绘制调用时,状态可能已经更改为以前的值

 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)
    {

    }   

嗯。它不眨眼。但是void运行肯定会被执行,因为当我在其中放入System.out.println时,它会被无限打印。嗯,谢谢,但我应该使用线程来实现这一点。就像,你为每个组件启动一个线程,它们以不同的速度在整个JPanel上闪烁。然后你剩下两个选项:1每次你改变状态为可见性时阻止EDT,如果在线程外执行此操作,请让线程在线程方法内使用swingutilites.invokeLater向EDT提交可运行类型。多线程的问题在于,没有内置任何东西可以阻止线程彼此更改状态。这是由争用条件引起的,因为无法确定两个线程在同一状态下修改/访问同一状态的结果。我继续并在回答中添加了第二个建议。我尝试了第二个建议。非常感谢。但每当我使用SETVISIBLE时,程序就会进入无限循环。它是如何进入无限循环的?你在调用器里放了什么?您是否重写了setVisible方法?