Threads Serielle Schnittstelle mit Listener / Aufrufendes GUI

snueffel

Mitglied
Hallo zusammen!

Aufgrund des Interesses an JAVA, welches mein Elektrotechnik-Studium geweckt hat, schreibe ich derzeit eine Software im Rahmen meiner Studienarbeit. Zunächst einmal ein "Danke", denn dieses Forum hat mir bei den Anfängen sehr geholfen, also schön, dass es euch gibt! :toll:

Leider habe ich derzeit ein Problem, was ich offenbar nicht alleine lösen kann: Über einen Button soll ein Thread gestartet werden, der über eine serielle Schnittstelle eine Zeichenkette (von einem Gerät) einliest. Grundsätzlich funktioniert das wunderbar; die gewünschten Zeichen erhalte ich. Ich nutze hierfür jssc.

Da im Vorfeld nicht klar ist, wie viele Zeichen übertragen werden (Das Ende des Strings wird mit einem "ENDE" signalisiert), nutze ich einen Listener, der eine zwischengespeicherte Zeichenkette genau dann erweitert, wenn ein weiteres Zeichen übertragen wurde; hierzu das Codefragment:
Java:
public void run()
    {
	try
	{
	    // Ein Einstellungsstring muss zunächst ausgegeben werden
	    serialPort.openPort();
	    serialPort.setParams(baudrate, databits, stopbits, parity, true, true);
	    char cr = 13;
	    einstellung = einstellung + cr;
	    serialPort.writeBytes(einstellung.getBytes());

	    // Anschließend kann auf Rückgaben gewartet werden
	    int mask = SerialPort.MASK_RXCHAR;
	    serialPort.setEventsMask(mask);
	    new SerialPortReader();
	    serialPort.addEventListener(new SerialPortReader());
	} catch (Exception e)
	{}
    }
    class SerialPortReader implements SerialPortEventListener
    {
	public void serialEvent(SerialPortEvent event)
	{
	    if (event.isRXCHAR())
	    {
		if (event.getEventValue() == 2)
		{
		    // Bytes im input-Buffer Kontrollieren
		    // sobald 2 bytes (1 Zeichen) verfügbar, String erweitern
		    try
		    {
			byte buffer[] = serialPort.readBytes(2);
			String neu = new String(buffer);
			s = s + neu;
			if (s.contains("ENDE") || s.contains("ENDE"))
			    serialPort.closePort();
		    } catch (SerialPortException e)
		    {}
		}
	    }
	}
    }

Wie schon zu erkennen ist, erweitert die Klasse "Thread", damit sich die aufrufende GUI-Klasse nicht "aufhängt". Dieses startet über einen Button den Thread, der natürlich bereits nach wenigen Millisekunden beendet ist (Es arbeitet ja nur noch der Listener). Wie teile ich jedoch dem aufrufenden Programm mit, dass der Port geschlossen wurde und der String abgerufen werden kann? :bahnhof: Weiterhin soll der Vorgang abgebrochen werden, sofern ein entsprechender Button betätigt wurde (Das funktioniert bisher natürlich auch nicht wie gewollt, da der Thread ja schon längst beendet ist, auch wenn noch nichts empfangen wurde). Ich hoffe ihr könnt mir helfen :)
 

rme

Top Contributor
Hallo :)

Du könntest dafür einen eigenen Listener implementieren:

- leg dir ein Interface namens SerialDataListener oder so an, das eine Methode onDataReady(String data) enthält
- implementier dieses Interface in der aufrufenden Klasse oder erzeuge eine anonyme Klasse, die es implementiert
- übergib das implementierende Objekt der Klasse, die den String einliest, und speicher es dort
- wenn der String gelesen wurde, ruf die Methode im Objekt auf, das das Interface implementiert. Dadurch erhält es auch gleichzeitig den String und muss ihn nicht selbst abholen.

Zum Unterbrechen kannst du die Methode interrupt() auf dem Thread aufrufen. Wenn der Thread gerade in einer blockierenden Operation ist, wird dort eine InterruptedException ausgelöst und du weißt dann, dass der Thread beendet werden soll. Ansonsten kannst du auch Thread.interrupted() innerhalb des Threads aufrufen, um zu prüfen, ob von außen unterbrochen wurde und dann alles beenden.

