# Applet Lesen auf 'n Server beibringen/schreiben funktioniert



## alphaChill (30. Sep 2007)

Moin an alle,

ich bin gerade dabei über ein Applet schreibend und lesend auf eine .txt-Datei auf einem Server zu zu greifen. Vorweg: Mein Applet ist signiert bzw. man kann diese über den Browser bestätigen. Zuerst bin ich im FAQ auf diesen Beitrag gestoßen:
Aus Applets in Dateien schreiben
Der PHP-Code hat bei mir leider nicht funktioniert, daher habe ich jemanden gefragt, der sich mit PHP einwenig auskennt und er hat folgende Datei für mich geschrieben:


```
<?php

define("FILE","datei.txt"); 	// Dateiname der zu speichernden Datei, bei Bedarf ändern
define("GET","var1");		// Bezeichnung der angehängten Daten, bei Bedarf ändern

$get = $HTTP_GET_VARS[GET];
$get .= "\r\n";
if (isset($get)) {
	if (is_writable(FILE)) {
		if (($FileHndl = fopen(FILE,'a'))) {
			fwrite($FileHndl,$get);
		}
	}
}

?>
```

Den Java-Teil habe ich aus dem FAQ-Thread übernommen:


```
try { 
URL home = getCodeBase(); 
String url = home.toString()+"php.php?var1="+tf.getText(); 
getAppletContext().showDocument(new URL(url)); 
} catch(Exception x) {} 
}
```


Jetzt zum Problem: Also der Text, der in die datei.txt rein soll, kommt auch rein, allerdings bekomme ich nur noch eine weiße Seite angezeigt, nachdem er über das Applet die txt-Datei gefüllt hat. Wie das genau aussieht, mit der weißen Seite, seht ihr ihr: 
main.ma.funpic.de/test3/
Also das Schreiben funktioniert, allerdings macht er das nicht im Hintergrund.

Hab's auch schon versucht in der Klasse eine Thread-Methode zu erstellen:


```
public void php() {

    new Thread() {

      public void run() {

        URL home = getCodeBase();
        String url = home.toString() + "write.php?var1=" + anzeigefeld.getText().toString();
        try {
          getAppletContext().showDocument(new URL(url));
        }
        catch (MalformedURLException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }

      }

    }.start();

  }
```

Und beim Button habe in der "actionPerformed"-Methode nur noch "php();" zum Auführen der Methode angegeben. Leider hat das auch nicht geholfen.

*[EDIT]:*
*Okay, schreiben im Hintergrund läuft jetzt!!* 
Habe einfach mal 'ne Thread-Klasse angelegt und damit läuft's dann auch:


```
package gaestebuch;

import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.JApplet;

public class Thread1 extends Thread{

  public Thread1() {
    super();
  }
  public void run() {
    
    JApplet j1 = new JApplet();
    
    URL home = j1.getCodeBase();
    String url = home.toString() + "write.php?var1=" + gaestebuch.anzeigefeld.getText().toString();
    try {
      j1.getAppletContext().showDocument(new URL(url));
    }
    catch (MalformedURLException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();

  }

}
}
```




Nur das Lesen funktioniert leider noch nicht...

Auch nicht, wenn ich bei "eineEingabeDatei = new FileReader("datei.txt");" anstatt "datei.txt" den URL-Pfad zur Datei angebe: "eineEingabeDatei = new FileReader("http://main.ma.funpic.de/test3/datei.txt");"


Hier der Code für den Lese-Thread:


```
package gaestebuch;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Thread2 extends Thread{

  public Thread2() {
    super();
  }
  public void run() {
    
    FileReader eineEingabeDatei = null;
    try {
      eineEingabeDatei = new FileReader("datei.txt");
      BufferedReader eingabeDatei = new BufferedReader(eineEingabeDatei);

      String zeile = eingabeDatei.readLine();
      while (zeile != null) {
        gaestebuch.anzeigefeld.append(zeile + "\n");
        gaestebuch.scroll();
        zeile = eingabeDatei.readLine();
      }

    }
    catch (IOException e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    }

    if (eineEingabeDatei != null)
      try {
        eineEingabeDatei.close();
      }
      catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
      }


  }
}
```


----------



## wayne (1. Okt 2007)

also zunächst mal muss dein java-programm nicht zwangsläufig ein applet sein um auf einen server zu schreiben oder von ihm zu lesen. da du aber ein gästebuch betreiben willst, ist das natürlich notwendig, aber nur, um dir dein gästebuch anzuzeigen und es dem benutzer zu ermöglichen neue einträge hinzu zu fügen. das beides wäre aber auch durch eine reine html seite möglich, die php-geschichte auf dem server hingegen ist schon sehr sinnvoll.

