001 // License: GPL. For details, see LICENSE file. 002 package org.openstreetmap.josm.gui; 003 004 import static org.openstreetmap.josm.tools.I18n.tr; 005 006 import java.awt.BorderLayout; 007 import java.awt.Color; 008 import java.awt.Image; 009 import java.awt.Insets; 010 import java.awt.event.ActionListener; 011 import java.beans.PropertyChangeEvent; 012 import java.beans.PropertyChangeListener; 013 014 import javax.swing.Action; 015 import javax.swing.BorderFactory; 016 import javax.swing.Icon; 017 import javax.swing.ImageIcon; 018 import javax.swing.JButton; 019 import javax.swing.SwingConstants; 020 import javax.swing.plaf.basic.BasicArrowButton; 021 022 import org.openstreetmap.josm.Main; 023 import org.openstreetmap.josm.tools.Destroyable; 024 import org.openstreetmap.josm.tools.ImageProvider; 025 import org.openstreetmap.josm.tools.Shortcut; 026 027 public class SideButton extends JButton implements Destroyable { 028 private final static int iconHeight = 20; 029 030 private PropertyChangeListener propertyChangeListener; 031 032 public SideButton(Action action) 033 { 034 super(action); 035 fixIcon(action); 036 doStyle(); 037 } 038 039 public SideButton(Action action, boolean usename) 040 { 041 super(action); 042 if(!usename) { 043 setText(null); 044 fixIcon(action); 045 doStyle(); 046 } 047 } 048 049 public SideButton(Action action, String imagename) 050 { 051 super(action); 052 setIcon(makeIcon(imagename)); 053 doStyle(); 054 } 055 056 private void fixIcon(Action action) { 057 // need to listen for changes, so that putValue() that are called after the 058 // SideButton is constructed get the proper icon size 059 if (action != null) { 060 action.addPropertyChangeListener(propertyChangeListener = new PropertyChangeListener() { 061 @Override 062 public void propertyChange(PropertyChangeEvent evt) { 063 if (evt.getPropertyName() == javax.swing.Action.SMALL_ICON) { 064 fixIcon(null); 065 } 066 } 067 }); 068 } 069 Icon i = getIcon(); 070 if (i != null && i instanceof ImageIcon && i.getIconHeight() != iconHeight) { 071 setIcon(getScaledImage(((ImageIcon) i).getImage())); 072 } 073 } 074 075 /** scales the given image proportionally so that the height is "iconHeight" **/ 076 private static ImageIcon getScaledImage(Image im) { 077 int newWidth = im.getWidth(null) * iconHeight / im.getHeight(null); 078 return new ImageIcon(im.getScaledInstance(newWidth, iconHeight, Image.SCALE_SMOOTH)); 079 } 080 081 public static ImageIcon makeIcon(String imagename) { 082 Image im = ImageProvider.get("dialogs", imagename).getImage(); 083 return getScaledImage(im); 084 } 085 086 // Used constructor with Action 087 @Deprecated 088 public SideButton(String imagename, String property, String tooltip, ActionListener actionListener) 089 { 090 super(makeIcon(imagename)); 091 doStyle(); 092 setActionCommand(imagename); 093 addActionListener(actionListener); 094 setToolTipText(tooltip); 095 } 096 097 // Used constructor with Action 098 @Deprecated 099 public SideButton(String name, String imagename, String property, String tooltip, Shortcut shortcut, ActionListener actionListener) 100 { 101 super(tr(name), makeIcon(imagename)); 102 if(shortcut != null) 103 { 104 shortcut.setMnemonic(this); 105 if(tooltip != null) { 106 tooltip = Main.platform.makeTooltip(tooltip, shortcut); 107 } 108 } 109 setup(name, property, tooltip, actionListener); 110 } 111 112 // Used constructor with Action 113 @Deprecated 114 public SideButton(String name, String imagename, String property, String tooltip, ActionListener actionListener) 115 { 116 super(tr(name), makeIcon(imagename)); 117 setup(name, property, tooltip, actionListener); 118 } 119 private void setup(String name, String property, String tooltip, ActionListener actionListener) 120 { 121 doStyle(); 122 setActionCommand(name); 123 addActionListener(actionListener); 124 setToolTipText(tooltip); 125 putClientProperty("help", "Dialog/"+property+"/"+name); 126 } 127 private void doStyle() 128 { 129 setLayout(new BorderLayout()); 130 setIconTextGap(2); 131 setMargin(new Insets(-1,0,-1,0)); 132 } 133 134 public void createArrow(ActionListener listener) { 135 setMargin(new Insets(0,0,0,0)); 136 BasicArrowButton arrowButton = new BasicArrowButton(SwingConstants.SOUTH, null, null, Color.BLACK, null); 137 arrowButton.setBorder(BorderFactory.createEmptyBorder()); 138 add(arrowButton, BorderLayout.EAST); 139 arrowButton.addActionListener(listener); 140 } 141 142 @Override 143 public void destroy() { 144 Action action = getAction(); 145 if (action instanceof Destroyable) { 146 ((Destroyable) action).destroy(); 147 } 148 if (action != null) { 149 if (propertyChangeListener != null) { 150 action.removePropertyChangeListener(propertyChangeListener); 151 } 152 setAction(null); 153 } 154 } 155 }