我正在为 Java Swing 编写这个 Google map 组件。我只需要使用谷歌静态 map 。我希望 map 根据读取用户输入的按钮操作进行更新,但包装在 JLabel 中的图像不会更新。
我将静态 map 缓存在 mapCache.jpg 中,并在每次 ActionListener 触发时将 JLabel mapContent 的图标设置为它。但它就是行不通。 mapCache.jpg 在我的系统上更新,但它只是在程序中不更新。我尝试从 JScrollPane 中删除 imageicon 或删除 mapContent,但这些都不起作用。我怀疑 JVM 缓存了图像文件。如果是这样,我该如何清除缓存?
这是我的类内容:
private static final long serialVersionUID = 2243575060653389810L;
private String latlong;
private int zoomLevel;
private JLabel mapContent;
private ImageIcon mapImage;
public MapComponent(float lat, float lon, int zoom){
latlong = validateLatlong(lat,lon);
zoomLevel = validateZoomLevel(zoom);
queryMap();
setLayout(new BorderLayout());
mapImage = new ImageIcon("mapCache.jpg");
mapContent = new JLabel(mapImage);
JScrollPane sp = new JScrollPane(mapContent);
add(sp, BorderLayout.CENTER);
JPanel inputPane = new JPanel();
JLabel latLabel = new JLabel("Latitude: ");
final JTextField latText = new JTextField(""+lat);
JLabel longLabel = new JLabel("Longitude: ");
final JTextField longText = new JTextField(""+lon);
JLabel zoomLabel = new JLabel("Zoom Level: ");
final JTextField zoomText = new JTextField(""+zoomLevel);
zoomText.setPreferredSize(new Dimension(20,15));
JButton mapGo = new JButton("Go");
mapGo.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
try{
queryMap(Float.parseFloat(latText.getText()), Float.parseFloat(longText.getText()), Integer.parseInt(zoomText.getText()));
mapImage.setImage(new ImageIcon("mapCache.jpg").getImage());
mapContent.setIcon(null);
mapContent.setIcon(mapImage); // Doesn't work!
}
catch(Exception ex){
ex.printStackTrace();
}
}
});
inputPane.add(latLabel);
inputPane.add(latText);
inputPane.add(longLabel);
inputPane.add(longText);
inputPane.add(zoomLabel);
inputPane.add(zoomText);
inputPane.add(mapGo);
add(inputPane, BorderLayout.PAGE_END);
setVisible(true);
}
private void queryMap(){
try {
String imageUrl = "http://maps.google.com/staticmap?center="+latlong+"&zoom="+zoomLevel+
"&size=1000x750&maptype=roadmap&markers="+latlong+
"&key=ABQIAAAAgb5KEVTm54vkPcAkU9xOvBR30EG5jFWfUzfYJTWEkWk2p04CHxTGDNV791-cU95kOnweeZ0SsURYSA&format=jpg";
System.out.println(imageUrl);
String destinationFile = "mapCache.jpg";
URL url = new URL(imageUrl);
InputStream is = url.openStream();
OutputStream os = new FileOutputStream(destinationFile);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
is.close();
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void queryMap(float lat, float lon, int zoom){
latlong = validateLatlong(lat,lon);
zoomLevel = validateZoomLevel(zoom);
queryMap();
}
private String validateLatlong(float lat, float lon){
lat = Math.min(lat, 90);
lat = Math.max(lat, -90);
lon = Math.min(lon, 90);
lon = Math.max(lon, -90);
return lat+","+lon;
}
private int validateZoomLevel(int zoom){
zoom = Math.min(zoom, 15);
zoom = Math.max(zoom, 1);
return zoom;
}
最佳答案
ImageIcon
,使用Image
作为其后备源,Image
将其图像数据缓存在内存中。在尝试将图像数据重新应用到标签之前,您需要刷新
图像数据
mapContent.setIcon(null);
mapImage.getImage().flush();
mapContent.setIcon(mapImage); // Doesn't work! - Does now :)
我还建议您查看The try-with-resources Statement并更好地处理您的资源,例如......
try (InputStream is = url.openStream(); OutputStream os = new FileOutputStream(destinationFile)) {
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
}
关于java - JLabel.setIcon() 无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32447629/