das das schreiben und lesen nicht zwangsläufig über ein applet passieren muss zeige ich dir durch zwei von meinen methoden, welche an eine php-seite text zum schreiben übermitteln bzw. dann den text aus einer datei lesen und weiterverarbeiten:

```
public void submitData(String data){
            try {        
                // URL zu dem php-script welches eine datei aus var1 erzeugt
                URL script = new URL("http://.../write.php?var1="+data);
                
                // zu dieser URL wird nun eine connection vorbereitet
                HttpURLConnection connection = (HttpURLConnection) script.openConnection();
                connection.setDoInput(true);
                connection.setDoOutput(true);
                connection.setUseCaches(false);
                connection.setRequestMethod("GET");
                connection.setRequestProperty("Accept","text/xml, application/xml, application/x-www-form-urlencoded");
                connection.setRequestProperty("Accept-Encoding", "identity"); 

                connection.connect();
        
                // wenn dein php-script kontroll-texte generiert, kannst du sie hier abfragen
                InputStream in = connection.getInputStream();
    
                // ob du auf die response reagierst oder sie, wie ich hier, einfach ausgibst, bleibt dir überlassen
                int available = in.available();
                if( available > 4 ){
                    byte[] b = new byte[available];
                    in.read(b);
                    for( int i = 0; i < b.length; i++ )
                        System.out.print((char)((int)b[i] & 0xFF));
                    System.out.println();
                }
                // stream muss natürlich geschlossen werden
                in.close();
                
                connection.disconnect();
            }
            catch( Exception e ){
                e.printStacktrace();
            }
}
```

zum thema response bzw. kontroll-texte hier ein wort, da du dich als php-nicht-fähig autest: du kannst jederzeit in php text an den browser oder dein applet zurückschreiben mit dem befehl echo. in deinem fall hast du in deinem php-script ja einige if zweige drin. wenn die alle zutreffen kannst du echo "OK"; zurückgeben lassen und dir selbstverständlich entsprechende else zweige machen, wo dann echo "ERROR" zurückgegeben wird. das könnte aber selbstverständlich auch echo "Hallo Welt"; heißen ... da bist du frei. grundsätzlich kann ich dir als hilfestellung dazu php.net empfehlen, die beschreiben dort php sehr einleuchtend und einfach.

hier jetzt eine methode von mir zum lesen:

```
public String read(){
        // hier herein wird der dateiinhalt gelesen
        StringBuffer textBuffer = new StringBuffer();
        InputStream in = null;
        try {
            // erst mal wieder eine url zur datei aufbauen
            URL url = new URL([url]http://.../datei.txt[/url]);
            
            // einen inputstream dorthin öffnen, denn wir wollen lesen
            in = url.openStream();
            
            // eigentlich ist die größe des puffers egal, zu große oder zu kleine array's bremsen die geschichte
            // bislang kam ich mit dieser größe ganz gut zurecht
            byte[] buffer = new byte[65535];
            
            // jetzt lesen wir die datei aus und schreiben sie byteweise in den text-puffer
            int numRead = 0;
            while ((numRead = in.read(buffer)) != -1)
                for( int i = 0; i < buffer.length; i++ )
                    textBuffer.append((char)((int)buffer[i] & 0xFF));            
        } 
        catch (Exception e) {
            e.printStackTrace();
        } 
        finally {
            try {
                // dannach stream schließen nicht vergessen
                if (in != null)             
                    in.close();
            } 
            catch (IOException e) {
                e.printStackTrace();
            }
        }        
        // zurückgeben des ergebnisses
        return textBuffer.toString();
}
```

es gibt beim lesen durch diese methode aber zwei probleme. erstens wird immer das gesammte array buffer[] in den textBuffer geschrieben, auch wenn dieses gar nicht mehr voll war. weiß jetzt auswendig nicht, wie das abzufangen war, aber ich denke, da wird dir schon was einfallen. schätze, daß beim letzten mal lesen, wenn also buffer[] unterfüllt wird, die bytes nach der datei mit 0 gefüllt sind, aber wie gesagt, probiers einfach mal aus. das zweite problem kann auftauchen, wenn der php-server eine andere zeichencodierung verwendet als dein java. das ist eigentlich ein problem des schreibens, beim lesen ist es wohl von der zeichencodierung vom webserver abhängig. mit normalen buchstaben wirst du kein problem haben, aber mit sonderzeichen wie ÄÖÜäöüß usw.. entweder probierst du dafür die beiden systeme aufeinander abzustimmen oder du überträgst den text codiert, so daß weder java noch php die zeichen unterschiedlich interpretieren kann, beispielsweise URL-encoded. beim lesen musst du dann halt das endergebnis wieder dekodieren.

