2014-08-12 8 views
5

Я хотел бы программно развернуть конкретный JMenuItem в JPopup. Например, в коде нижеПрограммно развернуть sub JMenuItems

import java.awt.event.ActionEvent; 

import javax.swing.AbstractAction; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JMenu; 
import javax.swing.JMenuItem; 
import javax.swing.JPanel; 
import javax.swing.JPopupMenu; 

public class AutoExpandSubMenusDemo extends JFrame { 

    private final JPopupMenu popup = new JPopupMenu("Popup"); 

    public AutoExpandSubMenusDemo() { 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 

     JMenu menuB = new JMenu("B"); 

     menuB.add(new JMenuItem("X")); 
     JMenuItem menuY = menuB.add(new JMenuItem("Y")); 
     menuB.add(new JMenuItem("Z")); 

     popup.add(new JMenuItem("A")); 
     popup.add(menuB); 
     popup.add(new JMenuItem("C")); 

     final JButton button = new JButton("Show Popup Menu"); 
     button.addActionListener(new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       popup.show(button, 0, button.getHeight()); 

       // Show menuY 
      } 
     }); 

     JPanel buttonPanel = new JPanel(); 
     buttonPanel.add(button); 
     getContentPane().add(buttonPanel); 
    } 

    public static void main(String[] args) { 
     AutoExpandSubMenusDemo f = new AutoExpandSubMenusDemo(); 
     f.setSize(500, 300); 
     f.setVisible(true); 
    } 
} 

Я хотел бы расширить всплывающее меню, так что элементы B (menuB)/Y (menuY) разлагаются и выбирается при нажатии кнопки.

Извините, если это то, что легко сделать, но я искал вокруг и не могу понять это.

я найти

MenuSelectionManager.defaultManager().setSelectedPath(...) 

однако это не работает, когда я попробовал это и Javadoc определяет, что она вызывается из LaF и не должен вызываться клиентами.

Любая помощь очень ценится.

+0

Если вы просто хотите, то же самое действие (от кнопки и пункта меню), происходит при нажатии на кнопку, просто используйте [ 'Action' ] (http://docs.oracle.com/javase/8/docs/api/javax/swing/Action.html). Подробнее см. В разделе [Как использовать действия] (http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html). Кнопка кнопки и кнопки меню может использовать одно и то же действие. На самом деле не вижу смысла вскрывать всплывающее окно, чтобы выбрать его, если только его только для глазных конфет –

+0

По выбранному Я имею в виду подсветку, которая возникает, когда мышь находится над элементом меню или она была перенесена на клавиатуру , а не фактическое инициирование связанного действия. Причина, по которой я делаю это, заключается в том, что я пытаюсь реализовать функцию справки, которая показывает пользователей, где определенные параметры, путем расширения соответствующих меню. – Jamesy82

+0

OK +1 хороший вопрос :-D –

ответ

5

Хотя я не рекомендую делать это, так как сама документация советует против него, вот как вы можете это сделать:

import java.awt.event.ActionEvent; 
import javax.swing.AbstractAction; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JMenu; 
import javax.swing.JMenuItem; 
import javax.swing.JPanel; 
import javax.swing.JPopupMenu; 
import javax.swing.MenuElement; 
import javax.swing.MenuSelectionManager; 
import javax.swing.SwingUtilities; 

public class AutoExpandSubMenusDemo extends JFrame { 

    private final JPopupMenu popup = new JPopupMenu("Popup"); 

    public AutoExpandSubMenusDemo() { 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 

     final JMenu menuB = new JMenu("B"); 

     menuB.add(new JMenuItem("X")); 
     final JMenuItem menuY = menuB.add(new JMenuItem("Y")); 
     menuB.add(new JMenuItem("Z")); 

     popup.add(new JMenuItem("A")); 
     popup.add(menuB); 
     popup.add(new JMenuItem("C")); 

     final JButton button = new JButton("Show Popup Menu"); 
     button.addActionListener(new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       popup.show(button, 0, button.getHeight()); 

       SwingUtilities.invokeLater(new Runnable() { 

        public void run() { 
         menuB.setPopupMenuVisible(true); 
         MenuSelectionManager.defaultManager().setSelectedPath(new MenuElement[]{popup, menuB, menuY}); 
        } 
       }); 

      } 
     }); 

     JPanel buttonPanel = new JPanel(); 
     buttonPanel.add(button); 
     getContentPane().add(buttonPanel); 
    } 

    public static void main(String[] args) { 
     AutoExpandSubMenusDemo f = new AutoExpandSubMenusDemo(); 
     f.setSize(500, 300); 
     f.setVisible(true); 
    } 
} 

