99import java .awt .Font ;
1010import java .awt .event .ActionListener ;
1111import java .awt .event .ActionEvent ;
12+ import java .awt .event .KeyListener ;
13+ import java .awt .event .KeyEvent ;
14+ import java .time .Instant ;
15+ import java .time .Duration ;
1216import java .util .Random ;
1317
1418
1519
16- public class TypingSpeedTestGUI extends JFrame implements ActionListener {
20+ public class TypingSpeedTestGUI extends JFrame implements ActionListener , KeyListener {
1721
1822 JLabel labelFraseParaDigitar ;
1923 JLabel labelResultadosWPM ;
2024 JLabel labelResultadosPrecisao ;
2125 JLabel labelResultadosErros ;
22-
2326 JTextArea areaDeDigitacao ;
24-
2527 JButton botaoIniciar ;
2628
2729 private String [] frases = {
@@ -33,9 +35,12 @@ public class TypingSpeedTestGUI extends JFrame implements ActionListener {
3335 };
3436
3537 private Random random = new Random ();
36-
3738 private String fraseAtual = "" ;
3839
40+ private boolean testePodeComecar = false ;
41+ private boolean testeEmAndamento = false ;
42+ private Instant inicio ;
43+
3944 public TypingSpeedTestGUI () {
4045
4146 setTitle ("Teste de Velocidade de Digitação (Swing)" );
@@ -51,6 +56,7 @@ public TypingSpeedTestGUI() {
5156 areaDeDigitacao .setFont (new Font ("Monospaced" , Font .PLAIN , 16 ));
5257 areaDeDigitacao .setLineWrap (true );
5358 areaDeDigitacao .setWrapStyleWord (true );
59+ areaDeDigitacao .addKeyListener (this );
5460 add (areaDeDigitacao , BorderLayout .CENTER );
5561
5662 JPanel painelSul = new JPanel ();
@@ -61,7 +67,6 @@ public TypingSpeedTestGUI() {
6167 labelResultadosErros = new JLabel ("Erros: --" );
6268
6369 botaoIniciar = new JButton ("Iniciar Teste" );
64-
6570 botaoIniciar .addActionListener (this );
6671
6772 painelSul .add (botaoIniciar );
@@ -75,30 +80,94 @@ public TypingSpeedTestGUI() {
7580
7681 @ Override
7782 public void actionPerformed (ActionEvent e ) {
78-
7983 if (e .getSource () == botaoIniciar ) {
80-
8184 iniciarNovoTeste ();
8285 }
8386 }
8487
8588 private void iniciarNovoTeste () {
86-
8789 int indiceAleatorio = random .nextInt (frases .length );
8890 fraseAtual = frases [indiceAleatorio ];
8991
90- labelFraseParaDigitar .setText ("<html><p style='paddinh: 5px; '>" + fraseAtual + "</p></html>" );
91-
92+ labelFraseParaDigitar .setText ("<html><p style='padding: 5px; '>" + fraseAtual + "</p></html>" );
9293 botaoIniciar .setText ("Reiniciar Teste" );
9394
9495 labelResultadosWPM .setText ("WPM: --" );
9596 labelResultadosPrecisao .setText ("Precisão: --%" );
9697 labelResultadosErros .setText ("Erros: --" );
9798
9899 areaDeDigitacao .setText ("" );
99-
100+ areaDeDigitacao .setEditable (true );
101+ testePodeComecar = true ;
102+ testeEmAndamento = false ;
100103 areaDeDigitacao .requestFocusInWindow ();
101104 }
105+
106+ private void finalizarTeste () {
107+ Instant fim = Instant .now ();
108+ String textoDigitado = areaDeDigitacao .getText ().trim ();
109+
110+ testeEmAndamento = false ;
111+ testePodeComecar = false ;
112+ areaDeDigitacao .setEditable (false );
113+
114+ System .out .println ("--- DEBUG INICIADO ---" );
115+ System .out .println ("Frase Original: [" + fraseAtual + "]" );
116+ System .out .println ("Texto Digitado: [" + textoDigitado + "]" );
117+ System .out .println ("--- DEBUG FINALIZADO ---" );
118+
119+ Duration duracao = Duration .between (inicio , fim );
120+ double tempoEmSegundos = duracao .toMillis () / 1000.0 ;
121+
122+ if (tempoEmSegundos == 0.0 ) {
123+ tempoEmSegundos = 0.01 ;
124+ }
125+
126+ int palavrasTotais = fraseAtual .split ("\\ s+" ).length ;
127+ double wpm = (palavrasTotais / tempoEmSegundos ) * 60.0 ;
128+
129+ int erros = 0 ;
130+ int lenOriginal = fraseAtual .length ();
131+ int lenDigitado = textoDigitado .length ();
132+ int lenComparacao = Math .min (lenOriginal , lenDigitado );
133+
134+ for (int i = 0 ; i < lenComparacao ; i ++) {
135+ if (fraseAtual .charAt (i ) != textoDigitado .charAt (i )) {
136+ erros ++;
137+ }
138+ }
139+ erros += Math .abs (lenOriginal - lenDigitado );
140+
141+ double precisao = Math .max (0.0 , ((double ) (lenOriginal - erros ) / lenOriginal ) * 100.0 );
142+
143+ labelResultadosWPM .setText (String .format ("WPM: %.2f" , wpm ));
144+ labelResultadosPrecisao .setText (String .format ("Precisão: %.2f%%" , precisao ));
145+ labelResultadosErros .setText (String .format ("Erros: %d" , erros ));
146+ }
147+
148+ @ Override
149+ public void keyTyped (KeyEvent e ) {
150+ if (testePodeComecar && !testeEmAndamento ) {
151+ inicio = Instant .now ();
152+ testeEmAndamento = true ;
153+ }
154+ }
155+
156+ @ Override
157+ public void keyPressed (KeyEvent e ) {
158+ if (e .getKeyCode () == KeyEvent .VK_ENTER ) {
159+ e .consume ();
160+ if (testeEmAndamento ) {
161+ finalizarTeste ();
162+ }
163+ }
164+ }
165+
166+ @ Override
167+ public void keyReleased (KeyEvent e ) {
168+ // chamado quando uma tecla é solta.
169+ // não será utilizado, mas é obrigatório ter.
170+ }
102171 public static void main (String [] args ) {
103172
104173 SwingUtilities .invokeLater (new Runnable () {
0 commit comments