gpt4 book ai didi

java - GUI线程更新问题

转载 作者:行者123 更新时间:2023-11-29 07:08:42 25 4
gpt4 key购买 nike

我有一个 GUI 类 Gui:

public class Gui extends JFrame implements Runnable
{

private JPanel outer, inner;
private JLabel[][] labels = new JLabel[22][12];
private Color[][] defaultMap, map;
Thread t;
private int row, col;
private Color color;

public Gui()
{
Container content = getContentPane();
content.setLayout(new BorderLayout());

setBackground(Color.BLACK);
setSize(1000, 1000);
setLocation(300, 0);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);

defaultMap = createMap();
draw(defaultMap);
}

public Color[][] createMap()
{
Color[][] map = new Color[22][12];
for (int i = 0; i < 22; i++)
{
for (int j = 0; j < 12; j++)
{
map[i][j] = Color.WHITE;
}
}
for (int i = 0; i < 22; i++)
{
map[i][0] = Color.GRAY;
map[i][11] = Color.GRAY;
}
for (int i = 0; i < 12; i++)
{
map[0][i] = Color.GRAY;
map[21][i] = Color.GRAY;
}
return map;
}

public void draw(Color[][] map)
{

outer = new JPanel();
outer.setLayout(new BorderLayout());
outer.setBackground(Color.WHITE);
outer.setPreferredSize(new Dimension());

inner = new JPanel();
inner.setLayout(new GridLayout(22, 12, 2, 2));
inner.setBackground(Color.BLACK);

for (int i = 0; i < 22; i++)
{
for (int j = 0; j < 12; j++)
{
labels[i][j] = new JLabel();
JLabel label = labels[i][j];
label.setPreferredSize(new Dimension(20, 20));
label.setBackground(map[i][j]);
label.setOpaque(true);
inner.add(label);
}
}

add(outer);
add(inner);
pack();
}

public void move(int row, int col, Color color)
{
System.out.println(row+","+col);
map = defaultMap;
map[row][col] = color;
t = new Thread(this);
t.start();
}

@Override
public void run()
{
draw(map);
}
}

这是从我的主类中调用的:

public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
try
{
gui = new Gui();
gui.setVisible(true);
gui.move(2,5,Color.GREEN);
Thread.sleep(1000);
gui.move(3,5,Color.GREEN);
Thread.sleep(1000);
gui.move(4,5,Color.GREEN);
} catch (InterruptedException ex)
{
Logger.getLogger(Tetris.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}

所以当 gui.move() 函数被调用时,奇怪的事情发生了。如果有帮助,您可以忽略其余部分或使用它。但每次都应该在 2,5 的 gui 中“添加”一个绿色 block ; 3,5;和 4,5;相隔 1 秒。

问题:

Gui 保持黑色一段时间,然后立即使用适当的网格和颜色重新绘制/更新,前两个 block 正确着色为绿色,但它在 4,5 处缺少最后一个 block 。同样,最初的“defaultMap”应该立即绘制,但事实并非如此,JFrame 是黑色的,直到所有内容都立即绘制在一起减去最后一个绿色 block 。然后每个绿色 block 应该在 1 秒后另一个上绘制。

有趣的是,Gui 中 move 方法中的 System.out.println() 位打印出行和列,正如我所期望的那样......它们在终端。所以这告诉我事情进展顺利。但是我不确定 Gui 是怎么回事...

编辑:故事略有不同。仔细检查后,我注意到最后一个绿色 block 确实在整个 map 被绘制后出现了一秒钟,但立即“消失”并重新绘制成白色。

最佳答案

您正在 EDT(事件调度线程)上 hibernate 。你永远不应该阻止 EDT。

  • 切勿在 EDT 上调用 sleepwait
  • 将所有长时间运行的任务移至其他线程(使用 ExecutorsSwingWorker)
  • 对于 UI 的重复或延迟更新,您可以使用 javax.swing.Timer
  • 所有 UI 操作都应在 EDT 上执行(使用 SwingUtilities.invokeLaterjavax.swing.TimerSwingWorker

swing tag wiki 中阅读有关 Swing 并发的更多信息.

关于java - GUI线程更新问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16567318/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com