我正在使用java。 我有一个点击事件,它在循环中将“正方形”添加到容器中。我希望每个方 block 在添加时都能正确显示。我尝试在单独的线程中运行“添加正方形”,但它不起作用。
这是我用于“公共(public)类 GuiController 实现 ActionListener、MouseListener”的一些代码:
@Override
public void mouseClicked(MouseEvent e)
{
//createBoardPane();
new Thread
(
new Runnable()
{
public void run()
{
showAnimation();
}
}
).start();
}
public void showAnimation()
{
for(int i = 0; i < model.getAnimationList().size(); i++)
{
String coord = model.getAnimationList().get(i);
int x = Integer.parseInt(coord.substring(0, coord.indexOf(',')));
int y = Integer.parseInt(coord.substring(coord.indexOf(',') + 1, coord.length() - 2));
boolean shouldPlacePiece = (coord.charAt(coord.length() - 1) == 'p');
if(shouldPlacePiece)
{
model.getView().getBoardPane().getComponent(x + (y * model.getBoardSize())).setBackground(Color.BLACK);
}
else
{
model.getView().getBoardPane().getComponent(x + (y * model.getBoardSize())).setBackground(Color.WHITE);
}
model.getView().getBoardPane().repaint();
long time = System.currentTimeMillis();
while((System.currentTimeMillis() - time) < 250)
{
// wait loop
}
}
}
感谢任何帮助!
最佳答案
创建一个单独的 Thread
来运行这个长时间运行的任务是一个绝妙的主意 - 除非您想在制作动画时锁定与 GUI 的交互。
现在,Swing GUI 对象不是线程安全的(除了少数异常(exception)),因此您不能从 Swing 的事件调度循环线程以外的线程使用它们。因此,在你的 for 循环中获取所有 GUI 更新代码,并用一个新的 Runnable(是的,另一个)包装它。
然后在循环的每次迭代中使用该 Runnable
调用 SwingUtilities.invokeLater(Runnable doRun)
。
然后您的 GUI 更新代码将被安排在事件调度循环上尽快运行,这将在您的工作线程进入休眠状态时发生(您是否有任何反对 Thread.sleep
的事情?)。
备选方案:使用 SwingWorker
代替 Thread
SwingWorker will create and manage a new the Thread为您发布数据,它 (SwingWorker) 将导致在事件调度循环的线程上运行。您将使用您的代码覆盖 doInBackground
。使用参数调用 publish
以推送到事件调度线程。使用代码覆盖 process
以处理这些参数并更新您的 GUI。
SwingWorker 的一个陷阱是它会在大约 33 毫秒的时间段内累积发布
ed 事件。如果您的发布频率高于此频率,您可能每 33 毫秒左右将所有事件聚集在一起。在您的情况下,更新之间的 250 毫秒应该不是问题。
关于java - 当组件添加到 JAVA 的单独线程中时,如何立即重绘容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11728953/