001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.widgets;
003
004import java.awt.Color;
005import java.awt.Dimension;
006import java.awt.Graphics;
007import java.awt.Graphics2D;
008import java.awt.event.ActionEvent;
009import java.awt.event.ActionListener;
010import java.awt.geom.Path2D;
011
012import javax.swing.Action;
013import javax.swing.Icon;
014import javax.swing.JButton;
015import javax.swing.JPopupMenu;
016
017/**
018 * Button triggering the appearance of a JPopupMenu when activated.
019 * @since 12955
020 */
021public class PopupMenuButton extends JButton implements ActionListener {
022    private JPopupMenu menu;
023
024    /**
025     * Constructs a new {@code PopupMenuButton}.
026     * @see JButton#JButton()
027     */
028    public PopupMenuButton() {
029        super();
030        this.initialize();
031    }
032
033    /**
034     * Constructs a new {@code PopupMenuButton}.
035     * @param a the <code>Action</code> used to specify the new button
036     * @see JButton#JButton(Action)
037     */
038    public PopupMenuButton(Action a) {
039        super(a);
040        this.initialize();
041    }
042
043    /**
044     * Constructs a new {@code PopupMenuButton}.
045     * @param i the Icon image to display on the button
046     * @see JButton#JButton(Icon)
047     */
048    public PopupMenuButton(Icon i) {
049        super(i);
050        this.initialize();
051    }
052
053    /**
054     * Constructs a new {@code PopupMenuButton}.
055     * @param t the text of the button
056     * @see JButton#JButton(String)
057     */
058    public PopupMenuButton(String t) {
059        super(t);
060        this.initialize();
061    }
062
063    /**
064     * Constructs a new {@code PopupMenuButton}.
065     * @param t the text of the button
066     * @param i the Icon image to display on the button
067     * @see JButton#JButton(String, Icon)
068     */
069    public PopupMenuButton(String t, Icon i) {
070        super(t, i);
071        this.initialize();
072    }
073
074    /**
075     * Pass-through to {@link JButton#JButton()} allowing associated popup menu to be set
076     * @param m the associated popup menu
077     */
078    public PopupMenuButton(JPopupMenu m) {
079        super();
080        this.initialize(m);
081    }
082
083    /**
084     * Pass-through to {@link JButton#JButton(Action)} allowing associated popup menu to be set
085     * @param a the <code>Action</code> used to specify the new button
086     * @param m the associated popup menu
087     */
088    public PopupMenuButton(Action a, JPopupMenu m) {
089        super(a);
090        this.initialize(m);
091    }
092
093    /**
094     * Pass-through to {@link JButton#JButton(Icon)} allowing associated popup menu to be set
095     * @param i the Icon image to display on the button
096     * @param m the associated popup menu
097     */
098    public PopupMenuButton(Icon i, JPopupMenu m) {
099        super(i);
100        this.initialize(m);
101    }
102
103    /**
104     * Pass-through to {@link JButton#JButton(String)} allowing associated popup menu to be set
105     * @param t the text of the button
106     * @param m the associated popup menu
107     */
108    public PopupMenuButton(String t, JPopupMenu m) {
109        super(t);
110        this.initialize(m);
111    }
112
113    /**
114     * Pass-through to {@link JButton#JButton(String, Icon)} allowing associated popup menu to be set
115     * @param t the text of the button
116     * @param i the Icon image to display on the button
117     * @param m the associated popup menu
118     */
119    public PopupMenuButton(String t, Icon i, JPopupMenu m) {
120        super(t, i);
121        this.initialize(m);
122    }
123
124    private void initialize(JPopupMenu m) {
125        this.menu = m;
126        this.initialize();
127    }
128
129    private void initialize() {
130        this.addActionListener(this);
131    }
132
133    /**
134     * Get the popup menu associated with this button
135     * @return the popup menu associated with this button
136     */
137    public JPopupMenu getPopupMenu() {
138        return this.menu;
139    }
140
141    /**
142     * Set the popup menu associated with this button
143     * @param m Menu to show when button is triggered
144     */
145    public void setPopupMenu(JPopupMenu m) {
146        this.menu = m;
147    }
148
149    @Override
150    public void actionPerformed(ActionEvent e) {
151        this.menu.show(this, 0, this.getHeight());
152    }
153
154    @Override
155    public void paint(Graphics g) {
156        super.paint(g);
157        Graphics2D g2d = (Graphics2D) g;
158
159        //
160        // paint small arrow in bottom right corner
161        //
162        Dimension size = this.getSize();
163
164        Path2D p = new Path2D.Float();
165        p.moveTo(size.getWidth() - 7, size.getHeight() - 4);
166        p.lineTo(size.getWidth() - 1, size.getHeight() - 4);
167        p.lineTo(size.getWidth() - 4, size.getHeight() - 1);
168        p.closePath();
169
170        g2d.setPaint(Color.BLACK);
171        g2d.fill(p);
172    }
173}