Как создать JButton с меню?
Я хочу создать панель инструментов в моем приложении. Если вы нажмете кнопку на этой панели инструментов, появится всплывающее меню, как на панели инструментов Eclipse. Я не знаю, как это сделать в Swing. Может кто-то помочь мне, пожалуйста? Я пробовал Google, но ничего не нашел.
7 ответов
В Swing это намного сложнее, чем нужно. Поэтому вместо того, чтобы указывать вам учебники, я создал полностью рабочий пример.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class ToolbarDemo {
public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setPreferredSize(new Dimension(600, 400));
final JToolBar toolBar = new JToolBar();
//Create the popup menu.
final JPopupMenu popup = new JPopupMenu();
popup.add(new JMenuItem(new AbstractAction("Option 1") {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "Option 1 selected");
}
}));
popup.add(new JMenuItem(new AbstractAction("Option 2") {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "Option 2 selected");
}
}));
final JButton button = new JButton("Options");
button.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
popup.show(e.getComponent(), e.getX(), e.getY());
}
});
toolBar.add(button);
frame.getContentPane().add(toolBar, BorderLayout.NORTH);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Я не понимаю, почему это сложнее, чем нужно, или почему вы должны использовать MouseListener. Решение от Steve McLeod работает, но то, где появится меню, зависит от того, где была нажата мышь. Почему бы просто не использовать ActionListener, как обычно используется для JButton. Кажется, не сложнее и не сложнее.
final JPopupMenu menu = new JPopupMenu();
menu.add(...whatever...);
final JButton button = new JButton();
button.setText("My Menu");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
menu.show(button, button.getBounds().x, button.getBounds().y
+ button.getBounds().height);
}
});
Это позиционирует меню примерно так же, как меню в JMenuBar для меня, и позиция соответствует. Вы можете разместить его по-другому, изменив x и y в menu.show().
Вот простой и хороший класс
import javax.swing.JPopupMenu;
import javax.swing.JToggleButton;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class MenuButton extends JToggleButton {
JPopupMenu popup;
public MenuButton(String name, JPopupMenu menu) {
super(name);
this.popup = menu;
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ev) {
JToggleButton b = MenuButton.this;
if (b.isSelected()) {
popup.show(b, 0, b.getBounds().height);
} else {
popup.setVisible(false);
}
}
});
popup.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
MenuButton.this.setSelected(false);
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {}
});
}
}
Я думаю, что это так же, как в AWT.
Вы должны поместить ActionCommand на эту кнопку и, когда она будет выполнена, отобразить всплывающее меню в соответствии с координатами мыши.
См. Раздел "Всплывающее меню" в разделе " Как пользоваться меню".
Я не уверен, что понимаю вас правильно, но если вы хотите знать, как сделать панели инструментов в Swing, отметьте это
Учебные руководства по Java: как использовать панели инструментов и это
Выше Адам Гуд спросил:
Есть ли в вашем решении поведение, при котором, если вы снова нажмете кнопку с меню, оно снова откроет меню, а не закроет его?
Это оказалось тестовой задачей. Я, наконец, решил это с помощью invokeLater, чтобы повторно исчезнуть всплывающее окно в этом конкретном случае. Мое решение также позволяет клиенту настраивать кнопку и всплывающее меню.
/**
* A button that will popup a menu.
* The button itself is a JLabel and can be adjusted with all
* label attributes. The popup menu is returned by getPopup;
* menu items must be added to it.
* <p>
* Clicks outside the menu will dismiss it.
*/
public class MenuButton extends JLabel
implements MouseListener, PopupMenuListener {
JPopupMenu popMenu;
@SuppressWarnings("")
public MenuButton() {
super();
popMenu = new JPopupMenu();
addMouseListener(this);
popMenu.addPopupMenuListener(this);
}
public JPopupMenu getPopup() { return popMenu; }
@Override
public void mousePressed(MouseEvent e) {
if ( ! popMenu.isShowing()) {
popMenu.show(this, 0, getBounds().height);
}
}
@Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
SwingUtilities.invokeLater(()->{
if (popMenu.isShowing()) {
// if shpwing, it was hidden and reshown
// by a mouse down in the 'this' button
popMenu.setVisible(false);
}
});
}
@Override public void mouseClicked(MouseEvent e) { }
@Override public void mouseReleased(MouseEvent e) { }
@Override public void mouseEntered(MouseEvent e) { }
@Override public void mouseExited(MouseEvent e) { }
@Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) { }
@Override public void popupMenuCanceled(PopupMenuEvent e) { }
} // end MenuButton
Пример вызова
MenuButton button = new MenuButton();
JPopupMenu menu = button.getPopup();
menu.add("Browse Sample");
menu.add("Save As ...");
Icon hamburger = IOUtils.loadIconResource(
IndexGofer.class, "images/hamburgerMenu.png");
(IOUtils is on page http://physpics.com/Java/tools/
You should use your own tool to load an icon.)
button.setIcon(hamburger);
button.setOpaque(false);