Falls das nicht ausführlich genug war, frag nochmal gezielt nach, dann beschreib ich die Stelle etwas ausführlicher :)
 

snueffel

Mitglied
Sauber! Vielen Dank für die schnelle Antwort, das war genau der "Tritt" in die Richtung, den ich gebraucht habe! :idea: Auf dem Trichter einen Listener zu implementieren, bin ich schon gekommen, allerdings war ich weit von einer konkreten Idee entfernt :bloed:

Solche antworten liebe ich ja: Kein konkreter Code, sondern etwas, dass einen beim Überlegen weiterhilft! :toll:

Und um alles zu vervollständigen, die Lösung mit dem interrupt(): Vorher wurde der Port im Listener geschlossen, jetzt gibt es eine extra Methode, die dies übernimmt. Bei einem manuellen Beenden kann der Port so noch geschlossen werden (Es muss nichtmal zwingend ein Thread gestartet werden, das war mein Denkfehler: Der Thread ist ja schon nach kürzester Zeit abgearbeitet, ich wollte ihn jedoch am Leben halten, bis der String komplett ist. Durch den Listener erübrigt sich dies).
 

rme

Top Contributor
Schön, dass du das so schnell umsetzen konntest :) Dann noch zwei kleine Tipps für den restlichen Code:

Du fügst momentan mit dem +-Operator das gelesene Zeichen an den String an. Das ist eine recht langsame Operation, weil dann erst neuer Speicher für den neuen String (alte Länge + angefügte Länge) reserviert werden muss, der alte String vollständig dort hineinkopiert werden muss und schließlich der neue String angefügt werden muss. Mit der Klasse StringBuilder oder StringBuffer kannst du statt + die Append-Methode verwenden, die nur selten neuen Speicher reservieren muss, weil sie genau für solche Operationen gedacht ist. Auf der kannst du am Ende toString aufrufen, um den zusammengebauten String herauszuholen. Siehe auch hier: Galileo Computing :: Java ist auch eine Insel – 4.4 Veränderbare Zeichenketten mit StringBuilder und StringBuffer

Dann verwendest du contains zum Prüfen, ob ENDE vorliegt. Da du das bei jedem empfangenen Byte machst, nehme ich an, dass ENDE nur am ENDE steht - du könntest dann statt contains lieber endsWidth verwenden. Der Vorteil ist, dass nicht bei jedem Byte der ganze String durchsucht werden muss, sondern nur die letzten 4 Zeichen.

Beide Sachen lohnen aber erst, wenn deine Strings ein paar hundert Zeichen überschreiten. Wenn die eh nur 50 Zeichen oder so lang sind, lohnt das evtl. nicht.
 
Zuletzt bearbeitet:

snueffel

Mitglied
Vielen Dank auch nochmals für die beiden Tipps! :)

Der Grund, warum ich den String so zusammengesetzt habe, war, dass ich erstmal sehen wollte, ob ich das Ganze überhaupt so eingelesen bekomme, wie ich möchte (Ich habe vorher noch nie eine serielle Schnittstelle mit JAVA angesprochen). Da ich jedoch maximal 30-40 Zeichen erwarte, werde ich es vermutlich bei der aktuellen Lösung belassen; den Code empfinde ich als einfacher lesbar und der Performancegewinn rechtfertigt eine Änderung kaum.

