# Lottozahlen-Generator Hilfe mit schreiben in Text-Label



## Specter (1. April 2011)

Hallo Leute,
bin neu hier im Forum weil ich mal ganz dringend eure Hilfe brauche.
Ich muss für die Schule einen Lottozahlen Generator schreiben, aber in einer Form Datei. Ich hab das Programm zum laufen gebracht per Konsole, jetzt will ichs halt in ne Form packen aber ich scheiter daran die generierte Zufallszahl per Button in das Text Label zu schreiben.
Hier einmal mein Quelltext:

```
import java.awt.*;
import java.awt.event.*;

/**
  *
  * Beschreibung
  *
  * @version 1.0 vom 31.03.2011
  * @author
  */

public class Lotto_frame_version extends Frame {
  // Anfang Attribute
  private Label label1 = new Label();
  private Button button1 = new Button();
  private Button button2 = new Button();
  private Label label2 = new Label();
  private TextField textField1 = new TextField();
  int zz = 0;
  int [] lz = new int[8];
  int n = 0;
  boolean doppelt = false;
  // Ende Attribute

  public Lotto_frame_version(String title) {
    // Frame-Initialisierung
    super(title);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent evt) { dispose(); }
    });
    int frameWidth = 300;
    int frameHeight = 300;
    setSize(frameWidth, frameHeight);
    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (d.width - getSize().width) / 2;
    int y = (d.height - getSize().height) / 2;
    setLocation(x, y);
    Panel cp = new Panel(null);
    add(cp);
    // Anfang Komponenten

    label1.setBounds(56, 8, 186, 24);
    label1.setText("Lottozahlen-Generator");
    label1.setFont(new Font("MS Sans Serif", Font.PLAIN, 18));
    cp.add(label1);
    button1.setBounds(16, 48, 75, 25);
    button1.setLabel("Ziehung");
    button1.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        button1_ActionPerformed(evt);
      }
    });
    cp.add(button1);
    button2.setBounds(16, 216, 75, 25);
    button2.setLabel("Löschen");
    button2.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        button2_ActionPerformed(evt);
      }
    });
    cp.add(button2);
    label2.setBounds(24, 88, 78, 20);
    label2.setText("Zusatzzahl");
    label2.setFont(new Font("MS Sans Serif", Font.PLAIN, 15));
    cp.add(label2);
    textField1.setBounds(112, 48, 161, 24);
    textField1.setText("");
    textField1.setEditable(false);
    cp.add(textField1);
    // Ende Komponenten

    setResizable(false);
    setVisible(true);
  }

  // Anfang Methoden
  public void button1_ActionPerformed(ActionEvent evt) {
    while (n <= 7) {                          // Zufallszahlen erzeugen
     zz = (int)(Math.random() * 100);
      if ((zz >= 1) && (zz <= 49)) {
       doppelt = false;
       for (int i = 0;i <= n;i++) {
         if (lz[i] == zz) {
         doppelt = true ;
         }
       }
       if (doppelt == false) {
        lz[n] = zz;
        n ++;
       }
      }                                  // Zufallszahlen erzeugen Ende
    }
    textField1.setText(zz);
  }

  public void button2_ActionPerformed(ActionEvent evt) {
    // TODO hier Quelltext einfügen
  }

  // Ende Methoden

  public static void main(String[] args) {
    new Lotto_frame_version("Lotto_frame_version");
  }
}
```

Bei dem Rot markierten zeigt er mir immer einen Fehler an, keine Ahnung warum.
Wäre super nett wenn mir da jemand helfen könnte.
Hier nochmal mein Quellcode des Konsolenprogramms:

```
public class lotto2 {

  public static void main(String[] args) {
    int zz = 0;
    int [] lz = new int[8];
    int n = 0;
    boolean doppelt = false;
    boolean tauschen = true;
    int tmp = 0;
    
    while (n <= 7) {                          // Zufallszahlen erzeugen
     zz = (int)(Math.random() * 100);
      if ((zz >= 1) && (zz <= 49)) {
       doppelt = false;
       for (int i = 0;i <= n;i++) {
         if (lz[i] == zz) {
         doppelt = true ;
         }
       }
       if (doppelt == false) {
        lz[n] = zz;
        n ++;
       }
      }                                  // Zufallszahlen erzeugen Ende
    }
    while (tauschen == true) {    // Zufallszahlen sortieren; bis auf Zusatzzahl
      tauschen = false;
      for (int i = 0;i < 5 ;i++ ) {
        if (lz[i] > lz[i+1]) {
         tmp = lz[i + 1];
         lz[i + 1] = lz[i];
         lz[i] = tmp;
         tauschen = true;
        }
      }
    }                             // Zufallszahlen sortieren Ende
    // Ausgabe der Zufallszahlen
    for (int i = 0; i < 6; i++){
    System.out.println(lz[i]);
    }
    System.out.println();
    System.out.println(lz[6]);
  }
  
}
```

Schonmal Danke im vorraus 

Mit freundlichen Grüßen


----------



## Specter (1. April 2011)

Okay, hab gerade herausgefunden das die setText Methode nur mit Strings geht, hab es deshalb mit String.valueOf umgewandelt. Nun mein nächstes problem, mir wird nur eine Zahl angezeigt, doch normalerweise sollten es doch 6 sein ?


----------



## Akeshihiro (2. April 2011)

Du fügst ja auch nur eine einzige Zahl ein, also kann auch nur eine Zahl angezeigt werden. Um alle Zahlen zu sehen müsstest du aus allen Zahlen einen String zusammensetzen und diesen dann einfügen.


----------



## Specter (2. April 2011)

Kannst du mir dabei evtl. helfen? Ich generiere ja 6 Zufallszahlen, wie kann ich die denn alle nebeneinander in dem TextLabel ausgeben? Ich krieg maximal eine Zahl rein im moment. Wär's vielleicht möglich das ich das so mach:

```
textField1.setText(String.valueOf(lz[0] + lz[1]));
```
Wäre das so irgendwie möglich? Sry für die blöden fragen, bin aber noch nicht so lange dabei mit Java zu programmieren


----------



## Akeshihiro (2. April 2011)

Also da du ja die Zahlen in einem Array aufbewahrst würde ich sagen, dass eine Schleife dabei gute Abhilfe schaffen könnte. In der Schleife wird ein String zusammegesetzt, sinnvollerweise mit einem StringBuilder, damit die JVM und vor allem der RAM nicht so leiden müssen. Zum Schluss nur noch das Ergebnis in das Textfeld einfügen und gut is.

```
StringBuilder sb = new StringBuilder();
for(int i = 0; i < lz.length; i++) {
	sb.append(String.valueOf(lz[i]));
	sb.append(" ");
}
textField1.setText(sb.toString());
```


----------



## Specter (2. April 2011)

Kannst du mir kurz erklären was es mit dem sb.append auf sich hat und mit dem sb.toString?
Wäre nett wenn du mir deren Funktion kurz erläutern könntest 
Vielen Dank schonmal


----------



## Akeshihiro (4. April 2011)

Also sowas kann man eigentlich sich durch die englische Sprache selbst zusammenreimen und wenn nicht, dann nachgooglen und in einer JavaAPI nachschauen ^^ append() fügt einfach die neue Zeichenkette, die an die Methode übergeben wird, der alten hinzu und toString() gibt die zusammengebaute Zeichenkette zurück. toString() hat üblicherweise die Funktion ein Objekt in Textform darzustellen, bei Listen die Listenelemente aufgelistet, bei GUI-Objekten ihre Einstellungen wie z.B. Position, Größe, etc.


----------



## Specter (5. April 2011)

