Java实现图形闪烁效果

xparmenides 2015-07-21 11:49:06
我希望能够在窗口中显示一个图形(比如一个矩形吧),然后这个图形能够闪烁,也就是每个0.5秒切换成另一种颜色。例如,开始是蓝色矩形,过0.5秒变成红色,再过0.5秒变回蓝色,依次切换颜色,闪烁5次后停止闪烁。我首先在窗口中加一个JPanel和一个按钮,按钮按下执行:
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
// TODO add your handling code here:
for (int i = 0; i < 5; i++){
jPanel1.repaint();
try {
Thread.sleep(500);
}
catch (InterruptedException e){
e.printStackTrace();
}
jPanel1.repaint();
}

然后,从JPanel类派生出DrawPanel类,并重写paintComponent方法:
    class DrawPanel extends JPanel{
private Color c = null;
protected void paintComponent(Graphics g){
super.paintComponent(g);
if (c == null || c == Color.blue)
c = Color.red;
else
c = Color.blue;
g.setColor(c);
g.fillRect(50, 50, 100, 100);
}
}

但是,效果并不是预期的闪烁效果。按下按钮后停顿一段时间没反应,接着颜色仅变化一次。请大家帮忙分析一下这个问题,谢谢!
...全文
691 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
xparmenides 2015-07-26
  • 打赏
  • 举报
回复
又看了一些文档,现在弄清楚问题的原因了。Swing使用单独的事件派发线程进行事件的派发处理。该线程从一个事件队列中按投递时间顺序从队列中取出每个事件,然后针对特定事件调用注册的处理方法。这样,事件的产生可能是并行的,但事件的处理却变成了串行的。一开始的绘图代码运行在事件派发线程中,但第一次repaint事件投递出去后,线程就sleep了,此时就无法派发事件,也就不能重画窗口了。经过5次循环,事件队列中堆积了5个repaint事件,只有当循环结束后,这5个事件才能获得派发和处理。但Swing似乎做了优化,即将连续的相同事件合并为一个事件,因此最后的结果是只重画了一次。
lliiqiang 2015-07-23
  • 打赏
  • 举报
回复
是不是只有事件被处理完之后才改变界面?
飏飏一蝶 2015-07-21
  • 打赏
  • 举报
回复
事件处理里面不要两个repaint.,循环代码你连着看,实际没变色,就第一次变了。另外Ui的耗时操作不要放到主线程,放EventQuene里试试。
Inhibitory 2015-07-21
  • 打赏
  • 举报
回复
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

public class Test extends JPanel {
    private Color[] colors = {Color.RED, Color.BLACK, Color.BLUE, Color.WHITE, Color.GREEN};
    private int currentColorIndex;

    public void randomPaint() {
        Random random = new Random();
        currentColorIndex = random.nextInt(colors.length);
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(colors[currentColorIndex]);
        g2d.fillRect(10, 10, 200, 200);
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame();
        final Test test = new Test();
        JButton startButton = new JButton("Start");

        frame.getContentPane().add(startButton, BorderLayout.NORTH);
        frame.getContentPane().add(test, BorderLayout.CENTER);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(new Dimension(500, 500));
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        startButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                Thread thread = new Thread(new Runnable() {
                    public void run() {
                        try {
                            for (int i = 0; i < 50; ++i) {
                                test.randomPaint();
                                Thread.sleep(1000);
                            }
                        } catch (Exception ex) { }
                    }
                });

                thread.start();
            }
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

62,635

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