我需要一个带有下拉式菜单的 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, -1, c.getHeight());
isShowingPopup = true;
}
}
});
// Skip when navigating with TAB.
setFocusable(true); // Was false first and should be false in the end.
menu.setFocusable(true);
}
}