Vielen Dank erstmal für deine Hilfe 
Ich bin bis jetzt nicht viel weiter gekommen. Ich hab jetzt einen Button der die 6 Zufallszahlen in das TextField 1 schreibt und gleichzeitig die Zusatzzahl in TextField 2 einträgt. Ich habe nun noch einen Button hinzugefügt, der den Inhalt der beiden TextFields löschen soll. Das hab ich folgender maßen gelöst:

```
textField1.setText("");
textField2.setText("");
```
Mein Problem ist jetzt nur, das wenn die TextFelder wieder zurückgesetzt sind, ich keine neuen Zahlen in die Textfelder schreiben kann. Woran liegt das? Hier mein vollständiger Code:

```
import java.awt.*;
import java.awt.event.*;

/**
  *
  * Beschreibung
  *
  * @version 1.0 vom 31.03.2011
  * @author
  */

public class Lotto_frame_version extends Frame {
  // Anfang Attribute
  private Label label1 = new Label();
  private Button button1 = new Button();
  private Button button2 = new Button();
  private Label label2 = new Label();
  private TextField textField1 = new TextField();
  int zz = 0;
  int [] lz = new int[8];
  int n = 0;
  boolean doppelt = false;
  private TextField textField2 = new TextField();
  boolean tauschen = true;
  int tmp = 0;
  // Ende Attribute

  public Lotto_frame_version(String title) {
    // Frame-Initialisierung
    super(title);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent evt) { dispose(); }
    });
    int frameWidth = 300;
    int frameHeight = 300;
    setSize(frameWidth, frameHeight);
    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (d.width - getSize().width) / 2;
    int y = (d.height - getSize().height) / 2;
    setLocation(x, y);
    Panel cp = new Panel(null);
    add(cp);
    // Anfang Komponenten

    label1.setBounds(56, 8, 186, 24);
    label1.setText("Lottozahlen-Generator");
    label1.setFont(new Font("MS Sans Serif", Font.PLAIN, 18));
    cp.add(label1);
    button1.setBounds(16, 48, 75, 25);
    button1.setLabel("Ziehung");
    button1.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        button1_ActionPerformed(evt);
      }
    });
    cp.add(button1);
    button2.setBounds(16, 216, 75, 25);
    button2.setLabel("Löschen");
    button2.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        button2_ActionPerformed(evt);
      }
    });
    cp.add(button2);
    label2.setBounds(24, 88, 78, 20);
    label2.setText("Zusatzzahl");
    label2.setFont(new Font("MS Sans Serif", Font.PLAIN, 15));
    cp.add(label2);
    textField1.setBounds(112, 48, 161, 24);
    textField1.setText("");
    textField1.setEditable(false);
    cp.add(textField1);
    textField2.setBounds(112, 88, 41, 24);
    textField2.setText("");
    textField2.setEditable(false);
    cp.add(textField2);
    // Ende Komponenten

    setResizable(false);
    setVisible(true);
  }

  // Anfang Methoden
  public void button1_ActionPerformed(ActionEvent evt) {
    while (n <= 7) {                          // Zufallszahlen erzeugen
     zz = (int)(Math.random() * 100);
      if ((zz >= 1) && (zz <= 49)) {
       doppelt = false;
       for (int i = 0;i <= n;i++) {
         if (lz[i] == zz) {
         doppelt = true ;
         }
       }
       if (doppelt == false) {
        lz[n] = zz;
        n ++;
       }
      }

     StringBuilder sb = new StringBuilder();
     for(int i = 0; i <= 5; i++) {
     sb.append(String.valueOf(lz[i]));
     sb.append(" ");
     }
     textField1.setText(sb.toString());
     textField2.setText(String.valueOf(lz[6]));
                                        // Zufallszahlen erzeugen Ende
    }

  }

  public void button2_ActionPerformed(ActionEvent evt) {
  textField1.setText("");
  textField2.setText("");
  }

  // Ende Methoden

  public static void main(String[] args) {
    new Lotto_frame_version("Lotto_frame_version");
  }
}
```
Und dann gibts da noch das Problem mit der Zahlensortierung, in meinem normalen Programm hab ich das ja so gemacht:

