简体   繁体   English

Java Swing会忽略repaint()吗?

[英]Java Swing ignores repaint()?

Basically I need one of my panels to be repainted at least 60 times per second. 基本上,我需要以每秒至少60次的速度对我的面板之一进行粉刷。 However I noticed, that if I don't move my mouse, FPS drops to ~5. 但是我注意到,如果不移动鼠标,FPS会下降到〜5。 I wrote program to test it. 我写了程序来测试它。

package test;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class Test extends JFrame implements ActionListener {

    Timer t;
    JLabel l;
    JPanel p;
    long lastT;

    public static void main(String[] args){
        new Test();

    }

    public Test(){
        add(p = new JPanel());
        p.add(l = new JLabel("0000000000000000000000000000000"));
        pack();
        lastT = System.nanoTime();
        t = new Timer(10, this);
        t.setRepeats(true);
        t.start();
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        long time = System.nanoTime();
        l.setText(String.valueOf((time - lastT)));
        repaint();
        lastT = time;
    }

}

It shows the interval between frames. 它显示帧之间的间隔。 If my mouse is inside the window, it changes much faster, if it is outside of window, it changes much slower, similar to my original problem. 如果我的鼠标在窗口内,它的变化要快得多,如果它在窗口外,它的变化要慢得多,类似于我的原始问题。 But the thing is, the number itself is not much different no matter if mouse is inside or outside, which means that Timer is shooting event at same interval. 但事实是,无论鼠标位于内部还是外部,数字本身并没有太大区别,这意味着Timer以相同的间隔拍摄事件。 So it means that the repaint() is ignored? 因此,这意味着repaint()被忽略了吗? How can it be fixed? 如何解决?

Please note that repaint is never guaranteed to work as the Swing repaint manager will ignore stacked repaint requests -- that is if repaint requests build up and are not able to be handled in a timely fashion due to code being run from the Swing event queue, only the last one is called. 请注意,由于Swing重绘管理器将忽略堆叠的重绘请求,因此永远不能保证重绘会工作-也就是说,如果重绘请求已建立并且由于从Swing事件队列中运行了代码而无法及时处理,只有最后一个被调用。 Please read Painting in AWT and Swing for more. 请阅读AWT和Swing中的绘画以获取更多信息。

Note however that there is no need to call repaint() in your code above, since changing the state of the JLabel's model will trigger a repaint on its own, and this would be a repaint of just the label itself, something that should be run more efficiently than calling repaint on the entire GUI. 但是请注意,在上面的代码中无需调用repaint() ,因为更改JLabel模型的状态将自行触发重新绘制,并且这将只是标签本身的重新绘制,应运行此操作比在整个GUI上调用repaint更有效。 Also note that 10 mSec is a very short time slice and a Swing Timer may not be accurately or reliably called at 10 msec. 还要注意,10毫秒是很短的时间片,摆动定时器可能无法在10毫秒时准确或可靠地调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM