Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Ich schreibe zyklisch in eine Variable.
Bsp.:
a = a + "dfhf"
später wieder einmal:
a = a + "iop"
Nun müsste ich folgendes machen:
Wenn x Millisekunden nach dem schreiben in die Variable a kein weiterer Wert erfolgt, soll eine Function ausgeführt werden.
Sollte innerhalb der x Millisekunden ein neuer Wert in die Variable geschrieben werden, resetet der Countdown und startet neu.
Danke für den Tipp. Leider komme ich noch nicht ganz zurecht was einmal ausführen und wiederholtes Ausführen betrifft.
Hast du eventuell ein paar Zeilen die mir helfen ?
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// if changed, do something
}
};
new Timer(delay, taskPerformer).start();
Danke, so hatte ich das schon.
Aber hier startet er ja immer wieder in dem angegeben Intervall, oder?
ich bräuchte nur einmal das er verzögert startet.
Ich muss aber einen laufenden Timer wieder abbrechen und neu starten können.
@Marcinek: Es für dich sicher hilfreich, wenn du aus der Doku das raus lesen kannst was zur Lösung beiträgt. Aber ich kenne die Doku und ich weiß wie man google einsetzt. Sonst hätte ich dieses Forum nicht gefunden. Daher möchte ich die bitten, mir keine Verweise mehr auf google zu posten. Dank dir!
Java:
timer = new Timer(0, taskPerformer);
timer.setInitialDelay(delay);
timer.start();
Sollte der Aufruf nicht einmal mit einer Verzögerung von "delay" starten? Er feuert mir immer die folgende:
Java:
ActionListener taskPerformer = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
try {
SC.setAnswer(Nachricht);
Nachricht = "";
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
};
in "delay" Millisekunden.
Erschwerend kommt hinzu das die Daten aus einer TCP Verbindung stammen. Hab zwar geprüft wenn NULL oder "" soll er den Timer ignorieren, aber ich erhalte einmal die "Nachricht" und dann zyklisch die Leere Zeichenketten.
Auch das Abbrechen scheint nicht so ohne zu sein?
Ich muss zuerst prüfen ob der timer NOT NULL und dann noch ob der timer läuft und erst dann kann ich ihn killen?
Mir kommt das nicht Ressourcen schonend vor, oder wo habe ich hier meinen Fehler?
Die ganze Anwendung schaut so aus:
Aus einer TCP Verbindung bekomme ich Strings. Diese sollen zusammengesetzt werden, sofern eine Pause zwischen den ankommenden Daten sind.
So soll aus:
Hello W
pause 5 ms
orld
pause 300 ms
here
pause 10 ms
we are
pause 1000 ms
Daraus soll eine Function zwei Aufrufe einer anderen Function machen, mit den 2 Strings:
"Hello World"
"here we are"
bei einer delay zeit von 100 ms
Hoffe ich konnte mein Vorhaben verständlich umschreiben.
aus java.util? Da sehe ich nicht den Konstruktor, den du verwendest (Timer(0, actionPerformer)).
Du befindest sich in einem Thread und dann hast du einen statischen zugriff auf eine Klasse "SC". Wie unterscheidest du den hier, wer was aus welcher Connection wie macht?
Es gibt viele Tutorials und auch hier mehrere Threads zu dem Thema eines aufbaus von Chat servern. Ich gehe davon aus, dass dir das weiterhelfen wird.
google: java simple chatserver
Aus deiner Beschreibung werde ich nicht so ganz schlau, was der sinn hier ist. Ist das eine Übung oder etwas, dass konkret zur Lösung eines Problems beitragen soll?
@Marcinek: Es für dich sicher hilfreich, wenn du aus der Doku das raus lesen kannst was zur Lösung beiträgt. [...] Daher möchte ich die bitten, mir keine Verweise mehr auf google zu posten. Dank dir!
bezüglich Sinn und google. Ich wollte nicht unhöflich sein, aber nur ein Link zur Doku hilft mir nicht, da ich die Java Doku ja an sich selber gefunden habe. Hilfreich wäre eine Stelle in der Doku zu nennen.
Ich habe nun denn aus java.util eingebaut. Der klappt auch. Denk ich hatte den aus java.swing(?)
Es sieht nun so aus:
Java:
public void run() {
try {
while(SC.clientSocket.isConnected()){
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(SC.clientSocket.getInputStream()));
char[] buffer = new char[200];
//blockiert bis Nachricht empfangen
int anzahlZeichen = bufferedReader.read(buffer, 0, 200);
tmpNachricht = new String(buffer, 0, anzahlZeichen);
if(tmpNachricht != null | tmpNachricht.length() > 0){
Nachricht = tmpNachricht + Nachricht;
if(timer != null){
timer.cancel();
}
timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
// Task here ...
try {
SC.setAnswer(Nachricht);
Nachricht = "";
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, delay);
}
}
SC.inFromServer.close();
SC.setAnswer("Thread beendet");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Um auf deine Frage des Sinn des Codes zu kommen:
Ich möchte mir in Java ein Addon für ein System schreiben, dass ich zu Hause nutzen kann.
Das "Muttersystem" hat eine Entwicklungsumgebung um eben eigenen Java Code ins System zu bringen und somit das Potenzial der Muttersoftware zu steigern.
Ich möchte mir einen generischen bidirektionalen TCP Client schreiben, damit ich diverse IP Geräte ansprechen kann.
Konkret zum Beispiel:
Logitech Squeezebox Mp3 Player
ATC-1000 RS232/RS422/RS485 serial Device (daran hängen dann RS485 Geräte und so weiter)
Über meinen Code bekomme ich die Daten aber abgehackt. Denn woher weiß den auch der TCP Client wann die Daten vom Quellgerät fertig gesendet sind. Entweder Carriage return oder über eine Zeitspanne von Inaktivität.
Damit sind wir beim Kern.
Die Wetterstation in meinem Haus sendet über RS485 die aktuellen Daten (Temperatur, Helligkeit, ...)
Diese werte ich in java aus und steuere damit das Haus.
Jedoch muss ich die Datenblöcke richtig lesen. Daher die timer Sache hier.
Eine Chatsoftware wäre "einfacher", da mittels .readLine() jede Zeile eindeutig gegeben ist. Bei anderen Geräten gibts das leider nicht.
Mein Client baut nur zu EINEM Gerät eine Verbindung auf! Daher kann ich die Daten vom Thread einfach zurückgeben, ohne zu unterscheiden, von welchen Thread es kommt. Es darf ja auch nur einer existieren.
Könntest du mir noch bestätigen ob das abbrechen eines Timer richtig ist? .isRunning gibts bei java.util nicht.
Im groben scheint es nun zu klappen (ersten 10 min) ... wobei aber der andere Thread zwecks Vebrindungsabbruch ebenso wichtig wäre.
Hm ich würd das ganz anders machen, besonders schwierig kommts mir allerdings nicht vor.
1. Eine Klasse bauen, die einen String kapselt und synchronisierten Schreib- und Lesezugriff darauf zur Verfügung stellt. Ausserdem wird beim Schreiben jeweils der Timestamp, wann das zuletzt passiert ist, gespeichert (System.currentTimeMillis)
2. In einer Endlosschleife jeweils Thread.sleep(x), danach gucken ob der letzte Schreibzugriff im Vergleich zum jetzt-Timestamp schon länger als die maximal erlaubte Zeit her ist, wenn nein, dann nix tun, wenn ja, dann String auslesen und das Objekt zurücksetzen. Wobei die Funktion, die das überprüft, auch innerhalb des Objektes stattfinden muss, damit die Synchronisation intakt bleibt (zwischen "prüfen ob timestamp.." und "ja? also lesen und neu" kann ja schon wieder der nächste Zugriff stattfinden, dessen Daten dann vom reset überschrieben werden würden).
Ich würde deinen Vorschlag gerne umsetzen.
zu 1. Soweit verständlich, aber synchronisierter Schreib- Lesezugriff sagt mir leider nichts. Muss ich die Variable speziell deklarieren? Der Sinn ist mir klar, aber die Umsetzung noch nicht.
zu 2. Wo soll die Endlosschleife laufen? In der Klasse von (1.)? Da würde mir ja die Klasse blockieren, oder?
zu 2.
Wobei die Funktion, die das überprüft, auch innerhalb des Objektes stattfinden muss
Du baust eine Klasse die einen String als Member-Variablen hat sowie einen long für den timestamp. Die Klasse hat zwei Funktionen: a) an den String was neues anhängen, b) überprüfe, ob...
der thread, der die neuen Zeichenketten entgegennimmt, fügt sie mittels funktion a an den String an. Ein weiterer Thread in Deinem Programm läuft in einer Endlosschleife und ruft Funktion b auf. innerhalb von Funktion b wird ermittelt, welcher der beiden Fälle vorliegt, und ggf. wird der interne String des Objekts zurückgegeben (und wieder geleert).