Simulation of TV Remote Control

5

I am developing a system where there should be a possibility for the user to interact with the program, pressing one or more numeric keys to change the display of multimedia contents (text, audio, video and image) simultaneously.

Currently the program requires the pressing of a key between 0 and 9 to navigate between the topics, but I need to expand this range to any values above 9. No other keys are allowed to "confirm" the offset to a certain topic, for example, press "Enter."

I'm searching for a form of the program to wait for a time interval, say 3 seconds, if no other key is pressed in this range, the program will "jump" to the corresponding topic of the key pressed, but if, on the other hand, press a second key, the program should wait another 3 seconds, and then "jump" to the topic corresponding to the value of the keys pressed. (I do not know if I made myself understood, but that's how a TV remote control works).

Which Java classes let you do this type of time-lapse check between a keystroke? Has anyone ever had anything like this?

    
asked by anonymous 14.03.2014 / 20:22

1 answer

3

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:

    
14.03.2014 / 22:53