/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* This program 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 program 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
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2005, by :
* Corporate:
* EADS Astrium SAS
* EADS CRC
* Individual:
* Claude Cazenave
*
* $Id: MenuBox.java,v 1.4 2008/07/22 15:57:25 ogor Exp $
*
* Changes
* -------
* 25 february 2008 : Initial public release (CC);
*
*/
package simtools.ui;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JToolBar;
import javax.swing.border.Border;
/**
* A MenuBox is an class that gathers a <b>set of actions</b> and <b>a default action</b>.
* MenuBox is composed of
* <ul>
* <li>A default icon whose behavior is attached to the current action
* <li>A drop-down JMenu that displays the list of actions.
* </ul>
* @author zxpletran007
*/
public class MenuBox extends JToolBar {
/** main button, i.e the one displayed close to the arrow button */
protected JButton mainButton;
/** arrow button*/
protected JButton arrowButton;
/** menu displayed when clicking on arrow button */
protected JMenu menu;
/**This icon is always displayed */
protected Icon defaultIcon;
/**
* @param defaultIcon
* @param actions - A list of actions held by drop down JMenu
*/
public MenuBox(Icon defaultIcon, List actions){
super();
this.defaultIcon = defaultIcon;
setFloatable(false);
// main button
mainButton = new JButton(defaultIcon);
mainButton.setMargin(new Insets(1,1,1,1));
// arrow button
arrowButton = new JButton(new SmallDownArrow());
arrowButton.setMaximumSize(new Dimension(11, 32));
arrowButton.setMinimumSize(new Dimension(11, 32));
arrowButton.setPreferredSize(new Dimension(11, 32));
arrowButton.setFocusPainted(false);
arrowButton.addMouseListener(new DropDownListener());
setEnabled(false);
// menu bar
menu = new JMenu();
menu.getPopupMenu().addContainerListener(new MenuContainerListener());
if (actions != null){
for(int i=0;i < actions.size();i++){
JMenuItem mi = new JMenuItem( (Action)actions.get(i));
menu.add(mi);
mi.addActionListener(new MenuItemActionListener());
}
// Set the current action to the first action
setCurrentAction((Action)actions.get(0));
}
JMenuBar bar = new JMenuBar();
bar.setMaximumSize(new Dimension(0, 100));
bar.setMinimumSize(new Dimension(0, 1));
bar.setPreferredSize(new Dimension(0, 1));
bar.add(menu);
add(bar);
add(mainButton);
add(arrowButton);
}
public void setEnabled(boolean enable) {
mainButton.setEnabled(enable);
arrowButton.setEnabled(enable);
}
private class MenuItemActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
setCurrentAction(((JMenuItem)e.getSource()).getAction());
}
}
/**
* This object watches for insertion/deletion of menu items in
* the popup menu, and disables the drop-down button when the
* popup menu becomes empty
* @author zxpletran007
*
*/
private class MenuContainerListener implements ContainerListener {
public void componentAdded(ContainerEvent e) {
setEnabled(true);
}
public void componentRemoved(ContainerEvent e) {
setEnabled(menu.getItemCount() != 0);
}
}
/**
* This object displays menu when clicking on arrow button
* @author zxpletran007
*
*/
private class DropDownListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
updateMenu();
menu.dispatchEvent(e);
}
}
/**
* Do something before displaying drop down JMenu
* Can be overwritten by subclasses.
*
*/
protected void updateMenu(){
}
/** An adapter that wraps a border object, and chops some number of
* pixels off the right hand side of the border.
*/
private class RightChoppedBorder implements Border {
private Border b;
private int w;
public RightChoppedBorder(Border b, int width) {
this.b = b;
this.w = width;
}
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Shape clipping = g.getClip();
g.setClip(x, y, width, height);
b.paintBorder(c, g, x, y, width + w, height);
g.setClip(clipping);
}
public Insets getBorderInsets(Component c) {
Insets i = b.getBorderInsets(c);
return new Insets(i.top, i.left, i.bottom, i.right - w);
}
public boolean isBorderOpaque() {
return b.isBorderOpaque();
}
}
/**
* An icon to draw a small downward-pointing arrow.
* @author zxpletran007
*
*/
private static class SmallDownArrow 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;
}
}
/**
* Set the current action
* @param currentAction
*/
public void setCurrentAction(Action currentAction) {
mainButton.setAction(currentAction);
mainButton.setIcon(defaultIcon);
mainButton.setText("");
}
}