【问题标题】:Timer Flickers When It Reaches 0定时器到达 0 时闪烁
【发布时间】:2014-01-22 12:36:03
【问题描述】:

导入库

public class Countdown1 extends Applet implements Runnable {
// getting user input

    String input = JOptionPane.showInputDialog("Enter seconds: ");
 // converting string to integer

    int counter = Integer.parseInt(input);

    Thread countdown;

    public void start() {
        countdown = new Thread(this);
        countdown.start();

    }

// executed by thread
    public void run() {

        Timer timer;

        timer = new Timer(1000, new ActionListener() /* counting down time inputted */ {
            public void actionPerformed(ActionEvent evt) {
                if (counter > 0) {

                    counter--;
// repainting each second

                    repaint();
                }
            }
        });
// timer started 

        timer.start();

    }

    public void paint(Graphics g) {
//painting text and time 

        g.setFont(new Font("Times New Roman", Font.BOLD, 35));
        g.drawString("Seconds: " + String.valueOf(counter), 260, 210);
        setBackground(Color.orange);
        setForeground(Color.magenta);

// change background to cyan when timer reaches 0
        if (counter == 0) {
            setBackground(Color.cyan);
        }
    }
}

【问题讨论】:

    标签: java timer flicker


    【解决方案1】:

    问题不在于您的Timer(尽管我确实质疑是否需要在单独的线程中启动它),问题在于覆盖paint

    Applet 这样的顶级容器不是双缓冲的,这意味着每个绘制动作都会拼命地发送到底层的Graphics 设备。

    现在你可以通过员工一些双缓冲过程来解决这个问题,或者你可以......

    • 改为从JApplet 扩展
    • 创建一个扩展自 JPanel 之类的自定义组件,并改写它的 paintComponent 方法,将您的自定义绘画移至此方法
    • 将此组件添加到小程序中。

    应该能解决眼前的问题……

    您还应该避免在任何paint 方法中调用setForegroundsetBackground。事实上,您应该避免在任何paint 方法中调用任何可能调用repaint 的方法...

    看看Performing Custom Painting

    我很确定String input = JOptionPane.showInputDialog("Enter seconds: "); 这是个坏主意。相反,您应该在 UI 中提供某种控件或选项来更改此值...

    粗略的例子

    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JApplet;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    public class Countdown1 extends JApplet {
    
        @Override
        public void init() {
            add(new CounterPane());
        }
    
        public class CounterPane extends JPanel {
    
            String input = JOptionPane.showInputDialog("Enter seconds: ");
    
            int counter = Integer.parseInt(input);
    
            public CounterPane() {
    
                Timer timer;
    
                timer = new Timer(1000, new ActionListener() /* counting down time inputted */ {
                    public void actionPerformed(ActionEvent evt) {
                        System.out.println(counter);
                        if (counter > 0) {
    
                            counter--;
    
                            setBackground(Color.orange);
                            setForeground(Color.magenta);
    
                            if (counter <= 0) {
                                setBackground(Color.cyan);
                            }
    
                            repaint();
                        }
                    }
                });
    
                timer.start();
    
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setFont(new Font("Times New Roman", Font.BOLD, 35));
                g.setColor(getForeground());
                g.drawString("Seconds: " + String.valueOf(counter), 260, 210);
            }
    
        }
    }
    

    【讨论】:

    • 希望它对您有所帮助;)
    • 这是相当延迟的,但是当我从 JApplet 而不是 Applet 扩展时,我的背景颜色变回白色,并且计时器在前一个数字之上重新绘制。
    • 我收到一条错误消息“找不到符号方法paintComponent(java.awt.Graphics)”
    • 那是因为在你的例子中你覆盖了paint,我确实建议不要这样做。 JApplet 没有 paintComponent 方法。相反,您应该创建一个从 JPanel 扩展的自定义组件,并将所有自定义绘画放入其中,然后将其添加到小程序
    • 我觉得我需要先走路再跑。我最近开始使用 Java,我对它的了解仅限于您面前的内容。我完全不明白你的意思。不过,我非常重视您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多