我不是Java程序员,我不确定我所做的是否正确,或者是否存在更好的方法来做到这一点。
我正在做一个多线程的swing Java应用。
我有许多swing组件(textfield, texarea, label, list,…),这些组件都是用许多线程设置和刷新的。
对于我的所有组件,我使用下面的代码(这只是一个很小的例子)来设置/刷新它。
Main.mainUI.setThumbLbl(image);
设置/刷新我的组件是一个好方法吗?(我在所有组件的其他线程中使用类似的东西)
还有其他更好的方法吗?
public class Main {
public static MyMainUI mainUI;
public static void main(String args[]) {
mainUI = new mainUI();
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
mainUI.setVisible(true);
}
});
}
}
Jframe:
public class MyMainUI extends JFrame {
private JLabel thumbLbl;
private JButton thumbBtn;
public MyMainUI(){
// add thumbLbl, thumBtn
...
thumBtn.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent evt) {
new MyThread().start();
}
});
}
public void setThumbLbl(final Image image) {
SwingUtilities.invokeLater(new Thread() {
@Override
public void run() {
thumbLbl.setIcon(new ImageIcon(image.getScaledInstance(thumbLblDim.width,
thumbLblDim.height, Image.SCALE_DEFAULT)));
}
});
}
}
线程:public class MyThread extends Thread {
@Override
public void run() {
//Get image from web server
...
Main.mainUI.setThumbLbl(image);
}
}
注:我写了这个示例代码在一个文本编辑器很快,也许有一些错误,但这不是我所要求的^^。
对不起,我的英语不好。
我的意思是这样的一个例子:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutionException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Main {
private static void createAndShowGui() {
JFrame frame = new JFrame("Main");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new MyMainUI());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
@SuppressWarnings("serial")
class MyMainUI extends JPanel {
public static final String IMG_URL_PATH = "http://duke.kenai.com/Oracle/OracleStrat.png";
private static final int PREF_W = 900;
private static final int PREF_H = 650;
private JLabel thumbLbl = new JLabel();
private JButton thumbBtn = new JButton("Get Image");
public MyMainUI() {
thumbBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
thumbBtn.setEnabled(false);
final ImageDownloader imgDownLoader = new ImageDownloader(IMG_URL_PATH);
imgDownLoader.execute();
imgDownLoader.addPropertyChangeListener(new ImgDownLoaderListener(imgDownLoader));
}
});
JPanel btnPanel = new JPanel();
btnPanel.add(thumbBtn);
setLayout(new BorderLayout());
add(new JScrollPane(thumbLbl), BorderLayout.CENTER);
add(btnPanel, BorderLayout.PAGE_END);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private class ImgDownLoaderListener implements PropertyChangeListener {
ImageDownloader imgDownLoader;
public ImgDownLoaderListener(ImageDownloader imgDownLoader) {
this.imgDownLoader = imgDownLoader;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
// swing worker is done
if (evt.getNewValue().equals(SwingWorker.StateValue.DONE)) {
thumbBtn.setEnabled(true);
try {
ImageIcon icon = imgDownLoader.get();
if (icon != null) {
thumbLbl.setIcon(icon);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
}
class ImageDownloader extends SwingWorker<ImageIcon, Void> {
private String imageUrlPath;
public ImageDownloader(String imageUrlPath) {
this.imageUrlPath = imageUrlPath;
}
@Override
protected ImageIcon doInBackground() throws Exception {
try {
URL imgUrl = new URL(imageUrlPath);
BufferedImage img = ImageIO.read(imgUrl);
return new ImageIcon(img); // return the ImageIcon
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null; // or return null if an error occurs
}
}
本例中的后台工作线程不了解GUI的结构。它所做的就是下载一个图像——就是这样,然后用PropertyChangeListener侦听完成的GUI通过调用worker上的get()
来获取图像,并决定它想用它做什么。