非EDT的Java重绘触发很慢

问题描述

我正在非EDT的线程中的JFrame的Swing组件上调用repaint()(与Swing侦听器/适配器/动作映射中的典型repaint调用相反)。从技术上讲,它是在javax.sound.midi Reciever的回调中调用的,但我认为这与一般情况没有什么不同。

该组件更新缓慢。此玩具代码显示一个JLabel,其文本应立即更新为当前时间,然后我们repaint,然后打印以输出当前时间。在我的系统上,标签和标准输出时间 look 正确-标签repaint的发生时间比标准输出早几毫秒。但是,标签视觉上不会更新一段时间,似乎是随机的,甚至是半秒。当它确实更新时,它会显示一个合理的时间,但是它是一个旧的时间。

在鼠标侦听器(或按键侦听器等)的回调中执行[更新显示时间,重绘,打印时间]测试,效果很好,延迟很短。当然,调用repaint仅安排它的发生,但是行为不应该相同,尤其是如果包装在SwingUtilities.invokelater中吗?我是否缺少事件优先级或简单的线程事实?如果没有JLabel,哪些组件需要很长时间才能重新粉刷?总之,如何从非Swing,非EDT线程调用repaint

非工作解决方案:

import javax.sound.midi.*;import javax.swing.*;import java.lang.reflect.InvocationTargetException;
public class Main {
    public static String time() {return (System.currentTimeMillis()/1000)+"."+(System.currentTimeMillis()%1000);}
    public static void main(String[] args) {
        JFrame w = new JFrame();
        JLabel label = new JLabel("hey");
        Transmitter tr = MidiUtil.firstTransmitterExcept("gervill","real time sequencer");//makes a MidiDevice and returns its transmitter
        tr.setReceiver(new Receiver(){public void send(final MidiMessage message,final long t) {
                try {
                    label.setText(time());
                    SwingUtilities.invokeAndWait(()->{label.paintImmediately(0,label.getWidth(),label.getHeight());});
                }catch(final InterruptedException ie) {}catch(final InvocationTargetException ite) {}
                System.out.println(time());
        }public void close() {}});
        w.add(label);
        w.pack();
        w.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
        w.setVisible(true);
    }
}

多谢您阅读。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)