Я знаю, как создавать подменю Java Swing с помощью JMenu. При наведении курсора мыши на объект JMenu, он отображает JPopupMenu показывая пункты подменю, как это:Динамически создавать подменю Java Swing
субменю JMenu
Моя проблема заключается в том, что в моем приложении, определяя, какие элементы меню будет иметь подменю дорого. Я не хочу заранее определять, должен ли конкретный элемент меню быть JMenu или просто JMenuItem. Я хочу сделать каждый элемент JMenuItem и отобразить подменю для него только в том случае, если пользователь запросит его, например, наведите указатель мыши на элемент меню. Как это:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Menu2 extends JFrame
{
public Menu2()
{
super("Menu2");
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu mItems = new JMenu("Items");
menuBar.add(mItems);
mItems.add(new JMI("A"));
mItems.add(new JMI("B"));
mItems.add(new JMI("C"));
JLabel stuff = new JLabel("Other stuff");
stuff.setPreferredSize(new Dimension(200,200));
getContentPane().add(stuff);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private class JMI extends JMenuItem
implements MouseListener
{
public JPopupMenu childrenPopup = null;
public JMI(String label)
{
super(label);
addMouseListener(this);
}
// MouseListener
public void mouseClicked(MouseEvent ev) {}
public void mouseEntered(MouseEvent ev)
{
// Show a submenu for item "B" only.
// In real life we'd want a Timer to delay showing the submenu
// until we are sure the user is hovering the mouse.
// For simplicity I've omitted it.
if (getText().equals("B")) {
if (childrenPopup == null) {
childrenPopup = new JPopupMenu();
// Expensive processing to determine submenu elements...
childrenPopup.add("D");
childrenPopup.add("E");
}
// Display the submenu
childrenPopup.show(this,getWidth(),0);
}
}
public void mouseExited(MouseEvent ev) {}
public void mousePressed(MouseEvent ev) {}
public void mouseReleased(MouseEvent ev) {}
}
public static void main(String[] args)
throws Exception
{
new Menu2().setVisible(true);
}
}
Единственная проблема заключается в том, что при отображении мой создан вручную JPopupMenu, остальная часть меню закрывается. В результате дисплей не выглядит, как раньше, а так:
Подменю отображается вручную
Обратите внимание, что я не сделал нажмите на пункт меню «B», только переехал мышь в нее. Меню не закрывалось из-за щелчка мышью.
Как я могу сделать то, что делает JMenu - отображает JPopupMenu, не закрывая остальное меню?
Может быть, вы могли бы попробовать заменить JMenuItem с JMenu после того, как вы определяете это на самом деле действительно есть подменю. – camickr
Я думаю, что новая идиома, подобная этой, приведет к запутыванию пользователей, и вам будет лучше, если ваша запись в меню всегда будет JMenuItem, которая вызывает модальный диалог (возможно, JOptionPane), показывающий динамически определенные варианты. – VGR
Спасибо, camickr и VGR, за ваши предложения по обходным решениям. Даже если мне нужно использовать обходной путь, я бы точно хотел узнать, почему показ всплывающего окна заставляет меню закрываться. Очевидно, что это можно сделать, не закрывая меню, поскольку JMenu это делает. – Vine