package org.trianacode.gui.hci; import javax.swing.*; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; /** * @author Andrew Harrison * @version 1.0.0 Nov 12, 2010 */ public class DropDownButton extends JButton { private boolean mouseInButton = false; private JPopupMenu popup; private PopupMenuListener menuListener; /** * Creates a new instance of MenuToggleButton */ public DropDownButton(Icon icon, JPopupMenu popup) { super(icon); this.popup = popup; addMouseListener(new MouseAdapter() { private boolean popupMenuOperation = false; public void mousePressed(MouseEvent e) { popupMenuOperation = false; JPopupMenu menu = getPopupMenu(); if (menu != null && getModel() instanceof Model) { Model model = (Model) getModel(); if (!model._isPressed()) { model._press(); menu .addPopupMenuListener(getMenuListener()); menu.show(DropDownButton.this, 0, getHeight()); popupMenuOperation = true; } else { model._release(); menu.removePopupMenuListener(getMenuListener()); popupMenuOperation = true; } } } public void mouseReleased(MouseEvent e) { // If we done something with the popup menu, we should consume // the event, otherwise the button's action will be triggered. if (popupMenuOperation) { popupMenuOperation = false; e.consume(); } } public void mouseEntered(MouseEvent e) { mouseInButton = true; } public void mouseExited(MouseEvent e) { mouseInButton = false; } }); setModel(new Model()); } private PopupMenuListener getMenuListener() { if (null == menuListener) { menuListener = new PopupMenuListener() { public void popupMenuWillBecomeVisible(PopupMenuEvent e) { } public void popupMenuWillBecomeInvisible( PopupMenuEvent e) { // If inside the button let the button's mouse listener // deal with the state. The popup menu will be hidden and // we should not show it again. if (!mouseInButton) { if (getModel() instanceof Model) { ((Model) getModel())._release(); } JPopupMenu menu = getPopupMenu(); if (null != menu) { menu.removePopupMenuListener(this); } } } public void popupMenuCanceled(PopupMenuEvent e) { } }; } return menuListener; } JPopupMenu getPopupMenu() { return popup; } private class Model extends DefaultButtonModel { private boolean _pressed = false; public void setPressed(boolean b) { if (_pressed) return; super.setPressed(b); } public void _press() { if ((isPressed()) || !isEnabled()) { return; } stateMask |= PRESSED + ARMED; fireStateChanged(); _pressed = true; } public void _release() { _pressed = false; setArmed(false); setPressed(false); setRollover(false); setSelected(false); } public boolean _isPressed() { return _pressed; } protected void fireStateChanged() { if (_pressed) return; super.fireStateChanged(); } @Override public void setArmed(boolean b) { if (_pressed) return; super.setArmed(b); } @Override public void setEnabled(boolean b) { if (_pressed) return; super.setEnabled(b); } @Override public void setSelected(boolean b) { if (_pressed) return; super.setSelected(b); } @Override public void setRollover(boolean b) { if (_pressed) return; super.setRollover(b); } } }