Большая часть этого кода принадлежит вам. Только добавлено:

SwingUtilities.invokeLater(new Runnable() { 

    public void run() { 
     menuB.setPopupMenuVisible(true); 
     MenuSelectionManager.defaultManager().setSelectedPath(new MenuElement[]{popup, menuB, menuY}); 
    } 
}); 

который, похоже, сработал.

Вы можете избежать злоупотребления MenuSelectionManager через 'MenuItem.setArmed (boolean)'.

SwingUtilities.invokeLater(new Runnable() { 

    public void run() { 
     menuB.setPopupMenuVisible(true); 
     menuB.setArmed(true); 
     menuY.setArmed(true); 
    } 
}); 

Всплывающее пребывания видны после выбора другого пункта меню или отклонения запроса JPopupMenu все еще необходимо решить, хотя.

Другим способом является подделкой событие мыши ...: D

SwingUtilities.invokeLater(new Runnable() { 

    public void run() {       
     MouseEvent event = new MouseEvent(
       menuB, MouseEvent.MOUSE_ENTERED, 0, 0, 0, 0, 0, false); 
     menuB.dispatchEvent(event); 
     menuY.setArmed(true); 
    } 
}); 

Таким образом, это как если бы пользователь на самом деле используется мышь.

+0

+1 для взлома событий мыши, он даже дает дополнительную глазную сладость небольшой задержки при открытии меню. Когда я тестировал их, кажется, что способ событий с мышью - лучшее решение для вопроса OP. – Aristocrates

2

Другой пример:

MenuSelectionManager.defaultManager().setSelectedPath(
    new MenuElement[] {popup, menuB, menuB.getPopupMenu()}); 

enter image description here

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

public class AutoExpandSubMenusDemo2 extends JFrame { 
    private final JPopupMenu popup = new JPopupMenu("Popup"); 

    public AutoExpandSubMenusDemo2() { 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 

    final JMenu menuB = new JMenu("B"); 

    menuB.add(new JMenuItem("X")); 
    final JMenuItem menuY = menuB.add(new JMenuItem("Y")); 
    menuB.add(new JMenuItem("Z")); 

    popup.add(new JMenuItem("A")); 
    popup.add(menuB); 
    popup.add(new JMenuItem("C")); 

    JPanel buttonPanel = new JPanel(); 
    buttonPanel.add(new JButton(new AbstractAction("Show menuB Popup") { 
     @Override public void actionPerformed(ActionEvent e) { 
     JButton button = (JButton) e.getSource(); 
     popup.show(button, 0, button.getHeight()); 
     //[Bug ID: JDK-6949414 JMenu.buildMenuElementArray() endless loop] 
     //(http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6949414) 
     //menuB.doClick(); 
     MenuSelectionManager.defaultManager().setSelectedPath(
      new MenuElement[] {popup, menuB, menuB.getPopupMenu()}); 
     } 
    })); 
    buttonPanel.add(new JButton(new AbstractAction("Select menuY") { 
     @Override public void actionPerformed(ActionEvent e) { 
     JButton button = (JButton) e.getSource(); 
     popup.show(button, 0, button.getHeight()); 
     MenuSelectionManager.defaultManager().setSelectedPath(
      new MenuElement[] {popup, menuB, menuB.getPopupMenu(), menuY}); 
     } 
    })); 
    getContentPane().add(buttonPanel); 
    } 

    public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     @Override public void run() { 
     createAndShowGUI(); 
     } 
    }); 
    } 
    public static void createAndShowGUI() { 
    JFrame f = new AutoExpandSubMenusDemo2(); 
    f.setSize(500, 300); 
    f.setVisible(true); 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^