等待AWT重绘完成

时间:2012-09-25 06:34:45

标签: java awt frame

我有Frame这是一种颜色,但角落里有一些文字。我设置颜色,实际从显示器读取颜色,然后根据这些测量值进行一些计算。

问题是,调用repaint()会导致Frame在之后绘制。我假设这是由于repaint()委托给了EDT,但由于在实际绘画工作之前/期间进行了测量,我得到的结果不正确。

我最初的想法是让一个听众完成绘画,但我重新更新文本的频率比我对颜色更频繁,我不想听这些事件。在进行测量之前,我该如何等待实际的绘画任务完成?

2 个答案:

答案 0 :(得分:0)

你能找到什么......

EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {

        Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
            @Override
            public void eventDispatched(AWTEvent event) {

                PaintEvent pe = (PaintEvent) event;

                String type = "";
                if (pe.getID() == PaintEvent.PAINT) {
                    type = "PAINT";
                } else if (pe.getID() == PaintEvent.PAINT_FIRST) {
                    type = "PAINT_FIRST";
                } else if (pe.getID() == PaintEvent.PAINT_LAST) {
                    type = "PAINT_LAST";
                } else if (pe.getID() == PaintEvent.UPDATE) {
                    type = "UPDATE";
                }

                System.out.println(type + "; pe.UpdateRec = " + pe.getUpdateRect() + "; pe.component = " + pe.getComponent());

            }
        }, AWTEvent.PAINT_EVENT_MASK);

        JFrame frame = new JFrame("Testing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(200, 200);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);


    }
});

现在,因为重绘请求可以快速思考,所以我很想在最后一个请求完成后不久发出一个小“延迟”......

private Timer updateTimer;

// ...

EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {

        updateTimer = new Timer(250, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // Update compulations here...
            }
        });
        updateTimer.setRepeats(false);
        updateTimer.setCoalesce(true);

        Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {

            @Override
            public void eventDispatched(AWTEvent event) {
                updateTimer.restart();
            }
        }, AWTEvent.PAINT_EVENT_MASK);
    }
}

这个想法是在最后一次重绘请求和编译开始之间至少允许250毫秒。您可能想稍微使用这些值,看看哪些适合您......

<强>更新

您也可以尝试JComponent.paintImmediately

  

绘制此组件及其所有组件中的指定区域   立即与该地区重叠的后代。

     

很少需要调用此方法。在大多数情况下,它更多   高效地调用重绘,这推迟了实际绘画和可以   将冗余请求折叠为单个绘制调用。这个方法是   如果在当前事件发生时需要更新显示,则非常有用   被派遣。

答案 1 :(得分:0)

我知道这是一个旧线程,但是如果有人在寻找答案,SwingUtilities有一个名为invokeAndWait(Runnable)的方法可以在AWT调度线程上与当前线程同步运行任务。请注意,如果您需要在事件分配线程中完成此操作,则无法完成此操作。