Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2015
    Messaggi
    11

    [JAVA] Simulare inserimento "\n" alla pressione del JButton

    Salve a tutti, questo è il mio primo post dato che, ahimè, non sono riuscito a trovare una risposta cercando in rete.

    Comincio con le parti di codice interessate:

    Qui ho il metodo pressEnter, che uso nel programma vero e proprio per interrompere l'esecuzione e dare modo all'utente di premere invio quando vuole continuare.
    codice:
     
    public static Scanner s = new Scanner(System.in);
       public static void pressEnter(){
    System.out.println("Premere INVIO per continuare."); s.nextLine();
    }
    Qui ho il JButton "continua", nella classe che rappresenta la finestra grafica, al quale vorrei associare un ActionListener che, alla pressione del pulsante, provochi l'evento che permette al programma di "sorpassare l'ostacolo" pressEnter.
    codice:
            JButton b = new JButton("Continua");
            b.addActionListener(new ActionListener() {
    @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub //COSA DIAVOLO DEVO METTERCI QUI????????:dhò::dhò: }
    });
    In sostanza, alla pressione di "continua", il programma deve effettivamente continuare. Solo che non voglio andare a cercare per tutto il codice le chiamate a pressEnter per sostituirle; piuttosto vorrei che "continua" soddisfacesse l'attesa provocata dal nextline.
    Grazie in anticipo e spero di essermi spiegato chiaramente
    Ultima modifica di Pafi; 02-05-2015 a 12:56

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da Pafi Visualizza il messaggio
    Qui ho il JButton "continua", nella classe che rappresenta la finestra grafica, al quale vorrei associare un ActionListener che, alla pressione del pulsante, provochi l'evento che permette al programma di "sorpassare l'ostacolo" pressEnter.
    codice:
            JButton b = new JButton("Continua");
            b.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // TODO Auto-generated method stub
    
    //COSA DIAVOLO DEVO METTERCI QUI????????:dhò::dhò:
    
                }
            });
    Grazie in anticipo e spero di essermi spiegato chiaramente
    Sì, hai spiegato chiaramente cosa vuoi ottenere ... ma non il contesto generale e perché vuoi fare una cosa del genere. La tua applicazione è sia "console" che "grafica"? E perché? Cosa fa la interfaccia grafica di più o di meno rispetto allo standard-input?
    Forse è una applicazione che prima era solo "console" e ora vuoi farla diventare solo "grafica" ma mantenendo l'input da standard-input?

    Spiega il contesto!
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    May 2015
    Messaggi
    11
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Sì, hai spiegato chiaramente cosa vuoi ottenere ... ma non il contesto generale e perché vuoi fare una cosa del genere. La tua applicazione è sia "console" che "grafica"? E perché? Cosa fa la interfaccia grafica di più o di meno rispetto allo standard-input?
    Forse è una applicazione che prima era solo "console" e ora vuoi farla diventare solo "grafica" ma mantenendo l'input da standard-input?

    Spiega il contesto!
    In sostanza è il progetto per un esame e si tratta di un monopoly molto semplificato. Prima era solo console, poi ho creato un JFrame in cui ho, tra le altre cose, una JTextArea in cui ho dirottato il system.out e un JTextField che fungeva da console di input. Il JTextField ora non serve più a nulla (numero di giocatori e nomi vengono da JDialog apposite) se non per la pressione di Invio.

    Poichè era solo console, secondo il principio del minimo impatto a cui tanto tiene la professoressa, implementare la grafica (per lo meno una così banale) dovrebbe essere possibile senza modificare il codice se non in pochi punti strategici. Ecco perchè non vorrei andare a caccia dei pressEnter sparsi

    PS: la JTextArea la tengo perchè è lì che si leggono tutti gli avvenimenti della partita in corso

  4. #4
    Utente di HTML.it
    Registrato dal
    May 2015
    Messaggi
    11

    Soluzione trovata, ma...

    Ho trovato la soluzione:
    codice:
    public class ButtonContinua extends JButton implements ActionListener{
    
    //    private final Scanner s = new Scanner(System.in);
        private final PipedInputStream stdinPipedInput;
        private final PipedOutputStream stdinPipedOutput;
        private final PrintStream stdinStream;
        
        public ButtonContinua(String contenuto) throws IOException{
            
            super(contenuto);
            
            stdinPipedInput = new PipedInputStream();
            stdinPipedOutput = new PipedOutputStream(stdinPipedInput);
            stdinStream = new PrintStream(stdinPipedOutput, true); // autoFlush
            
            setVisible(true);
    
            addActionListener(this);    
        }
        
        public InputStream getIn() {
            return stdinPipedInput;
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            System.out.println("\n");    
    //        s.nextLine();
            stdinStream.println("\n");
    
        }  
    }
    Ora c'è un altro piccolo problema: quando premo il pulsante innesco un "doppio Enter", ossia do il segnale a DUE pressEnter consecutivi. Ho provato (come si vede nel codice) a inserire un nextLine() extra sperando che "consumasse" uno dei due Enter, ma l'unico risultato è il blocco del programma, probabilmente in attesa di un Enter che non arriverà mai. Idee?

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Sì, invece del "vero" System.in usare PipedInputStream/PipedOutputStream potrebbe essere una soluzione ma .... è molto delicata da trattare.
    Infatti PipedInputStream/PipedOutputStream vanno usati da thread differenti e la documentazione lo dice chiaramente:

    Typically, data is read from a PipedInputStream object by one thread and data is written to the corresponding PipedOutputStream by some other thread. Attempting to use both objects from a single thread is not recommended, as it may deadlock the thread.

    Quindi: il piped output è usato nel contesto del Event Dispatch Thread ..... e il piped input in quale thread è usato? Insomma, in quale contesto fai quel s.nextLine() ?
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  6. #6
    Utente di HTML.it
    Registrato dal
    May 2015
    Messaggi
    11
    A dirla tutta...il mio programma... è costituito da un unico thread e devo ammettere di non aver mai avuto a che fare con più di un flusso di esecuzione fin'ora, se non in qualche programmino di prova...

  7. #7
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da Pafi Visualizza il messaggio
    A dirla tutta...il mio programma... è costituito da un unico thread
    Quando il main() della applicazione viene avviato, quello è un thread, è il "main" thread. La gestione della interfaccia grafica Swing e degli eventi è nel EDT (Event Dispatch Thread) che è un altro thread .... non è il main thread.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  8. #8
    Utente di HTML.it
    Registrato dal
    May 2015
    Messaggi
    11
    Oddio giusto, scusami ma, come avrai già capito, non ho ancora radici ben piantate nel territorio dei thread. Spero di aver capito bene la domanda, ma in ogni caso ti do due risposte:

    1. System.setIn(buttonContinua.getIn()); viene fatto nel costruttore della Finestra(che estende JFrame).

    2. Il metodo pressEnter(), al cui interno viene chiamato il nextLine(), viene chiamato decisamente nel main thread, poichè fa parte del codice relativo al programma senza grafica.

    Spero di aver risposto alla tua domanda.
    Grazie per la pazienza

  9. #9
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da Pafi Visualizza il messaggio
    1. System.setIn(buttonContinua.getIn()); viene fatto nel costruttore della Finestra(che estende JFrame).
    Non mi è chiaro se qui sei nel main thread o nel EDT. Nel main generalmente è "buona" prassi (io lo faccio sempre) usare il solito invokeLater per avviare la creazione della interfaccia utente già fin da subito nel EDT.
    Comunque questo punto è meno importante.

    Quote Originariamente inviata da Pafi Visualizza il messaggio
    2. Il metodo pressEnter(), al cui interno viene chiamato il nextLine(), viene chiamato decisamente nel main thread, poichè fa parte del codice relativo al programma senza grafica.
    Questo sì, è più importante. E vuol dire che l'approccio dei piped input/output tecnicamente può funzionare.

    Quote Originariamente inviata da Pafi Visualizza il messaggio
    quando premo il pulsante innesco un "doppio Enter", ossia do il segnale a DUE pressEnter consecutivi.
    Già ... riguardando meglio il codice che hai scritto mi pare ovvio!

    stdinStream.println("\n");

    O fai stdinStream.print("\n");
    Oppure fai stdinStream.println();

    Altrimenti se fai un mix è naturale che Scanner "veda" 2 newline (nota: è una cosa interna e non è documentata nel javadoc ma in Scanner il pattern del newline è "\r\n|[\n\r\u2028\u2029\u0085]", quindi accetta sia CR+LF che CR che LF).
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  10. #10
    Utente di HTML.it
    Registrato dal
    May 2015
    Messaggi
    11
    Quote Originariamente inviata da andbin Visualizza il messaggio
    (nota: è una cosa interna e non è documentata nel javadoc ma in Scanner il pattern del newline è "\r\n|[\n\r\u2028\u2029\u0085]", quindi accetta sia CR+LF che CR che LF).
    Non credo di capire cosa intendi, ma mi informerò in rete senza scomodarti oltre

    Quote Originariamente inviata da andbin Visualizza il messaggio
    Già ... riguardando meglio il codice che hai scritto mi pare ovvio!

    stdinStream.println("\n");

    O fai stdinStream.print("\n");
    Oppure fai stdinStream.println();

    Altrimenti se fai un mix è naturale che Scanner "veda" 2 newline
    Non l'avrei mai scoperto. Sarei potuto morire cercando questo errore mascherato Ti ringrazio infinitamente, sia per l'aiuto che per la pazienza che hai portato. Ora il progetto è quasi terminato, devo solo fare un po' di refactoring e cancellare tutte le millemila righe di codice "vecchio" che ho lasciato lì, commentate, in attesa di chissà cosa

    Grazie ancora e tanti saluti

    PS: Devo in qualche modo segnalare che la questione è stata risolta?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.