[英]How to synchronize ImageIcon in ImageLoader
我最近开始在 Java 中使用多线程,但遇到了一个问题,我认为是由于缺少同步。
这是我写的 ImageLoader:
package util;
import javax.swing.ImageIcon;
public class ImageLoader extends Thread {
private String file;
private ImageIcon icon;
public ImageLoader(String file) {
this.file = file;
}
@Override
public void run() {
ImageIcon icon = new ImageIcon(this.file);
this.icon = icon;
super.run();
}
public synchronized ImageIcon returnIcon() {
return this.icon;
}
}
我在我的 GUI 类中使用这个 ImageLoader:
package gui;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import util.ImageLoader;
public class HauptGui extends JComponent {
public HauptGui() {
initUI();
}
private void initUI() {
int bilderAnzahl = 3;
this.setLayout(new GridLayout(1, 1));
JPanel bilderPanel = new JPanel(new GridLayout(bilderAnzahl, 1));
for (int i = 0; i < bilderAnzahl; i++) {
JLabel jbl = new JLabel();
ImageLoader loader = new ImageLoader("./Picture.jpg");
loader.start();
jbl.setIcon(loader.returnIcon());
jbl.setBorder(BorderFactory.createEtchedBorder());
jbl.setPreferredSize(new Dimension(200, 50));
bilderPanel.add(jbl);
}
JScrollPane scrPn = new JScrollPane(bilderPanel);
this.add(scrPn);
}
}
问题是在线程调用 run-Method 之前调用了 ImageLoader 的 returnIcon-Method,因此 ImageIcon 仍然为 null。
我如何同步这个?
不,您的问题与同步无关,而与在创建图像对象之前简单地请求图像对象有关。 解决方案是在完成加载后在回调中获取图像对象。 在这种情况下,SwingWorker 可以很好地工作,在这种情况下,您可以通过调用.get()
从工作人员的 done 方法中的 SwingWorker 获取图像对象,或者您可以使用 PropertyChangeListener 进行回调。 有关如何使用 SwingWorkers 的详细信息,请参见课程:Swing中的并发。
例如(代码未测试)
public class ImageLoader2 extends SwingWorker<BufferedImage, Void> {
private String path = ""; /// String to resource path
public BufferedImage doInBackground() throws Exception {
return ImageIO.read(ImageLoader2.class.getResource(path));
}
}
然后像这样运行它:
ImageLoader2 loader = new ImageLoader2();
loader.addPropertyChangeListener(pce -> {
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
try {
BufferedImage img = loader.get();
ImageIcon icon = new ImageIcon(img);
// use icon here...
} catch catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
// handle exception here
}
}
});
loader.execute();
旁注
ImageIO.read(...)
来执行此操作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.