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
部分,请阅读