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