Package com.sshtools.ui.awt

Source Code of com.sshtools.ui.awt.ActionMenuBar$MenuAction

package com.sshtools.ui.awt;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Panel;
import java.awt.Point;
import java.awt.SystemColor;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.FilteredImageSource;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Enumeration;
import java.util.Vector;

import com.sshtools.ui.awt.tooltips.ToolTipManager;

/**
* A menubar implementation
*
* @author $Autho$
*/
public class ActionMenuBar extends Panel implements FocusListener, ComponentListener, PropertyChangeListener {

    Vector menus = new Vector();
    Window menuWindow;
    MenuCanvas menuCanvas;
    MenuAction currentMenu;
    Frame parentFrame;
    Color disabledForeground = SystemColor.textInactiveText;
    boolean toolTipsEnabled;
    String icons;
    String iconType = ActionButton.SMALL_ICONS;
    int imageTextGap = 4;
    Separator separator;
    Color baseBackground = null;
    Color baseForeground = null;

    public ActionMenuBar() {
        super();
        separator = new Separator(Separator.HORIZONTAL);
        separator.setPreferredSize(new Dimension(0, 5));
        setLayout(new ToolLayout(separator));
        setBackground(SystemColor.control);
        setForeground(SystemColor.controlText);
        //    add(separator);
    }

    public void setImageTextGap(int imageTextGap) {
        invalidate();
        this.imageTextGap = imageTextGap;
        validate();
        repaint();
    }

    public void setIconType(String iconType) {
        invalidate();
        this.iconType = iconType;
        validate();
        repaint();
    }

    public void setToolTipsEnabled(boolean toolTipsEnabled) {
        this.toolTipsEnabled = toolTipsEnabled;
        if (!toolTipsEnabled) {
            ToolTipManager.getInstance().hide();
        }
    }

    public void setDisabledForeground(Color disabledForeground) {
        this.disabledForeground = disabledForeground;
        repaint();
    }

    public void addActionMenu(ActionMenu actionMenu) {
        final MenuAction menuAction = new MenuAction(actionMenu);
        ActionButton button = new ActionButton(menuAction) {
            public boolean isFocusTraversable() {
                return true;
            }

            public boolean isFocusable() {
                return true;
            }

        };
        button.addItemListener(new ItemListener() {

            public void itemStateChanged(ItemEvent e) {
                if (currentMenu != null) {
                    hideMenuWindow();
                    showMenuWindow(menuAction);
                }
            }

        });
        for (Enumeration e = actionMenu.children(); e.hasMoreElements();) {
            Action action = (Action) e.nextElement();
            action.addPropertyChangeListener(this);
        }
        menuAction.setButton(button);
        if(baseForeground != null) {
            button.setBaseForeground(baseForeground);
        }
        if(baseBackground != null) {
            button.setBaseBackground(baseBackground);
        }
        menus.addElement(menuAction);
        button.addFocusListener(this);
        add(button);
    }

