0

如果我使用 使用单独的线程从 Java 中充斥 Swing 事件队列SwingUtilities.invokeLater(..),则事件调度线程无法跟上步伐,事件队列填满并且应用程序运行缓慢。

例如......在下面的例子中,我只能看到屏幕上显示的几个整数(mac os-x yosemite,java 8 update 25):

import javax.swing.*;
import java.awt.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.IntStream;

public class SwingForcePaintingQuestion {

    public static void main(String[] args) throws InterruptedException {
        final AtomicReference<JLabel> labelRef = new AtomicReference<>();

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Frame42");
                frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                frame.setPreferredSize(new Dimension(600, 400));
                frame.getContentPane().setLayout(new BorderLayout());
                JLabel label = new JLabel("Hello");
                label.setHorizontalAlignment(SwingConstants.CENTER);
                frame.add(label, BorderLayout.CENTER);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                labelRef.set(label);
            }
        });

        while (labelRef.get() == null) {
            Thread.sleep(1);
        }

        Thread.sleep(1000);

        System.out.println("Starting filling the EventQueue");

        int start = 1;
        int endExclusive = 10000000;
        IntStream.range(start, endExclusive).forEach(value ->
                        SwingUtilities.invokeLater(() -> {
                            labelRef.get().setText(value + "");
                        })
        );

        SwingUtilities.invokeLater(() -> labelRef.get().setText("Done. Did you see all values between " + start + " and " + endExclusive + "?"));
    }
}

有没有办法“放慢速度”,这样我才能真正看到 GUI 中的每一个变化?调用标签repaint后在某处调用某种方法?setText(..)

疯狂的闪烁是完全可以的,因为我希望我的眼睛比像素可以改变的“慢”。目前这个例子表现得“奇怪”,最后我看到一个特定的数字,比如让我们说 1070201 一整秒,然后我看到 1531452 一整秒。

当然,我可以使用SwingUtilities.invokeAndWait(..)而不是为SwingUtilities.invokeLater(..)“生产”主线程建立背压,以防止“填满”事件队列。难道没有别的办法了吗?

4

0 回答 0