# JTable aktualisieren mit 1 Sekundenschritten



## Nikke123 (1. Dezember 2011)

Hallo Leute,

Ich möchte eine GUI Schreiben, die eine Schlange an einer Kasse in der Mensa mit Studenten veranschaulicht. Mein Quellcode birgt aber noch einige Fehler, befasse mich auch erst seid kurzem mit GUIs. Bevor ich sage was ich will, hier mal mein Quellcode:


```
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.DefaultTableModel;
/**
  *
  * Beschreibung
  *
  * @version 1.0 vom 01.12.2011
  * @author Niklas Riecken
  */


class output{

      static Schlange warteSchlange = new Schlange();
      static Random zufallszahl = new Random();
      static Student student;
      static DefaultTableModel model = new DefaultTableModel();
      static JLabel t;
      static JFrame f;

      public output(){

             //Frame erstellung
             JFrame f = new JFrame("Mensaschlange");
             f.setLayout(new BorderLayout());
             
             //Labelerstellung
             JLabel l = new JLabel("Studenten in der Mensaschlange");
             JLabel t = new JLabel("Durchschnittliche Wartezeit: 1 min");
             l.setHorizontalAlignment(JLabel.CENTER);
             t.setHorizontalAlignment(JLabel.CENTER);

             //Tabelle
             JTable table = new JTable(model);
             JScrollPane pane = new JScrollPane(table);
             model.addColumn("Student");
             model.addColumn("Wartezeit");
             model.addColumn("Mahlzeiten");
             int x = model.getRowCount();

             //Panelregelungen
             f.getContentPane().add(BorderLayout.NORTH, l);
             f.getContentPane().add(BorderLayout.SOUTH, t);
             f.getContentPane().add(BorderLayout.CENTER, pane);
             f.pack();
             f.setVisible(true);
             emuliere();
      }
      
      public static void emuliere() {
             double aktuelleZeit = 0;
             double studentenmenge = 0;
             double wartezeitgesamt = 0;
             double durchschnittlichewartezeit = 0;
             for(int i=1; i<=5; i++){
                     student = new Student(aktuelleZeit);
                     warteSchlange.enqueue(student);
                     studentenmenge++;
                     model.addRow(new Object[]{student.getNummer(), durchschnittlichewartezeit + 1 + " min", student.getEssen()});
             }
             while (aktuelleZeit <=100) {
                   if (zufallszahl.nextInt(100)>50) {
                     student = new Student(aktuelleZeit);
                     warteSchlange.enqueue(student);
                     model.addRow(new Object[]{student.getNummer(), durchschnittlichewartezeit + 1 + " min", student.getEssen()});
                     warteSchlange.enqueue(student);
                     studentenmenge++;
                   }
                   if (zufallszahl.nextInt(100)>50 && warteSchlange.isEmpty() == false){
                     wartezeitgesamt = wartezeitgesamt + (aktuelleZeit - student.getStartzeit());
                     student = (Student)warteSchlange.front();
                     warteSchlange.dequeue();
                   };
             durchschnittlichewartezeit = (wartezeitgesamt / studentenmenge);
             aktuelleZeit++;
             }
             durchschnittlichewartezeit = (wartezeitgesamt / studentenmenge);

      }
}
```

Die Klasse output wird von einer anderen GUI aus aufgerufen. Ich möchte gerne, dass der die while schleife durchläuft aber nach jedem Durchlauf eine Sekunde lang wartet. Dann möchte ich noch, dass wenn das dequeue stattfindet, der gemachte Tabelleneintrag ( was immer die letzte Zeile sein muss!! ) gelöscht wird. Außerdem soll, die durchschnittliche Wartezeit die im SOUTH per Label angezeigt wird sich ebenfalls immer aktualisiert. Wie bekomme ich das hin?

Danke für eure Hilfe schonmal im Vorraus!
Niklas


----------



## genodeftest (1. Dezember 2011)

