简体   繁体   中英

JMenuBar with drop-down list for hidden JMenu

Want to create a JMenuBar. If window-JFrame.width to small to show all JMenu of JMenuBar, a Button appears in JMenuBar and all hidden JMenu can chosen in a drop-down list. How can I realize it, please?

I'd look at JToolBar , illustrated here . You can use any required layout and most L&Fs allow the bar to become a floating window.

Use CardLayout to have a panel that contains both the normal menu, and a menu implemented with the button. Then add a ComponentListener ( ComponentAdapter ) to it and select the desired menu implementation in the listener's componentResized() method.

In code it would look roughly like this:

JMenuBar createCustomMenu() {
    final CardLayout layout = new CardLayout();
    final JMenuBar menu = new JMenuBar();
    menu.setLayout(layout);

    // Here you should create the normal, wide menu
    JComponent normalMenu = createNormalMenu();
    // Here you create the compressed, one button version
    JComponent compressedMenu = createCompressedMenu();

    menu.add(normalMenu, "normal");
    menu.add(compressedMenu, "compressed");

    menu.addComponentListener(new ComponentAdapter() {
        public void componentResized(ComponentEvent e) {
            if (menu.getPreferredSize().getWidth() > menu.getWidth()) {
                layout.show(menu, "compressed");
            } else {
                layout.show(menu, "normal");
            }
        }
    });

    return menu;
}

(edit: changed to return JMenuBar , since it seems to work just fine)

Here is some old code I was playing with 5 years ago. Its been so long I don't even remember how well the code works. It was designed for a JToolBar but it may give you some ideas on how to do this with a JMenuBar:

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
/**
*
* @author subanark
*/
public class PopupMenuLayout implements java.awt.LayoutManager
{
    private JPopupMenu popupMenu = new JPopupMenu();
    private JButton popupButton = new JButton(new PopupAction());

    /** Creates a new instance of PopupMenuLayout */
    public PopupMenuLayout()
    {
    }

    /** If the layout manager uses a per-component string,
    * adds the component <code>comp</code> to the layout,
    * associating it
    * with the string specified by <code>name</code>.
    *
    * @param name the string to be associated with the component
    * @param comp the component to be added
    */
    public void addLayoutComponent(String name, Component comp)
    {
    }

    /**
    * Lays out the specified container.
    * @param parent the container to be laid out
    */
    public void layoutContainer(Container parent)
    {
        //  Position all buttons in the container

        Insets insets = parent.getInsets();
        int x = insets.left;
        int y = insets.top;
        System.out.println("bottom: " + insets.bottom);
        int spaceUsed = insets.right + insets.left;

        for (int i = 0; i < parent.getComponentCount(); i++ )
        {
            Component aComponent = parent.getComponent(i);
            aComponent.setSize(aComponent.getPreferredSize());
            aComponent.setLocation(x,y);
            int componentWidth = aComponent.getPreferredSize().width;
            x += componentWidth;
            spaceUsed += componentWidth;
        }

        //  All the buttons won't fit, add extender button
        //  Note: the size of the extender button changes once it is added
        //  to the container. Add it here so correct width is used.

        int parentWidth = parent.getSize().width;

        if (spaceUsed > parentWidth)
        {
            popupMenu.removeAll();
            parent.add(popupButton);
            popupButton.setSize( popupButton.getPreferredSize() );
            int popupX = parentWidth - insets.right - popupButton.getSize().width;
            popupButton.setLocation(popupX, y );
            spaceUsed += popupButton.getSize().width;
        }

        //  Remove buttons that don't fit and add to the popup menu

//      System.out.println(spaceUsed + " ::: " + parentWidth);

        int lastVisibleButtonIndex = 1;

        while (spaceUsed > parentWidth)
        {
            lastVisibleButtonIndex++;
            int last = parent.getComponentCount() - lastVisibleButtonIndex;

            Component component = parent.getComponent( last );
            component.setVisible( false );
            spaceUsed -= component.getSize().width;

            addComponentToPopup(component);

//          popupButton.setLocation( button.getLocation() );
//          System.out.println(spaceUsed + "  :  " + parentWidth);
        }

    }

