2015-09-08 3 views
0

Я пишу этот компонент Google Map для Java Swing. Мне нужно использовать только статическую карту Google. Я хочу, чтобы карта обновлялась на основе действия кнопки, которое считывает ввод пользователя, но изображение, которое обернуто в JLabel, просто не обновляется.JLabel.setIcon() не работает по желанию

I кэш статическую карту в mapCache.jpg и установить значок по JLabel mapContent «s к нему каждый раз, когда ActionListener пожаров. Но это просто не работает. mapCache.jpg обновляется в моей системе, но она просто не обновляется в программе. Я попытался удалить imageicon или удалить mapContent из JScrollPane, но ни один из них не работал. Я подозреваю, что 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; 
} 

ответ

2

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); 
    } 
} 
+0

Спасибо! Я не знал, что у изображения есть .flush() ... – Fenwick

+0

@MadProgrammer Когда я делаю flush перед setIcon, моя иконка исчезает вообще. Есть идеи? – called2voyage

+0

@ called2voyage Единственное, что я могу придумать, это то, что значок больше не существует (или все еще перезагружен) – MadProgrammer

2

изображение кэшируется вам необходимо очистить его с помощью:

icon = new ImageIcon(...); 
icon.getImage().flush(); 
label.setIcon(icon); 

Или вы можете просто использовать ImageI/O, чтобы прочитать изображение:

label.setIcon(new ImageIcon(ImageIO.read(new File(imageName))));