Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Java - Come si può inserire in un codice java l'immissione di un valore di tipo char da tastiera senza dover premere invio?
Forum - Java - Come si può inserire in un codice java l'immissione di un valore di tipo char da tastiera senza dover premere invio?

Avatar
musical wrighter (Normal User)
Newbie


Messaggi: 19
Iscritto: 26/09/2018

Segnala al moderatore
Postato alle 23:16
Venerdì, 06/12/2024
Ciao a tutti. Per spiegare meglio cosa sto cercando in pratica cerco di ottenere quello che in ambiente c++ si ottiene perfettamente e facilmente col metodo _getch() della libreria conio.h. Chi programma in entrambi i linguaggi sa che si tratta si di un input bloccante, ma non sbloccabile esclusivamente col tasto invio. Vorrei sapere quale funzione analoga esiste in java. Mi serve per un'app console per Windows che ho costruito, completamente funzionante tranne per questa piccola correzione  / miglioramento che intendo apportarvi ma che per quanto abbia setacciato il web non mi sono mai imbattuto in qualche soluzione che potesse funzionare. Si tratta di un gioco a tris una persona contro il computer. In cui l'utente mette virtualmente la pedina in una casella digitando un numero da 1 a 9. Dove 1 corrisponde alla casella in alto a sinistra, e 9 a quella in basso a destra. Il computer fa lo stesso ma con un generatore random sempre da 1 a 9 o meglio da 0 a 8. Il tutto con una base musicale che suona in loop e vengono comunicate le mosse di entrambi sia a schermo sia con audio che ho registrato con la mia voce. Di seguito i codici di tutte le classi utilizzate
Codice sorgente - presumibilmente Java

  1. package tastiera;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.IOException;
  5. import java.io.InputStreamReader;
  6.  
  7. import javax.swing.JOptionPane;
  8.  
  9. public class Lettura {
  10.         public String riga(String mSchermo)
  11. {
  12. String imTesto;
  13. System.out.println(mSchermo);
  14. try
  15. {
  16. BufferedReader invio=new BufferedReader(virtualK);
  17. imTesto=invio.readLine();
  18. }
  19. catch(IOException e)
  20.         {
  21.         imTesto="Spiacente, sto riscontrando qualche problema tecnico";
  22. }
  23. return imTesto;
  24. }
  25. public String finestra(String mSchermo)
  26. {
  27. String imTesto=JOptionPane.showInputDialog(mSchermo);
  28. return imTesto;
  29. }
  30. public int convNumerica(String caratteri)
  31. {
  32. int numero;
  33.         try
  34.         {
  35.                 numero=Integer.parseInt(caratteri);
  36.         }
  37.         {
  38.         numero=-1;
  39.         caratteri="Impossibile convertire. Sembra che i caratteri inseriti non siano tutti numeri interi";
  40. }
  41. return numero;
  42. }
  43. }