viel erfolg

wayne


----------



## alphaChill (3. Okt 2007)

Erstmal vielen Dank für die Mühe! Habe die letzten 2 Tage rumprobiert und es läuft auch (teilweise)...
Die Formatierung des Textes geht, via codierer, nicht verloren, der läuft einwandfrei 
Das einzige, was mir z.Z. noch Probleme macht, ist folgendes:

Wenn etwas in der Datei "datei.txt" drin steht und das Applet geladen wird, wird auch schön der Inhalt in das Haupt-Anzeigfeld geladen. Das heißt, dass das auslesen der Datei ja funktioniert. Allerdings funktioniert das nicht, wenn das Applet läuft 
Damit die Datei beim Starten ausgelesen wird, habe ich den Code um den ensprechenden Thread zu starten in die Mehtode "init()" der Applet-Klasse gepackt. Das funktioniert auch! Auch, wenn ich aus den Thread-Klassen normale Klassen mache und dann die entsprechende Methode zum Lesen aufrufe!

Was nicht funkioniert:
Wenn ich einen Beitrag über die Oberfläche schreibe und dann auf "Senden" klicke, wird der Text, der geschrieben wurde nicht auf dem Hauptanzeigefenster ausgegeben, aber in die Datei geschrieben! Also Lesen und Schreiben an sich funktionieren, allerdings holt er nicht den Inhalt der Datei wärend das Programm läuft. 

Hier mal die einzelnen Klassen:


Applet-Main-Klasse:

