Archief - [Prog][Java]Communicatie tussen threads

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

Hellsgamerz

Legacy Member
Ik ben bezig met een klein project waarin zowel sockets als een GUI gebruikt worden. Nu probeer ik een systeem op te zetten waarbij de socketdata in een textveld (swing, JTextArea) komt te staan. Hierbij gebruik ik threads (uiteraard).

Nu vroeg ik me af hoe je best de communicatie tussen threads laat verlopen?

De simpelste manier is het JTextArea-object meegeven waarin de data moet komen bij de constructor van de sockets. Dit is echter niet flexibel genoeg naar mijn zin.

Ik had het volgend idee: ieder object dat een thread start implementeert een interface. Die interface heeft een methode (laten we die doMethodInStarter noemen). Bij het implementeren schrijf je de code hiervan in detail in de klasse die de thread start. Aan het object dat je in een aparte thread start geef je het object mee waarin je de thread start (via this). Zo kan je altijd data verzenden naar de 'parent'-thread, en kan die afhandelen op zijn eigen manier, los van de andere thread.

Heeft iemand een beter idee? Ik ben net een jaar bezig met java in school en krijg dit allemaal nog wel, maar wachten is niet mn sterkste kant :D

forloRn_

Legacy Member
Akkoord, maar je zal in ieder geval in je nieuwe thread, of in de parent thread moeten verwijzen naar parent.textArea, dus blijft er van je flexibiliteit niet veel meer over (de parent zal sowieso een JTextArea moeten bevatten). Je zal de parent-klasse moeten extenden met een JTextArea voor deze bepaalde toepassing.

Of begrijp ik het verkeerd?

Bavo_acku

Legacy Member
Implementeer het Observer pattern. In Java komt dat neer op gebruik van EventListener model, onegeveer wat jij zegt.

Geinteresseerde objecten subscriben zichzelf op een broadcaster (producer), door een listener interface te implementeren (consumer).

Als je ooit ActionListener of MouseListener hebt gebruikt, zo dus. Er bestaat een goede package in Swing met utility classes daarvoor.

Hellsgamerz

Legacy Member
MVC design pattern, observer, observable, :applause:

Ik kan nu events versturen van mijn socketthread naar de textarea op de GUI, volgens model-view-controller en de Observable's.

gui: view
controller: controller (maakt gui en socket objecten en registreert socket als observable, is ook main-methode)
sockets: model

Enige probleem nu: hoe voer ik nu methodes uit van de socketklasse na op een knop te klikken in de gui? Ik zou eigenlijk de socket en de Gui-klasse zowel observer en observable kunnen maken het zo doen, maar ik denk niet dat dat de juiste manier is.

WHiSPy

Legacy Member
Je actions van de view worden in MVC sowieso op de controller uitgevoerd, zodus ik zie 't probleem niet. Je maakt gewoon 'n methode aan met de nodige functionaliteit en roept die op als de KeyPressed getriggerd wordt. :)

Hellsgamerz

Legacy Member
Ik kan niet werken met de controller van Swing he.

(tenzij ik mn termen door mekaar haal, ik heb nog maar 3 dagen naar MVC zitten kijken en het is niet altijd even makkelijker).

Het enige wat ik heb is mn eigen geschreven controllerklasse (die de gui en het socketobject maakt en de observers vastlegt). Maar die kan ik moeilijk gebruiken om een methode uit te voeren in het model bij een event van de view (connectie maken bij klikken op een knop)? Of wel? Want dan zou de view moeten weten hoe de controller werkt, wat niet de bedoeling is dachtik :doh:

WHiSPy

Legacy Member
Indien je op 'n knop klikt in 'n swing applicatie, dan vuurt ie toch 'n event af? Maak gewoon 'n eventlistener aan en zet de code die uitgevoerd moet worden daarin.

Hellsgamerz

Legacy Member
Hoe langer ik eraan werk hoe lelijker mn app eruit gaat zien :cry:

Ik heb alles es herwerkt in een nieuwe applicatie. Nu heb ik 2 klassen: Gui en SocketConnection.

  • Gui is de GUI (tja :woohoo: ). 3 knoppen (connect, disconnect en send), 3 textvakken (host, port, command) en 1 textarea.

  • SocketConnection is een connectie over een socket. Bevat oa connect en disconnect methodes.

Wat ik eigenlijk wil is een zeer flexibele manier om deze 2 te verbinden.
  • SocketConnection extends Observable om zo inkomende commands over een socket door te geven aan eender welk object die ernaar wil luisteren.

Wat blijft er nu over? De events van de GUI doorgeven. Nu ben ik niet gewoon om met events te werken (ik doe deze app om het te leren ook). De meeste voorbeelden (oa op de site van sun) maken een nieuwe klasse als een event gebeurd. Maar hoe weet die klasse nu welke code ze moet gaan uitvoeren? Lijkt mij dat je dan ergens in je applicatie een grote lijst if's krijgt om te bepalen welke methode moet aangeroepen worden. Dat is ook de enige manier waarop ik nu zit te denken: in de constructor van de GUI een object doorgeven en daar alle events aan koppelen. Maar hoe ik dat object dan ga ontwerpen is mij ook een raadsel :confused:

