猿问

多次更改JPanel的背景颜色

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


我的接口类:


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

        }

    }



四季花海
浏览 86回答 1
1回答

摇曳的蔷薇

根据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(). 
随时随地看视频慕课网APP

相关分类

Java
我要回答