我正在使用一个包含多个 jCheckBoxMenuItem
的 JPopupMenu
。用户可以选中/取消选中多个 CheckBox
。但是当我点击 JFrame
时,PopupMenu
没有隐藏。
这是完整的代码。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PopupTest extends JFrame {
JButton button1;
public PopupTest() {
setTitle("Popup Test !");
setSize(400, 400);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
button1 = new JButton("Click me!");
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int count = 250; // this count value is dynamic
JPopupMenu menu = new JPopupMenu();
JCheckBoxMenuItem item = null;
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
JScrollPane scrollPane = new JScrollPane(panel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setPreferredSize(new Dimension(125, 200));
for (int i = 1; i <= count; i++) {
item = new JCheckBoxMenuItem("Page : " + i, new ImageIcon("test.png"));
item.setHorizontalTextPosition(JMenuItem.RIGHT);
item.addActionListener(new OpenAction(menu, button1));
panel.add(item);
}
menu.add(scrollPane);
JCheckBoxMenuItem selectAll = new JCheckBoxMenuItem("Select All", new ImageIcon("test.png"));
selectAll.addActionListener(new OpenAction(menu, button1));
menu.insert(selectAll, 0);
if (!menu.isVisible()) {
Point p = button1.getLocationOnScreen();
menu.setLocation((int) p.getX(), (int) p.getY() + button1.getHeight());
menu.setVisible(true);
} else {
menu.setVisible(false);
}
}
});
add(button1);
}
private static class OpenAction implements ActionListener {
private JPopupMenu menu;
private JButton button;
private OpenAction(JPopupMenu menu, JButton button) {
this.menu = menu;
this.button = button;
}
@Override
public void actionPerformed(ActionEvent e) {
String chkBoxText = e.getActionCommand().toString();
AbstractButton aButton = (AbstractButton) e.getSource();
boolean selected = aButton.getModel().isSelected();
Icon checkedIcon = new ImageIcon("test1.png");
Icon uncheckedIcon = new ImageIcon("test.png");
JScrollPane pane = null;
JViewport viewport = null;
JPanel panel = null;
JCheckBoxMenuItem item = null;
pane = (JScrollPane) menu.getComponent(1); //0th component is "Select All" check box
viewport = pane.getViewport();
panel = (JPanel) viewport.getComponent(0);
int totalChkBoxComponent = panel.getComponentCount();
if (selected) {
System.out.println(chkBoxText + " is Checked!");
if (chkBoxText.trim().equalsIgnoreCase("select all")) {
for (int i = 0; i < totalChkBoxComponent; i++) {
item = (JCheckBoxMenuItem) panel.getComponent(i);
item.setSelected(selected);
item.setIcon(item.isSelected() ? checkedIcon : uncheckedIcon);
}
}
} else if (!selected) {
System.out.println(chkBoxText + " is Un-Checked!");
if (chkBoxText.trim().equalsIgnoreCase("select all")) {
for (int i = 0; i < totalChkBoxComponent; i++) {
item = (JCheckBoxMenuItem) panel.getComponent(i);
item.setSelected(selected);
item.setIcon(item.isSelected() ? checkedIcon : uncheckedIcon);
}
} else { // this is for, after checking "Select All", if any other is unchecked, then "Select ALL" should be unchecked.
item = (JCheckBoxMenuItem) menu.getComponent(0);
item.setSelected(selected);
item.setIcon(selected ? checkedIcon : uncheckedIcon);
}
}
aButton.setIcon(aButton.isSelected() ? checkedIcon : uncheckedIcon);
}
}
public static void main(String args[]) {
new PopupTest();
}
}
请帮忙。谢谢。
最佳答案
首先,您的代码并不是执行此类操作的最佳方式。您不应在每次单击按钮时都创建一个新菜单,而应创建一次并将其作为字段引用。
PopupMenu
没有隐藏的原因是您显式调用了 setVisible(true);
并尝试在 setVisible(false);
中分配给按钮而不是框架的完全相同的 ActionListener
。
你可以:
1. 向框架添加另一个监听器,以在单击时将菜单可见性设置为 false
2. 使用show
方法代替setVisible
:
menu.show(button1, 0, button1.getHeight());
代替
menu.setLocation((int) p.getX(), (int) p.getY() + button1.getHeight());
menu.setVisible(true);
但是在我们的例子中,这会导致菜单消失等其他问题。 IMO 最好的方法是重新设计代码。
关于java - 单击背景 jFrame 后,jPopupMenu 未隐藏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22283955/