Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    Javafx Aggiornare Gui on un metodo di una classe esterna

    Buon giorno a tutti, Io sono poco esperto e spero di riuscire a spiegarmi
    Ho fatto un programmino che fa una simulazione usando javafx, in guesta gui c'� una text area nella quale vorrei scrivere del testo quando in una metodo di una classe che ho creato per fare questa simulazione si verifica una cerca condizione.
    Non sapendo come fare ho provato cos�:

    codice:
    for(int i = 0; i < nSimulazioni; i++)
    {
        .... .....
        if(numero>0){
             this.UI.upDateMessaggio(messaggioRisultato);
         }
    }
    In un ciclo se si verifica una cerca condizione richiamo una funzione della gui upDateMessaggio nella mia classe ho creato una variabile privata che punta alla gui in modo da poter richiamarne la funzione


    nella classe controller della gui ho creato quella funzione

    codice:
        @FXML
        void doEseguiVarie(ActionEvent event) {
            this.txtResult.setText("");
            this.simulazioni = new SimulatoreMultiplo(this.txtNSimulazioni.getText(), this);
            this.simulazioni.startSimulazioni();
        }
        
        public void upDateMessaggio(String messaggio){
            this.txtResult.appendText(messaggio);
        }
    la funzione doEseguiVarie � eseguita da un pulsante, la funzione this.simulazioni.startSimulazioni(); � quella che mi lancia il ciclo for di prima

    Facendo in questo modo la cosa funziona ma parzialmente, il ciclo for a senda della simulazione potrebbe essere anche molto lungo tipo 100000000 di cilci, il sistema mi aggiorna la textArea con this.txtResult.appendText(messaggio); ma solo alla fine della simulazione. Io vorrei che continuasse ad aggiungere righe mano a mano che i dati emergono.

    Ho provato a cercare su internet ma non sono riuscito a trovare una soluzione che io sia in grado di capire.
    Avete qualche consiglio?
    un uomo senza panza e come un cielo senza stelle ...mio tris ...

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da clingonboy Visualizza il messaggio
    il sistema mi aggiorna la textArea con this.txtResult.appendText(messaggio); ma solo alla fine della simulazione.
    Non me ne intendo granché di JavaFX ma il threading è molto simile a quello di Swing: esiste un singolo e unico thread dedicato alla UI, in Swing è convenzionalmente chiamato Event Dispatch Thread (EDT), in JavaFX se non sbaglio viene chiamato il "JavaFX application thread".
    Questo tipo di thread si occupa in generale del dispacciamento degli eventi e della gestione dei componenti (in Swing in questo contesto vengono disegnati i componenti, in JavaFX non ne sono certo).

    Comunque il punto è che il thread della UI NON va mai tenuto "impegnato" con del proprio codice, altrimenti la UI è "congelata" poiché il framework della UI (Swing o JavaFX che sia) in quel periodo di tempo non può riavere il controllo e quindi procedere con altri eventi, painting, ecc..

    La soluzione non è banale: il multi-threading. Direttamente al livello più basso (Runnable/Thread) oppure con astrazioni di più alto livello se/come offerte dal framework della UI. In Swing esiste lo SwingWorker (da Java 6), in JavaFX non so ora se c'è un equivalente.

    Ma il punto è che bisogna avere le idee chiare sul multi-threading: sincronizzazione, mutua-esclusione, visibilità delle modifiche tra i thread, locking, meccanismi di wait/notify, ecc... Senza questi concetti non si va molto lontano ..
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Quote Originariamente inviata da andbin Visualizza il messaggio

    La soluzione non è banale: il multi-threading. Direttamente al livello più basso (Runnable/Thread) oppure con astrazioni di più alto livello se/come offerte dal framework della UI. In Swing esiste lo SwingWorker (da Java 6), in JavaFX non so ora se c'è un equivalente.

    Ma il punto è che bisogna avere le idee chiare sul multi-threading: sincronizzazione, mutua-esclusione, visibilità delle modifiche tra i thread, locking, meccanismi di wait/notify, ecc... Senza questi concetti non si va molto lontano ..
    Grazie sei stato gentile, la tua risposta mi ha chiarito le idee, avevo paura che si andesse verso quella direzione, vorra' dire che mi rimbocchero' le maniche.
    un uomo senza panza e come un cielo senza stelle ...mio tris ...

  4. #4
    Mi sono fatto coraggio e ho provato:

    codice:
        void doEseguiVarie(ActionEvent event) {
        	
        	this.simulazioni = new SimulatoreMultiplo(txtNSimulazioni.getText(), this);
        	
        	Task task = new Task()
        	{
        		@Override protected Integer call() throws Exception
        		{
        			txtResult.setText("");
        	    	simulazioni.startSimulazioni();
        	    	
        			return 1;
        		}
        	};
        	new Thread(task).start();
        }
        
        public void upDateMessage(String messaggio)
        {
        	txtResult.appendText(messaggio);
        }
    ho creato un trade e ho lanciato la funzione simulazioni.startSimulazioni(); al suo interno.

    In questo modo funzione, grazie @andbin per avermi indirizzato per questa strada.

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da clingonboy Visualizza il messaggio
    In questo modo funzione
    Nì, non è comunque appropriato. JavaFX (come Swing) non è thread-safe. C'è una documentazione di Oracle:
    Concurrency in JavaFX
    dove lo dice chiaramente. Si può accedere e modificare la interfaccia utente SOLO nel contesto del JavaFX Application thread. Nel contesto di un altro thread (come il tuo per il tuo Task), non è appropriato fare txtResult.setText("");

    Quel Task è specifico di JavaFX e l'uso con Thread è documentato ed ok. Vedi Task. In particolare poi la sezione "A Task Which Modifies The Scene Graph" dove mostra l'uso del Platform.runLater (che è l'equivalente del SwingUtilities.invokeLater di Swing).

    E vedo che Task offre una serie di meccanismi di updateMessage/updateProgress/ecc per semplificare l'aggiornamento della UI.

    Credo che devi andare molto più "a fondo" su JavaFX piuttosto che scalfire solo la punta dell'iceberg.
    Ultima modifica di andbin; 19-04-2016 a 09:27
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  6. #6
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Nì ...

    Credo che devi andare molto più "a fondo" su JavaFX piuttosto che scalfire solo la punta dell'iceberg.
    hai ragione, sono stato un po' frettoloso perchè volevo arrivare in fretta al risultato finale senza preoccuparmi se quello che facevo era corretto e robusto.
    Mi devo leggere con attenzione la documentazione.
    Poi ti faccio sapere.
    Grazie ancora.
    un uomo senza panza e come un cielo senza stelle ...mio tris ...

  7. #7
    C'è un professore universitario che pubblica su youtube le sue lezioni, una di queste è focalizzata sulla gestione dei thrade proprio con javafx. Mi permetto di condividerla qui perché l'ho trovata molto interessata e dettagliata e come è stata utile a me può essere utile a molti.
    https://youtu.be/MGozAl32Jtc
    un uomo senza panza e come un cielo senza stelle ...mio tris ...

Tag per questa discussione

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 © 2025 vBulletin Solutions, Inc. All rights reserved.