```
package gaestebuch;

import java.awt.BorderLayout;
import java.util.GregorianCalendar;

import javax.swing.JPanel;
import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class gaestebuch extends JApplet {

  private JPanel      jContentPane   = null;
  private JPanel      jPanel         = null;
  private JButton     jButton        = null;
  private JScrollPane jScrollPane    = null;
  static JTextArea    anzeigefeld    = null;
  private JLabel      namelabel      = null;
  private JTextField  nametxtField   = null;
  private JLabel      kommentarlabel = null;
  private JScrollPane jScrollPane1   = null;
  static JTextArea    kommentarArea  = null;
  
  Thread1 th1;
  Thread2 th2;
  /**
   * This method initializes jPanel
   * 
   * @return javax.swing.JPanel
   */

  public static void scroll() {
    anzeigefeld.setCaretPosition(anzeigefeld.getText().length());
  }

  private JPanel getJPanel() {
    if (jPanel == null) {
      kommentarlabel = new JLabel();
      kommentarlabel.setBounds(new java.awt.Rectangle(376, 146, 155, 25));
      kommentarlabel.setText("Kommentar:");
      namelabel = new JLabel();
      namelabel.setBounds(new java.awt.Rectangle(376, 67, 151, 23));
      namelabel.setText("Name:");
      jPanel = new JPanel();
      jPanel.setLayout(null);
      jPanel.add(getJButton(), null);
      jPanel.add(getJScrollPane(), null);
      jPanel.add(namelabel, null);
      jPanel.add(getNametxtField(), null);
      jPanel.add(kommentarlabel, null);
      jPanel.add(getJScrollPane1(), null);
    }
    return jPanel;
  }

 
  

  /**
   * This method initializes jButton
   * 
   * @return javax.swing.JButton
   */
  private JButton getJButton() {
    if (jButton == null) {
      jButton = new JButton();
      jButton.setText("Senden");
      jButton.setSize(new java.awt.Dimension(100,35));
      jButton.setLocation(new java.awt.Point(350,429));
      jButton.addActionListener(new java.awt.event.ActionListener() {

        @SuppressWarnings("deprecation")
        public void actionPerformed(java.awt.event.ActionEvent e) {
          th1 = new Thread1();
          anzeigefeld.setText("");
          // anzeigefeld.setFont(new java.awt.Font("Arial", 1, 20));
          // String,int,int
          new java.awt.Font("Comic Sans MS", 1, 14);
          GregorianCalendar cal = new GregorianCalendar();
          String name = nametxtField.getText();
          String kommentar = kommentarArea.getText();
          nametxtField.setText("");
          kommentarArea.setText("");
           anzeigefeld.append("________________________________________\n--------------------------------\nZeit:"+cal.getTime()+"\n--------------------------------\nName: "+name+"\n--------------------------------\nKommentar: "+kommentar+"\n\n");
          //anzeigefeld.append("Name: "+ name +"\n"+"Kommentar: "+ kommentar+"\n"+"\n");
          //anzeigefeld.append(name+kommentar+"Zeit: "+cal.getTime());
          th1.start();
          try {
            Thread.sleep(500);
          }
          catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
          }
          th1.stop();
          th1= null;
          
          
          
          th2 = new Thread2();
          th2.start();
          try {
            Thread.sleep(500);
          }
          catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
          }
          th2.stop();
          th2= null;
         
          

        }
      });
    }
    return jButton;
  }

  /**
   * This method initializes jScrollPane
   * 
   * @return javax.swing.JScrollPane
   */
  private JScrollPane getJScrollPane() {
    if (jScrollPane == null) {
      jScrollPane = new JScrollPane();
      jScrollPane.setBounds(new java.awt.Rectangle(30, 30, 286, 391));
      jScrollPane.setViewportView(getAnzeigefeld());
    }
    return jScrollPane;
  }

  /**
   * This method initializes jTextArea
   * 
   * @return javax.swing.JTextArea
   */
  private JTextArea getAnzeigefeld() {
    if (anzeigefeld == null) {
      anzeigefeld = new JTextArea();
      anzeigefeld.setEditable(false);
    }
    return anzeigefeld;
  }

  /**
   * This method initializes jnametxtField
   * 
   * @return javax.swing.JTextField
   */
  private JTextField getNametxtField() {
    if (nametxtField == null) {
      nametxtField = new JTextField();
      nametxtField.setBounds(new java.awt.Rectangle(376, 102, 142, 33));
    }
    return nametxtField;
  }

  /**
   * This method initializes jScrollPane1
   * 
   * @return javax.swing.JScrollPane
   */
  private JScrollPane getJScrollPane1() {
    if (jScrollPane1 == null) {
      jScrollPane1 = new JScrollPane();
      jScrollPane1.setBounds(new java.awt.Rectangle(376, 181, 190, 210));
      jScrollPane1.setViewportView(getKommentarArea());
    }
    return jScrollPane1;
  }

  /**
   * This method initializes jTextArea1
   * 
   * @return javax.swing.JTextArea
   */
  private JTextArea getKommentarArea() {
    if (kommentarArea == null) {
      kommentarArea = new JTextArea();
      kommentarArea.setEditable(true);
    }
    return kommentarArea;
  }

  /**
   * @param args
   */
  public static void main(String[] args) {
    gaestebuch buch1 = new gaestebuch();
    

  }

  /**
   * This is the default constructor
   */

  public gaestebuch() {
    super();
  }

  /**
   * This method initializes this
   * 
   * @return void
   */
  public void init() {
    this.setSize(640, 480);
    this.setContentPane(getJContentPane());
    th2 = new Thread2();
    th2.start();
    try {
      Thread.sleep(500);
    }
    catch (InterruptedException e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    }
    th2.stop();
    th2= null;
   

  }

  /**
   * This method initializes jContentPane
   * 
   * @return javax.swing.JPanel
   */
  private JPanel getJContentPane() {
    if (jContentPane == null) {
      jContentPane = new JPanel();
      jContentPane.setLayout(new BorderLayout());
      jContentPane.add(getJPanel(), java.awt.BorderLayout.CENTER);
    }
    return jContentPane;
  }

}
```



Klasse zum Schreiben der Datei auf dem Server:

```
package gaestebuch;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;



public class Thread1 extends Thread{ // DATEI SCHREIBEN
  
  

  
  
  

  public Thread1() {
    super();
  }
  public void run() {
    String data = gaestebuch.anzeigefeld.getText().toString();
    
    String data2 = codierer.codieren(data);
  
    try{  
    // URL zu dem php-script welches eine datei aus var1 erzeugt
    URL script = new URL("http://main.ma.funpic.de/test3/write.php?var1="+data2); 
    
    // zu dieser URL wird nun eine connection vorbereitet
    HttpURLConnection connection = (HttpURLConnection) script.openConnection(); 
    connection.setDoInput(true); 
    connection.setDoOutput(true); 
    connection.setUseCaches(false); 
    connection.setRequestMethod("GET"); 
    connection.setRequestProperty("Accept","text/xml, application/xml, application/x-www-form-urlencoded"); 
    connection.setRequestProperty("Accept-Encoding", "identity"); 

    connection.connect(); 

    // wenn dein php-script kontroll-texte generiert, kannst du sie hier
    // abfragen
    InputStream in = connection.getInputStream(); 
    
    in.close(); 
    
    connection.disconnect(); 
    } 
    catch( Exception e ){ 
    e.printStackTrace(); 
    }
    
 
    

   
    
 
   
  }

}
```