Questa era una classe di un progetto esterno che utilizzo ogni volta che creo progetti che prevedono input da tastiera. In Eclipse importo il classpat ogni volta. Al suo interno a un metodo per inserire linee di testo da riga di comando, che usa un InputStreamReader che legge System.in affiancato da un BufferedReader. Ha un altro metodo per creare finestre di dialogo, quindi se non esistono sistemi da riga di comando va bene anche se suggerite soluzioni del pacchetto Swing. Tanto anche in un progetto di tipo console si può importare. E l'ultimo metodo attualmente presente converte una stringa di caratteri in numeri interi. Se troverò una soluzione al problema topic di questa discussione amplierò questa classe aggiungendo un quarto metodo chiamato per esempio inputIstantaneo. Anche la prossima è una classe esterna che importo in ogni progetto che deve riprodurre file audio
Codice sorgente - presumibilmente Java

  1. package musicpachet;
  2.  
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.net.URL;
  6. import java.time.LocalTime;
  7.  
  8. import javax.sound.sampled.AudioInputStream;
  9. import javax.sound.sampled.AudioSystem;
  10. import javax.sound.sampled.Clip;
  11. import javax.sound.sampled.LineUnavailableException;
  12. import javax.sound.sampled.UnsupportedAudioFileException;
  13.  
  14. public class Player {
  15.         boolean succes=false;
  16.         File brano;
  17. URL branoOnLine;
  18. Clip cassa;
  19. public String caricamento(String nome)
  20. {
  21.         String erroreC;
  22. try
  23. {
  24. if(nome.substring(0,4).equals("http"))
  25. {
  26. branoOnLine=new URL(nome);
  27. musica=AudioSystem.getAudioInputStream(branoOnLine);
  28. }
  29. else
  30.         {
  31. brano=new File(nome);
  32. musica=AudioSystem.getAudioInputStream(brano);
  33.         }
  34. cassa=AudioSystem.getClip();
  35. cassa.open(musica);
  36. erroreC="Caricamento del brano avvenuto con successo!";
  37. succes =true;
  38. }
  39. catch(IOException e)
  40. {
  41. erroreC="Il file \""+nome+"\" non è stato trovato";
  42. succes=false;
  43. }
  44.         {
  45. erroreC="Questo tipo di file non è supportato. Caricamento di \""+nome+"\" non riuscito";
  46. succes=false;
  47. }
  48.         {
  49. erroreC="Linea non disponibile. Caricamento di \""+nome+"\" non riuscito";
  50. succes=false;
  51. }
  52. return erroreC;
  53. }
  54. public void riproduzione(int volte)
  55. {
  56. if(succes)
  57. {
  58. if(volte==1) {cassa.start();}
  59. else if(volte>1){cassa.loop(volte-1);}
  60. else{System.out.println("Errore nel riferimento alla riproduzione. L'argomento deve essere un numero intero positivo");}
  61. }
  62. }
  63. public void ritardo(int r)
  64. {
  65.         if(r>0)
  66. {
  67. LocalTime attesa=LocalTime.now();
  68. int fine=attesa.getSecond()+r;
  69. if(fine>59){fine=fine-60;}
  70. while(attesa.getSecond()!=fine) {attesa=LocalTime.now();}
  71. }
  72.         else {System.out.println("Errore nel riferimento al ritardo. L'argomento deve essere un numero intero positivo");}
  73. }
  74. public void chiusura()
  75. {
  76. if(succes)
  77. {
  78. cassa.stop();
  79. cassa.close();
  80. }
  81. }
  82.  
  83. }


Ed ecco invece le classi vere e proprie dell'audiotris
Codice sorgente - presumibilmente Java

  1. package audiotris;
  2.  
  3. public class Giocatore {
  4.         String pedine;
  5.         int lancio,sort;
  6.         boolean v;
  7. }