    public void remove(int index) {
        synchronized (getTreeLock()) {
            super.remove(index);
            MenuAction menuAction = (MenuAction) menus.elementAt(index);
            menuAction.button.removeFocusListener(this);
            menus.removeElementAt(index);
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#finalize()
     */
    protected void finalize() throws Throwable {
        super.finalize();
        if (menuWindow != null) {
            parentFrame.removeComponentListener(this);
        }
    }

    void showMenuWindow(MenuAction menu) {
        currentMenu = menu;
        if (menuWindow == null) {
            parentFrame = UIUtil.getFrameAncestor(this);
            if (parentFrame == null) {
                parentFrame = UIUtil.getSharedFrame();
            }
            parentFrame.addComponentListener(this);
            menuWindow = new Window(parentFrame);
            menuCanvas = new MenuCanvas();
            if(baseBackground != null) {
                menuCanvas.setBaseBackground(baseBackground);
            }
            if(baseForeground != null) {
                menuCanvas.setBaseForeground(baseForeground);
            }
            menuCanvas.itemHeight = currentMenu.button.getSize().height;
            menuWindow.setLayout(new GridLayout(1, 1));
            menuWindow.add(menuCanvas);
        }
        int x = currentMenu.button.getLocationOnScreen().x;
        int y = currentMenu.button.getLocationOnScreen().y;
        y += currentMenu.button.getSize().height;
        menuWindow.setLocation(x, y);
        Dimension d = menuCanvas.getPreferredSize();
        menuCanvas.setMenu(currentMenu.menu);
        menuWindow.setSize(0, 0);
        menuWindow.pack();
        menuWindow.setVisible(true);
        currentMenu.button.setPressed(true);

    }

    void hideMenuWindow() {
        if (menuWindow != null) {
            menuWindow.setVisible(false);
            if (currentMenu != null) {
                currentMenu.button.setPressed(false);
            }
            currentMenu = null;
        }
    }

    /**
     * @return
     */
    public int getMenuCount() {
        return menus.size();
    }

    class MenuAction extends AbstractAction {

        private ActionMenu menu;
        private ActionButton button;

        MenuAction(ActionMenu menu) {
            super(menu.getDisplayName());
            this.menu = menu;
        }

        /*
         * (non-Javadoc)
         *
         * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
         */
        public void actionPerformed(ActionEvent e) {
            if ((e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) {
                showMenuWindow(this);
            } else {
                hideMenuWindow();
            }
        }

        void setButton(ActionButton button) {
            this.button = button;
        }

    }

    class MenuCanvas extends Canvas implements MouseMotionListener, MouseListener {

        ActionMenu menu;
        int borderWidth = 1;
        Insets insets = new Insets(1, 16, 1, 16);
        Color borderColor = SystemColor.controlShadow;
        int sel = -1;
        Color selectionBackground = SystemColor.controlLtHighlight;
        Color selectionForeground = SystemColor.textText;
        int itemHeight = 16;
        String toolTipText;
        Image backingStore;

        MenuCanvas() {
            addMouseMotionListener(this);
            addMouseListener(this);
            setBackground(SystemColor.control);
            setForeground(SystemColor.controlText);
        }
       
        void setBaseBackground(Color base) {
            if(base == null) {
                selectionBackground = SystemColor.controlHighlight;
                setBackground(SystemColor.control);
            }
            else {
                selectionBackground = base.darker();
                setBackground(base);
            }
        }
       
        void setBaseForeground(Color base) {
            if(base == null) {
                borderColor = SystemColor.controlShadow;
                selectionForeground = SystemColor.controlText;
                setForeground(SystemColor.controlText);
            }
            else {
                borderColor=  base.darker();
                selectionForeground = base.brighter();
                setForeground(base);
            }
        }

        public Dimension getPreferredSize() {
            if (menu == null || getGraphics() == null) {
                return new Dimension(0, 0);
            }
            int w = 0;
            int h = 0;
            int iw = 0;
            FontMetrics fm = getFontMetrics(getFont());
            for (Enumeration e = menu.children(); e.hasMoreElements();) {
                Action action = (Action) e.nextElement();
                if(action.getName().equals(ActionMenu.SEPARATOR.getName())) {
                    h += separator.getPreferredSize().height;
                }
                else {
                  String imagePath = null;
                  if (iconType.equals(ActionButton.SMALL_ICONS)) {
                      imagePath = (String) action.getValue(Action.SMALL_IMAGE_PATH);
                  } else if (iconType.equals(ActionButton.LARGE_ICONS)) {
                      imagePath = (String) action.getValue(Action.IMAGE_PATH);
                  }
                  String n = (String) action.getValue(Action.SHORT_DESCRIPTION);
                  n = n == null ? action.getName() : n;
                  w = Math.max(w, fm.stringWidth(n));
                  itemHeight = Math.max(itemHeight, fm.getHeight());
                  if (imagePath != null) {
                      Image img = UIUtil.loadImage(action.getClass(), imagePath);
                      if (img != null) {
                          UIUtil.waitFor(img, this);
                          iw = Math.max(iw, img.getWidth(this));
                          itemHeight = Math.max(itemHeight, img.getHeight(this));
                      }
                  }
                  h += itemHeight;
                }
            }
            if (iw != 0) {
                w += iw;
                w += imageTextGap;
            }
            if (insets != null) {
                w += insets.left + insets.right;
                h += insets.top + insets.bottom;
            }
            w += borderWidth * 2;
            h += borderWidth * 2;
            return new Dimension(w, h);
        }

        public void update(Graphics g) {
            paint(g);
        }

        public Dimension getMinimumSize() {
            return getPreferredSize();
        }

        public void setMenu(ActionMenu menu) {
            this.menu = menu;
            menuCanvas.sel = -1;
        }

        public void paint(Graphics ig) {
            Dimension s = getSize();
            if (backingStore == null
                            || (backingStore != null && (s.width != backingStore.getWidth(this) || s.height != backingStore
                                            .getHeight(this)))) {
                if (backingStore != null) {
                    backingStore.getGraphics().dispose();
                }
                backingStore = createImage(s.width, s.height);
            }
            Graphics g = backingStore.getGraphics();
            g.setColor(getBackground());
            g.fillRect(0, 0, s.width - 1, s.height - 1);
            int px = 0;
            int py = 0;
            g.setColor(borderColor);
            for (int i = 0; i < borderWidth; i++) {
                g.drawRect(px, py, s.width - px - 1, s.height - py - 1);
                px++;
                py++;
            }
            if (insets != null) {
                px += insets.left;
                py += insets.top;
            }
            if (menu != null) {
                Action m = null;
                FontMetrics fm = getFontMetrics(getFont());
                //                py += fm.getHeight() - fm.getDescent();
                int i = 0;
                for (Enumeration e = menu.children(); e.hasMoreElements();) {
                    m = (Action) e.nextElement();
                    if(m.getName().equals(ActionMenu.SEPARATOR.getName())) {
                        int h = separator.getPreferredSize().height;
                        int sw = s.width - ( insets == null ? 0 : ( ( insets.left + insets.right ) / 2 ) ) - ( borderWidth * 2 );
                        separator.setBounds(0, 0, sw, h);
                        int sx = (s.width - sw ) / 2;
                        g.translate(sx, py);
                        separator.paint(g);
                        g.translate(-sx, -py);
                        py += h;
                    }
                    else {
                      String n = (String) m.getValue(Action.SHORT_DESCRIPTION);
                      n = n == null ? m.getName() : n;
                      if (m.isEnabled()) {
                          if (i == sel) {
                              g.setColor(selectionBackground);
                              int ty = borderWidth + (insets != null ? insets.top : 0) + (py - borderWidth - insets.top );
                              g.fillRect(borderWidth, ty, s.width - (borderWidth * 2), itemHeight);
                              if (borderWidth != 0) {
                                  g.setColor(borderColor);
                                  g.drawLine(borderWidth, ty, (borderWidth * 2) + s.width - 1, ty);
                                  g.drawLine(borderWidth, ty + itemHeight - 1, (borderWidth * 2) + s.width - 1, ty + itemHeight - 1);
                              }
                              g.setColor(selectionForeground);
                          } else {
                              g.setColor(getForeground());
                          }
                      } else {
                          g.setColor(disabledForeground);
                      }
                      String imagePath = null;
                      if (iconType.equals(ActionButton.SMALL_ICONS)) {
                          imagePath = (String) m.getValue(Action.SMALL_IMAGE_PATH);
                      } else if (iconType.equals(ActionButton.LARGE_ICONS)) {
                          imagePath = (String) m.getValue(Action.IMAGE_PATH);
                      }
                      int toff = 0;
                      if (imagePath != null) {
                          Image img = UIUtil.loadImage(m.getClass(), imagePath);
                          if(!m.isEnabled()) {
                              img = createImage(new FilteredImageSource(img.getSource(),
                              new GrayFilter()));
                              UIUtil.waitFor(img, this);
                          }
                         
                          if (img != null) {
                              g.drawImage(img, px, py + ((itemHeight - img.getHeight(this)) / 2), this);
                              toff = imageTextGap + img.getWidth(this);
                          }
                      }
                      g.drawString(n, px + toff, py + fm.getHeight() - fm.getDescent() + ((itemHeight - fm.getHeight()) / 2));
                      py += itemHeight;
                    }
                    i++;
                }
            }
            ig.drawImage(backingStore, 0, 0, this);
        }

        int getIndexForLocation(int x, int ey) {
            int idx = -1;
            if (menu != null && getGraphics() != null) {
                int y = borderWidth;
                if (insets != null) {
                    y += insets.top;
                }
                FontMetrics fm = getFontMetrics(getFont());
                Action m = null;
                for (Enumeration e = menu.children(); e.hasMoreElements();) {
                    idx++;
                    m = (Action) e.nextElement();                  
                    if(!m.getName().equals(ActionMenu.SEPARATOR.getName())) {
                        y+= itemHeight;
                        if(y >= ey) {
                            return idx;
                        }
                    }
                    else {
                        y += separator.getPreferredSize().height;
                    }
                }
            }
            return idx;
        }

        /*
         * (non-Javadoc)
         *
         * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
         */
        public void mouseDragged(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        /*
         * (non-Javadoc)
         *
         * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
         */
        public void mouseMoved(MouseEvent e) {
            sel = getIndexForLocation(e.getX(), e.getY());
            if (sel != -1) {
                Action action = menu.getChild(sel);
                if (action.isEnabled()) {
                    String tip = (String) action.getValue(Action.LONG_DESCRIPTION);
                    if (tip != null) {
                        Point p = getLocationOnScreen();
                        if (toolTipsEnabled) {
                            ToolTipManager.getInstance().requestToolTip(this, p.x + e.getX() + 4, p.y + e.getY() + 4, tip);
                        }
                    }
                } else {
                    sel = -1;
                    if (toolTipsEnabled) {
                        ToolTipManager.getInstance().hide();
                    }
                }
                repaint();
            }
        }

        /*
         * (non-Javadoc)
         *
         * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
         */
        public void mouseClicked(MouseEvent e) {
            if ((e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) {
                int clicked = getIndexForLocation(e.getX(), e.getY());
                if (clicked != -1 && clicked < menu.getChildCount()) {
                    Action action = menu.getChild(clicked);
                    action.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, action.getName(), e.getModifiers()));
                }
            }
            hideMenuWindow();

        }

        /*
         * (non-Javadoc)
         *
         * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
         */
        public void mousePressed(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        /*
         * (non-Javadoc)
         *
         * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
         */
        public void mouseReleased(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        /*
         * (non-Javadoc)
         *
         * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
         */
        public void mouseEntered(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        /*
         * (non-Javadoc)
         *
         * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
         */
        public void mouseExited(MouseEvent e) {
            // TODO Auto-generated method stub

        }
    }

    /*
     * (non-Javadoc)
     *
     * @see java.awt.event.FocusListener#focusGained(java.awt.event.FocusEvent)
     */
    public void focusGained(FocusEvent e) {
    }

    /*
     * (non-Javadoc)
     *
     * @see java.awt.event.FocusListener#focusLost(java.awt.event.FocusEvent)
     */
    public void focusLost(FocusEvent e) {
        hideMenuWindow();
    }

    /**
     * 
     */
    public void removeAllMenuItems() {
        for (Enumeration e = menus.elements(); e.hasMoreElements();) {
            MenuAction act = (MenuAction) e.nextElement();
            for (Enumeration e2 = act.menu.children(); e2.hasMoreElements();) {
                Action a = (Action) e2.nextElement();
                a.removePropertyChangeListener(this);
            }
        }
        hideMenuWindow();
        menus.removeAllElements();
        removeAll();
        doLayout();
    }

    /*
     * (non-Javadoc)
     *
     * @see java.awt.event.ComponentListener#componentResized(java.awt.event.ComponentEvent)
     */
    public void componentResized(ComponentEvent e) {
        hideMenuWindow();
    }

    /*
     * (non-Javadoc)
     *
     * @see java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent)
     */
    public void componentMoved(ComponentEvent e) {
        hideMenuWindow();
    }

    /*
     * (non-Javadoc)
     *
     * @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
     */
    public void componentShown(ComponentEvent e) {
    }

    /*
     * (non-Javadoc)
     *
     * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
     */
    public void componentHidden(ComponentEvent e) {
        hideMenuWindow();
    }

    /*
     * (non-Javadoc)
     *
     * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
     */
    public void propertyChange(PropertyChangeEvent evt) {
        repaint();
    }

    /**
     * @param background
     */
    public void setBaseBackground(Color baseBackground) {
        setBackground(baseBackground == null ? SystemColor.control : baseBackground);
        this.baseBackground = baseBackground;
        for(Enumeration e = menus.elements(); e.hasMoreElements(); ) {
            MenuAction m = (MenuAction)e.nextElement();
            m.button.setBaseBackground(baseBackground);
        }
        if(menuCanvas != null) {
            menuCanvas.setBaseBackground(baseBackground);
        }
    }

    /**
     * @param background
     */
    public void setBaseForeground(Color baseForeground) {
        setForeground(baseForeground == null ? SystemColor.controlText : baseForeground);
        this.baseForeground = baseForeground;
        for(Enumeration e = menus.elements(); e.hasMoreElements(); ) {
            MenuAction m = (MenuAction)e.nextElement();
            m.button.setBaseForeground(baseForeground);
        }
        if(menuCanvas != null) {
            menuCanvas.setBaseForeground(baseForeground);
        }
    }
}
TOP

Related Classes of com.sshtools.ui.awt.ActionMenuBar$MenuAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.