我可以批量处理一些Swing组件更新,以便重新绘制所有内容吗?

hey*_*cam 5 java swing

我的JToolBar中有一堆按钮,我根据应用程序的状态将其中一些设置为禁用或启用.我发现当我一次更新一些按钮时,它们并非同时重新绘制.我想确保当我设置一些禁用/启用的按钮时,它们都会同时改变状态.

下面是一个小测试,演示了这个问题.(它需要当前目录中的文件a.png用作按钮图标.)运行时,会显示一个带有10个按钮的工具栏.在终端按Enter键将切换所有按钮的禁用状态.至少在我的机器上,每次执行此操作时,按钮都会以看似随机的顺序重新绘制,而不是一次性完成.

似乎双缓冲可以解决问题,虽然我尝试的第一件事(在JToolBar上设置双缓冲)似乎没有影响任何东西.

谢谢,

卡梅伦

import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.util.*;

public class Test {
    public static void main(String[] args) throws IOException {
        final JButton[] bs = new JButton[10];
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrame f = new JFrame("test");
                JToolBar t = new JToolBar();
                f.getContentPane().add(t);
                for (int i = 0; i < bs.length; i++) {
                    bs[i] = new JButton(new ImageIcon("a.png"));
                    t.add(bs[i]);
                }
                f.pack();
                f.setVisible(true);
            }
        });
        BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
        for (;;) {
            r.readLine();
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    for (JButton b : bs) {
                        b.setEnabled(!b.isEnabled());
                    }
                }
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

iny*_*iny 2

只要启用状态更改发生在一个事件线程运行中,它们就会发生,这样在无效状态之间就不会出现任何情况。所以我想这只是一个绘画问题?只是看起来很糟糕吗?

更改行为的一种可能方法是为容器(例如工具栏)添加重绘调用,以便立即重绘更大的区域,而不是单独重绘每个按钮。