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 }