```
while (tauschen == true) {    // Zufallszahlen sortieren; bis auf Zusatzzahl
      tauschen = false;
      for (int i = 0;i < 5 ;i++ ) {
        if (lz[i] > lz[i+1]) {
         tmp = lz[i + 1];
         lz[i + 1] = lz[i];
         lz[i] = tmp;
         tauschen = true;
        }
      }
    }
```
Aber wenn ich das in mein neues Programm einfüge, dann gibt er mir als erste Zahl immer eine 0 aus und sortiert die anderen aber nicht. Kann mir da noch jemand abhilfe schaffen? Wäre echt super wenn mir dabei behilflich sein könnte, muss das Programm bis Donnerstag vormittag fertig haben 

Schonmal vielen Dank im vorraus


----------



## Akeshihiro (6. April 2011)

Wo musst du das abgeben, is das nen Schulprojekt? Weil so würde ich persönlich den Code nicht abgeben, da müsste noch hier und da was getan werden, schon allein vom Optischen her. Fehler hab ich soweit korrigiert, auch den Code an sich verändert, damit da ein wenig Ordnung rein kommt. Allerdings weiß ich nicht wie weit du bist, weshalb ich den Code in der Form auch nicht poste, zumal es nicht meine Aufgabe ist das für dich zu machen.

Das mit dem Neugenerieren der Zahlen klappt nicht, weil deine while-Schleife da muckt. Die Variable n wird bei dir ja nirgends auf 0 zurückgesetzt, daher springt die Schleife auch nicht an, wenn du neue Zahlen generieren willst.
Das mit dem Sortieren klappt wunderbar, keine Ahnung warum das bei dir nicht will.

Dann zu den Verbesserungsvorschlägen:
Ich habe gesehn, dass du bei den Schleifen mit festen Zahlen als Begrenzer arbeitest. Solltest du nach Möglichkeit vermeiden. Wenn sich die Größe von deinem Array ändert, dann kommt das schon wieder nicht hin und du musst überall die Schleifen anpassen. Das ist nicht nur unnötige Arbeit, sondern auch unübersichtlich und es kann sein, dass man hier und da was vergisst und dann gibts Fehler.
Bleiben wir auch gleich beim Array. Warum hat das Array 8 Felder, wenn du nur 7 brauchst? Es sind doch 6 Lottozahlen und 1 Zusatzzahl, macht bei mir 7.
Dann die Benennung der Variablen. Von mir aus kannst du deutsche Bezeichner verwenden, aber auch auf deutsch sollten sie eindeutig sein und vor allem auch aussagekräftig. lz oder zz z.B. sind keine guten Variablen, weil man auf den ersten Blick nicht erkennt, was sie machen und Kommentare diesbezüglich habe ich auch nirgends gefunden. Ich meine es handelt sich hier um ein Lottziehungsprogramm, da kommt man schon auf den Sinn der Abkürzungen, sollte man aber vermeiden. Und die Textfelder, Buttons und Labels sind einfach stumpf durchnummeriert, da weiß man gar nich welches Objekt wofür is. Ausnahmen sind halt Zählvariablen für Schleifen (i, j, k, etc.), da in der Programmierwelt jeder sofort weiß worum es sich dabei handelt und die Variablen zudem auch eh nur temporär für die Schleifen existieren, daher also auch keine bedeutende Rolle spielen. Der Klassenname ist so auch nicht Java-typisch. In Java geht man bei der Benennung nach der Kamelhöcker-Variante vor, also LottoFrameVersion. Das gilt so eigentlich für alle Bezeichner.
Dann großes Thema Kommentare. Man sollte schon gut kommentieren. Man brauchts nicht übertreiben und jede Zeile kommentieren, aber vor allem an wichtigen Stellen sollte man mal kurz nen Kommentar schreiben, damit man auch sofort weiß, was da gleich kommt. Kommentare ersparen zudem das Lesen und Interpretieren vom Code, also auch Zeit, weil man weiß was passiert (oder zumindest was passieren sollte) ohne den Code gelesen zu haben. Vor allem als Anfänger erspart das einem auch viel Ärger, weil man oft die Gedankengänge noch nicht so sortieren kann, dann fängt man mit einer Sache an, springt zur nächsten, bekommt ne neue Idee und schon weiß man gar nicht mehr, was man eigentlich machen wollte. Daher besonders bei wichtigen Stellen einen kurzen, aber ausführlichen Kommentar schreiben, was man vor hat. Das hilft dannach auch dabei zu entscheiden, ob man jetzt das Ziel erreicht oder etwas völlig anderes fabriziert hat.

