Bueno tratando de dar una respuesta "aceptable" a la pregunta de visitante a mi blog, que tenia o tiene la duda de "como cerrar automaticamente un JOptionPane transcurrido un cierto tiempo", problema que me parecio sencillo al principio, controlar el tiempo no habia problema, con un Timer basta y sobra, pero despues de investigar un poco no encontre un comando en java para cerrar el JOptionPabe, el hide() no me funciono, el dispose() no existe para esta clase, el setvisible() no jala, asi que quedandome sin opciones, recorde un consejo de un viejo amigo, "cuando tengas un problema que al parecer no tiene solucion, da un paso atras para ampliar tu vision y asi encontraras la solucion mas facilmente",asi que ampliando mi mundo y mirando mejor mi problema, busque una solucion alternativa, hice uso de la clase Robot, esta clase simula acciones que puede realizar el usuario como pulsaciones de taclas o movimientos del raton e incluso clics del mismo raton, puede no ser la mejor solucion, pero funciona.
El ejemplo que realice para esta demostracion, es una aplicacion trivial, que muestra una pregunta en un JOptionPane y desaparece despues de un tiempo.
El ejemplo que realice para esta demostracion, es una aplicacion trivial, que muestra una pregunta en un JOptionPane y desaparece despues de un tiempo.
La clase en cuestion, la llame "tictac.java", si lo se, soy un asco para colocar nombres mis clases, pero bueno, esta clase tiene el metodo mostrar_pregunta(String p, int d). recibe como parametros la pregunta en cuestion y el tiempo en segundos que se desea mostrar el JOptionPane en pantalla, pasado este tiempo, que es controlado por el metodo Comenzar_a_contar(), el JOptionPase se cerrara automaticamente haciendo uso de la clase Robot, que simula la presion de la tecla escape KeyEvent.VK_ESCAPE, la respuesta se almacena en una variable de tipo String "respuesta", para su uso posteriormente.
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
/**
* @web http://jc-mouse.blogspot.com/
* @author Mouse
*/
public class tictac {
//para la animacion
private Timer tiempo ;
private TimerTask task;
//para almacenar la respuesta
private String respuesta=null;
private int duracion = 3;//tiempo
private JFrame padre;
private boolean isrun=false;
public tictac(){
}
public void mostrar_pregunta(String p, int d){
this.duracion = d;
//comienza a contar el tiempo
Comenzar_a_contar();
//se muestra el JOptionPane
this.respuesta = JOptionPane.showInputDialog(this.padre, p , JOptionPane.QUESTION_MESSAGE);
//si contesto antes de que acabe el tiempo
if(isrun){
detener();
actualizar();
}
//System.out.println("Respuesta " + this.respuesta);
}
/* se ejecuta cuando acaba el tiempo */
public void time_is_over(){
try {
Robot robot = new Robot();
//se asigna una respuesta vacia
this.respuesta = "No tengo idea";
// se actualiza
actualizar();
//se presiona la tecla escape
robot.keyPress(KeyEvent.VK_ESCAPE);
} catch (AWTException ex) {
Logger.getLogger(tictac.class.getName()).log(Level.SEVERE, null, ex);
}
}
/* actualiza los objetos del frame padre */
public void actualizar(){
//se añade la respuesta al objeto label de miframe
miframe.lbRes.setText("Respuesta: " + this.respuesta);
miframe.lbtiempo.setText("0");
miframe.lbRes.repaint();
}
/* metodo que lleva el tiempo disponible para contestar*/
public void Comenzar_a_contar() {
isrun=true;
tiempo = new Timer();
task = new TimerTask() {
int contador=0;
public void run() {
contador++;
miframe.lbtiempo.setText(String.valueOf(contador));
System.out.println("tiempo transcurrido: " + contador);
if(contador == duracion){
System.out.println("Se acabo el tiempo, mala suerte");
time_is_over();
detener();
}
}
};
tiempo.schedule(task,0,1000);
}
/* detiene la animacion */
public void detener() {
isrun=false;
tiempo.cancel();
task.cancel();
}
}
Este metodo tiene un contra, la aplicacion tiene que estar siempre visible, caso contrario no funciona, la clase robot realiza la pulsacion de la tecla escape, pero con la aplicacion que se encuentre en primer plano, al perder el foco la aplicacion en java, pierde el evento de pulsacion y el JOptionPane continuara visible.
Asi que como respuesta alternativa, puede utilizarse un JFrame que tenga la apariencia de un JOptionPane, si no es estrictamente necesario utilizar la clase JOptionPane, el funcionamiento es el mismo, con la diferencia de que ya no es necesario el uso de la clase Robot para cerrar el objeto, ya que un Jframe cuenta con el metodo dispose() para cerrar la ventana.
El video para mas detalles
y no puede faltar el codigo fuente, en Netbeans 6.0
Muchas gracias, me fue de gran ayuda el código, funciona a la perfección.
ResponderEliminarExcelente!
ResponderEliminargracias por el aporte!
muy bueno!
de nada :)
ResponderEliminarGracias me sirvio el robot :)
ResponderEliminarGracias, gracias, estaba buscando esto, me ha servido mucho. Dios los bendiga,
ResponderEliminarMUCHAS GRACIAS!!!!
ResponderEliminarestuve dias pensando en dar una solucion a SALIR DE UN JOPTIONPANE y gracias a ti ya tengo un solucion.
SALUDOS y sigue adelante con este blog