2012-04-02 64 views
2

我有一個新的UI我正在使用Java實現,並且在實現包含JMenu(以及幾個JMenuItems)的JPopupMenu時遇到問題,它本身包含幾個JMenuItems。 JPopupMenu出現在我點擊人民幣的地方,看起來不錯,但是儘管我盡了最大的努力去追加()他們,但當鼠標懸停時,「連接」JMenu似乎沒有任何孩子。
enter image description here無法將JMenuItem添加到JPopupMenu中的JMenu

查看了幾個在線的例子,我還沒有看到任何具體實現mouseEntered()的監聽器來推出子項。我想到我在菜單初始化方法中弄亂了一些東西。

我附上了相關的代碼,供您細讀。

//Elsewhere... 
private JPopupMenu _clickMenu; 
//End Elsehwere... 

private void initializeMenu() 
{ 
    _clickMenu = new JPopupMenu(); 
    _clickMenu.setVisible(false); 

    _clickMenu.add(generateConnectionMenu()); 

    JMenuItem menuItem; 
    menuItem = new JMenuItem("Configure"); 
    addMenuItemListeners(menuItem); 
    _clickMenu.add(menuItem); 

    menuItem = new JMenuItem("Status"); 
    addMenuItemListeners(menuItem); 
    _clickMenu.add(menuItem); 
} 

private JMenu generateConnectionMenu() 
{ 
    JMenu menu = new JMenu("Connect"); 

    List<Port> portList = _database.getAllPortsInCard(_cardId); 

    for(int i = 0; i < portList.size(); i++) 
    { 
     menu.add(new JMenuItem(portList.get(i).getName())); 
    } 

    return menu; 
} 

的代碼肯定不是最漂亮的,但去容易對我,它已經改變了今天太多次允許的,而我試圖找出爲什麼這是不工作的時間。我想這可能是一個範圍問題,但我已經嘗試了一些不同的代碼配置無濟於事。隨意詢問任何後續問題,或者讓我明顯失察(這是在......之前發生的)。謝謝大家!

編輯: 粉筆這一個缺乏與Java經驗和Swing ...我手動定位,並使得JPopupMenu可見,而不是使用JComponent.setComponentPopupMenu(menu)方法。在完成上述圖像(本身爲JButton)中的卡模塊之後,子菜單正確顯示。下面包含了初始化代碼的一個不同的功能版本。

private void initializeMenu() 
{ 
    _cardMenu = new JPopupMenu(); 

    JMenu menu = new JMenu("Connect"); 

    JMenuItem menuItem; 
    menuItem = new JMenuItem("1"); 
    menu.add(menuItem); 

    menuItem = new JMenuItem("2"); 
    menu.add(menuItem); 

    _cardMenu.add(menu); 
    _cardMenu.add(new JMenuItem("Configure")); 
    _cardMenu.add(new JMenuItem("Status")); 

    _mainButton.setComponentPopupMenu(_cardMenu); //Important, apparently! 
} 

所以,經驗教訓。謝謝你們的幫助!

回答

2

這是common Bug或Swing屬性,在一瞬間只能看到一個Lightweight彈出窗口,同樣的問題是例如。從JComboBox added into JPopupMenu彈出,

  • 變化Lightweight屬性爲Heavyweight
更好

  • 使用un_decorated JDialogJOptionPaneJComponents

編輯@trashgod

  • 一切正常,我除外,所有JMenus,JMenuItems是可見的,屢燃煤正確evets

代碼

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

public class ContextMenu implements ActionListener, MenuListener, MenuKeyListener { 

    private JTextArea textArea = new JTextArea(); 

    public ContextMenu() { 
     final JPopupMenu contextMenu = new JPopupMenu("Edit"); 
     JMenu menu = new JMenu("Sub Menu"); 
     menu.add(makeMenuItem("Sub Menu Save")); 
     menu.add(makeMenuItem("Sub Menu Save As")); 
     menu.add(makeMenuItem("Sub Menu Close")); 
     menu.addMenuListener(this); 
     JMenu menu1 = new JMenu("Sub Menu"); 
     menu1.add(makeMenuItem("Deepest Sub Menu Save")); 
     menu1.add(makeMenuItem("Deepest Sub Menu Save As")); 
     menu1.add(makeMenuItem("Deepest Sub Menu Close")); 
     menu.add(menu1); 
     menu1.addMenuListener(this); 
     contextMenu.add(menu); 
     contextMenu.add(makeMenuItem("Plain Save")); 
     contextMenu.add(makeMenuItem("Plain Save As")); 
     contextMenu.add(makeMenuItem("Plain Close")); 
     contextMenu.addMenuKeyListener(this); 
     JFrame frame = new JFrame(); 
     JPanel panel = new JPanel(); 
     panel.setLayout(new BorderLayout()); 
     frame.add(panel); 
     panel.setComponentPopupMenu(contextMenu); 
     textArea.setInheritsPopupMenu(true); 
     panel.add(BorderLayout.CENTER, textArea); 
     JTextField textField = new JTextField(); 
     textField.setInheritsPopupMenu(true); 
     panel.add(BorderLayout.SOUTH, textField); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(400, 200); 
     frame.setVisible(true); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     textArea.append(e.getActionCommand() + "\n"); 
    } 

    private JMenuItem makeMenuItem(String label) { 
     JMenuItem item = new JMenuItem(label); 
     item.addActionListener(this); 
     return item; 
    } 

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

      @Override 
      public void run() { 
       ContextMenu contextMenu = new ContextMenu(); 
      } 
     }); 
    } 

    public void menuSelected(MenuEvent e) { 
     textArea.append("menuSelected" + "\n"); 
    } 

    public void menuDeselected(MenuEvent e) { 
     textArea.append("menuDeselected" + "\n"); 
    } 

    public void menuCanceled(MenuEvent e) { 
     textArea.append("menuCanceled" + "\n"); 
    } 

    public void menuKeyTyped(MenuKeyEvent e) { 
     textArea.append("menuKeyTyped" + "\n"); 
    } 

    public void menuKeyPressed(MenuKeyEvent e) { 
     textArea.append("menuKeyPressed" + "\n"); 
    } 

    public void menuKeyReleased(MenuKeyEvent e) { 
     textArea.append("menuKeyReleased" + "\n"); 
    } 
} 
+0

啊,謝謝!這可以在Mac OS X上正常工作。我注意到您的工廠方法'makeMenuItem()'有助於避免常見的重新使用局部變量的問題。對不起,我不能再次投票。 – trashgod 2012-04-03 08:05:33

+0

編輯與聽衆arest,按預期工作,WinXP,Java6 – mKorbel 2012-04-03 08:05:37

2

我沒有看到中所示的代碼一個明顯的問題,儘管@ mKorbel的觀點可能適用。作爲參考,這ControlPanel增加了一個subMenu與幾個項目。

+0

爲什麼'setVisible(false)'?該菜單稍後在程序中是否可見? – trashgod 2012-04-03 07:11:55

+0

以後我會設置菜單的可見性,我喜歡在創建新組件時確定新組件的行爲。這可能沒有必要。 – 2012-04-03 15:18:39