Klasse zum Lesen der Datei auf dem Server:

```
package gaestebuch;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class Thread2 extends Thread{ // DATEI LESEN
  
  public String read(){ 
    // hier herein wird der dateiinhalt gelesen 
    StringBuffer textBuffer = new StringBuffer(); 
    InputStream in = null; 
    try { 
        // erst mal wieder eine url zur datei aufbauen 
        URL url = new URL("http://main.ma.funpic.de/test3/datei.txt"); 
        
        // einen inputstream dorthin öffnen, denn wir wollen lesen 
        in = url.openStream(); 
        
        // eigentlich ist die größe des puffers egal, zu große oder zu kleine array's bremsen die geschichte 
        // bislang kam ich mit dieser größe ganz gut zurecht 
        byte[] buffer = new byte[1]; 
        
        // jetzt lesen wir die datei aus und schreiben sie byteweise in den text-puffer 
        int numRead = 0; 
        while ((numRead = in.read(buffer)) != -1) {
             for( int i = 0; i < buffer.length; i++ ) {
                textBuffer.append((char)((int)buffer[i] & 0xFF));
            }}
    } 
    catch (Exception e) { 
        e.printStackTrace(); 
    } 
    finally { 
        try { 
            // dannach stream schließen nicht vergessen 
            if (in != null)              
                in.close(); 
        } 
        catch (IOException e) { 
            e.printStackTrace(); 
        } 
    }        
    // zurückgeben des ergebnisses 
    return textBuffer.toString(); 
}

  public Thread2() {
    super();
  }
  public void run() {
    
String data3 = codierer.decodieren(read());
System.out.println(data3);     // Hier wird mir auch nur, das was akutell auf dem Anzeigefeld ist ausgegeben, nicht der Inhalt der datei.txt !!

gaestebuch.anzeigefeld.setText(data3);

  
  }
   
  
}
```


----------



## wayne (4. Okt 2007)

hab mir jetzt gar nicht den ganzen code durchgelesen sondern nur den lese-teil, denn dort ist meiner meinung nach auch die lösung für dein problem zu platzieren.

damit das ganze funktioniert, also dein benutzer jederzeit auch die updates von anderen nutzern lesen kann, ohne das applet neu laden zu müssen, muss dein lesethread kontinuierlich die datei auslesen. dann, und nur dann, wenn sich an deren inhalt etwas geändert hat, sollte er den inhalt neu anzeigen lassen. die hälfte des weges dazu bist du bereits gegangen, indem du das lesen in einen Thread ausgelagert hast. nun musst du diesem nur noch beibringen, daß er nicht nur einmal zu lesen hat und mit dem bestehenden inhalt vergleicht, ob ein update notwendig ist (letzteres gehört meiner meinung nach zu einer sauberen programmierung, muss aber nicht sein). das mit dem kontinuierlichen lesen funktioniert mittels lesen, vergleichen, warten, lesen, vergleichen, warten ... :

```
private String backupData = "";

public void run() { 
    while( !isInterrupted() ){ // hier kann auch eine alternative oder auch zusätzliche abbruchbedingung stehen
        String data3 = codierer.decodieren(read()); 

        if( !backupData.equals(data3) ){
            gaestebuch.anzeigefeld.setText(data3); 
            backupData = data3;
        }

        waitFor(1000);
    }
}

private synchronized waitFor(long ms){
    try {
        sleep(ms); // alternativ geht auch wait(ms);
    }
    catch( Exception e ){
        e.printStacktrace();
    }
}
```
ich denke, daß sollte dein problem lösen. 

ein anderes problem ist mir noch aufgefallen, als ich an dieser lösung schrieb. wenn mehrere benutzer gleichzeitig etwas ins gästebuch schreiben, könnte es vorkommen, daß php dir die einträge durcheinander würfelt. das lässt sich php-seitig vermeiden, indem du zunächst abfrägst, ob die datei bereits geöffnet ist und wenn ja, wartest, bis sie geschlossen wurde. entweder so, oder über etwas anderes, etwas in der art einer semaphore. frag mich aber bitte nicht nach dem php-code dazu, denn in php bin ich längst nicht so fit wie in java. ich müsste mir aus php.net die benötigten befehle zusammensuchen, würde es bestimmt hinkriegen, aber müsste halt auch ca. 2-3 stunden mit suchen und probieren verbringen. sprich, ich hätte den gleichen aufwand, wie du, wenn du nach der lösung hierfür suchst. oder du postest halt in einem einschlägigen php-forum.

