// Copyright (C) 2005 Mammoth Software LLC // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // // Contact the author at: info@mammothsoftware.com package com.mammothsoftware.frwk.ddb; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JPopupMenu; import javax.swing.JToolBar; import javax.swing.border.Border; import javax.swing.border.CompoundBorder; /** * A Drop Down Button. * * @author m. bangham * Copyright 2005 Mammoth Software LLC */ public class DropDownButton extends JButton implements ActionListener { private JPopupMenu popup = new JPopupMenu(); private JToolBar tb = new ToolBar(); private JButton mainButton; private JButton arrowButton; private boolean directActionEnabled = true; private ActionListener directAction = null; public DropDownButton(Icon icon) { this(); mainButton = new RolloverButton(icon, 25, false); arrowButton = new RolloverButton(new DownArrow(), 11, false); init(); } public DropDownButton(Icon icon, int size) { this(); mainButton = new RolloverButton(icon, size, false); arrowButton = new RolloverButton(new DownArrow(), 11, false); init(); } public DropDownButton(RolloverButton mainButton, RolloverButton arrowButton) { this(); this.mainButton = mainButton; this.arrowButton = arrowButton; init(); } private DropDownButton() { super(); setBorder(null); } public void setToolTipText(String text) { mainButton.setToolTipText(text); arrowButton.setToolTipText(text); } public void setEnabled(boolean enabled) { super.setEnabled(enabled); mainButton.setEnabled(enabled); arrowButton.setEnabled(enabled); } public void updateUI() { super.updateUI(); setBorder(null); } protected Border getRolloverBorder() { return BorderFactory.createRaisedBevelBorder(); } private void initRolloverListener() { MouseListener l = new MouseAdapter(){ Border mainBorder = null; Border arrowBorder = null; public void mouseEntered(MouseEvent e) { mainBorder = mainButton.getBorder(); arrowBorder = mainButton.getBorder(); mainButton.setBorder(new CompoundBorder(getRolloverBorder(), mainBorder)); arrowButton.setBorder(new CompoundBorder(getRolloverBorder(), arrowBorder)); mainButton.getModel().setRollover(true); arrowButton.getModel().setRollover(true); } public void mouseExited(MouseEvent e) { mainButton.setBorder(mainBorder); arrowButton.setBorder(arrowBorder); mainButton.getModel().setRollover(false); arrowButton.getModel().setRollover(false); } }; mainButton.addMouseListener(l); arrowButton.addMouseListener(l); } private void init() { initRolloverListener(); Icon disDownArrow = new DisabledDownArrow(); arrowButton.setDisabledIcon(disDownArrow); arrowButton.setMaximumSize(new Dimension(11,100)); mainButton.addActionListener(this); arrowButton.addActionListener(this); setMargin(new Insets(0, 0, 0, 0)); // Windows draws border around buttons, but not toolbar buttons // Using a toolbar keeps the look consistent. tb.setBorder(null); tb.setMargin(new Insets(0, 0, 0, 0)); tb.setFloatable(false); tb.add(mainButton); tb.add(arrowButton); add(tb); setFixedSize(mainButton, arrowButton); } /* * Forces the width of this button to be the sum of the widths of the main * button and the arrow button. The height is the max of the main button or * the arrow button. */ private void setFixedSize(JButton mainButton, JButton arrowButton) { int width = (int)(mainButton.getPreferredSize().getWidth() + arrowButton.getPreferredSize().getWidth()); int height = (int)Math.max(mainButton.getPreferredSize().getHeight(), arrowButton.getPreferredSize().getHeight()); setMaximumSize(new Dimension(width, height)); setMinimumSize(new Dimension(width, height)); setPreferredSize(new Dimension(width, height)); } /** * Removes a component from the popup * @param component */ public void removeComponent(Component component) { popup.remove(component); } /** * Adds a component to the popup * @param component * @return */ public Component addComponent(Component component) { return popup.add(component); } /** * If true, the direct action will be executed * when the left button is clicked. * If false, both the left and the right part of the button * work the same way * @param value set toggle behaviour */ public void setDirectActionEnabled(boolean value) { this.directActionEnabled = value; } public void actionPerformed(ActionEvent ae) { // if the directAction behaviour is enabled, and a directAction is set, and // the source of the event is the left part, if (directActionEnabled && directAction != null && ae.getSource() == mainButton) { ae.setSource(this); directAction.actionPerformed(ae); } else { // otherwise just show the drop-down. JPopupMenu popup = getPopupMenu(); popup.show(this, 0, this.getHeight()); } } public JPopupMenu getPopupMenu() { return popup; } private static class DownArrow implements Icon { Color arrowColor = Color.black; public void paintIcon(Component c, Graphics g, int x, int y) { g.setColor(arrowColor); g.drawLine(x, y, x+4, y); g.drawLine(x+1, y+1, x+3, y+1); g.drawLine(x+2, y+2, x+2, y+2); } public int getIconWidth() { return 6; } public int getIconHeight() { return 4; } } private static class DisabledDownArrow extends DownArrow { public DisabledDownArrow() { arrowColor = new Color(140, 140, 140); } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); g.setColor(Color.white); g.drawLine(x+3, y+2, x+4, y+1); g.drawLine(x+3, y+3, x+5, y+1); } } private static class ToolBar extends JToolBar { public void updateUI() { super.updateUI(); setBorder(null); } } /** * Set the Action that will be executed when the main part of the dropdown button is clicked. * This value is only used if set * @param defaultAction A menuitem, action or other actionListener that will get invoked */ public void setDirectAction(ActionListener defaultAction) { directAction = defaultAction; } @Override /** sets the icon for the left part only */ public void setIcon(Icon icon) { mainButton.setIcon(icon); } }