为了账号安全,请及时绑定邮箱和手机立即绑定

多次更改JPanel的背景颜色

多次更改JPanel的背景颜色

四季花海 2024-01-25 21:40:30
我正在尝试制作一个小程序,其中包括根据时间更改面板的颜色。现在我只是尝试做那部分而不做其余的。所以我只写了一个只有一个面板的小界面,我想在循环内多次更改颜色。问题是,即使线程暂停正确的时间,面板的颜色也不会正确更改。它只是有时在循环中改变,而不是每次都改变。我的接口类:import javax.swing.*;import java.awt.*;//creates the Interfacepublic 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 millisecondspublic 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();        }    }
查看完整描述

1 回答

?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

根据Swing 的并发性,您不能简单地Thread.sleep确定ThreadGUI 运行的位置,因为它会冻结 GUI,因此事件无法发生。相反,对于任何类型的动画或长时间繁重的任务(视为Thread.sleep其中之一),应使用Swing Timers和Swing Workers 。对于你的情况,ajavax.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(),但它实际上是 aJPanel而不是 a JFrame。所以,更好的名字可能是getPanel()


查看完整回答
反对 回复 2024-01-25
  • 1 回答
  • 0 关注
  • 75 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信