Java JPanel在第二次加载时不显示图像
我正在创建一个从SQL数据库提取数据的项目。当数据加载时,我希望最终用户看到加载帧。在第一次运行时,它显示带有图像的帧。第二次,当用户更改他看到的区域时,帧再次出现,但这一次直到动作中的函数完成后才显示图像。你能看看我的代码并指出我做错了什么吗Java JPanel在第二次加载时不显示图像,java,image,swing,jframe,Java,Image,Swing,Jframe,我正在创建一个从SQL数据库提取数据的项目。当数据加载时,我希望最终用户看到加载帧。在第一次运行时,它显示带有图像的帧。第二次,当用户更改他看到的区域时,帧再次出现,但这一次直到动作中的函数完成后才显示图像。你能看看我的代码并指出我做错了什么吗 confirm.addActionListener(new ActionListener() { ArrayList<String> newZones = new ArrayList<String>();
confirm.addActionListener(new ActionListener()
{
ArrayList<String> newZones = new ArrayList<String>();
public void actionPerformed(ActionEvent e)
{
JFrame loadingFrame = new JFrame();
JPanel loadingPanel = new JPanel();
loadingFrame.setSize(500, 500);
JLabel loadingL = new JLabel(new ImageIcon("C:/Users/gria/Desktop/Images/Loading.png"));
loadingPanel.add(loadingL);
loadingFrame.add(loadingPanel);
loadingFrame.validate();
loadingFrame.repaint();
loadingFrame.pack();
loadingFrame.setVisible(true);
// The Image will not show until this function finishes which is where all the data base connections take place.
Console.SetZones(newZones);
}
});
confirm.addActionListener(新ActionListener()
{
ArrayList newZones=新的ArrayList();
已执行的公共无效操作(操作事件e)
{
JFrame loadingFrame=新JFrame();
JPanel loadingPanel=新的JPanel();
加载框架。设置尺寸(500500);
JLabel loadingL=新的JLabel(新的图像图标(“C:/Users/gria/Desktop/Images/Loading.png”);
加载面板。添加(加载L);
加载框架。添加(加载面板);
加载frame.validate();
加载frame.repaint();
装入frame.pack();
loadingFrame.setVisible(真);
//在该函数完成之前,图像不会显示,所有数据库连接都在该函数中进行。
控制台。设置区域(新区域);
}
});
卢卡斯·罗特在评论中给出了正确答案。问题似乎出在你身上
(lframeecreated==false)
要确保在执行数据库代码之前加载映像,请调用Console.SetZones(newZones)代码>内部:
在该函数完成之前,图像不会显示,所有数据库连接都在该函数中进行
Swing是单线程的,这意味着调用任何可能需要大量时间的任务都会阻止Swing执行其正常任务(绘制、事件调度等),直到该任务完成。您的代码调用以下命令:
// The Image will not show until this function finishes which is where all the data base connections take place.
Console.SetZones(newZones);
…在ActionListener
实现中,这意味着正在事件调度线程(EDT)上调用它。要避免这种情况,请以新的方式调用此方法或使用。无论采用哪种方式,都要确保使用SwingUtilities.invoke*
或如果使用SwingWorker其方法,从不同线程对Swing的任何调用都被分派到EDT,这可能是因为在第一次之后,它不再执行if(LFrameCreated==false)
中的代码,因此它不会更新映像。2) 发布一个帖子会增加你得到一个好答案的机会。3)你的代码中似乎不必要地过度使用了static。4) 变量和方法名称应该以小写字母开头(编码约定)。2)我实际上要求的代码更少。A应该将代码缩小为一个可编译的示例,其中只包含重现问题所需的行。(请实际阅读我链接到的页面)我没有模拟Console.SetZones(newZones)代码>还没有,但是可以通过EventQueue.invokeLater(…)
调用它。我认为这将确保在继续之前加载映像:因此替换Console.SetZones(newZones)代码>与EventQueue.invokeLater(()->Console.SetZones(newZones))代码>。就是这样。谢谢你的帮助,也谢谢你的建议。如果你把这个作为一个答案,我会给你打上正确的标记。也许最好接受copeg的答案。我忘了提到背景信息,比如EDT和其他选择,比如Thread或SwingWorker。如果您想实现进度条,SwingWorker也很有用。取出进度条,处理框架并重新创建它会导致相同的问题。
// The Image will not show until this function finishes which is where all the data base connections take place.
Console.SetZones(newZones);