Well, what you need is a timer! The Timer class can be useful to you.
You'll also need to pick up the system date and time, I think it's easier that way. You can do this through:
long tempoInicio = System.currentTimeMillis();
//Pega a data e hora do sistema em milisegundos.
Okay, I did a little example, hope it serves what you want. It works with a keyboard from 0 to 9 and it resets the time from the last entered key, thus allowing you to enter multiple numbers. After 3 seconds of the last keystroke, a routine is executed.
Here is the code:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;
public class Tecla extends JFrame implements ActionListener {
//Botões
public JButton botao[][] = new JButton[4][3];
//Conteúdo dos botões
public String conteudo[][] = new String[4][3];
//Texto dos botões
public String texto = "123456789R0X";
//Valor da tecla(s) pressionada(s)
public String teclaPressionada = "";
//Momento da ultima tecla pressionada
public long tempoInicio = System.currentTimeMillis();
//Momento atual
public long tempoFim = System.currentTimeMillis();
//Botão foi pressionado?
public boolean pressionado = false;
//Timer
private Timer timer = new Timer();
private TimerTask schedule;
JTextField campo = new JTextField();
public Tecla() {
//Cria a janela, define tamanho, cor etc...
final Container tela = getContentPane();
tela.setLayout(new FlowLayout(FlowLayout.LEFT));
setTitle("Teclado");
setSize(245, 362);
setResizable(false);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
setUndecorated(true);
setBackground(new Color(100, 100, 100, 100));
this.setLocationRelativeTo(null);
setFocusable(true);
//Cria botões
for (int i = 0, cont = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) {
botao[i][j] = new JButton("<html><center><h1>"
+ texto.charAt(cont) + "</h1></center></html>");
conteudo[i][j] = "" + texto.charAt(cont);
botao[i][j].setPreferredSize(new Dimension(75, 75));
botao[i][j].setBorder(new LineBorder(Color.blue, 2));
botao[i][j].setBackground(Color.white);
botao[i][j].setEnabled(true);
botao[i][j].setVisible(true);
botao[i][j].addActionListener(this);
tela.add(botao[i][j]);
cont++;
}
}
botao[3][2].setBorder(new LineBorder(Color.red, 2));
campo.setPreferredSize(new Dimension(238, 30));
campo.setEditable(false);
campo.setVisible(true);
tela.add(campo);
}
@Override
public void actionPerformed(ActionEvent e) {
//Atualiza valor atual
tempoFim = System.currentTimeMillis();
if (tempoFim - tempoInicio >= 3000) {
reset();
}
loop:
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) {
if (e.getSource() == botao[3][2]) {
System.exit(0);
}
if (e.getSource() == botao[3][0]) {
reset();
break loop;
}
if (e.getSource() == botao[i][j]) {
tempoInicio = System.currentTimeMillis();
botao[i][j].setBorder(new LineBorder(Color.green, 2));
if (!pressionado) {//Se pressionado for falso
pressionado = true;
teclaPressionada = conteudo[i][j];
break loop;
} else {
teclaPressionada += conteudo[i][j];
break loop;
}
}
}
}
}
public void Temporizador() {
schedule = new TimerTask() {
@Override
//Função que é chamada a cada 100ms
public void run() {
//Imprime quanto tempo decorreu desde o ultimo botão pressionado
System.out.println("Temporizador: " + (tempoFim - tempoInicio));
tempoFim = System.currentTimeMillis();//Atualiza valor atual
campo.setText(teclaPressionada);
//Se demorou mais do que 3 segundos...
if ((tempoFim - tempoInicio >= 3000)
&& (!(teclaPressionada.isEmpty()))) {
//Faz alguma coisa:
JOptionPane.showMessageDialog(null,
"Você apertou: " + teclaPressionada);
reset();//Reseta valores originais
}
}
};
timer.schedule(schedule, 0, 100);//Executa tarefa a cada 100ms
}
public void reset() {
pressionado = false;
teclaPressionada = "";
tempoInicio = System.currentTimeMillis();
//Devolve a cor azul aos botões.
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) {
botao[i][j].setBorder(
new LineBorder(Color.blue, 2));
}
}
botao[3][2].setBorder(new LineBorder(Color.red, 2));
}
}
Important , you have to call the method responsible for the Timer, you can do this shortly after calling the Frame:
Tecla tecla = new Tecla();
tecla.setVisible(true);
tecla.Temporizador();
It may also be useful to stop the Timer, for this use:
schedule.cancel();
If you want to resume, just call again.
Basically, I get the system date-time from when the key was pressed, which is constantly updated by the Timer, and subtracts it with the current system date-time thus getting the time difference. The Timer runs every 100ms and contains an if that checks if 3 seconds have elapsed. Maybe not the best way to do this, but it was the way I found it. I count on the help of the community to find a more elegant way to do this.
It looks like this: