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}