2009-11-25 2 views
5

Nella mia classe di applicazione principale ho un oggetto di JTextArea (ad esempio txtArea). Ho creato due altri thread nel programma main_application. I due thread che ho creato sono per la lettura e la scrittura in porta seriale. Ora voglio mettere la porta seriale per leggere i dati del buffer in un oggetto JTextArea. Quindi ho bisogno di passare l'oggetto JTextArea creato in main_application a read-thread in modo che read-thread possa mettere l'output di lettura su JTextArea.Come passare oggetto dalla discussione principale a un'altra discussione in java

Ma dopo aver fatto questo sto affrontando un problema di accesso al puntatore nullo. Quando controllo l'oggetto JTextArea in main_application non è nullo ma dopo averlo passato al thread ne ho verificato il null. Non so come succede .... se ogni geek mi può aiutare sarò felice ....

Grazie, Surjya

+0

Come stai passando l'oggetto? Puoi fornire una dozzina di righe di codice che dimostrino il tuo problema? – Suppressingfire

risposta

1

oggetti di condivisione tra le discussioni possono ottenere molto disordinato, si consiglia di leggere su Actor model per un approccio diverso. Nello specifico nell'arena della GUI, un aiuto per il codice di avvicinamento Model-View-Controller.

Ma tornando alla domanda, si potrebbe rapidamente incidere rendendo il vostro JTextArea una variabile statica e solo lasciando tutti i diversi thread modificare l'istanza statica a volontà:

public static JTextArea TXTAREA 

void main_application(){ 
    //set up app 
    ... 
    TXTAREA = new JTextArea() 
    ... 
} 

poi nel tuo thread lettura seriale, imposta il testo per TXTAREA. Questa soluzione non è l'ideale, penso che un approccio migliore sarebbe utilizzare un approccio MVC e avere un controller che accetta il valore da inserire nell'area di testo.

+0

Non dovrebbe essere 'TXTAREA' volatile? (disclaimer: non ho ancora letto la concorrenza di java nella pratica, ma è sulla mia lista da fare :)) – wds

0
  1. La pubblicazione del riferimento JTextArea su un altro thread non è corretta perché i compomenti Swing sono basati su MVC (in realtà model-ui). Quindi, il tuo modo generale di lavorare con i componenti swing è di aggiornare i loro modelli e lasciare che la visualizzazione (ui) mostri la modifica;
  2. Un altro punto è che la maggior parte dei componenti oscillanti non sono thread-safe, vale a dire che non si può essere sicuri che l'applicazione funzioni correttamente se si utilizza il componente swing dal thread su EDT;

Quindi, si dovrebbe effettuare le seguenti operazioni: ogni volta che si dispone di nuovi dati da visualizzare presentare nuovo compito di JTextArea aggiornamento di contenuto che deve essere eseguito dalla EDT. È possibile farlo tramite SwingUtilities.invokeLater()

2

Come menzionato in un'altra risposta, è possibile modificare solo il contenuto di un componente Swing sul thread di oscillazione stesso. Un buon modo per assicurarsi che tutti gli altri thread facciano questo è di non esporre l'effettiva JTextArea, ma piuttosto di fornire agli altri oggetti un metodo sicuro per aggiungere testo all'area di testo dalla tua main_application, in questo modo:

public class main_application {

private JTextArea txtArea; 

public void addText(final String txt) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      txtArea.setText(txtArea.getText() + txt); 
     } 
    }); 
} 

}

Questo è un semplice esempio, ma è possibile estenderlo in base alle proprie esigenze. Ciò inoltre utilizza un modo più costoso di aggiungere al testo poiché aggiunge due stringhe immutabili. È possibile utilizzare JTextArea.getDocument() per recuperare il modello e quindi utilizzare i metodi di mutazione nel documento per aggiornare il testo in modo più efficiente.Tuttavia, fornendo un metodo come questo è possibile modificare l'implementazione in futuro senza influire sugli altri thread o oggetti.

Si noti che il parametro txt è finale che è necessario in modo che possa essere fatto riferimento direttamente nella classe interna anonima.

Si potrebbe voler disaccoppiare questo dalla classe principale dell'applicazione e creare un'interfaccia o una classe per il/i metodo/i modi/modi in cui si desidera manipolare l'area di testo degli altri thread e quindi consegnarli a un oggetto che avvolge questa area di testo.