我的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());
}
}
});
}
}
}
答案 0 :(得分:2)
只要在一个事件线程运行中发生启用状态更改,就会发生这种情况,以便在无效状态之间无法进行任何操作。所以我想这只是一个绘画问题?它看起来很糟糕?
更改行为的一种可能方法是为容器添加重绘调用(例如工具栏),以便一次重新绘制更大的区域,而不是单独重新绘制每个按钮。
答案 1 :(得分:1)
在XP上使用JDK6可以正常使用。
我发现您的代码没有任何问题。我一次启用/禁用了多个组件而没有问题。
问题是因为您接受来自终端的输入?尝试在框架上添加一个单独的按钮,这样点击它就会导致按钮的状态发生变化。
答案 2 :(得分:0)
@camickr我在Windows 7上使用JDK6。我使用EventQueue.invokeLater()启动了更改,因为在我的应用程序中,导致工具栏按钮需要更新状态的原因发生在另一个线程中,所以我使用EventQueue。 invokeLater()那里。我尝试从EDT做所有事情(即,从其中一个按钮上的ActionListener执行setEnabled()调用)但我仍然有同样奇怪的重新绘制。
@iny对,它看起来很糟糕。我确实认为,因为所有的状态变化都发生在一个EventQueue Runnable中,所有的绘画都会在它结束后立刻发生,但我猜不是。你在JToolBar上调用repaint()的建议确实合并了按钮的所有绘画,谢谢! (一旦我的未注册帐户(我似乎无法回复)和我最近注册的帐户合并,我将接受您的回答。)