Repaint() funktioniert nicht

redbull1990

Grünschnabel
Ich will ein kleines Programm schreiben, das mir immer eine bestimmte Anzahl von Buchstaben eines Wortes im Gui anzeigt. Die Anzahl wird von 2 Threads ermitttelt, die synchronisiert eine Variable erhöhen. Jedes mal wenn die Anzahl erhöht wird, soll die Gui neu gezeichnet werden. Nur das funktioniert leider nicht. Denn wenn ich repaint() auf rufe, wird weder die paint() nocht die paintComponents()- Methode aufgerufen.
Bsp: Wort = "Hallo"...
H --> Ha --> Hal --> Hall --> Hallo und dann das ganze wieder von vorne.

Wer weiß woran das liegen kann?
 
Wenn du aus einem Thread heraus die GUI aktualisieren möchtest solltest du SwingUtilities.invokeLater(Runnable) verwenden.

(Bitte nächstes mal ins richtige Unterforum posten :))
 
Hallo,

die Antwort von zeja kann ich jetzt nicht ganz nachvollziehen, aber um das Problem
angehen zu können bedarf es etwas mehr Information.

Wie ist die GUI-Aufgebaut, wo schreibst du wie deinen String usw.

Gruß JAdix
 
In SWING darf prinzipiell nur der GUI-Thread die GUI aktualsieren. Deswegen sollte man solche GUI-Zugriffe in einem invokeLater kapseln.

Aus der Doku der Methode:
This method should be used when an application thread needs to update the GUI.

Das würde ich daher als erstes versuchen.
 
Hallo,

Ick sech mol,

"should be used" is nich "must be used" wa !

Wenn ich aus einem Thread heraus lediglich über die repaint()-Methode auf
die GUI-Einwirke denke ich ist das aus Thread-Save-Überlegungen nicht als
kritisch zu bewerten.

Sicher es kann mir passieren das ein repaint mal nicht zum gewünschten
Zeitpunkt ausgeführt wird, aber ich denke das hier die Problematik wo anders
liegt.

Gruß JAdix
 
Java:
public class Threads extends Thread implements Runnable{

   /**
    * Instanz auf ThreadsSynchronized..
    * 
    */
   private ThreadsSynchronized ts;

   /**
    * Konstruktor, der die Anzahl der Threads festlegt und startet
    * 
    */
   public Threads() {
      Thread[] t = new Thread[2];
      ThreadsSynchronized th = new ThreadsSynchronized();

      for (int i = 0; i < 2; i++) {
         t[i] = new Threads(th);
         t[i].start();
      }
   }

   /**
    * Konstruktor, der den Namen und die Instanz setzt
    * 
    * @param ts
    *            Instanz auf die Klasse ThreadsSynchronized
    * 
    */
   public Threads(ThreadsSynchronized ts) {
      this.ts = ts;
   }

   /**
    * lässt die Threads laufen..
    * 
    */
   
   public void run() {
      while (true) {
         System.out.println("Sichtbare Buchstaben: " + ts.erhoehen());
      }
   }
 
}

Java:
public class ThreadsSynchronized{

   /**
    * Text der durchläuft
    * 
    */
   private String text = "Terminverwaltung";
   
   /**
    * Angezeigten Buchstaben
    * 
    */
   private int anzBst = 0;

   /**
    * Höchstanzahl der angzeigten Buchstaben
    * 
    */
   private int laenge = text.length();

   public synchronized int erhoehen() {
      int ret;

      if (anzBst <= laenge) {
         ret = anzBst;
      }
      else {
         anzBst = 0;
         ret = anzBst;
      }

      anzBst++;
      new Laufschrift();
      
      return ret;
   }   
}

Java:
public class Laufschrift extends JPanel {

   /**
    * 
    */
   private static final long serialVersionUID = -1463345723052588523L;

   /**
    * setzt die Schriftart, Schriftgröße umd zusätzlich noch Fett
    * 
    */
   private Font f = new Font("SansSerif", Font.BOLD, 20);

   /**
    * Text der durchläuft
    * 
    */
   private String text = "Terminverwaltung";

   /**
    * Breite des "Kasten"
    * 
    */
   private int breite;

   /**
    * Höhe des "Kasten"
    * 
    */
   private int hoehe;

   /**
    * X-Koordinate
    * 
    */
   private int x;

   /**
    * Y-Koordinate
    * 
    */
   private int y;

   /**
    * Höchstanzahl der angzeigten Buchstaben
    * 
    */
   private int laenge = text.length();

   public Laufschrift() {
      repaint();
      Graphics g = getGraphics();

      y = getSize().height / 2 + hoehe;
      x = getSize().width / 2 + breite;

      // g.setFont(f);
      //
      // // Hintergrundfarbe
      // g.setColor(Color.GREEN);
      //
      // g.fillRect(0, 0, getSize().width, getSize().height);
      //
      // // Schriftfarbe
      // g.setColor(Color.RED);
      //
      // g.drawString(text.substring(0, laenge), x, y);
   }

   protected void paintComponent(Graphics g) {
      super.paintComponent(g);

      System.out.println("JA");

      y = getSize().height / 2 + hoehe;
      x = getSize().width / 2 + breite;

      g.setFont(f);

      // Hintergrundfarbe
      g.setColor(Color.GREEN);

      g.fillRect(0, 0, getSize().width, getSize().height);

      // Schriftfarbe
      g.setColor(Color.RED);

      g.drawString(text.substring(0, laenge), x, y);
   }

}
 
Zuletzt bearbeitet von einem Moderator:
Hallo,

also vorab, wie Du das mit den Konstruktoren in Deiner Threads-Klasse machst,
ist in meinen Augen etwas unschön. Speziell das aus Zeile 18.

In Zeile 33 deiner ThreadsSynchronized-Klasse erzeugst du immer wieder ein neues
JPanel welches keinen Bezug zur Oberfläche hat. Du must schon immer mit dem
Laufschrift-JPanel arbeiten welches du zu deiner GUI zugefügt hast und auf
dieses ein repaint() ausführen !
(Nebenbei, lass mich raten Zeile 52 in der Laufschrift-Klasse liefert nur null)

Gruß JAdix
 
Zurück