1

我做了一个定制JComboBox。为此,我使用了一个JPopupMenu包含JCheckBoxMenuItem. 但显然,在更改PopupMenuListener popupMenuWillBecomeInvisible之前正在运行。JCheckBoxMenuItem任何想法如何解决?我不想在JCheckBoxMenuItem.

public class ListenerTest  extends JFrame implements ActionListener, PopupMenuListener {

    private JPopupMenu menu;
    private List<JCheckBoxMenuItem> menuItems;

    private JCheckBoxMenuItem i1;
    private JCheckBoxMenuItem i2;
    private JCheckBoxMenuItem i3;

    public ListenerTest(){

        // Create button
        JButton b = new JButton("Click me!");
        b.addActionListener(this);

        // Create Popupmenu
        menu = new JPopupMenu();
        menu.addPopupMenuListener(this);

        // Add CheckBoxes to PopupMenu 
        menuItems = new LinkedList<JCheckBoxMenuItem>();
        i1 = new JCheckBoxMenuItem("1");
        i2 = new JCheckBoxMenuItem("2");
        i3 = new JCheckBoxMenuItem("3");
        menu.add(i1);
        menu.add(i2);
        menu.add(i3);

        this.add(b);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.pack();
        this.setVisible(true);
    }

    public static void main(String[] args){
        new ListenerTest();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // Show PopupMenu when button is clicked
        menu.show(this, 0, this.getHeight());
    }

    @Override
    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}

    @Override
    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
        // Check which checkBoxes is checked when popup menu is closed(currently one step behind)
        System.out.println(i1.isSelected());
        System.out.println(i2.isSelected());
        System.out.println(i3.isSelected());
    }

    @Override
    public void popupMenuCanceled(PopupMenuEvent e) {}
}
4

1 回答 1

3

一个“可能的”解决方案与一个 kludge 相比,是使用你的popupMenuWillBecomeInvisible(...)但将你的状态检查排队到 Swing 事件队列中,以便它稍后执行它的操作,在当前事件队列上的所有项目都完成之后。但是,这不能保证有效。

@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {

  SwingUtilities.invokeLater(new Runnable() {
     public void run() {
        System.out.println(i1.isSelected());
        System.out.println(i2.isSelected());
        System.out.println(i3.isSelected());
     }
  });
}
于 2013-05-21T15:44:34.883 回答