2013-07-23 84 views
1

想要創建一個JMenuBar。如果window-JFrame.width小到顯示JMenuBar的所有JMenu,則Button會出現在JMenuBar中,並且所有隱藏的JMenu都可以在下拉列表中選擇。我怎麼能意識到這一點?JMenuBar帶隱藏JMenu的下拉列表

回答

1

使用CardLayout有一個包含正常菜單和使用按鈕實現的菜單的面板。然後向它添加一個ComponentListenerComponentAdapter),並在偵聽器的componentResized()方法中選擇所需的菜單實現。

在代碼中它看起來大致是這樣的:

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; 
} 

(編輯:更改爲返回JMenuBar,因爲它似乎只是正常工作)

2

我想看看JToolBar,說明here。您可以使用任何所需的佈局,並且大多數L允許條形成浮動窗口。

1

這是我5年前玩過的一些舊代碼。它已經很長時間了,我甚至都不記得代碼是如何工作的。它被設計爲一個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; 
    } 
} 

在這種情況下,工具欄按鈕被轉換爲JMenu的時候沒有空間可用。在你的情況下,你已經有了一個JMenu,所以你應該能夠將JMenu從JMenuBar移動到彈出菜單。但是,在確定菜單欄的首選大小之前,您需要更改代碼以始終將菜單從彈出菜單移回菜單欄。