Codice sorgente - presumibilmente Java

  1. package audiotris;
  2.  
  3. import java.util.Random;
  4.  
  5. import musicpachet.Player;
  6. import tastiera.Lettura;
  7.  
  8. public class Motore {
  9.         Giocatore io=new Giocatore(),tu=new Giocatore();
  10.         Player base=new Player(),annuncio=new Player(),occupata=new Player(),nonContemplata=new Player(),vincita=new Player(),parita=new Player(),perdita=new Player(),risultato=new Player();
  11. Random caso=new Random();
  12. Lettura select=new Lettura();
  13.         String[]caselle={"alto a sinistra","alto al centro","alto a destra","medio a sinistra","medio al centro","medio a destra","basso a sinistra","basso al centro","basso a destra"};
  14.         String prosegui;
  15. void opposti()
  16.         {
  17.                 tu.sort=caso.nextInt(2);
  18.                 if(tu.sort==1) {io.sort=0;}
  19.         else {io.sort=1;}
  20.         }
  21.         String denomina(int numero,String nome)
  22.         {
  23.         if(numero==1) {nome="cerchio";}
  24.         else {nome="croce";}
  25.         return nome;
  26.         }
  27.         void mossa(Giocatore turno)
  28.         {
  29.         System.out.println(denomina(turno.sort,turno.pedine)+" in "+caselle[turno.lancio]); prosegui=annuncio.caricamento(denomina(turno.sort,turno.pedine)+" in "+caselle[turno.lancio]+".wav");
  30. if(prosegui.equals("Caricamento del brano avvenuto con successo!")){annuncio.riproduzione(1);}
  31.         else {System.out.println(prosegui);}
  32. caselle[turno.lancio]=denomina(turno.sort,turno.pedine);
  33.         }
  34.         Giocatore vittoria(Giocatore turno)
  35.         {
  36.         if(caselle[0].equals(denomina(turno.sort,turno.pedine))&&caselle[1].equals(denomina(turno.sort,turno.pedine))&&caselle[2].equals(denomina(turno.sort,turno.pedine))||caselle[3].equals(denomina(turno.sort,turno.pedine))&&caselle[4].equals(denomina(turno.sort,turno.pedine))&&caselle[5].equals(denomina(turno.sort,turno.pedine))||caselle[6].equals(denomina(turno.sort,turno.pedine))&&caselle[7].equals(denomina(turno.sort,turno.pedine))&&caselle[8].equals(denomina(turno.sort,turno.pedine))) {turno.v=true;}
  37.         else if(caselle[0].equals(denomina(turno.sort,turno.pedine))&&caselle[3].equals(denomina(turno.sort,turno.pedine))&&caselle[6].equals(denomina(turno.sort,turno.pedine))||caselle[1].equals(denomina(turno.sort,turno.pedine))&&caselle[4].equals(denomina(turno.sort,turno.pedine))&&caselle[7].equals(denomina(turno.sort,turno.pedine))||caselle[2].equals(denomina(turno.sort,turno.pedine))&&caselle[5].equals(denomina(turno.sort,turno.pedine))&&caselle[8].equals(denomina(turno.sort,turno.pedine))) {turno.v=true;}
  38.         else if(caselle[0].equals(denomina(turno.sort,turno.pedine))&&caselle[4].equals(denomina(turno.sort,turno.pedine))&&caselle[8].equals(denomina(turno.sort,turno.pedine))||caselle[2].equals(denomina(turno.sort,turno.pedine))&&caselle[4].equals(denomina(turno.sort,turno.pedine))&&caselle[6].equals(denomina(turno.sort,turno.pedine))) {turno.v=true;}
  39.         else {turno.v=false;
  40.         }
  41.         return turno;
  42.         }
  43.         void turnoComputer()
  44.         {
  45.                 do
  46.         {
  47.         io.lancio=caso.nextInt(9);
  48.         }
  49.         while(caselle[io.lancio].equals("cerchio")||caselle[io.lancio].equals("croce"));
  50.                         mossa(io);
  51. }
  52. int interazioneUtente()
  53. {
  54.         int pulsante;
  55.         switch(select.riga("Digita un numero da 1 a 9"))
  56. //Nella versione definitiva intendo sostituire questa riga con switch(select.inputIstantaneo())
  57.         {
  58.         case"1":{pulsante=1; break;}
  59.         case"2":{pulsante=2; break;}
  60.         case"3":{pulsante=3; break;}
  61.         case"4":{pulsante=4; break;}
  62.         case"5":{pulsante=5; break;}
  63.         case"6":{pulsante=6; break;}
  64.         case"7":{pulsante=7; break;}
  65.         case"8":{pulsante=8; break;}
  66.         case"9":{pulsante=9; break;}
  67. default:{pulsante=0; break;}
  68. }
  69. return pulsante;
  70. }
  71. void turnoPersona()
  72. {
  73.         do
  74.         {
  75. tu.lancio=interazioneUtente();
  76. tu.lancio=tu.lancio-1;
  77. if(tu.lancio<0)
  78. {
  79. System.out.println("Opzione non contemplata."); prosegui=nonContemplata.caricamento("non contemplata.wav");
  80. if(prosegui.equals("Caricamento del brano avvenuto con successo!")){nonContemplata.riproduzione(1);}
  81. else {System.out.println(prosegui);}
  82. }
  83. //E con questo ho risolto anche il problema di eventuali immissioni da parte dell'utente di caratteri diversi da numeri da 1 a 9
  84. else if(caselle[tu.lancio].equals("cerchio")||caselle[tu.lancio].equals("croce"))
  85. {
  86. System.out.println("Casella già occupata. Provane un'altra"); prosegui=occupata.caricamento("occupata.wav");
  87. if(prosegui.equals("Caricamento del brano avvenuto con successo!")){occupata.riproduzione(1);}
  88. else {System.out.println(prosegui);}
  89. }
  90. }
  91. while(tu.lancio<0||caselle[tu.lancio].equals("cerchio")||caselle[tu.lancio].equals("croce"));
  92.         mossa(tu);
  93. }
  94. void partita()
  95. {
  96. io.v=false;
  97. tu.v=false;
  98. opposti();
  99. int d=9;
  100. while(!vittoria(io).v&&!vittoria(tu).v&&d>0)
  101. {
  102. prosegui=base.caricamento("base.wav");
  103. if(prosegui.equals("Caricamento del brano avvenuto con successo!")){base.riproduzione(1000);}
  104. else {System.out.println(prosegui);}
  105. if(d<9) {annuncio.ritardo(2);}
  106. turnoComputer();
  107. d--;
  108. if(d>0&&!vittoria(io).v)
  109. {
  110. turnoPersona();
  111. d--;
  112. }
  113. base.chiusura();
  114. }
  115. occupata.chiusura();
  116. nonContemplata.chiusura();
  117. String terminePartita;
  118. if(vittoria(io).v)
  119. {
  120. prosegui=perdita.caricamento("perdita.wav");
  121. if(prosegui.equals("Caricamento del brano avvenuto con successo!")) {perdita.riproduzione(1);}
  122. else {System.out.println(prosegui);}
  123. prosegui=risultato.caricamento("vinto io.wav");
  124. risultato.ritardo(2);
  125. if(prosegui.equals("Caricamento del brano avvenuto con successo!")){risultato.riproduzione(1);}
  126. else {System.out.println(prosegui);}
  127. terminePartita="Ho vinto io!";
  128. }
  129. else if(vittoria(tu).v)
  130. {
  131. prosegui=vincita.caricamento("vittoria.wav");
  132. if(prosegui.equals("Caricamento del brano avvenuto con successo!")){vincita.riproduzione(1);}
  133. else {System.out.println(prosegui);}
  134. prosegui=risultato.caricamento("vinto tu.wav");
  135. risultato.ritardo(2);
  136. if(prosegui.equals("Caricamento del brano avvenuto con successo!")){risultato.riproduzione(1);}
  137. else {System.out.println(prosegui);}
  138. terminePartita="Hai vinto tu!";
  139. }
  140. else
  141. {
  142. prosegui=parita.caricamento("parità.wav");
  143. if(prosegui.equals("Caricamento del brano avvenuto con successo!")) {parita.riproduzione(1);}
  144. else {System.out.println(prosegui);}
  145. prosegui=risultato.caricamento("finisce in pari.wav");
  146. risultato.ritardo(2);
  147. if(prosegui.equals("Caricamento del brano avvenuto con successo!")){risultato.riproduzione(1);}
  148. else {System.out.println(prosegui);}
  149. terminePartita="Sono esaurite le caselle disponibili! Finisce in pari!";
  150. }
  151. prosegui=select.finestra(terminePartita+" Digita \"esci\" per uscire dal Gioco. O qualsiasi altro valore, anche chiudere questa finestra senza scrivere, per iniziare una nuova partita");
  152. if(!prosegui.toLowerCase().equals("esci"))
  153. {
  154. caselle[0]="alto a sinistra";
  155. caselle[1]="alto al centro";
  156. caselle[2]="alto a destra";
  157. caselle[3]="medio a sinistra";
  158. caselle[4]="medio al centro";
  159. caselle[5]="medio a destra";
  160. caselle[6]="basso a sinistra";
  161. caselle[7]="basso al centro";
  162. caselle[8]="basso a destra";
  163. }
  164. vincita.chiusura();
  165. parita.chiusura();
  166. perdita.chiusura();
  167. annuncio.chiusura();
  168. risultato.chiusura();
  169. }
  170. }


