java - 单击背景 jFrame 后,jPopupMenu 未隐藏

标签 java swing jcheckbox jpopupmenu

我正在使用一个包含多个 jCheckBoxMenuItemJPopupMenu。用户可以选中/取消选中多个 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/

相关文章:

java - 下一行间距问题

java - 具有可调整大小和固定大小标签的 Swing 布局

Java 'CheckBox Node Tree Sample' DefaultMutableNode 没有任何监听器?

JavaFX Medusa Gauges 显示阈值 TileKpiSkin

java - 如何在android中使用jsoup自动登录网页?

java - Java中UTC日期解析不一致

java - JTable计算最后一列的总和

java - Java中如何处理表单?

java - JTable 中的 JCheckBox 值

java - 如何在java中的jtable中的特定行添加复选框?