Necesitaba un JButton con un menú de estilo desplegable adjunto. Así que tomé un JPopupMenu y lo adjunté al JButton de la manera que se puede ver en el siguiente código. Lo que tiene que hacer es lo siguiente:Mostrar/ocultar un JPopupMenu desde un JButton; FocusListener no funciona?
- mostrar la ventana emergente cuando se hace clic
- ocultar que si se hace clic una segunda vez
- ocultar que si se selecciona un elemento en la ventana emergente
- ocultar que si el usuario clics en otro lugar en la pantalla
Estas 4 cosas funcionan, pero debido a la bandera booleana que estoy usando, si el usuario hace clic en otro lugar o selecciona un elemento, tengo que hacer clic dos veces en el botón antes de que se muestre de nuevo Es por eso que traté de agregar un FocusListener (que no responde en absoluto) para arreglarlo y configurar el indicador como falso en estos casos.
EDIT: Último intento en un puesto de respuesta ...
Éstos son los oyentes: (. Está en una clase JButton se extiende, por lo que el segundo oyente está en el 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;
}
}
});
He estado peleando con esto por mucho tiempo ahora. Si alguien puede darme una pista sobre lo que está mal con esto, ¡sería genial!
Gracias!
Código:
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);
}
}
Entonces, el principal problema que tengo es que focusGained() y focusLost() nunca se disparan, aunque sigo haciendo que aparezca y desaparezca. – Joanis