viel erfolg

wayne


----------



## alphaChill (4. Okt 2007)

Leider läuft dein Code nicht 

Von "data3" kommt leider nur der Schriftsatz, der im Anzeigefenster akutell angezeigt wird und mehr nicht. Es scheint fast so, als ob der der Text, der gerade in die "datei.txt" geschrieben wurde, gar nicht existieren würde. Tut er aber definitiv, da die "datei.txt" sich pro Eintrag vergrößert und wenn ich sie runterlade und decodiere steht auch alles drin. Beim erstenmal, wenn die Datei gelesen wird, wird auch noch alles gelesen aber mehr als das, was beim ersten mal gelesen wurde, wird dann nicht mehr gelesen...

Edit: Was mir auch aufgefallen ist, dass wenn die "datei.txt" leer ist und ich dann das Applet starte und einen Beitrag verfasse wird dieser via php-Datei in die "datei.txt" geschrieben und auch gleich wieder gelesen und in dem Anzeigefenster ausgegeben. Allerdings werden alle weiteren Beiträge, die ich verfasse nicht sofort angezeigt, erst wenn ich den Browser schließe und wieder öffene.

Habe das ganze mal hier um testen hochgeladen:

http://main.ma.funpic.de/test3/


----------



## wayne (4. Okt 2007)

???:L hm, hört sich eigentlich danach an, als würdest du irgendwo das gelesene nicht übernehmen. der sourcecode der klasse decodierer fehlt mir leider um das vollends zu überprüfen. kannst du mal versuchen in der klasse, die du zum lesen vom server verwendest, also die mit der methode read(), kurz vor dem lesen einen breakpoint zu setzen, welcher auf den 2. pass erst anhält, und ab da den weg des textes mal zu verfolgen bzw. zugucken, wie die variable textBuffer gefüllt wird? ich meine dort, in zeile 25 von dem code, den du als letztes von dieser klasse gepostet hast. dann könntest du so überprüfen, ob der inhalt korrekt von deinem server gelesen wird, also mit dem neu hinzugefügten text und vielleicht auch rausfinden, wo der fehler liegt. und wenn dein breakpoint kein 2. mal erreicht wird, weißt du, daß dein lesethread nach dem ersten mal lesen unerklärlicherweise beendet wurde. dann müsstest du dessen abbruchbedingungen mal überprüfen. zumindest mal für heute abend/morgen früh sollte das als beschäftigung reichen ... weil mir nämlich jetzt nach 12 stunden programmierarbeit hier in meiner firma der kopf brummt und ich aktuell grad nur noch heim und abendessen möchte. morgen guck ich aber nochmal nach, wie's dir geht, versprochen   

ciao

wayne


----------



## alphaChill (4. Okt 2007)