Al termine di ogni partita s'interrome la musica del gioco e vengono riprodotti contemporaneamente sia una musica diversa a seconda se ha vinto l'utente ha vinto il computer o sono state occupate tutte le caselle senza che nessuno facesse tris. Perdita.wav, vittoria.wav e parità.wav sono le 3 musiche. Vinto io.wav, vinto tu.wav e finisce in pari.wav sono invece i rispettivi annunci vocali dell'esito del gioco
Codice sorgente - presumibilmente Java

  1. package audiotris;
  2.  
  3. public class AudioTris {
  4.  
  5.         public static void main(String[] args) {
  6. Motore m=new Motore();
  7. do
  8. {
  9. m.partita();
  10. }
  11. while(!m.prosegui.toLowerCase().equals("esci"));
  12.         }
  13.  
  14. }


E questo è quanto. Se qualcuno sa  come eliminare l'invio dalla digitazione dei numeri me lo scriva nella risposta. Nel codice che avete letto durante la partita l'utente non deve premere più di un tasto alla volta dal momento che i numeri che servono sono da 1 a 9. E se preme tasti diversi come le lettere il programma non va comunque avanti. Comunica solo vocalmente e a schermo che l'opzione non è contemplata. La conferma con l'invio è per tato del tutto superflua. Il gioco tra l'altro acquisirebbe anche un se pur minimo grado di difficoltà in più. Nel fare le prove con questa mia prima versione mi è anche capitato di sbagliare a digitare, e non mancare il tris solo perché ho potuto cancellare con backspace e riscrivere prima di confermare con invio. Grazie in anticipo a chi mi risponderà e buona serata a tutti.

Ultima modifica effettuata da musical wrighter il 10/12/2024 alle 17:50
PM Quote
Avatar
Carlo (Member)
Guru^2


