Ho un'applicazione che deve dare dei messaggi in una text area, finchè non finisce un certo processo che può durare qualche secondo, ma quando parte il processo l'interfaccia rimane in uno stato di congelamento totale! Come lo evito?
Grazie![]()
Ho un'applicazione che deve dare dei messaggi in una text area, finchè non finisce un certo processo che può durare qualche secondo, ma quando parte il processo l'interfaccia rimane in uno stato di congelamento totale! Come lo evito?
Grazie![]()
Utilizzando i Thread.
ok, ma chi dovrebbe estendere Thread?
O forse intendevi di creare un thread a parte che gestisca questi messaggi?
E' un problema più volte trattato in questo forum qui c'è uno dei thread in cui è stato discussa la cosa.
ok mi sono letto il post; mi è venuto in mente un'idea: creare una classe thread contenente una coda, il cui metodo run non fa altro che prelevare stringhe dalla coda e "appenderle" nella text area.
Ho un'altra domanda: quando viene avviata un'applicazione, compresa di gui, quanti thread sono attivi premettendo che non ce ne siano creati dal programmatore? e perchè molte operazioni sono gestite dall'EDT e non dal thread principale dell'applicazione?
My 2 cents. Se ho capito (perché non mi è del tutto chiaro):
- hai una applicazione grafica
- l'applicazione fa partire un processo esterno (non hai specificato come, con un bottone, un timer? e poi con cosa lo esegui? Runtime.exec?)
- questo processo genera un output che tu vuoi visualizzare in una text area (almeno così ho capito)
Ora, sempre che abbia capito, tu vorresti far scrivere il processo in una coda di messaggi, e poi creare
un thread che svuota la coda e popola la textarea.
Ora, (1) il problema, se è così, permane, perché è l'esecuzione del processo (la Process.getInputStream in particolare se usi quest API) che ti blocca la GUI e (2) si risolve facilmente mettendo tutta l'esecuzione del processo in un thread, senza code.
Questo semplice programmino, ti fa vedere quanti thread sono in esecuzione all'avvio del programma stesso, che non fa uso di GUI:Originariamente inviato da John360
Ho un'altra domanda: quando viene avviata un'applicazione, compresa di gui, quanti thread sono attivi premettendo che non ce ne siano creati dal programmatore?
Eseguendolo si dovrebbe ottenre questo output:codice:public class NumeroThread { public static void main(String[] args) { // Ottengo il ThreadGroup padre di tutto ThreadGroup mainGroup = Thread.currentThread( ).getThreadGroup( ); ThreadGroup parentGroup; while ( ( parentGroup = mainGroup.getParent() ) != null ) { mainGroup = parentGroup; } // Stampo la stima del numero di thread attualmente attivi System.out.println("In totale ci sono circa " + mainGroup.activeCount() + " threads attivi.\n"); // Vediamoli Thread[] totThreads = new Thread[ mainGroup.activeCount() ]; while ( mainGroup.enumerate(totThreads, true) == totThreads.length ) { totThreads = new Thread[ totThreads.length * 2 ]; } for(Thread t : totThreads) if (t != null) System.out.println( t.getName() ); } }
Questo dovrebbe darti un'idea di quanti thread ci siano sottobanco che girano.codice:In totale ci sono circa 5 threads attivi. Reference Handler Finalizer Signal Dispatcher Attach Listener main
L'EDT è il thread che si occupa di gestire gli eventi utente (generati dall'interfaccia grafica). Si occupa di prendere in carico gli eventi e distribuirli ai componenti predisposti a riceverli, nonchè di ridisegnare (di conseguenza) l'intera interfaccia grafica in risposta a tali eventi.e perchè molte operazioni sono gestite dall'EDT e non dal thread principale dell'applicazione?
Ciao.![]()
"Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza
grazie lele XD come sempre molto paziente a spiegare tutto per bene!
Rispondendo a coder: no, non c'è nessun processo esterno, semplicemente alla pressione di un pulsante l'applicazione dei fare dei determinati calcoli, e mostrare(o aggiornare) di volta in volta quello che ottiene su una text area, il tutto finchè non termina tutta l'operazione. Questa operazione viene eseguita da un oggetto istanziato e fatto partire nel metodo action performed(proprio alla pressione di quel preciso pulsante.
Scusami ma non ho ben capito cosa vuoi dire... spero di essere stato più chiaro ora, gentilmente potresti spiegarmi la tua soluzione?
Ti faccio "gentilmente" un esempioguarda se ti può andare bene.
Ho fatto una piccola correzione, ora è ok.codice:import java.awt.*; import java.awt.event.*; import javax.swing.*; class MioCalcolo implements Runnable { private Thread thread; private JTextArea jta; public MioCalcolo(JTextArea jta) { this.jta = jta; } public boolean esegui() { if (thread != null && thread.isAlive()) return false; thread = new Thread(this); thread.start(); return true; } public void run() { for (int i = 0; i < 3; i++) { jta.append("Calcolo in fase: " + i + "\n"); try { Thread.sleep(1000); } catch (InterruptedException ie) { } } } } class Demo extends JFrame { private MioCalcolo mc; private JTextArea jta; public Demo() { // jtextarea jta = new JTextArea(5, 20); // jbutton mc = new MioCalcolo(jta); JButton start = new JButton("Start"); start.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { boolean ret = mc.esegui(); if (!ret) jta.append("Ancora in esecuzione\n"); } }); // jframe getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS)); jta.setAlignmentX(Component.CENTER_ALIGNMENT); start.setAlignmentX(Component.CENTER_ALIGNMENT); add(jta); add(start); setSize(400, 300); } public static void main(String args[]) { new Demo().setVisible(true); } }
benissimo! ho capito, fai una sorta di wrap della text area praticamente!
Grazie per la spiegazione![]()