Java 多次更改JPanel的背景颜色

Java 多次更改JPanel的背景颜色,java,swing,jpanel,Java,Swing,Jpanel,我正在尝试制作一个小程序,其中包括基于时间改变面板的颜色。 现在我只想做那部分而不做其他的。所以我只编写了一个只有一个面板的小界面,我想在一个循环中多次更改颜色。 问题是,即使线程暂停的时间正确,面板的颜色也不会正确更改。它只是在循环中有时发生变化,而不是每次 我的接口类: import javax.swing.*; import java.awt.*; //creates the Interface public class Interface extends JFrame { pr

我正在尝试制作一个小程序,其中包括基于时间改变面板的颜色。 现在我只想做那部分而不做其他的。所以我只编写了一个只有一个面板的小界面,我想在一个循环中多次更改颜色。 问题是,即使线程暂停的时间正确,面板的颜色也不会正确更改。它只是在循环中有时发生变化,而不是每次

我的接口类:

import javax.swing.*;
import java.awt.*;

//creates the Interface
public class Interface extends JFrame {
    private JPanel frame1;

    public Interface (String titel) {
        super(titel);
        setSize(600, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.frame1 = new JPanel();
        this.frame1.setPreferredSize(new Dimension (200, 200));
        setLayout(new FlowLayout());
        add(frame1);
        this.setVisible(true);
    }

    public JPanel getFrame1() {
        return frame1;
    }

}
我的暂停课:

import java.util.TimerTask;


//supposed to pause the thread by @pause amount of milliseconds
public class Pause extends TimerTask {
    private int pause;

    public Pause(int pause){
        this.pause = pause;
    }

    @Override
    public void run() {
        System.out.println("Timer"+ pause+" task started at:"+System.currentTimeMillis());
        pause();
        System.out.println("Timer task"+ pause+" ended at:"+System.currentTimeMillis());
    }

    public void pause() {
        try {
            Thread.sleep(this.pause);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
我的眨眼课

import javax.swing.*;
import java.awt.*;
public class Blink {
    private JPanel frame1;
    public Blink(Interface anInterface){
        this.frame1 = anInterface.getFrame1();
    }

    // blink should change the color of the JPanel inside my Frame. 
    // Its supposed to change to red for 200 ms
    // and then to white again for 1000 ms.
    // this should be repeated 10 times.
    public void blink() {
        Pause pause1 = new Pause(200);
        Pause pause2 = new Pause(1000);
        pause2.run();
        int i = 1;
        while(i <= 10){
            i++;
            frame1.setBackground(Color.red);
            frame1.repaint();
            pause1.run();
            frame1.setBackground(Color.white);
            frame1.repaint();
            pause2.run();
        }
    }

    public static void main ( String[] args ) {
        Interface anInterface = new Interface("Title");
        anInterface.setVisible(true);
        Blink blink = new Blink(anInterface);
        blink.blink();
    }
}

import javax.swing.*;
导入java.awt.*;
公共类闪烁{
私有JPanel框架1;
公共闪烁(接口){
this.frame1=interface.getFrame1();
}
//闪烁应该会改变帧内JPanel的颜色。
//它应该在200毫秒内变为红色
//然后再次变白1000毫秒。
//这应该重复10次。
公共图书馆{
暂停暂停1=新暂停(200);
暂停暂停2=新暂停(1000);
pause2.run();
int i=1;
而(据我所知,你不能简单地
Thread.sleep
GUI运行的
Thread
,因为它会冻结它,因此事件不会发生。相反,对于任何类型的动画或长时间繁重的任务(考虑
Thread.sleep
),应该使用。在您的情况下,
javax.swing.Timer
更合适

其用法的一个示例:

public class Blink {
    private JPanel frame1;
    private int pause1TimesRan;
    private int pause2TimesRan;

    private Timer pauser1, pauser2;

    public Blink(Interface anInterface) {
        this.frame1 = anInterface.getFrame1();
        //Create pauser 1 with delay 200ms
        pauser1 = new Timer(200, e -> {
            if (pause1TimesRan == 10) {
                pauser1.stop();
                return;
            }
            Color color = randomColor();
            frame1.setBackground(color);
            System.out.println("Pauser #1 changed background to: " + color);
            pause1TimesRan++;
        });
        //Create pauser 2 with delay 1000ms
        pauser2 = new Timer(1000, e -> {
            if (pause2TimesRan == 10) {
                pauser2.stop();
                return;
            }
            Color color = randomColor();
            frame1.setBackground(color);
            System.out.println("Pauser #2 changed background to: " + color);
            pause2TimesRan++;
        });
    }

    private static Color randomColor() {
        return new Color((int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255));
    }

    public void blink() {
        pauser1.start();
        pauser2.start();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            Interface anInterface = new Interface("Title");
            anInterface.setVisible(true);
            Blink blink = new Blink(anInterface);
            blink.blink();
        });
    }

    static class Interface extends JFrame {
        private JPanel frame1;

        public Interface(String titel) {
            super(titel);
            setSize(600, 400);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.frame1 = new JPanel();
            this.frame1.setPreferredSize(new Dimension(200, 200));
            setLayout(new FlowLayout());
            add(frame1);
            this.setVisible(true);
        }

        public JPanel getFrame1() {
            return frame1;
        }

    }
}
一个非主题建议是正确命名方法(和变量)。您调用了方法
getFrame1()
,但它实际上是
JPanel
,而不是
JFrame
。因此,更好的名称可能是
getPanel()
。另外,关于
SwingUtilities.invokeLater
部分,请阅读