001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.layer.markerlayer; 003 004import java.awt.BorderLayout; 005import java.awt.Cursor; 006import java.awt.Image; 007import java.awt.event.ActionEvent; 008import java.awt.event.ActionListener; 009import java.net.URL; 010import java.util.Collections; 011 012import javax.swing.Icon; 013import javax.swing.ImageIcon; 014import javax.swing.JDialog; 015import javax.swing.JLabel; 016import javax.swing.JOptionPane; 017import javax.swing.JPanel; 018import javax.swing.JScrollPane; 019import javax.swing.JToggleButton; 020import javax.swing.JViewport; 021 022import org.openstreetmap.josm.Main; 023import org.openstreetmap.josm.data.coor.LatLon; 024import org.openstreetmap.josm.data.gpx.GpxConstants; 025import org.openstreetmap.josm.data.gpx.GpxLink; 026import org.openstreetmap.josm.data.gpx.WayPoint; 027import org.openstreetmap.josm.tools.ImageProvider; 028 029/** 030 * Marker representing an image. Uses a special icon, and when clicked, 031 * displays an image view dialog. Re-uses some code from GeoImageLayer. 032 * 033 * @author Frederik Ramm <frederik@remote.org> 034 * 035 */ 036public class ImageMarker extends ButtonMarker { 037 038 public URL imageUrl; 039 040 public ImageMarker(LatLon ll, URL imageUrl, MarkerLayer parentLayer, double time, double offset) { 041 super(ll, "photo.png", parentLayer, time, offset); 042 this.imageUrl = imageUrl; 043 } 044 045 @Override public void actionPerformed(ActionEvent ev) { 046 final JPanel p = new JPanel(new BorderLayout()); 047 final JScrollPane scroll = new JScrollPane(new JLabel(loadScaledImage(imageUrl, 580))); 048 final JViewport vp = scroll.getViewport(); 049 p.add(scroll, BorderLayout.CENTER); 050 051 final JToggleButton scale = new JToggleButton(ImageProvider.get("misc", "rectangle")); 052 053 JPanel p2 = new JPanel(); 054 p2.add(scale); 055 p.add(p2, BorderLayout.SOUTH); 056 scale.addActionListener(new ActionListener(){ 057 @Override 058 public void actionPerformed(ActionEvent ev) { 059 p.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 060 if (scale.getModel().isSelected()) { 061 ((JLabel)vp.getView()).setIcon(loadScaledImage(imageUrl, Math.max(vp.getWidth(), vp.getHeight()))); 062 } else { 063 ((JLabel)vp.getView()).setIcon(new ImageIcon(imageUrl)); 064 } 065 p.setCursor(Cursor.getDefaultCursor()); 066 } 067 }); 068 scale.setSelected(true); 069 JOptionPane pane = new JOptionPane(p, JOptionPane.PLAIN_MESSAGE); 070 JDialog dlg = pane.createDialog(Main.parent, imageUrl.toString()); 071 dlg.setModal(false); 072 dlg.toFront(); 073 dlg.setVisible(true); 074 } 075 076 private static Icon loadScaledImage(URL u, int maxSize) { 077 Image img = new ImageIcon(u).getImage(); 078 int w = img.getWidth(null); 079 int h = img.getHeight(null); 080 if (w>h) { 081 h = Math.round(maxSize*((float)h/w)); 082 w = maxSize; 083 } else { 084 w = Math.round(maxSize*((float)w/h)); 085 h = maxSize; 086 } 087 return new ImageIcon(img.getScaledInstance(w, h, Image.SCALE_SMOOTH)); 088 } 089 090 @Override 091 public WayPoint convertToWayPoint() { 092 WayPoint wpt = super.convertToWayPoint(); 093 GpxLink link = new GpxLink(imageUrl.toString()); 094 link.type = "image"; 095 wpt.attr.put(GpxConstants.META_LINKS, Collections.singleton(link)); 096 return wpt; 097 } 098 099}