desplegable - Entrar evento clave no funciona en el cuadro de diálogo en Javafx?
javafx combobox get selected item (2)
No recomiendo hacer que todos los botones respondan para ingresar , ya que eso es contrario a cómo funcionan la mayoría de los cuadros de diálogo de IU.
Normalmente, un botón con foco se disparará cuando presione el espacio , no ingrese . Sin embargo, hay botones especiales que se activarán en teclas específicas: un botón predeterminado disparará al entrar y un botón de cancelar se activará en esc . Por lo general, solo tendrá uno de cada uno de estos tipos especiales de botones en su cuadro de diálogo, de modo que puedan dispararse mediante el acelerador de teclado especial, independientemente del botón que tenga actualmente el foco.
Además, diferentes sistemas de escritorio de escritorio tienen diferentes estándares en la colocación de botones predeterminados y de cancelación en un sistema de diálogo. Esto es para ayudar al usuario a encontrar fácilmente estos botones especiales en cualquier diálogo. El sistema de diálogo JavaFX implementa una lógica interna para localizar botones en los diálogos donde el usuario esperaría verlos en diferentes sistemas operativos de escritorio.
Supongamos que quiere que los tipos de botones de su ejemplo se definan como predeterminados o que se cancelen y se coloquen en la posición correcta para dichos botones para su SO, entonces puede hacer lo siguiente:
ButtonType buttonTypeTwo = new ButtonType(
"Two",
ButtonBar.ButtonData.OK_DONE
);
ButtonType buttonTypeThree = new ButtonType(
"Three",
ButtonBar.ButtonData.CANCEL_CLOSE
);
Tenga en cuenta que el sistema JavaFX ha cambiado automáticamente la posición de los botones y parte del resaltado en color. Cuando el usuario presione enter , se disparará "Two", cuando el usuario presiona esc , se disparará "Three". Si ejecuta el mismo código en Windows o Linux, es probable que los botones se ubiquen de manera diferente, de acuerdo con el estándar de posicionamiento de botones que se use para esos sistemas operativos.
Si no desea que JavaFX vuelva a colocar sus botones de acuerdo con los estándares del sistema operativo, pero desea que respondan aún a las teclas enter y esc , puede buscar los botones y modificar directamente los atributos del botón como se muestra a continuación:
Button buttonTwo = (Button) alert.getDialogPane().lookupButton(buttonTypeTwo);
buttonTwo.setDefaultButton(true);
Button buttonThree = (Button) alert.getDialogPane().lookupButton(buttonTypeThree);
buttonThree.setCancelButton(true);
Recomiendo dejar que JavaFX coloque apropiadamente botones de tipos específicos en lugar de realizar búsquedas como arriba.
También recomiendo configurar al menos un botón CANCEL_CLOSE o OK_DONE en su JavaFX Alert, de lo contrario, el usuario puede tener dificultades para cerrar la alerta, ya que el diálogo probablemente no responderá a las pulsaciones de teclas que el usuario espera.
He intentado el siguiente código, funciona bien con el evento del mouse, pero cuando uso un evento clave, es decir, la tecla ENTER en cualquier botón que no muestra el resultado.
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle(null);
alert.setHeaderText(null);
alert.setGraphic(null);
alert.setContentText("Choose your option.");
ButtonType buttonTypeOne = new ButtonType("One");
ButtonType buttonTypeTwo = new ButtonType("Two");
ButtonType buttonTypeThree = new ButtonType("Three");
alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeThree);
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == buttonTypeOne) {
System.out.println("One");
} else if (result.get() == buttonTypeTwo) {
System.out.println("Two");
} else if (result.get() == buttonTypeThree) {
System.out.println("Three");
}
No sé si esto no es una especie de solución alternativa, pero al menos funciona:
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
[...]
ButtonType buttonTypeTwo = new ButtonType("Two");
ButtonType buttonTypeThree = new ButtonType("Three");
alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeThree);
//Create a button for every ButtonType you add to your alert and give it a Eventhandler
Button button1 = (Button) alert.getDialogPane().lookupButton(buttonTypeOne);
Button button2 = (Button) alert.getDialogPane().lookupButton(buttonTypeTwo);
Button button3 = (Button) alert.getDialogPane().lookupButton(buttonTypeThree);
button1.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if(event.getCode() == KeyCode.ENTER)
alert.setResult(buttonTypeOne);
}
});
button2.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if(event.getCode() == KeyCode.ENTER)
alert.setResult(buttonTypeTwo);
}
});
button3.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if(event.getCode() == KeyCode.ENTER)
alert.setResult(buttonTypeThree);
}
});
//go ahead with your code
Optional<ButtonType> result = alert.showAndWait();
[...]
Simplemente crea algunos botones y les asigna los botones reales en su alerta. En el siguiente paso, puede asignar a cada botón un Manejador de eventos que solo (en este ejemplo) comprueba, cuando se suelta cualquier tecla, si la tecla fue INTRO y establece el resultado.
Supongo que hay mejores soluciones para esto. Pero es la forma más fácil que me viene a la mente actualmente. Espero que te ayude