Bei dem Tip endsWith() zu verwenden sieht das ganze anders aus: Auch hier war das nur provisorisch so implementiert, da ich wusste, dass irgendwann ein "ENDE" kommt. Hieran muss ich zwar noch ein CR anhängen, aber die Überprüfung geht sicherlich besser. Ich muss nämlich leider jedes einzelne Zeichen prüfen, damit ich auch wirklich alle habe.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Daten über serielle Schnittstelle empfangen Allgemeine Java-Themen 4
Q Selbständig ActionEvent auslösen zum Daten senden über serielle Schnittstelle Allgemeine Java-Themen 7
stroggi Serielle Schnittstelle (jssc) - Flush benötigt? Allgemeine Java-Themen 2
T Input und Outputstream , serielle Schnittstelle Allgemeine Java-Themen 1
M Serielle Schnittstelle ansteuern - mit Processing Bibliothek Allgemeine Java-Themen 4
I Serielle Schnittstelle Allgemeine Java-Themen 5
N Serielle Schnittstelle / COM-Port auslesen und die empfangenen Daten verarbeiten Allgemeine Java-Themen 1
O Zugriff auf Serielle Schnittstelle - Keine Ports gefunden. Allgemeine Java-Themen 8
G serielle Schnittstelle einlesen Allgemeine Java-Themen 13
D Datenübertragung über serielle Schnittstelle Allgemeine Java-Themen 4
G Problemme mit serielle Schnittstelle Allgemeine Java-Themen 9
MQue serielle Schnittstelle Allgemeine Java-Themen 2
E serielle Schnittstelle Allgemeine Java-Themen 6
N Serielle Schnittstelle ansprechen Allgemeine Java-Themen 9
J serielle Schnittstelle unter Linux Allgemeine Java-Themen 3
W Zugriff auf lokale serielle Schnittstelle via Applet Allgemeine Java-Themen 3
A Serielle Schnittstelle | Barcodescan | ohne Tastatur Allgemeine Java-Themen 11
G Zugriff auf serielle Schnittstelle mit Java 1.5.0 Allgemeine Java-Themen 11
J serielle schnittstelle unter linux Allgemeine Java-Themen 3
ms_cikar RS232 Serielle Baudrate automatisch einstellen Allgemeine Java-Themen 1
L Java und Serielle COM Ports Allgemeine Java-Themen 4
R Virtuelle Serielle Schnittstellen mit RXTX Allgemeine Java-Themen 2
F Serielle Kommunikation Allgemeine Java-Themen 20
J javax.comm findet serielle ports nicht Allgemeine Java-Themen 2
L Serielle Kommunikation Allgemeine Java-Themen 6
G Serielle Verbindung zu einem Handy Allgemeine Java-Themen 3
P serielle Schnitttstelle Allgemeine Java-Themen 14
G javax.comm bzw serielle Schhnittstelle? Allgemeine Java-Themen 2
V Funktionale Schnittstelle in Java Allgemeine Java-Themen 3
Tarrew OpenAPI Schnittstelle - Mehrere Kunden mit unterschiedlichen Zugriffsrechten Allgemeine Java-Themen 2
B Schnittstelle zwischen MySQL und Apache Allgemeine Java-Themen 8
Meeresgott Best Practice Mini REST-Schnittstelle Allgemeine Java-Themen 4
P Schnittstelle java Programm zu Webserver / Browser Allgemeine Java-Themen 2
M Schnittstelle Datanorm Allgemeine Java-Themen 2
H Daten via COM Schnittstelle erhalten Allgemeine Java-Themen 2
I Java - perfekte Schnittstelle für Hacker? Allgemeine Java-Themen 8
M Java-Pawn Schnittstelle ? Allgemeine Java-Themen 0
L COM Schnittstelle in Java programmieren Allgemeine Java-Themen 4
T Schnittstelle zu Bash?! Allgemeine Java-Themen 2
D Aufgabe: Schnittstelle und Proxy implementieren Allgemeine Java-Themen 2
H Interface Generische Schnittstelle (rekusiv) Allgemeine Java-Themen 2
B Schnittstelle von Facebook zu Java(Eclipse) für meine Internetseite Allgemeine Java-Themen 20
U Realisierung einer "Plugin-Schnittstelle": Allgemeine Java-Themen 12
A Input/Output Applet-Zugriff auf PHP-Schnittstelle (externer Server) Allgemeine Java-Themen 22
M Schnittstelle für durchgereichte Interaktionen in Komponentenhierarchie? Allgemeine Java-Themen 3
P Auslesen serieller Schnittstelle - umwandeln von byteArray Allgemeine Java-Themen 3
S Problem mit serieller Schnittstelle Allgemeine Java-Themen 10
M Zugriff auf Parallel-Schnittstelle Allgemeine Java-Themen 2
P Schnittstelle über Webservice SOAP Allgemeine Java-Themen 11
MQue Schnittstelle programmieren Allgemeine Java-Themen 2
H lpt1 schnittstelle Allgemeine Java-Themen 6
M Schnittstelle java.util.Set Allgemeine Java-Themen 9
G Kommunikation mit der seriellen Schnittstelle Allgemeine Java-Themen 6
M Paralle Schnittstelle ansprechen Allgemeine Java-Themen 2
P TCPIP Schnittstelle Allgemeine Java-Themen 2
D Daten aus einer Seriellen Schnittstelle empfangen Allgemeine Java-Themen 22
D HTML Schnittstelle Allgemeine Java-Themen 4
T parallele Schnittstelle auslesen Allgemeine Java-Themen 5
S Problem mit Ansteuerung von serieller Schnittstelle Allgemeine Java-Themen 7
Q Schnittstelle/Abstrakte Klasse schreibt Annotation vor? Allgemeine Java-Themen 4
T Java Schnittstelle Active Directory Allgemeine Java-Themen 5
Q Typecast zwischen Klassen mit implementierter Schnittstelle Allgemeine Java-Themen 4
M RS232 Schnittstelle ansteuern (Floppy durch Laptop ersetzen) Allgemeine Java-Themen 2
Z java->schnittstelle->excel Allgemeine Java-Themen 2
V gezielte Datenbankeinträge über JDBC schnittstelle Allgemeine Java-Themen 10
H javax.comm und Parallele Schnittstelle (PIN für PIN) Allgemeine Java-Themen 7
X Java Schnittstelle zu AIML Allgemeine Java-Themen 2
S String an COM-Schnittstelle senden Allgemeine Java-Themen 6
D Schnittstelle zwischen zwei Klassen? Allgemeine Java-Themen 2
J PS/2-Schnittstelle ansprechen Allgemeine Java-Themen 7
Y Zugriff auf Com-Schnittstelle Allgemeine Java-Themen 5
S Abhören der com-Schnittstelle Allgemeine Java-Themen 3
H Zugriff auf parallele Schnittstelle Allgemeine Java-Themen 4
C Implementieren einer Schnittstelle (Interface), Ausnahmen Allgemeine Java-Themen 7
berserkerdq2 Was heißt es mit FXML Listener zu setzen ind Buttons zu erstellen? Allgemeine Java-Themen 6
L Wie programmiert man einen Listener? Allgemeine Java-Themen 1
H Listener Verständnisproblem Allgemeine Java-Themen 5
D Action Listener Problem Allgemeine Java-Themen 3
S Key Listener mit Strg + s Allgemeine Java-Themen 12
K Threads Listener für Future finish Allgemeine Java-Themen 2
TheWhiteShadow Listener Reihenfolge Allgemeine Java-Themen 4
D Listener auf System.out.err / System.out.println Allgemeine Java-Themen 5
A Listener für constructor einer bestimmen Klasse Allgemeine Java-Themen 9
E Bild mit Listener einfügen Allgemeine Java-Themen 3
P Listener für Tastatureingaben ohne Focus Allgemeine Java-Themen 4
serjoscha WatchDog Thread und Listener Allgemeine Java-Themen 10
hdi Listener für Desktop-Veränderungen Allgemeine Java-Themen 7
T JTextField in Listener leeren Allgemeine Java-Themen 2
lenniii Listener & JList Allgemeine Java-Themen 3
K Key listener ohne Fokus aktiv behalten ? Allgemeine Java-Themen 12
G Code-Convention für Listener Allgemeine Java-Themen 2
T Observer vs Listener Allgemeine Java-Themen 18
S Listener Allgemeine Java-Themen 3
P Abstrakte Elternklasse als Listener Allgemeine Java-Themen 6
MQue KeyAction listener Allgemeine Java-Themen 2
M generische Listener Allgemeine Java-Themen 2
S Listener für Kalender Allgemeine Java-Themen 2
B Observer vs Listener (GUI-Programmierung) Allgemeine Java-Themen 5
J Listener für Ende eines Threads gesucht... Allgemeine Java-Themen 5
S Listener Implentierung bei Eingabe in Textfeld Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben