JLabel.setIcon() 无法正常工作
JLabel.setIcon() does not work as desired
我正在为 Java Swing 编写此 Google 地图组件。我只需要使用 Google 静态地图。我希望地图根据读取用户输入的按钮操作进行更新,但包装在 JLabel 中的图像不会更新。
我在 mapCache.jpg 中缓存静态地图,并在每次 ActionListener 触发。但它就是行不通。 mapCache.jpg 在我的系统上更新了,但它只是没有在程序中更新。我试图从 JScrollPane 中删除 imageicon 或删除 mapContent,但这些都不起作用。我怀疑 JVM 缓存了图像文件。如果是这样,我该如何清除缓存?
这是我的 class 里面的东西:
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
将其图像数据缓存在内存中。在尝试将图像数据重新应用到标签之前,您需要 flush
图像数据
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);
}
}
图像已缓存,您需要使用以下方法刷新它:
icon = new ImageIcon(...);
icon.getImage().flush();
label.setIcon( icon );
或者您可以只使用 ImageI/O 来读取图像:
label.setIcon( new ImageIcon(ImageIO.read( new File(imageName) ) ) );
我正在为 Java Swing 编写此 Google 地图组件。我只需要使用 Google 静态地图。我希望地图根据读取用户输入的按钮操作进行更新,但包装在 JLabel 中的图像不会更新。
我在 mapCache.jpg 中缓存静态地图,并在每次 ActionListener 触发。但它就是行不通。 mapCache.jpg 在我的系统上更新了,但它只是没有在程序中更新。我试图从 JScrollPane 中删除 imageicon 或删除 mapContent,但这些都不起作用。我怀疑 JVM 缓存了图像文件。如果是这样,我该如何清除缓存?
这是我的 class 里面的东西:
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
将其图像数据缓存在内存中。在尝试将图像数据重新应用到标签之前,您需要 flush
图像数据
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);
}
}
图像已缓存,您需要使用以下方法刷新它:
icon = new ImageIcon(...);
icon.getImage().flush();
label.setIcon( icon );
或者您可以只使用 ImageI/O 来读取图像:
label.setIcon( new ImageIcon(ImageIO.read( new File(imageName) ) ) );