package com.explodingpixels.widgets;
import com.explodingpixels.painter.Painter;
import com.explodingpixels.swingx.EPToggleButton;
import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.event.*;
public class PopdownButton {
private final EPToggleButton fButton;
private PopupMenuCustomizer fPopupMenuCustomizer;
private JPopupMenu fPopupMenu = new JPopupMenu();
public PopdownButton(Icon icon, PopupMenuCustomizer popupMenuCustomizer) {
if (popupMenuCustomizer == null) {
throw new IllegalArgumentException("The list of items to add to" +
"the popup menu cannot be null.");
}
fButton = new EPToggleButton(icon);
fButton.setPressedIcon(icon);
fPopupMenuCustomizer = popupMenuCustomizer;
init();
}
private void init() {
fButton.addMouseListener(createToggleButtonMouseListener());
fButton.addMouseMotionListener(createToggleButtonMouseMotionListener());
fPopupMenu.addPopupMenuListener(createPopupMenuListener());
// this is a trick to get hold of the client property which prevents
// closing of the popup when the button is pressed.
JComboBox box = new JComboBox();
Object preventHide = box.getClientProperty("doNotCancelPopup");
fButton.putClientProperty("doNotCancelPopup", preventHide);
}
public void setBackgroundPainter(Painter<AbstractButton> painter) {
fButton.setBackgroundPainter(painter);
}
public JComponent getComponent() {
return fButton;
}
public void setPressedIcon(Icon pressedIcon) {
fButton.setPressedIcon(pressedIcon);
}
private void showPopupMenu() {
fPopupMenu.pack();
fPopupMenu.show(fButton, 0, fButton.getHeight());
}
private void hidePopupMenu() {
fPopupMenu.setVisible(false);
fButton.setSelected(false);
}
private MouseListener createToggleButtonMouseListener() {
return new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
// if the button is not in the selected state, then hide the
// popup menu. note that showing the popup menu is always
// handled by the mousePressed method.
if (!fButton.isSelected()) {
hidePopupMenu();
}
}
@Override
public void mousePressed(MouseEvent e) {
// allways show the menu on a mouse pressed. the mouse clicked
// event will take care of dismissing the popup menu if the
// button has gone into an unselected state.
showPopupMenu();
}
@Override
public void mouseReleased(MouseEvent e) {
MenuSelectionManager manager = MenuSelectionManager.defaultManager();
manager.processMouseEvent(e);
}
};
}
private MouseMotionListener createToggleButtonMouseMotionListener() {
return new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
MenuSelectionManager.defaultManager().processMouseEvent(e);
}
};
}
private PopupMenuListener createPopupMenuListener() {
return new PopupMenuListener() {
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
fPopupMenuCustomizer.customizePopup(fPopupMenu);
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
// make sure the button accuratley reflects the visibility of
// the popup menu.
fButton.setSelected(false);
}
public void popupMenuCanceled(PopupMenuEvent e) {
// no implementation.
}
};
}
}