Also unter der Entwicklungsumgebung läuft das Applet einwandfrei, tut seine Arbeit, wie ich es mir vorgestellt habe. Beiträge werden geschrieben und auch alle, auch mehrere nach einander gelesen.
Hab mir schon überlegt, ob es am Browser liegt, aber Opera und IE machen die gleichen Faxen, selbst auf unterschiedlichen Rechnern... Werde es morgen mal unter Suse Linux testen, wobei ich bezweifel, dass es dort besser/anders läuft, da Java Java ist...
Mit Breakpoints habe ich i.d.R. nichts zu tun, da ich bis jetzt nur keine Programme geschrieben habe, die nach ein bisschen Testen dann liefen. Habe aber mal einen an die entsprechende Stelle gesetzt "Hit Count" auf 2 (hab's auch mit 1 gestet, da ich mir nicht sicher war, ob er bei 0 oder 1 startet). Habe meistens 'ne TimeoutException bekommen:

```
Exceptions occurred attempting to resume.
  org.eclipse.jdi.TimeoutException: Timeout occurred while waiting for packet 155. occurred resuming thread.
```
Leider kenn ich mich mit den Breakpoints auch nicht wirklich aus... Aber ich werde mich morgen noch mal näher mit beschäftigen, jetzt erst mal schlafen  :wink:
Achja: Wegen mir musst du dir keinen Stress machen, ich bin dir auch noch sehr dankbar, wenn du dir 'n paar Tage Zeit lässt.

Hier noch mal meine Codiererklasse:


```
package gaestebuch;

public class codierer {


  public static String codieren (String S1) {    // String S1 wird zum codieren wird eingenommen
    int j = 0;
    String S2 = "";
    for (int i = 0; i < S1.length(); i++) { // Codierer
      j = (int) S1.charAt(i);
      S2 = S2 + j + "q";
    }
      
    return S2;     // String S2 wird zum Verschicken weggegeben... 
  }
  
  
  public static String decodieren (String S2) { // String S2 (codiert) wird zum decodieren wird eingenommen
    int i = 0;
    char c = 0;
    String S3 = "";
    String S4 = "";
    for (i = 0; i < S2.length(); i++) {   // Decodierer
      c = S2.charAt(i);
      if (c != 'q'){
        S3 = S3 + c;
      }
    else {
      String ze = S3;
      int z = Integer.valueOf(ze);
      S3 = "";      
      S4 = S4 + ascii(z); 
    }   
    }
    return S4;  // String S4 (decodiert) wird zum Verschicken weggegeben... 
  }
  
  
  
  
  
  
  
  
  
  public static char ascii (int wert) {
    switch(wert){
      case 10: return '\n';
      case 32: return ' ';
      case 33: return '!';
      case 35: return '#';
      case 36: return '$';
      case 37: return '%';
      case 38: return '&';
      case 39: return '´';
      case 40: return '(';
      case 41: return ')';
      case 42: return '*';
      case 43: return '+';
      case 44: return ',';
      case 45: return '-';
      case 46: return '.';
      case 47: return '/';
      case 48: return '0';
      case 49: return '1';
      case 50: return '2';
      case 51: return '3';
      case 52: return '4';
      case 53: return '5';
      case 54: return '6';
      case 55: return '7';
      case 56: return '8';
      case 57: return '9';
      case 58: return ':';
      case 59: return ';';
      case 60: return '<';
      case 61: return '=';
      case 62: return '>';
      case 63: return '?';
      case 64: return '@';
      case 65: return 'A';
      case 66: return 'B';
      case 67: return 'C';
      case 68: return 'D';
      case 69: return 'E';
      case 70: return 'F';
      case 71: return 'G';
      case 72: return 'H';
      case 73: return 'I';
      case 74: return 'J';
      case 75: return 'K';
      case 76: return 'L';
      case 77: return 'M';
      case 78: return 'N';
      case 79: return 'O';
      case 80: return 'P';
      case 81: return 'Q';
      case 82: return 'R';
      case 83: return 'S';
      case 84: return 'T';
      case 85: return 'U';
      case 86: return 'V';
      case 87: return 'W';
      case 88: return 'X';
      case 89: return 'Y';
      case 90: return 'Z';  
      case 91: return '[';
      case 93: return ']';
      case 94: return '^';
      case 95: return '_';
      case 97: return 'a';
      case 98: return 'b';
      case 99: return 'c';
      case 100: return 'd';
      case 101: return 'e';
      case 102: return 'f';
      case 103: return 'g';
      case 104: return 'h';
      case 105: return 'i';
      case 106: return 'j';
      case 107: return 'k';
      case 108: return 'l';
      case 109: return 'm';
      case 110: return 'n';
      case 111: return 'o';
      case 112: return 'p';
      case 113: return 'q';
      case 114: return 'r';
      case 115: return 's';
      case 116: return 't';
      case 117: return 'u';
      case 118: return 'v';
      case 119: return 'w';
      case 120: return 'x';
      case 121: return 'y';
      case 122: return 'z';
      case 123: return '{';
      case 124: return '|';
      case 125: return '}';
      case 126: return '~';
      case 181: return 'µ';
      case 187: return '»';
      case 191: return '¿';
      case 196: return 'Ä';
      case 214: return 'Ö';
      case 220: return 'Ü';
      case 223: return 'ß';
      case 228: return 'ä';
      case 239: return 'ï';
      case 246: return 'ö';
      case 252: return 'ü';
      default: return '°';
    }
  }

}
```


----------



## wayne (5. Okt 2007)

das ist schon recht komisch, daß das in der entwicklungsumgebung funktioniert und im browser nachher nicht mehr. da nutzen dann natürlich breakpoints auch nichts mehr.

zu denen hier kurz ein wort zur erklärung. in deiner entwicklungsumgebung (bei mir eclipse) setzt du auf eine bestimmte zeile einen breakpoint. die anzahl der hitcounts bezieht sich darauf, wie oft der breakpoint durchlaufen wird, bevor er das programm anhält. ist der hitcount = 0, so stoppt das programm beim ersten kontakt mit dem breakpoint, ist der hitcout = 1 so wird das programm erst anhalten, wenn der breakpoint ein zweites mal erreicht wird. wenn das programm den breakpoint erreicht wird es pausiert. eclipse fällt bei dieser gelegenheit auch gleich in eine andere view, die sogenannte debug-view. jede der mir bekannten entwicklungsumgebungen bietet dir breakpoints an und gleichzeitig damit auch die möglichkeit per tastendruck mit der abwicklung deines programms fortzufahren. im allgemeinen gibt es dabei 3 relevante tasten, eine um einfach nur zur nächsten anweisung zu gehen, also ggf. auch in eine methode hinein, eine um in der aktuellen methode zu bleiben und diese zeilenweise abzuarbeiten und eine um die aktuelle methode abzuarbeiten und in die aufrufende methode zu gelangen. dazu gibt es natürlich auch noch tasten bzw. buttons um das programm abzubrechen oder einfach fortzufahren. das wichtigste ist aber ein fenster, welches dir die inhalte der variablen anzeigt. falls du eclipse benutzt findest du es, falls du mit den views probleme haben solltest, unter Window/Show View/Variables. das ganze ist äusserst praktisch, da du jederzeit dir ansehen kannst, was ein bestimmter codeteil mit deinen variablen macht.

nur wie gesagt ist es in diesem fall wohl das verkehrte mittel. anstatt einen breakpoint in diese zeile 25 zu setzen schreib doch einfach mal nach der while-schleife in zeile 26, also zwischen die beiden geschweiften klammern in zeile 29 ein System.out.println(textBuffer); rein.

das würde auch den vorteil bringen, daß du gleichzeitig testest, ob der lese-thread auch wirklich läuft. wenn ja, müsste einmal pro sekunde der gesammte text des gästebuchs in die konsole ausgegeben werden.

bin schon am überlegen, ob das ein caching-problem des browsers sein könnte, aber da ich das ding gestern bei mir in meinem opera gestartet hab und es da auch net funktioniert hat, zweifel ich da dran.

viel glück

wayne


----------



## alphaChill (5. Okt 2007)

Habe jetz den "Fehler" gefunden. Also im Programm können wir noch lange suchen, dort ist er leider/zum Glück (wie man's sieht ;-) ) nicht. Wenn man in der Windows-Systemsteuerung unter "Java" => "Temporäre Internet-Dateien" => "Einstellungen" den Harken bei "Temporäre Dateien auf Computer belassen" rausmacht, dann läuft auch das Applet, wie in Eclipse (nutze ich auch als Entwicklungsumgebung), zumindest mit dem IE, Opera scheint wieder eigene Einstellungen zu nutzen...
Da die Einstellung zum Cachen  jedoch standardmäßig aktiviert ist, wäre es interessant zu wissen, ob es nicht eine Methode gibt, die das für dieses Applet daktiviert. Sonst müssten allle User, die das Gästebuch benutzten wollen erstmal diese Einstellung ändern...
Und danke für den Breakpoint-Kurs


----------



## wayne (6. Okt 2007)

also doch was mit dem cache. nur halt nicht im browser sondern in java. das da auch gecached wird, wusste ich noch gar nicht, insofern hast du mir da auch wieder was neues gezeigt. ich glaube nicht, daß es möglich ist, daß das applet diese einstellung verändert. um erlich zu sein hätte ich das ganze warscheinlich eh auf basis einer datenbank anstatt auf einer datei aufgebaut. da hat man dann auch gleich seine tabellenstruktur und passende sql-statements um beispielsweise einem user zu gestatten seine geposteten einträge wieder zu verändern (per update-statement) oder überhaupt mal nebenbei noch eine benutzerverwaltung zu realisieren (was du sonst ebenfalls per datei machen musst, und wenn die auch nur .htaccess heißt). jedenfalls klasse, daß das ganze nun funktioniert *schulterklopf*

wünsche dir alles gute und weiterhin frohes schaffen

wayne


----------



## alphaChill (6. Okt 2007)

Das ganze über eine Datenbank zu realisieren, werde ich ggf. in einem halben Jahr können. Lerne jetzt das 3. Jahr Java in der Schule und uns wurde vor nicht mal einem Monat gezeigt, wie man eine Oberfläche erstellt. Daher bin ich auf Java beschränkt, erst im zweiten Halbjahr der 13. Klasse lernen wir dann auch mit php und Datenbanken um zu gehen, wobei das auch nur ein hables Jahr, danach bin ich mit der Schule fertig.
Nunja es gibt ja auch noch Volkhochsschulen und was ich studieren möchte, weiß ich auch noch nicht.

Vielen Dank für die Zeit und Mühe, die du aufgebracht hast  :toll:


----------