Hi
Pack deinen Code bitte in java-Tags (siehe meine Signatur).
Und normalerweise solltest du nicht die Tabelle in festen Zeitintervallen neu zeichnen/aktualisieren, sondern:
a) die Funktionalität per Listener implementieren (aktives Abfragen von Werten ist böse weil unnötige Rechenlast und hohe Delays)
b) per Timer regelmäßig eine Methode ausführen, die nach geänderten Daten sucht und ggf. neu zeichnet (siehe http://openbook.galileocomputing.de/javainsel9/javainsel_19_028.htm )


----------



## Nikke123 (1. Dezember 2011)

Also die Java Tags hab ich gemacht. Was du mit Listener meinst, verstehe ich noch nicht ganz aber der Teil mit der While Schleife und der ForSchleife ist vorgegeben von meinem Lehrer. Eigentlich erfüllt das Programm mit der Konsole seinen Zweck aber ich möchte das gerne erweitern  mit einer GUI um selber die GUI und Anweundungen damit zu erlernen. zu B ehm kannst du mir das kurz erläutern wie ich das einbringen muss?

Danke schonmal 
Niklas


----------



## vfl_freak (2. Dezember 2011)

Moin,



Nikke123 hat gesagt.:


> Also die Java Tags hab ich gemacht.


Nö, hast Du nicht .... Du hast CODE-Tags gemacht 

Gruß
Klaus


----------



## sheel (2. Dezember 2011)

Es sind doch Javatags?
Ich versteh da "Ok, jetzt hab ich Javatags".

Vorher war es übrigens [PHP]...[/PHP].

Zum Thema: Was verstehst du bei B am Link nicht?


----------



## Nikke123 (2. Dezember 2011)

Ich verstehe einfach das nicht so ganz genau:

```
javax.swing.Timer t = new javax.swing.Timer( 1000, new ActionListener() {
  public void actionPerformed( ActionEvent e ) {
    p.repaint();
  }
});
t.start();   // t.stop() beendet.
```
Kann mir das bitte wer erklären?


----------



## sheel (2. Dezember 2011)

Damit setzt du einen Timer in Gang, der jede Sekunde

```
p.repaint();
```
macht.

Ist nur eine vllt. ungewohnte Schreibweise,
die Methode so im Konstruktor definieren.


----------



## Nikke123 (2. Dezember 2011)

Okay... Da spuckt der schonmal keine Fehlermeldungen bei raus und alles klappt. Jetzt soll das Programm im Abschnitt der While Schleife nach jedem Durchlauf 1 Sekunde warten. Wie bekomme ich das hin? Denn mit:

```
Thread.sleep(1000);
```
klappt das nicht.

Wenn ich:

```
try {
                 Thread.sleep(2000);
             } catch (InterruptedException e) {
                 //nichts
             }
```
mache, und mein Programm starte, wird der Frame erzeugt aber meine Tabelle ist nicht zu sehen der Panel ist quasi alles weis und der XButton funktioniert auch nicht mehr dann muss ich den Prozess beenden...


----------



## sheel (2. Dezember 2011)

Sleeps gehören, wenn überhaupt, nicht in einen Gui-Thread.
Das Aufhängen in dem Fall ist völlig normal.


----------



## Nikke123 (2. Dezember 2011)

Soweit so gut, aber wie regle ich es denn dann, dass die While Schleife nach jedem Durchgang eine Sekunde wartet bevor sie den nächsten Durchgang macht?


----------



## genodeftest (2. Dezember 2011)

Du sollst nicht in einer while-Schleife warten. Nutze einfach den Timer.


----------



## Nikke123 (5. Dezember 2011)

Aber der Timer macht ja nur Repaint ich will aber dass der in der While Schleife nach jedem Durchgang eine Sekunde abwartet bevor der den nächsten Durchlauf macht


----------



## vfl_freak (5. Dezember 2011)

Moin,



Nikke123 hat gesagt.:


> Aber der Timer macht ja nur Repaint ich will aber dass der in der While Schleife nach jedem Durchgang eine Sekunde abwartet bevor der den nächsten Durchlauf macht



siehe vorletzter Post:


genodeftest hat gesagt.:


> Du sollst nicht in einer while-Schleife warten. Nutze einfach den Timer


also TIMER anstelle der WHILE-Schleife !

Gruß
Klaus


----------

