2013-02-08 289 views
2

我需要在JPanel中有一個JMenu(帶有箭頭的那個,它可以顯示JMenuItem)。問題是,當我這樣做時JMenu沒有激活鼠標滾動... 我不知道如何做到這一點,如果這是可能的。將JMenu添加到JPanel

+2

你加'JMenu's到一個'JMenuBar',並且調用'JFrame'的'setJMenuBar()'方法 - 我不認爲你可以將它添加到'JPanel'。並且確保你的'JMenu'充滿了物品! – moonwave99 2013-02-08 11:25:58

+0

嗨,我知道這個解決方案,但它不是我想要的。我真的想要一個JMenu直接進入JPanel ......這是問題所在。 – paranoia25 2013-02-08 12:46:41

+0

然後考慮在JInternalFrames中使用'JDesktopPane',或者定義你自己的'JComponent'。 – moonwave99 2013-02-08 13:08:31

回答

0

你必須傳遞的JPanel佈局BorderLayout那麼您可以在面板中添加菜單欄:

JPanel p = new JPanel(); 
p.setLayout(new BorderLayout()); 
p.add(menubar, BorderLayout.NORTH); 
+0

那麼對JMenu的改變呢?用BorderLayout替換FlowLayout會影響大小和位置,但不會影響行爲。 – 2013-02-08 11:50:24

+0

我試過這個例子,它的工作原理和正常行爲。 – 2013-02-08 11:58:47

+0

是什麼例子? 3行代碼不是一個例子。 – 2013-02-08 12:16:54

3

如果你包裹在JMenuBarJMenu,它按預期工作。

這裏是一個演示的例子:

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JFrame; 
import javax.swing.JMenu; 
import javax.swing.JMenuBar; 
import javax.swing.JMenuItem; 
import javax.swing.JOptionPane; 
import javax.swing.SwingUtilities; 

public class TestMenus { 

    private JMenuBar createMenuBar(String name, int depth) { 
     JMenuBar bar = new JMenuBar(); 
     bar.add(createMenu(name, depth)); 
     return bar; 
    } 

    private JMenu createMenu(String name, int depth) { 
     JMenu menu = new JMenu(name); 
     for (int i = 0; i < 5; i++) { 
      if (depth > 0) { 
       menu.add(createMenu("sub-" + name, depth - 1)); 
      } 
     } 
     for (int i = 0; i < 5; i++) { 
      menu.add(createMenuItem("Menu item " + (i + 1))); 
     } 
     return menu; 
    } 

    private JMenuItem createMenuItem(String name) { 
     final JMenuItem jMenuItem = new JMenuItem(name); 
     jMenuItem.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       JOptionPane.showMessageDialog(jMenuItem, "Successfully pressed a menu item"); 
      } 
     }); 
     return jMenuItem; 
    } 

    protected void initUI() { 
     JFrame frame = new JFrame(TestMenus.class.getSimpleName()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(createMenuBar("Root menu", 3)); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new TestMenus().initUI(); 
      } 
     }); 
    } 

} 

的結果:

Result of menus added to a JFrame content pane

+0

嗨!這不是我想要的樣子。我希望JMenu直接出現在面板中(而不是JMenuBar)。 – paranoia25 2013-02-08 12:44:52

+1

@ paranoia25你的問題不清楚。如果你已經放了一個[SSCCE](http://sscce.org),你會直接得到更好的答案。現在關於你的問題,我不會直接將'JMenu'添加到'JPanel'中,而是使用'ActionListener'來添加'JButton',以打開'JPopupMenu'。爲了讓'JButton'看起來像一個'JMenu',你可能需要做一些定製和訪問L&F的默認值。 – 2013-02-08 12:55:44

+3

+1''JToolBar'可能是'JMenuBar'的一個吸引人的備選'容器',如[這裏](http://stackoverflow.com/a/14630345/230513)所示。 – trashgod 2013-02-08 15:15:25

2

這裏是另一種方式來解決這個問題,我認爲是更接近你想要什麼。它涉及擴展JMenuBar以使它看起來像一個JMenu對象。

該類包含一個名爲menu的對象JMenu。添加方法被覆蓋,所以你要添加到菜單而不是JMenuBar(你可能需要重寫一些更多的添加方法來使這個完美)。

有幾個選擇與繪畫。我不知道你是否想要JMenuBar的按鈕樣式外觀,所以我包含了一些選項的一些評論來定製,以及JMenuBar的下劃線外觀。

這裏是按鈕的結果看,無邊界: UnclickedClicked

這裏是沒有按鈕的外觀和無邊框結果: UnclickedClicked

import java.awt.*; 
import javax.swing.*; 

public class JPanelMenu extends JMenuBar{ 

public static void main(String[] args) { 
    JFrame f = new JFrame("Menu Test"); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    JMenu jmenu = new JMenu("J Menu"); 
    jmenu.add(new JMenuItem("Menu Item")); 

    JPanelMenu m = new JPanelMenu("Menu"); 
    m.add(jmenu); 
    m.add(new JMenuItem("Menu Item 1")); 
    m.add(new JMenuItem("Menu Item 2")); 

    JPanel background = new JPanel(); 
    background.add(m);  
    f.setContentPane(background); 
    f.pack(); 
    f.setVisible(true); 
} 

//This is the JMenu that is shown 
private JMenu menu; 

public JPanelMenu(String title) { 
    super(); 
    menu = new JMenu(title); 
    super.add(menu); 
} 

@Override 
public Component add(Component comp) { 
    //You add the the JMenu instead of the JMenuBar 
    return menu.add(comp); 
} 

@Override 
public JMenu add(JMenu c) { 
    //You add the the JMenu instead of the JMenuBar 
    return (JMenu) menu.add(c); 
} 

@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 

    //Include these two lines to remove the button look 
    //Or remove this method to keep the button look 
    //g.setColor(getBackground()); 
    //g.fillRect(0, 0, getWidth(), getHeight()); 
} 

@Override 
protected void paintBorder(Graphics g) { 
    //Remove this line to remove the underline look 
    //when you remove the button look 
    //An alternative is to you setBorderPainted(false); 
    //when you create the object or in the constructor 
    //Or remove this method to keep the border 
    //super.paintBorder(g); 
} 
} 
+0

嗨!這是更接近的解決方案!但這仍然不是我正在尋找的。我想直接在JPanel中使用JMenu。在您的解決方案中,JMenu仍然位於JMenuBar中,用戶必須通過JMenuBar才能看到並訪問JMenu。 – paranoia25 2013-03-27 07:08:49

+0

@ paranoia25據我所知,沒有辦法做到這一點,因爲你需要一個JMenuBar的工作。這個解決方案仍然使用JMenuBar,但是你可以通過調用Paint方法使其看起來不存在。 – 2013-04-07 02:08:39