    private void addComponentToPopup(Component component)
    {
        System.out.println(component.getClass());

        if (component instanceof JButton)
        {
            JButton button = (JButton)component;
            JMenuItem menuItem = new JMenuItem(button.getText());
            menuItem.setIcon( button.getIcon() );

            ActionListener[] listeners = button.getActionListeners();

            for (int i = 0; i < listeners.length; i++)
                menuItem.addActionListener( listeners[i] );

            popupMenu.insert(menuItem, 0);
        }

        if (component instanceof JToolBar.Separator)
        {
            popupMenu.insert( new JSeparator(), 0);
        }
    }

    /**
    * Calculates the minimum size dimensions for the specified
    * container, given the components it contains.
    * @param parent the component to be laid out
    * @see #preferredLayoutSize
    */
    public Dimension minimumLayoutSize(Container parent)
    {
        return popupButton.getMinimumSize();
    }

    /** Calculates the preferred size dimensions for the specified
    * container, given the components it contains.
    * @param parent the container to be laid out
    *
    * @see #minimumLayoutSize
    */
    public Dimension preferredLayoutSize(Container parent)
    {
        //  Move all components to the container and remove the extender button

        parent.remove(popupButton);
/*
        while ( popupMenu.getComponentCount() > 0 )
        {
            Component aComponent = popupMenu.getComponent(0);
            popupMenu.remove(aComponent);
            parent.add(aComponent);
        }
*/
        //  Calculate the width of all components in the container

        Dimension d = new Dimension();
        d.width += parent.getInsets().right + parent.getInsets().left;

        for (int i = 0; i < parent.getComponents().length; i++)
        {
            Component component = parent.getComponent(i);
            component.setVisible( true );
            d.width += component.getPreferredSize().width;
            d.height = Math.max(d.height, component.getPreferredSize().height);
        }

//      d.height += parent.getInsets().top + parent.getInsets().bottom + 5;
        d.height += parent.getInsets().top + parent.getInsets().bottom;
        return d;
    }

    /** Removes the specified component from the layout.
    * @param comp the component to be removed
    */
    public void removeLayoutComponent(Component comp)
    {
    }

    protected class PopupAction extends AbstractAction
    {
        public PopupAction()
        {
            super(">>");
        }

        public void actionPerformed(ActionEvent e)
        {
            JComponent component = (JComponent)e.getSource();
            popupMenu.show(component,0,component.getHeight());
        }
    }

    public static void main(String[] argv)
    {
        ActionListener simpleAction = new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                System.out.println(e.getActionCommand());
            }
        };

        JToolBar toolBar = new JToolBar();
        toolBar.setLayout(new PopupMenuLayout());
        toolBar.add( createButton("one", simpleAction) );
        toolBar.add( createButton("two", simpleAction) );
        toolBar.add( createButton("three", simpleAction) );
        toolBar.add( createButton("four", simpleAction) );
        toolBar.add( createButton("five", simpleAction) );
        toolBar.add( createButton("six", simpleAction) );
        toolBar.addSeparator();
        toolBar.add( createButton("seven", simpleAction) );
        toolBar.add( createButton("eight", simpleAction) );
        toolBar.addSeparator();
        toolBar.add( createButton("nine", simpleAction) );
        toolBar.add( createButton("ten", simpleAction) );

        JFrame f = new JFrame();
        f.getContentPane().setLayout(new BorderLayout());
        f.getContentPane().add(toolBar,BorderLayout.NORTH);
        f.setBounds(300,200,400,300);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }

    private static JButton createButton(String text, ActionListener listener)
    {
        JButton button = new JButton(text);
        button.addActionListener( listener );
        return button;
    }
}

In this case the toolbar button was converted to a JMenu when no space was available. In you case you already have a JMenu, so you should be able to juse move the JMenu from the JMenuBar to the popup menu. However you will need to change the code to always move the menus from the popup menu back to the menu bar before determining the preferred size of the menu bar.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM