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.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 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", 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(ev1 -> { 057 p.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 058 if (scale.getModel().isSelected()) { 059 ((JLabel) vp.getView()).setIcon(loadScaledImage(imageUrl, Math.max(vp.getWidth(), vp.getHeight()))); 060 } else { 061 ((JLabel) vp.getView()).setIcon(new ImageIcon(imageUrl)); 062 } 063 p.setCursor(Cursor.getDefaultCursor()); 064 }); 065 scale.setSelected(true); 066 JOptionPane pane = new JOptionPane(p, JOptionPane.PLAIN_MESSAGE); 067 if (!GraphicsEnvironment.isHeadless()) { 068 JDialog dlg = pane.createDialog(Main.parent, imageUrl.toString()); 069 dlg.setModal(false); 070 dlg.toFront(); 071 dlg.setVisible(true); 072 } 073 } 074 075 private static Icon loadScaledImage(URL u, int maxSize) { 076 Image img = new ImageIcon(u).getImage(); 077 int w = img.getWidth(null); 078 int h = img.getHeight(null); 079 if (w > h) { 080 h = (int) Math.round(maxSize*((double) h/w)); 081 w = maxSize; 082 } else { 083 w = (int) Math.round(maxSize*((double) w/h)); 084 h = maxSize; 085 } 086 return new ImageIcon(img.getScaledInstance(w, h, Image.SCALE_SMOOTH)); 087 } 088 089 @Override 090 public WayPoint convertToWayPoint() { 091 WayPoint wpt = super.convertToWayPoint(); 092 GpxLink link = new GpxLink(imageUrl.toString()); 093 link.type = "image"; 094 wpt.put(GpxConstants.META_LINKS, Collections.singleton(link)); 095 return wpt; 096 } 097}