简体   繁体   English

JMenuBar带有隐藏JMenu的下拉列表

[英]JMenuBar with drop-down list for hidden JMenu

Want to create a JMenuBar. 想要创建一个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. 如果window-JFrame.width为small来显示JMenuBar的所有JMenu,则在JMenuBar中会出现一个Button,并且可以在下拉列表中选择所有隐藏的JMenu。 How can I realize it, please? 我怎么能意识到这一点呢?

I'd look at JToolBar , illustrated here . 我会看一下这里所示的JToolBar You can use any required layout and most L&Fs allow the bar to become a floating window. 您可以使用任何所需的布局,大多数L&F允许栏成为浮动窗口。

Use CardLayout to have a panel that contains both the normal menu, and a menu implemented with the button. 使用CardLayout一个包含普通菜单和使用该按钮实现的菜单的面板。 Then add a ComponentListener ( ComponentAdapter ) to it and select the desired menu implementation in the listener's componentResized() method. 然后向其中添加ComponentListenerComponentAdapter )并在侦听器的componentResized()方法中选择所需的菜单实现。

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) (编辑:更改为返回JMenuBar ,因为它似乎工作得很好)

Here is some old code I was playing with 5 years ago. 这是我5年前玩的一些旧代码。 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: 它是为JToolBar设计的,但它可能会为您提供有关如何使用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. 在这种情况下,当没有可用空间时,工具栏按钮被转换为JMenu。 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. 在你的情况下你已经有了一个JMenu,所以你应该可以将JMenu从JMenuBar移动到弹出菜单。 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. 但是,在确定菜单栏的首选大小之前,您需要更改代码以始终将菜单从弹出菜单移回菜单栏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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