(ik begin er een hekel aan te hebben om het hier te vragen, maar ik vind totaal geen voorbeelden/tutorials/docs die én de werkwijze én goed design tonen :$ )

S3cT0r

Legacy Member
Ik weet niet precies hoe dat zit met Swing, maar met de Win32 API gebeurt ook alles event-driven (dwz, elk windowtje (alles is een window) heeft een ID), en om alle knopjes en dingetjes de juiste actie te laten uitvoeren, bouwt men een grote switch ala:

Code:
int dialogcallback(..., int id) {
   switch (id) {
      case DLG_BTN1:
         {
            doe stuff voor button 1;
         }
      break;

      case DLG_LST1:
         {
            doe stuff voor listview 1;
         }
      break;

      case default:
         {
             dit ken ik niet, stuur terug naar WinAPI;
         }
   }
}

Wss zit er niet al te veel anders op dan ongeveer hetzelfde te gaan doen, tenzij ik Swing verkeerd heb ingeschat.

Bavo_acku

Legacy Member
WHiSPy zei:
Indien je op 'n knop klikt in 'n swing applicatie, dan vuurt ie toch 'n event af? Maak gewoon 'n eventlistener aan en zet de code die uitgevoerd moet worden daarin.

De logica zegt van wel, toch zie je vaak Swing hangen als je een dure operatie uitvoert op een GUI event.
Een voorbeeld dat in me opkomt is dat de knop ingedrukt blijft 'hangen' indien het niet verwerkt wordt in andere thread.

MilM

Legacy Member
Ik ben ook geen expert, maar eens poging doen.

MVC is model, view, controller (zoals je al weet)

view is gewoon het uiterlijk, de buttons zijn controllers en model bevat inhoudelijke info.
View en controller kunt ge eventueel samen nemen (noemen ze dan model + interface)

Uw model klasse zou moeten gewoon velden bevatten met info ( over die strings bv)
En setters om deze velden te veranderen en getters om ze op te vragen
Bij deze setters zet je een extra lijntje (bv fireStateChanged() , hangt af van luisteraars)
Je krijgt dan bv:
.... setWaarde (int waarde){
this.waarde = waarde;
fireStateChanged();
}
Tevens bevat uw model een lijst van geregistreerde luisteraars

dan heb je dus de controller. Die gebruikt de setters van het model om de info te veranderen.

En de view zal de getters gebruiken om d einfo op te vragen die ze nodig hebben voor de view.

Wanneer er iets verandert in uw model, zal hij door die fireStateChanged() dit automatisch aan al zijn views doorgeven en die kunnen dan hun view aanpassen aan de veranderingen.


-----------------------------------------------------------------

Over die gebeurtenissen.
Buttons genereren een ActionEvent wanneer je op die button klikt
Een JTextField genereert ook een ActionEvent wanneer je op ENTER klikt
In die code van de ActionListener zet je dn wat e rmoet gebeuren als er een ActionEvent plaats vindt.

Dus je doet bv field.addActionListener(new MyOwnListener());
Nu is er bij uwe field (JTextField een luisteraar geregistreerd)
Wanneer je op ENTER klikt zal hij automatisch de code van MyOwnListener uitvoeren

Die code die automatisch uitgevoerd wordt vershchilt naargelang de luisteraar
Bij een Actionlistener is dat de methode 'public void actionPerformed (ActionEvent e)'
Dus MyOwnListener implementeert ActionListener en je moet een methode actionPerformed aanmaken met daarin uw uiteindelijke code die moet uitgevoerd worden.


Dus concreet. Je hebt een button/field. Je voegt daar een luisteraar aan toe. Dat is een eigen klasse die bv ActionListener implementeert (In dit geval zijn het ActionEvents)
En in die eigen klasse hoef je enkel actionPerformed te schrijven van methode (meer methodes mogen natuurlijk ook)
Je moet eventueel wle aan uw eigen klasse argumenten meegeven en daar dan setters ofzo ...


------------------------------------------------------------------------

Over die threads.
Zelf nog nie echt mee gewerkt.
Maar eens proberen.

Je hebt een klasse waar de code instaat die moet uitgeveord worden.
Die klasse is implementeert Runnable
In deze klasse moet er zich een methode bevinden 'public void run()'

Dus volgens mij heb je twee mogelijkheden.
Je maakt een thread aan in een bepaalde klasse, daarna voer je een settermethode uit op deze Thread. Deze vult een bepaalde waarde in een veld in uw threadklasse.
En in de methode run() kun je daar dan gebruik van maken.

Of je gebruik setters om bv uw model te geven en dan gebruik je getters van het model om d einfo op te halen.

Gecombineerd met uw ActionListener, kun je dus wanneer je iets ingeeft en je duwt op ENTER of op een knop, dat hij automatisch de waarde ophaalt, hij zet deze in een veld in het model, je maakt een thread aan, dan doeje thread.setModel(model); en dan kun je in uwe thread klasse alles ophalen wat je wenst (je maakt gewoon setters aan in uw model)

of in plaats van uw model te 'setten', zet je direct uw info in een veld in uw thread klasse.
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan