Wachsende log-Datei einlesen

Improof

Erfahrenes Mitglied
Hi,

die NullPointerException hat mit dem Link nichts zu tun. Da geht es darum, die Oberfläche sich auch aktualisieren zu lassen, damit du den neuen Text auch im Textfeld siehst.
Das einzige, was in deiner run-Methode null sein kann, ist deine Variable (die du auch noch klein schreiben solltest, dann passt alles ;)). Offenbar wird diese außerhalb erst danach initialisiert.

Wichtig in Java ist folgendes:
Es gibt keine Referenzen, alles was übergeben wird wird ausnahmslos kopiert!

Beispiel:
Java:
StyledText prozessstream;
RunLogThread thread = new RunLogThread(prozessstream);
prozessstream = new StyledText();

Bei der Übergabe ist prozessstream null. Und auch, wenn du später etwas zuweist, die Variable wurde kopiert und bleibt innerhalb von RunLogThread auch null.

Ich kann mir bei deinem Code und der geworfenen Exception eigentlich nichts anderes vorstellen, was die Ursache sein kann. Prüf mal nach, ob das Textfeld erst hinterher instanziert wird.

Falls das nicht der Grund für den Fehler sein sollte, müsstest du mal einen Codeausschnitt von außerhalb posten, also wo dein RunLogThread() und das Textfeld instanziert werden.

Gruß
Daniel
 

sheel

I love Asm
Mein Link hatte eigentlich ein anderes Ziel als die Erklärung von Nullpointerexceptions:

Die üblichen Java-GUI-Frameworks habe eine Reihe von Problemen, wenn die GUI-Elemente aus mehreren Threads angesprichen werden. Um es ordentlich zu machen, kann man in SWT der Methode Display.getDefault().asyncExec() ein Runnable übergeben, das die Änderungen am StyledText vornimmt, statt die Änderungen eben direkt zu machen. (Für Swing gibt es ähnlich dazu invokeAndWait und invokeLater)
 
Zuletzt bearbeitet:

Joerg66

Erfahrenes Mitglied
Das Textfeld funktioniert eigentlich einwandfrei, denn mein erster Gedanke war, mit den Rückgabewerten an die nötigen Informationen zu kommen. Das klappt, prima, auch die Aktualisierung usw.
Nur die Infos die ich bekomme bringen mich nicht weiter.
Ich poste mal den relevanten code. Die Reihenfolge stimmt, aber überflüssiges hab ich weggelassen. Vielleicht könnt ihr dann mehr erkennen.
Ich bin kein Profi und schreibe nichtmal ein Programm pro Jahr, also die ganzen Fachausdrücke sind mir nicht unbedingt geläufig :)
Jaaa, die Variablen sind nicht richtig benannt, ich weiß, aber wenn ich das jetzt ändere, hole ich mir vielleicht Probleme, die ich bisher nicht hatte, weil mir irgendwo ein Fehler passiert.
Java:
  ProcessBuilder magmaprocess = new ProcessBuilder ();
  StyledText prozessstream;
  Thread runlog = new Thread (new RunLogThread(prozessstream));
..........
......//Textfeld einfügen
...
    Group prozessausgaben = new Group(shell, SWT.NONE);
    prozessausgaben.setText("Prozessausgaben");
    prozessLayout = new GridLayout();
    prozessausgaben.setLayout(prozessLayout);
    GridData prozessdata = new GridData();
    prozessdata.horizontalAlignment = GridData.FILL;
    prozessdata.horizontalSpan = 11;
    prozessLayout.numColumns = 3;
    prozessausgaben.setLayoutData(prozessdata);
    
    prozessstream = new StyledText(prozessausgaben, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
    GridData prozessstreamdata = new GridData();
    prozessstreamdata.horizontalAlignment = GridData.FILL;
    prozessstreamdata.horizontalSpan = 1;
    prozessstreamdata.heightHint = 250;
    prozessstreamdata.widthHint = 800;
    prozessstream .setLayoutData(prozessstreamdata);
..........
......//Textfeld mit Rückgabewert füllen, aber in blauer Farbe Datum und Uhrzeit vor jeder Zeile
...
    magmaprocess.command(list);
    mp = magmaprocess.start();
    Aus[i].setBackground(new Color(display,100,200,100));
  Aus[i].update();
    String line;
    Reader stream = new InputStreamReader(mp.getInputStream());
    BufferedReader instream = new BufferedReader(stream);
    while ((line = instream.readLine()) != null){
      logDate = new Date();
      prozessstream.insert(sdf.format(logDate) + ": " + line + "\n");
      prozessstreamstyle.start = 0;
      prozessstreamstyle.length = 20;
      prozessstreamstyle.foreground = blau;
      prozessstream.setStyleRange(prozessstreamstyle);
    }
    instream.close();
 

Improof

Erfahrenes Mitglied
Da passiert bei dir genau das, was ich gemeint habe:

Zeile 3: Definition von prozessstream, ist aber null (noch keine Zuweisung / Initialisierung passiert, also das was du mit new ... machst)
Zeile: 4: RunLogThread wird erzeugt, prozessstream so wie er ist (also null) wird kopiert und übergeben
Zeile: 18: Da erzeugst du erst deinen prozessstream. Dieser ist nun nicht mehr null, aber die kopierte Version innerhalb von RunLogThread eben schon!

Du musst da die Reihenfolge ändern! Die Erzeugung von RunLogThread darf erst nach der Erzeugung von prozessstream erfolgen!

Gruß
Daniel
 

Joerg66

Erfahrenes Mitglied
@Improof: Vielen Dank für die ausführliche Erklärung, das habe ich jetzt verstanden und ändere.

@sheel: Sicher ist da nichts schlimm und genauso sicher wirst Du wohl Recht haben. Ich gehe jetzt aber erstmal auf die Suche nach einem Wörterbuch um zu übesetzen, was Du meinst mit "Runnable übergeben" usw.
Aber auch Dir vielen Dank für Deine Mühe
 

sheel

I love Asm
Runnable ist der Name eines Interfaces, wie im verlinkten Code zu sehen ist
(auch ohne English...)

Java:
Display.getDefault().asyncExec(new Runnable() {
    public void run() {
        //hier aufs Textfeld zugreifen
    }
});
 

Joerg66

Erfahrenes Mitglied
@sheel: Das "Wörterbuch" bezog sich jetzt nicht auf Englisch, sondern auf Fachchinesisch.
Beispiel: Du möchtest eine Gibsfigur gießen und hast etwas Grundwissen und eine Vorstellung. Du fängst an und stößt auf Probleme, die Du in einem Gießerei-Forum postest. Dann kommt einer (das könnte ich sein) und erklärt Dir die Lösung, gespickt mit Fachbegriffen. Könntest Du mir folgen? Nein.
Du erwartest von jedem, den Du fragst eine verständliche Antwort, ob Du einen Elektriker fragst oder einen Fliesenleger oder wen auch immer, möglichst noch ein Beispiel oder Zeichnung, was sich direkt auf Dein Problem bezieht. Das ist der übliche Umgang.
Nur wenn man programmiertechnisch ein Problem hat, dann wird das selten gemacht, da wir 10 mal mehr Text geschrieben als nötig, statt eine klare Antwort zu geben.
Ich bin Dir ja dankbar, das Du Dich mit meinem Problem beschäftigst, aber ich benötige keinen Lernweg, sondern eine Lösung meines Problems. Selbst wenn ich mir das selbst zusammengefrickelt hätte, gemerkt habe ich mir das Ergebnis sicher nicht, da ich zu dem Thema schon so viel gelesen und probiert habe, das ich im Hirn gar nicht mehr auseinandersortieren könnte, was jetzt letztlich das Richtige war.
Im Hauptprogramm steht jetzt:
Java:
    Group prozessausgaben = new Group(shell, SWT.NONE);
    StyledText prozessstream = new StyledText(prozessausgaben, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
    Thread runlog = new Thread (new RunLogThread(prozessstream));

In der Datei "RunLogThread.java" steht jetzt folgendes.
Java:
public class RunLogThread implements Runnable {
   private StyledText Textfeld;

   public RunLogThread(StyledText prozessstream) {
     Textfeld = prozessstream;

   Display.getDefault().asyncExec(new Runnable(){
     public void run(){
       Textfeld.insert("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Test: \n");
     }
     });
   }

    public void run() {
     System.out.println("Run im extra Thread");
   }
}
Ich bekomme keinen Fehler mehr angezeigt, die untere run() wurde verlangt, wird aber nie ausgeführt.
Im Textfeld erscheint das "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Test:", aber dann scheint das Programm abzustürzen.
Vielleicht magst Du (oder irgendwer anderes) Dir das ja mal ansehen und mir mit einer Antwort antworten, nicht mit einer Frage, Aufgabe oder Pseudocode.
Halt so, wie jeder eine Antwort auf eine Frage erwartet, auch ihr, wenn ihr jemanden fragt.
Ich hoffe, ich habe mich nicht im Ton vergriffen und bedanke mich nochmals ....
 

sheel

I love Asm
Nur wenn man programmiertechnisch ein Problem hat, dann wird das selten gemacht, da wir 10 mal mehr Text geschrieben als nötig, statt eine klare Antwort zu geben.
Naja, sollen wir für dich das Programm schreiben, oder willst du lernen, wie man es selber machen kann?
Die Grundannahme hier ist die zweite Variante.
(Beispiele)
...
Das ist der übliche Umgang
...
aber ich benötige keinen Lernweg, sondern eine Lösung meines Problems.
Ah ja.
Wie gesagt, wir sehen dich eben nicht als Kunden, wie in deinen Beispielen

(Und auch bei Aufträgen im Software-entwickeln sind einfach mehr Details von Kundenseite her nötig. Ein "leg von hier bis hier Fließen, die blau karierten, und los gehts" gibts nicht)

Allerdings...
Vielleicht magst Du (oder irgendwer anderes) Dir das ja mal ansehen und mir mit einer Antwort antworten, nicht mit einer Frage, Aufgabe oder Pseudocode.
...weiß ich sowieso nicht, wo ich dir Aufgaben oder Pseudocode gegeben habe.
Zuerst ein Link, dann eine Kurzbeschreibung warum man den Code dort braucht weil dein Englisch "mies" ist (laut dir selber), dann eine Frage (na gut, eine Frage) warum du das nicht verwenden willst und einen 1:1 reinkopierbaren Code.

Das Finden vom "Absturz"-Grund (wirklich ein Absturz?) wird ohne deine Mithilfe bzw. Fragenstellen nicht möglich sein, es sind nämlich zu wenig Informationen hier ersichtlich. Eine mögliche Variante wäre natürlich, das gesamte Programm herzugeben und dann jemand anderen da drin den Fehler suchen zu lassen, aber ob das jemand machen will...
 
Zuletzt bearbeitet:

Improof

Erfahrenes Mitglied
Um die Antwort von @sheel noch zu ergänzen:
Wenn du einen Elektriker oder Fliesenleger etwas fragst, dann erhälst du vielleicht eine klarere Antwort, als wenn es ums Programmieren geht. Aber das liegt auch an der Art deines Problems: Bei dir geht es um Oberflächen, Textfelder usw. Das kann halt (gerade für jemanden, der nicht viel vom Programmieren versteht) auch schnell viel komplizierter werden als irgendein kleiner Code im Hintergrund, der einfach nur Summen bildet o.ä. Also musst du auch verstehen, wenn dann "Fachchinesisch" gesprochen wird, da man davon ausgeht, dass du eben schon mehr Erfahrung hast.
Und um zu dem Beispiel mit den Handwerkern zurückzukommen: Spätestens, wenn du Hilfe benötigst, bei dem was du tust, werden auch diese Geld von dir für ihre Leistung verlangen.

Hier im Forum kann man kostenlose Hilfe erwarten, mit der du dein Problem selbständig lösen kannst. Es gibt genug User, die sich um Anfänger kümmern, umfangreiche Hilfestellungen geben und sich wirklich mit den Problemen anderer beschäftigen, obwohl sie selber in der Arbeit wahrscheinlich genug zu tun hätten. Ich spreche da auch von mir. Sobald du aber verlangst, dass dir jemand eine fertige Lösung gibt, dann ist das auch nichts anderes, wie wenn du einen Handwerker engagierst. Und warum sollten wir unsere Arbeit für Lau machen? ;)


Um dir nun aber doch noch irgendwie zu helfen:
Im Textfeld erscheint das "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Test:", aber dann scheint das Programm abzustürzen.
... das reicht einfach nicht.

SO kann niemand daraus schließen, was dein Problem ist. Es gibt zig Fehler, die ein Programm zum Absturz bringen können, wie z.B. die NullPointerException, die du vor ein paar Tagen hattest. Du musst uns mindestens mitteilen, was für eine Exception geworfen wurde. Besser noch: Wo der Fehler auftritt. Wenn du weißt, welche Exception es war (und du hast bewiesen, dass du das wissen kannst), dann solltest du nicht nur den Namen, sondern einen vollständigen StackTrace sehen: Das ist das Teil, dass insgesamt bei einem Fehler ausgegeben wird, wo steht, in welcher Klasse, in welcher Methode und in welcher Zeile der Fehler auftrat.

Gruß
Daniel