Und du solltest mehr über Auslagerung in Methoden nachdenken. Eigentlich das gesammte Programm ist im Konstruktor drin. Das sieht nicht nur doof aus, das ist auch ziemlich unübersichtlich. Das ist aber nicht nur beim Konstruktor so, das gillt generell für alle Methoden: nicht zu groß machen. Man hätte beispielsweise die Geschichte mit den Komponenten in eine Methode auslagern können, genauso die Einstellungen des Frames an sich und schon wäre der Konstruktor auf wenige Zeile geschrumpft. Bei der Komponenten-Methode aber auch nicht alles stumpf in eine Methode kloppen, sondern auch nochmal unterteilen, z.B. für jede Komponente eine eigene Methode.
Diese Auslagerung hat mehrere Vorteile. Zum einen sieht der Code viel sauberer aus und ist auch viel strukturierter. Zum anderen musst du aber auch nicht lange suchen, wenn sich irgendwo was ändert. Zum Beispiel bei den Komponenten weißt du genau welche Komponente in welcher Methode ist. Dann springst du einfach zu der Methode und schon kanns losgehn. Und wohl der wichtigste Grund überhaupt (kommt hier aber kaum zum Tragen): Wiederverwendbarkeit. So kann man eine Methode immer wieder verwenden anstatt das Zeug, das in der Methode steht, mehrmals im Code hinzutippen oder zu kopieren. Das sparrt nicht nur Zeilen, sondern macht die Sache nochmal übersichtlicher und sollte sich bei dem Ablauf mal was ändern, dann muss man nicht an mehreren Stellen Anpassungen machen, sondern nur in der Methode und man hats überall auf dem neusten Stand.

Joa, ich glau das waren auch so ziemlich die größten Sachen, die mir aufgefallen sind. Ich weiß, dass das für dich jetzt wahrscheinlich ganz schön viel ist und du wahrscheinlich auch nicht alles verstehst, aber versuch das mal umzusetzen, das wird beim Lehrer gleich einen besseren Eindruck hinterlassen.

Achso, was mir noch aufgefallen ist: Beim Generieren der Zahlen, da lässt du gleich in der Schleife die Zahlen zu einer Zeichenkette zusammentackern und gibst sie auch noch aus. Das ist aber Murcks. Erst den Kram generieren lassen (dafür ja die Schleife), dann sortieren (hasst du wahrscheinlich nicht drin, weils nicht geklappt hat) und dann erst ausgeben. Das heißt nur das Generieren findet in der while-Schleife statt, das Sortieren und Ausgeben muss da raus.
Und Variablen nach Möglichkeit erst dann deklarieren, wenn sie auch gebraucht werden. Ich denke da z.B. an tauschen, doppelt, n und son Zeug. Das hat nix mit der Klasse an sich zu tun, weshalb sie nix bei den Attributen zu suchen haben, und die Übersicht geht dabei auch wieder flöten, weil man gar nicht weiß, was das werden soll.


----------