Messaggi: 1420
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 13:21
Sabato, 07/12/2024
Puoi usare KeyListener che ti mette a disposizione:

keyPressed(KeyEvent e)
keyReleased(KeyEvent e)
keyTyped(KeyEvent e)




Ultima modifica effettuata da Carlo il 07/12/2024 alle 14:06


in programmazione tutto è permesso
PM Quote
Avatar
musical wrighter (Normal User)
Newbie


Messaggi: 19
Iscritto: 26/09/2018

Segnala al moderatore
Postato alle 17:45
Martedì, 10/12/2024
Testo quotato

Postato originariamente da Carlo:

Puoi usare KeyListener che ti mette a disposizione:

keyPressed(KeyEvent e)
keyReleased(KeyEvent e)
keyTyped(KeyEvent e)





Ho provato questo
Codice sorgente - presumibilmente Java

  1. KeyEvent evento;       
  2. public void inputIstantaneo()
  3. {
  4.         KeyListener l=new KeyListener(this);
  5. l.keyReleased(evento);
  6. }


E mi esce il seguente errore
Cannot instantiate the type KeyListener
Che comunque anche prima d scoprire che così non compilava ero già perplesso dal fatto che keyReleased fosse un tipo void. E suppongo lo siano anche keyTyped e keyPressed. L'oggetto KeyEvent avrà mi auguro da qualche partte un attributo di tipo char il cui valore viene acquisito tramite questi tre metodi. Altrimenti non capisco come si possano processare i tasti premuti e ascoltati dal keyListener

PM Quote
Avatar
Carlo (Member)
Guru^2


Messaggi: 1420
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 19:55
Mercoledì, 11/12/2024
KeyListener funziona su un JFrame, ti ho scritto due righe, ho usato NetBeans:
Codice sorgente - presumibilmente Java

  1. package keylistener1;
  2.  
  3. import javax.swing.*;
  4. import java.awt.event.KeyEvent;
  5. import java.awt.event.KeyListener;
  6. /*
  7.  *  Carlo
  8.  */
  9. public class KeyListener1 {
  10.  
  11.    public static void main(String[] args) {
  12.         // Creazione di un frame
  13.         JFrame frame = new JFrame("KeyListener Example");
  14.         frame.setSize(400, 300);
  15.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  16.  
  17.         // Creazione di un'area di testo
  18.         JTextArea textArea = new JTextArea();
  19.         textArea.setEditable(false); // Rendiamo l'area di testo non modificabile
  20.         textArea.append("digita sulla tastiera" + "\n");
  21.        
  22.         //KeyListener all'area di testo
  23.         textArea.addKeyListener(new KeyListener() {
  24.             @Override
  25.             public void keyTyped(KeyEvent e) {
  26.                 // Evento chiamato quando viene digitato un carattere
  27.                 textArea.append("Tasto digitato: " + e.getKeyChar() + "\n");
  28.             }
  29.  
  30.             @Override
  31.             public void keyPressed(KeyEvent e) {
  32.                 // Evento chiamato quando un tasto viene premuto
  33.                 textArea.append("Tasto premuto: " + KeyEvent.getKeyText(e.getKeyCode()) + "\n");
  34.             }
  35.  
  36.             @Override
  37.             public void keyReleased(KeyEvent e) {
  38.                 // Evento chiamato quando un tasto viene rilasciato
  39.                 textArea.append("Tasto rilasciato: " + KeyEvent.getKeyText(e.getKeyCode()) + "\n");
  40.             }
  41.         });
  42.  
  43.         // Area di testo al frame
  44.         frame.add(new JScrollPane(textArea));
  45.         frame.setVisible(true);
  46.     }  
  47. }



Ho riletto meglio la tua domanda, non mi ero accorto che volevi intercettare i tasti dalla console al volo.
La Console non permette la lettura del buffer di tastiera finché non si preme invio, ci sono delle librerie, per esempio JNA:

https://github.com/java-native-access/jna

Personalmente non l'ho mai usata, lessi solo la documentazione qualche tempo fa.
Pastrocchiare con la console per fargli fare quello che non fa, non è una buona idea.

Il tuo codice è facilmente adattabile ad un Jframe.

EDIT: allegato lo zip che contiene: KeyListener1.jar


Carlo ha allegato un file: KeyListener1.zip (1622 bytes)
Clicca qui per scaricare il file

Ultima modifica effettuata da Carlo il 12/12/2024 alle 20:29


in programmazione tutto è permesso
PM Quote