Мне нужно иметь JMenu
(тот со стрелкой справа, который может отображать JMenuItem
) в JPanel
. Проблема в том, что когда я это делаю, JMenu
не активируется при переносе мыши ... Я не знаю, как это сделать, и если это возможно.Добавление JMenu в JPanel
ответ
Вы должны пройти в макет JPanel BorderLayout, то вы можете добавить строку меню в панели:
JPanel p = new JPanel();
p.setLayout(new BorderLayout());
p.add(menubar, BorderLayout.NORTH);
И что это изменит для JMenu? Замена FlowLayout на BorderLayout влияет на размер и местоположение, но не на поведение. –
Я пробовал этот пример, и он работает и имеет нормальное поведение. –
Какой пример? 3 строки кода не являются примером. –
Если вы обернуть ваш JMenu
в JMenuBar
, он работает, как ожидалось.
Вот демонстрационный пример:
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();
}
});
}
}
результат:
Привет! Это не тот взгляд, который я бы хотел. Я хотел бы, чтобы JMenu отображался непосредственно на панели (а не на JMenuBar). – paranoia25
@ paranoia25 ваш вопрос непонятный об этом. Если бы вы поставили [SSCCE] (http://sscce.org), у вас был бы лучший ответ напрямую. Теперь о вашей проблеме я бы не добавил JMenu непосредственно в «JPanel», а скорее из «JButton» с «ActionListener», который открывает «JPopupMenu». Чтобы сделать 'JButton' похожим на' JMenu', вам, вероятно, придется выполнить некоторую настройку и получить доступ к L & F по умолчанию. –
+1 JToolBar может быть привлекательной альтернативой 'Container' для' JMenuBar', как показано [здесь] (http://stackoverflow.com/a/14630345/230513). – trashgod
Вот еще один способ решения этой проблемы, которые я думаю, что ближе к тому, что вы хотите. Он включает расширение JMenuBar
, чтобы придать ему вид объекта JMenu
.
Класс содержит JMenu
Объект, называемый меню. Методы добавления переопределяются, поэтому вы добавляете в меню вместо JMenuBar
(Возможно, вам придется переопределить еще несколько методов добавления, чтобы сделать это идеально).
Есть несколько вариантов с изображением. Я не был уверен, что вам нужен стиль в стиле кнопки JMenuBar
, поэтому я включил несколько комментариев по некоторым параметрам, чтобы настроить его, а также подчеркнуть внешний вид JMenuBar
.
Вот результат кнопки смотреть без границ:
Вот результат, без кнопки выглядят и без границ:
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);
}
}
Привет! Это самое близкое решение! Но это все еще не совсем то, что я ищу. Я хотел бы JMenu прямо в JPanel. В вашем решении JMenu все еще находится в JMenuBar, и пользователь должен щелкнуть JMenuBar, чтобы увидеть и получить доступ к JMenu. – paranoia25
@ paranoia25 насколько я знаю, нет никакого способа сделать это, потому что для этого вам нужен JMenuBar. В этом решении по-прежнему используется JMenuBar, но вы можете сделать так, чтобы он выглядел так, как будто там нет никого, возившись с методами Paint. –
Вы добавляете 'JMenu's к 'JMenuBar', и вы вызываете' setJMenuBar() 'метод' JFrame' - я не думаю, что вы можете добавить его в 'JPanel'. И убедитесь, что ваш 'JMenu' заполнен элементами! – moonwave99
Привет, я знаю это решение, но это не тот, который я хочу. Я действительно хочу, чтобы JMenu попал прямо в JPanel ... Это проблема. – paranoia25
Затем рассмотрите использование 'JDesktopPane' с' JInternalFrames' или определите свой собственный JComponent'. – moonwave99