涂料的效果延迟达500毫秒

时间:2016-12-11 07:36:28

标签: java swing paint

我有一个以十几秒为单位显示时间的Java程序。每个数字都是一个单独的组件,组件被分组在一个JPanel中,该JPanel位于占据大部分屏幕的JFrame的角落附近。数字由专用线程更新,该线程以100ms wait()循环。当数字改变时,它被重新绘制。

调度似乎正在起作用:以100ms的间隔适当调用repaint()和paint(),但显示只每500ms更新一次。

但是,如果我将鼠标移到JFrame上,或者反复按一个键(控制并移动两个工作),则显示更新更快。

如果我每100毫秒重新绘制JFrame的内容窗格,那么显示会正确更新,但JFrame中的其他所有内容都会被不必要地重新绘制。重新绘制包含时间显示的JFrame部分没有明显效果,但重新绘制JFrame 的大部分区域(不包括时间显示)会更新时间。

我已尝试将数字基于JComponent并调用paintImmediately()(来自事件调度线程),没有明显差异。

解释可能是EDT等待500毫秒超时并且没有被paint()通知。有没有办法可以明确通知EDT测试这个?

我可以通过在一个单独的重量级容器中显示时间来解决这个问题,但我想了解导致这种行为的原因。

这是一个产生此行为的简短程序。 1.7版本的线条始终平稳旋转。使用1.8版本时,它首先会平稳移动,但在两秒钟内它会开始跳跃。请注意,角度在绘制过程中会增加,因此如果要合并涂料,线条仍然会平滑旋转但速度会更慢。

我不相信有必要从美国东部时间调用重画,但我已经尝试了它并没有任何区别。 for 循环不在EDT中运行,因此睡眠不会阻止显示更新。

    package bugs;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class DisplayRefresh {
    private class Cmpt extends Component {
        private static final int    POINTS = 16;
        int     m_ix;

        public Cmpt()
        {
            m_ix = 0;
        }

        public void paint(Graphics g)
        {
            Dimension sz = getSize();
            int rx = (sz.width - 1) / 2;
            int ry = (sz.height - 1) / 2;
            Double w = Math.PI * m_ix / POINTS;
            int x = (int)Math.floor(Math.sin(w) * rx);
            int y = (int)Math.floor(Math.cos(w) * ry);
            g.drawLine(rx - x, ry - y, rx + x, ry + y);
            m_ix = (m_ix + 1) % POINTS;
        }
    }

    JFrame      m_frame;
    Cmpt        m_cmpt;

    public static void main(String[] args) {
        (new DisplayRefresh()).exec();
    }

    private void exec()
    {
        m_frame = new JFrame();
        m_frame.setLayout(null);
        m_frame.setSize(600, 600);
        m_frame.setVisible(true);
        m_cmpt = new Cmpt();
        m_cmpt.setSize(64, 64);
        m_frame.add(m_cmpt);
        m_cmpt.setLocation(500, 100);
        if (SwingUtilities.isEventDispatchThread()) {
            System.out.println("This is the event dispatch thread");
        } else {
            System.out.println("This is NOT the event dispatch thread");
        }
        for (int i = 0; i < 100; i++) {
            m_cmpt.repaint(10);
            try {
                Thread.sleep(100);
            } catch(InterruptedException exc) {
                System.out.println(exc.toString());
            }
        }
        m_frame.dispose();
        System.exit(0);
    }
}

1 个答案:

答案 0 :(得分:-1)

我刚刚使用Java 1.7.0_80而不是1.8.0_92进行了重新编译,显示现在已经及时更新,问题的答案是&#34;是什么导致了这种行为?&#34;是这个版本的java的特性

我现在尝试了1.8.0_111版本。这与1.8.0_92具有相同的刷新延迟。