java – 从JButton显示/隐藏JPopupMenu; FocusListener无法正常
我需要一个带有附加下拉样式菜单的JButton.所以我拿了一个JPopupMenu并以你在下面的代码中看到的方式将它附加到JButton.它需要做的是:
>单击时显示弹出窗口 这4件事情都有效,但由于我正在使用的布尔标志,如果用户点击其他地方或选择了一个项目,我必须在按钮上单击两次才会再次显示.这就是为什么我试图添加一个FocusListener(绝对没有响应)来修复它并在这些情况下将标志设置为false. 编辑:最后一次尝试回答帖子…… 以下是监听器:(它在一个扩展JButton的类中,所以第二个监听器在JButton上.) // Show popup on left click. menu.addFocusListener(new FocusListener() { @Override public void focusLost(FocusEvent e) { System.out.println("LOST FOCUS"); isShowingPopup = false; } @Override public void focusGained(FocusEvent e) { System.out.println("GAINED FOCUS"); } }); addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("isShowingPopup: " + isShowingPopup); if (isShowingPopup) { isShowingPopup = false; } else { Component c = (Component) e.getSource(); menu.show(c,-1,c.getHeight()); isShowingPopup = true; } } }); 我现在已经用这个太久了.如果有人能给我一个关于这个问题的线索,那就太好了! 谢谢! 码: public class Button extends JButton { // Icon. private static final ImageIcon ARROW_SOUTH = new ImageIcon("ArrowSouth.png"); // Unit popup menu. private final JPopupMenu menu; // Is the popup showing or not? private boolean isShowingPopup = false; public Button(int height) { super(ARROW_SOUTH); menu = new JPopupMenu(); // menu is populated somewhere else // FocusListener on the JPopupMenu menu.addFocusListener(new FocusListener() { @Override public void focusLost(FocusEvent e) { System.out.println("LOST FOCUS"); isShowingPopup = false; } @Override public void focusGained(FocusEvent e) { System.out.println("GAINED FOCUS"); } }); // ComponentListener on the JPopupMenu menu.addComponentListener(new ComponentListener() { @Override public void componentShown(ComponentEvent e) { System.out.println("SHOWN"); } @Override public void componentResized(ComponentEvent e) { System.out.println("RESIZED"); } @Override public void componentMoved(ComponentEvent e) { System.out.println("MOVED"); } @Override public void componentHidden(ComponentEvent e) { System.out.println("HIDDEN"); } }); // ActionListener on the JButton addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("isShowingPopup: " + isShowingPopup); if (isShowingPopup) { menu.requestFocus(); isShowingPopup = false; } else { Component c = (Component) e.getSource(); menu.show(c,c.getHeight()); isShowingPopup = true; } } }); // Skip when navigating with TAB. setFocusable(true); // Was false first and should be false in the end. menu.setFocusable(true); } } 解决方法
这是另一种方法,即使不是优雅的,也不是太糟糕的,而且据我所知,它可以起作用.首先,在最顶端,我添加了第二个名为showPopup的布尔值.
FocusListener必须如下: menu.addFocusListener(new FocusListener() { @Override public void focusLost(FocusEvent e) { System.out.println("LOST FOCUS"); isShowingPopup = false; } @Override public void focusGained(FocusEvent e) { System.out.println("GAINED FOCUS"); isShowingPopup = true; } }); isShowingPopup布尔值在其他任何地方都不会改变 – 如果它获得焦点,它会假定它已经显示,如果它失去了焦点,它就会认为它没有. 接下来,按钮上的ActionListener是不同的: addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("isShowingPopup: " + isShowingPopup); if (showPopup) { Component c = (Component) e.getSource(); menu.show(c,c.getHeight()); menu.requestFocus(); } else { showPopup = true; } } }); 现在真的是新的一点.它是按钮上的MouseListener: addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { System.out.println("ispopup?: " + isShowingPopup); if (isShowingPopup) { showPopup = false; } } @Override public void mouseReleased(MouseEvent e) { showPopup = true; } }); 基本上,在菜单失去焦点之前会调用mousePressed,因此isShowingPopup反映了在按下按钮之前是否显示了弹出窗口.然后,如果菜单在那里,我们只是将showPopup设置为false,这样actionPerformed方法一旦被调用就不显示菜单(在放开鼠标之后). 这种情况在每种情况下都表现如预期但只有一种:如果显示菜单并且用户将鼠标按在按钮上但将其释放到其外部,则从未调用actionPerformed.这意味着showPopup仍为false,下次按下按钮时菜单未显示.要解决此问题,mouseReleased方法会重置showPopup.据我所知,在actionPerformed之后调用mouseReleased方法. 我玩了一下结果按钮,做了我能想到的所有按钮,它按预期工作.但是,我并非100%确定事件将始终以相同的顺序发生. 最终,我认为这至少值得尝试. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |