www.r-krell.de
Webangebot für Schule und Unterricht, Software, Fotovoltaik und mehr

Willkommen/Übersicht  >  Informatik  >  Java-Seite b1) (2017)

Informatik mit Java

Teil b1)_2017
Einführung in das Programmieren mit Swing-Oberflächen



Eine vollständige Übersicht aller meiner Seiten "Informatik mit Java" gibt's auf der Informatik-Hauptseite!

Auf dieser Seite b1)_2017 finden Sie:


zum Seitenanfang / zum Seitenende



Programmieren von Swing-Anwendungen mit dem Java-Editor

Im Folgenden wird davon ausgegangen, dass Sie - wie auf Seite a) beschrieben -- eine aktuelle SDK und den Java-Editor installiert haben. Während auf meinen weiterhin verfügbaren "Informatik-mit-Java"-Seiten b) ff über einen längeren Zeitraum Berichte zusammengetragen wurden, die sich i.W. auf Informatik-Leistungskurse stützen, in denen zunächst mit dem Hamster und dann mit Stift&Co in das Programmieren eingeführt wurde, habe ich 2017 in einem Grundkurs einen anderen Weg beschritten: Algorithmik und Programmieren werden direkt durch Schreiben von Anwendungen mit moderner Oberfläche erlernt! Durchgeführt wird bzw. wurde der Unterricht in einem halbjährigen Grundkurs in der Einführungsphase der gymnasialen Oberstufe. Die heterogene Schülerschaft bringt ganz überwiegend keinerlei Vorkenntnisse über Programmieren mit; viele Schülerinnen und Schüler hatten früher nicht mal Informatik-Unterricht. Allerdings habe ich im ersten Halbjahr in diesem Kurs neben Grundzügen der Bild- und Textverarbeitung in den sinnvollen Gebrauch von Tabellenkalkulation und Datenbankprogrammen (inkl. Datenbankentwurf nach der 2. NF mit ER-Diagrammen) eingeführt. Das Programmieren in Java begann aber genau so wie hier dargestellt und ohne weitere Präliminarien.

Die Oberflächen der geschriebenen Programme werden mit dem GUI-Builder des Java-Editors per Maus erstellt; besondere Eigenschaften der Oberflächenelemente werden im Objektinspektor ergänzt bzw. angepasst. Der dafür vom GUI-Builder automatisch erzeugte Programmtext soll nicht verändert und braucht nicht verstanden zu werden. Eigener Programmtext für die Funktionalität wird zunächst nur in die ActionPerformed-Methoden der Schaltflächen geschrieben. Für jede Arbeit des Programms muss also ein Knopf in die Oberfläche gesetzt werden, der die gewünschte Funktion auslöst. Der Quelltext zur Funktionalität der Knöpfe soll sehr wohl verstanden und gezielt (weiter) entwickelt werden - damit und dafür wird das Programmieren erlernt! Im Folgenden ist dieser selbst geschriebene Quelltext farbig unterlegt.

Die Oberflächen werden in Swing geschrieben. Seit der Ende Februar 2017 erschienenen Version 14 unterstützt der Java-Editor auch JavaFX; allerdings hatte der Unterricht schon vorher begonnen.




zum Seitenanfang / zum Seitenende

Oberfläche des ersten Programms (P1),
erzeugt mit dem Java-Editor



Gewünscht ist ein Programm, das den Benutzer auf Knopfdruck grüßt (oder natürlich auch die Welt, falls vor dem Betätigen der [Grüßen]-Schaltfläche als Name "Welt" eingetippt wurde). Die Oberfläche könnte etwa wie folgt aussehen:

Oberfläche des Programms P1

Um dieses Programm zu schreiben, wird einfach der „Java-Editor" gestartet und dort mit dem Menübefehl Datei | Neu ein neuer JFrame erzeugt. Nach Wahl eines Ordners und Eingabe eines Programm- bzw. Klassennamens (etwa "P1_Gruss") öffnen sich zwei Fenster: Das Formular P1_Gruss.jfm für die Oberfläche und das Fenster P1_Gruss.java für den Java-Programmtext ("Quelltext"). Aus dem Reiter "Swing 1" werden ein JLabel, ein JTextField, zwei JButtons und noch ein JTextField auf das Formular gezogen. Mit dem Objektinspektor wird der Text des JLabels von "text" auf "Bitte Namen eingeben:" verändert;

Ansicht Java-Editor beim Erstellen der Oberfläche

außerdem erhalten die Textfelder und Schaltflächen an Stelle der automatisch erzeugten Namen "jTextField1", "jButton1", "jButton2" und "jTextField2" die sprechenden Namen "jTfEingabe", "jBtLoesch", "jBtGruss" und "jTfAusgabe". Die ersten drei Buchstaben kürzen den Typ des Bildschirmobjekts ab. Weiterhin wird der Text auf den Knöpfen abgeändert und die Editierbarkeit des Ausgabefeldes von true auf false gesetzt. Der Java-Editor erzeugt automatisch eine Menge Quelltext, der aber nicht beachtet und nicht verändert werden muss.

Ansicht Java-Editor mit Objekt-Inspektor

Dieses Programm kann schon kompiliert und (mit dem grünen Pfeil) gestartet werden. In das neue, in der Bildschirmmitte erscheinende Fenster kann bereits Text in die Eingabezeile eingetippt werden; auch lassen sich die Knöpfe betätigen - allerdings passiert beim Klick auf die Knöpfe noch nichts. Die Funktionalität muss - wie im Folgenden beschrieben - von Hand ergänzt werden: und zwar an den mit //TODO .. gekennzeichneten Stellen in den beiden bereits automatisch angelegten ActionPerformed-Methoden der Knöpfe. Nur hier - im Bild in den Zeilen 78 und 82 - beginnt jetzt das Programmieren durch die Schülerinnen und Schüler! Die blauen Kommentare "// TODO hier Quelltext einfügen" werden dazu überschreiben bzw. entfernt.

Ansicht Java-Editor mit TODO-Stellen für Knopf-Methoden


zum Seitenanfang / zum Seitenende



Java-Programmen P1: getText und setText, normale Befehlsabfolge und EVA-Prinzip



Nachdem die Oberfläche des Programms "P1_Gruss" wie oben beschrieben erstellt wurde, muss jetzt dem Computer mitgeteilt werden, was er beim Druck auf die beiden Schaltflächen machen soll.

Oberfläche des Programms P1

Beginnen wir mit dem [ Löschen ]-Knopf: Hier ist klar, dass die beiden Textfelder gelöscht werden sollen, d.h. nachher kein Text mehr drin stehen soll - der Text leer sein soll. Der mitgeteilte Javabefehl jTfEingabe.setText("") wird als naheliegend verstanden. Auch die Anweisungen im [ Grüßen ]-Knopf sind einsichtig. Hier wurden in der letzten Methode drei Zeilen verwendet, um an die früher viel beschworene Dreiteilung jedes Programms nach dem EVA-Prinzip zu erinnern: Eingabe - Verarbeitung - Ausgabe:




2 Struktogramme für P1  public void jBtLoesch_ActionPerformed(ActionEvent evt) {
    jTfEingabe.setText(
"");
    jTfAusgabe.setText(
"");
  } 
// end of jBtLoesch_ActionPerformed

  public void jBtGruss_ActionPerformed(ActionEvent evt) {
    String rein = jTfEingabe.getText();
    String raus = 
"Der Computer grüßt dich mit: Hallo "+rein;
    jTfAusgabe.setText(raus);
  } 
// end of jBtGruss_ActionPerformed




Im Javaeditor sieht der grün unterlegte Quelltext so aus:

Ansicht Java-Editor mit selbst geschriebenen Methoden


Natürlich hätte das Zusammensetzen des festen, hier vom Editor blau gefärbten Textes mit dem eingegebenen, vom Programm aus dem Eingabefeld geholten Namen (in der Variablen rein) auch in der Klammer hinter setText passieren können:

  public void jBtGruss_ActionPerformed(ActionEvent evt) {
    String rein = jTfEingabe.getText();

    jTfAusgabe.setText(
"Der Computer grüßt dich mit: Hallo "+rein);
  } 
// end of jBtGruss_ActionPerformed

Und letztlich könnte man den Methodenrumpf sogar zu einem -- allerdings weniger gut lesbaren -- Einzeiler zusammen ziehen:

  public void jBtGruss_ActionPerformed(ActionEvent evt) {
    jTfAusgabe.setText(
"Der Computer grüßt dich mit: Hallo "+jTfEingabe.getText());
  } 
// end of jBtGruss_ActionPerformed


Andererseits kann bei mehreren Zeilen schon das Variablenkonzept angesprochen werden, wobei deutlich werden muss, dass nur vor der ersten Verwendung der Typ zu Definition angegeben wird; bei der späteren Verwendung entfällt die Typangabe.


Übungs-Aufgaben zu P1

  1. Ändern Sie das Programm, sodass die Ausgabe in der Form "Carla, sei gegrüßt" erfolgt.
  2. Erweitern Sie das Programm auf zwei Eingabefelder (für Vor- und Nachnamen) und lassen etwa "Hallo, Carla Musterfrau, sei gegrüßt" ausgeben (mit Leerstelle zwischen Vor- und Nachnamen!).


zum Seitenanfang / zum Seitenende

Java-Programm P2: Einseitige Verzweigung



Während normalerweise die Befehle vom Computer genau in der aufgeschriebenen Reihenfolge abgearbeitet werden und dabei jede Anweisung genau einmal ausgeführt wird, können Kontrollstrukturen dies ändern. Bei einer Verzweigung wird der Befehl oder werden alle Befehle im Rumpf der Verzweigung entweder nach wie vor einmal ausgeführt (wenn die Bedingung zutrifft), oder sie werden gar nicht ausgeführt. Die Abfolge wird nicht verändert, aber manche Befehle werden statt genau einmal jetzt höchstens einmal ausgeführt, nämlich situationsabhängig vielleicht auch gar nicht. Das Programm P2 erfordert eine solche Verzweigung: Wieder soll die Person, deren Name eingegeben wurde, gegrüßt werden. Allerdings sollen Frauen mit "Hallo, liebe Carla" und Männer mit "Hallo, lieber Georg" gegrüßt werden. Es ist klar, dass dem Computer dazu das Geschlecht der Person mitgeteilt werden muss (geschieht hier über JRadioButtons). Und während bei Männern ein "r" and das "liebe" angehängt werden muss, kann diese Ergänzung bei Frauen entfallen.

Oberfläche des Programms P2

Damit ein JRadioButton beim Anklicken automatisch den anderen, früher angeklickten (oder im Objekt-Inspektor auf Selected = true gesetzten) JRadioButton ausschaltet, müssen sie einer gemeinsamen Gruppe angehören. Im Java-Editor wird dazu eine JButtonGroup auf das Formular gezogen. Die Buttongroup sieht man bein Laufenlassen des Programm nicht. Aber den einzelnen Radiobuttons kann jetzt jeweils im Objektinspektor diese Gruppe zugewiesen werden; außerdem erstellt der Javaeditor dann automatisch eine Methode zur bequemen Abfrage des gewählten Radiobuttons.

Ansicht Java-Editor mit Oberflächenformular und ButtonGroup
Während der [ Löschen ]-Button genauso funktioniert und programmiert wird, wie oben im Programm P1, wird die Verzweigung im [ Grüßen ]-Knopf wie folgt realisiert:


Struktogramm für P2  public void jBtGruss_ActionPerformed(ActionEvent evt) {
    String rein = jTfEingabe.getText();
    String raus = 
"Hallo, liebe";
    
if (buttonGroup1_getSelectedRadioButtonLabel().equals("männlich"))
    {
      raus = raus + 
"r";
    }
    raus = raus + 
" " +rein;
    jTfAusgabe.setText(raus);
  } 
// end of jBtGruss_ActionPerformed


Dass das "r" richtig erscheint, zeigt nochmal eine Bildschirmansicht des Java-Editors mit veränderter Eingabe:

Ansicht Java-Editor mit Quelltext(-Ausschnitt) und laufendem P2

Übungs-Aufgaben zu P2

  1. Ändern Sie das Programm, sodass Männer mit "Hallo, Programmiermeister Alexander" und Frauen mit "Hallo, Programmiermeisterin Carla" begrüßt werden.
  2. Erweitern Sie das Programm auf zwei if-Abfragen: Männer kriegen an "Hallo, " noch "Herr ", Frauen noch "Frau " angehängt, sodass entweder "Hallo, Herr Alexander" oder "Hallo, Frau Carla" ausgegeben wird. Untersuchen Sie, ob die Reihenfolge beider if-Abfragen im Programmtext das Ergebnis verändert.


zum Seitenanfang / zum Seitenende

Java-Programm P3: Zwei- und mehrseitige Verzweigung



Bei Anreden kann i.d.R. nur genau eine von zwei Alternativen gewählt werden. Deshalb ist es - anders als in der Übungsaufgabe 2 zu P2 - nicht nötig, nochmal nachzufragen, ob man die Anrede "Herr" haben will, wenn man keine "Frau" ist: Wer nicht als "Frau" angeredet werden will, gilt automatisch als "Herr" und umgekehrt. Deshalb sind nicht zwei einseitige Verzweigungen mit zwei Fragen nötig, sondern es reicht eine Abfrage mit einer zweiseitigen Verzweigung, bei der genau ein Zweig gewählt wird.



Oberfläche des Programms P3
Soll beim Gruß sogar die Tageszeit berücksichtigt werden, ist eine mehrfache Verzweigung mit mehr als 2 Möglichkeiten sinnvoll. Während hier durch die Radiobuttons immer eine gültige Alternative ausgewählt werden muss (wenn zuvor im Objekt-Inspektor genau eine Zeit als selected voreingestellt wurde), kann in anderen Anwendungen noch ein default:-Fall als Ersatz-Möglichkeit sinnvoll sein, wenn kein case-Wert gewählt wurde.


Struktogramm für P3 mit if-else und switch-case  public void jBtGruss_ActionPerformed(ActionEvent evt) {
    String rein = jTfEingabe.getText();
    String raus;
    
    
if (bGAnrede_getSelectedRadioButtonLabel().equals("Herr"))
    {
      raus = 
"Herr ";
    } 
    
else
    {
      raus = 
"Frau ";
    }
    
    
switch (bGZeit_getSelectedRadioButtonLabel()) 
    {
      
case "Morgen" : raus = "Guten Morgen, "+ raus;  break;
      
case "Tag"    : raus = "Guten Tag, "+ raus;     break;
      
case "Abend"  : raus = "Guten Abend, "+ raus;   break;
      
case "Nacht"  : raus = "Gute Nacht, "+ raus;    break;    
    } 
// end of switch
    
    jTfAusgabe.setText(raus+rein);
  } 
// end of jBtGruss_ActionPerformed



Übungs-Aufgaben zu P3

  1. Im Programm gibt es jetzt offenbar zwei (Radio-)ButtonGroups. Welche und wieso? Und welche Radiobuttons gehören zu jeder Gruppe?
  2. Setzen Sie mit dem Objekt-Inspektor nicht eine Anrede und eine Tageszeit von vorneherein auf Selected = true (bzw. setzen Sie wieder bei allen Radiobuttons Selected auf false). Starten Sie dann das Programm, geben nur einen Namen an, klicken aber keinen Radiobutton an und lassen Sie sich grüßen! Begründen Sie, warum in einer Verzweigung trotzdem etwas getan wird und in der anderen hingegen offensichtlich nichts!
  3. Ergänzen Sie in der switch-case-Anweisung eine fünften Fall und wiederholen Sie Aufgabe 2. Erklären Sie das Ergebnis und vervollständigen Se das Struktogramm!
  4.     switch (bGZeit_getSelectedRadioButtonLabel()) 
        {
          
    case "Morgen" : raus = "Guten Morgen, "+raus;  break;
          
    case "Tag"    : raus = "Guten Tag, "+raus;     break;
          
    case "Abend"  : raus = "Guten Abend, "+raus;   break;
          
    case "Nacht"  : raus = "Gute Nacht, "+raus;    break;
          
    default       : raus = "Mahlzeit, "+raus;      break;    
        } 
    // end of switch
        

  5. Ersetzen Sie im Programm die switch-case-Anweisung durch vier if-Abfragen - mal ohne, mal mit else. Prüfen Sie in beiden Fällen das Verhalten des Programms bzw. des [ Grüßen ]-Knopfes mit verschiedenen gedrückten Radiobuttons. Zeichnen Sie außerdem für beide Fälle jeweils ein Struktogramm und überlegen, welche Version der switch-case-Anweisung näher kommt.
  6.   // Version 1 
        if (bGZeit_getSelectedRadioButtonLabel().equals("Morgen")) {
          raus = 
    "Guten Morgen, "+raus;
        }   
        
    if (bGZeit_getSelectedRadioButtonLabel().equals("Tag")) {
          raus = 
    "Guten Tag, "+raus;
        } 
        
    if (bGZeit_getSelectedRadioButtonLabel().equals("Abend")) {
          raus = 
    "Guten Abend, "+raus;
        } 
        
    if (bGZeit_getSelectedRadioButtonLabel().equals("Nacht")) {
          raus = 
    "Gute Nacht, "+raus;
        }  
    //**
        

      // Version 2    
        if (bGZeit_getSelectedRadioButtonLabel().equals("Morgen")) {
          raus = 
    "Guten Morgen, "+raus;
        } 
    else {
          
    if (bGZeit_getSelectedRadioButtonLabel().equals("Tag")) {
            raus = 
    "Guten Tag, "+raus;
          } 
    else {
            
    if (bGZeit_getSelectedRadioButtonLabel().equals("Abend")) {
              raus = 
    "Guten Abend, "+raus;
            } 
    else {
              
    if (bGZeit_getSelectedRadioButtonLabel().equals("Nacht")) {
                raus = 
    "Gute Nacht, "+raus;
              } 
    else {
                raus = 
    "Mahlzeit, "+raus;
              }
            } 
          } 
        }      
          

  7. Zusatzfrage zu Aufgabe 4: Kann bei Version 1 auch der Mahlzeit-Fall dadurch hinzugefügt werden, dass nach der letzten } anstelle von //** noch
        else {
          raus = 
    "Mahlzeit, "+raus;
      } 

    ergänzt wird? Testen Sie ggf. diesen Fall und ziehen Sie Ihre Struktogramme aus Aufgabe 4 für die Erklärung zu Rate!
  8. Das break in der switch-case-Anweisung kann auch weggelassen werden. Entfernen Sie aus dem Original-Programm (wie oben gelb unterlegt) z.B. im (case "Tag")-Fall am Ende der Zeile das break; und testen Sie das Verhalten des so veränderten Programms für verschiedene ausgewählte Tageszeiten. Können Sie erkennen, was passiert? Erkundigen Sie sich ggf. und machen Sie sich Gedanken, wann ein fehlendes break sinnvoll sein könnte!
  9. Das Programm P3 sollte die zwei- und die mehrseitige Verzweigung motiviert einzuführen. Weil hier allerdings - anders als in P2 - die Labeltexte der gewählten Radiobuttons und die zur Ausgabe raus hinzugefügten Texte weitgehend identisch sind, könnte die gesamte gelb unterlegte Methode fast durch folgenden kurzen, verzweigungsfreien Quelltext ersetzt werden:
      
      
    public void jBtGruss_ActionPerformed(ActionEvent evt) {
        String rein = jTfEingabe.getText();
        jTfAusgabe.setText(
    "Guten "+bGZeit_getSelectedRadioButtonLabel()+", "
                           + bGAnrede_getSelectedRadioButtonLabel() + " " + rein); 
     
     } // end of jBtGruss_ActionPerformed

    Prüfen Sie diese Behauptung, erkennen Sie das einzige Problem und versuchen Sie dieses Problem durch eine Verzweigung ähnlich wie im Programm P2 zu lösen!


zum Seitenanfang / zum Seitenende

Java-Programm P4: TicTacToe als spielerische Anwendung des bisher Gelernten
(plus globalem Attribut und eigener Methode)



Nichts erhöht die Freude am Programmieren so stark, wie ein erfolgreich selbst programmiertes, funktionsfähiges Spiel, das hier in drei Stadien gezeigt wird

Oberfläche des Programms P4 beim Start   Oberfläche des Programms P4 während des Spiels   Oberfläche des Programms P4 am Spielende

Die "X" und "O" werden abwechselnd auf die gedrückten Knöpfe geschrieben; das Textfeld zeigt aktuelle Informationen zum Spiel und mit [ Neustart ] werden wieder alle Knopf-Beschriftungen gelöscht, der zug-Zähler auf 0 gesetzt und so das Spiel wieder in den Anfangszustand gebracht.

Weil noch keine Reihungen zur Verfügung stehen, werden die neun Knöpfe einzeln im GUI-Builder in die Oberfläche gesetzt und mit dem Objekt-Inspektor sinnvoll benannt. Ich habe sie mit ObenLinks, ObenMitte, ObenRechts, MitteLinks, MitteMitte;... usw. bis UntenRechts bezeichnet bzw. tatsächlich jBtObLi, jBtObMi,.. bis jBtUnRe genannt. Die Beschriftung eines gedrückten Knopfes kann in dessen ActionPerformed-Methode leicht mit dem schon von Textfeldern bekannten setText verändert werden, z.B. etwa durch jBtObLi.setText("X");

Schnell wird klar, dass allerdings kein festes "X" im .setText("X") stehen darf und auch die abwechselnde Verwendung von .setText("O") bei jedem zweiten Knopf keine Lösung ist, weil nicht vorhersehbar ist, in welcher Reihenfolge die Knöpfe später gedrückt werden. Vielmehr muss es eine übergeordnete Variable (außerhalb der Knopf_ActionPerformed-Methoden) geben, die sich merkt, welcher Spieler - "X" oder "O" - als nächster dran ist. Hier dient das Attribut spieler diesem Zweck. Außerdem muss nach jedem Knopfdruck der Wert von spieler gewechselt werden (von "X" nach "O" und umgekehrt). Dieser Wechsel könnte neun mal, nämlich in jedem Knopf, programmiert werden. Leichter ist es allerdings, den Wechsel einmal in eine eigene Methode auszulagern (ähnlich der ButtonGroup_getSelectedRadioButtonLabel-Methode in P2 und P3, die allerdings automatisch vom Java-Editor bzw. dessen GUI-Builder angelegt wurde). Und diese jetzt selbst zu schreibende bzw. geschriebene Methode spielerWechseln wird dann aus jedem Knopf heraus aufgerufen.

Von meinen Schülerinnen und Schülern wurde hingegen nicht sofort daran gedacht, in einem weiteren Attribut (der globalen Variable zug) die Anzahl der Züge mit zu zählen, damit der Computer Unentschieden erkennen kann bzw. das Weiterspielen nach einem Sieg verbietet. Als menschlicher Spieler erkennt man auf einen Blick, dass alle Knöpfe voll sind (und kein Gewinn angezeigt wird, also Unentschieden erreicht wurde) oder man sieht den Gewinn und startet normalerweise in beiden Fällen mit [ Neustart ] ein neues Spiel - und probiert meist gar nicht aus, ob noch weitere Züge möglich sind. Deshalb wurde von den meisten Schülern auch nicht geprüft, ob ein gedrückter Knopf tatsächlich vorher leer war: erst nach mehreren Testspielen wurde eher zufällig mal ein falscher, bereits beschrifteter Knopf gedrückt (und Einzelne betrogen damit dann lieber gelegentlich ihre Mitspieler, statt das Programm zu verbessern). Die für diese Überprüfungen nötigen Programmteile habe ich nachstehend rot gefärbt; sie sind anfangs verzichtbar und können später ergänzt werden.



  
  String spieler = 
"X";
  int zug = 0;
  
  
private void spielerWechseln()
  {
    
switch (spieler) 
    {
      
case "X" : spieler = "O"break;
      
case "O" : spieler = "X"break;
      
default  : spieler = "?";        
    } 
// end of switch
    jTfAnzeige.setText("\""+spieler+"\" ist am Zug"); 
  }
  
  
public void jBtObLi_ActionPerformed(ActionEvent evt) {
    if (zug<9 && jBtObLi.getText().equals("")) 
    {

      jBtObLi.setText(spieler);
      
if ((jBtObMi.getText().equals(spieler) && jBtObRe.getText().equals(spieler))
        ||(jBtMiLi.getText().equals(spieler) && jBtUnLi.getText().equals(spieler))
        ||(jBtMiMi.getText().equals(spieler) && jBtUnRe.getText().equals(spieler))) 
        {
          jTfAnzeige.setText(
"Sieg für \""+spieler+"\"!");
          
zug = 10;
        } 
// end of if
        else if (zug>=8)
          {
            jTfAnzeige.setText("Unentschieden!");  
          } 
          
else
          {
            
zug = zug+1;
            spielerWechseln();
          }
    
} // end of if
  } // end of jBtObLi_ActionPerformed

  public void jBtObMi_ActionPerformed(ActionEvent evt) {
    
if (zug<9 && jBtObMi.getText().equals("")) 
    {

      jBtObMi.setText(spieler);
      
if ((jBtObLi.getText().equals(spieler) && jBtObRe.getText().equals(spieler))
        ||(jBtMiMi.getText().equals(spieler) && jBtUnMi.getText().equals(spieler))) 
        {
          jTfAnzeige.setText(
"Sieg für \""+spieler+"\"!");
          
zug = 10;
        } 
// end of if
        else if (zug>=8)
          {
            jTfAnzeige.setText("Unentschieden!");  
          } 
          
else
          
{
            zug = zug+1;

            spielerWechseln();
          }
    
} // end of if
  } // end of jBtObMi_ActionPerformed

  public void jBtObRe_ActionPerformed(ActionEvent evt) {
   ...

Neu sind hier auch die mehrteiligen Bedingungen (wobei && 'und' bedeutet: alle Teil-Bedingungen müssen wahr sein, damit der if-Fall ausgeführt wird). Da eine Dreier-Gewinnstellung nur beim Druck auf einen Knopf geschlossen werden kann, muss in jeder Knopf-Methode überprüft werden, welche Dreier mit diesem Knopf eventuell vervollständigt werden könnten. Ein Dreier ist dann vollständig, wenn die zwei anderen Knöpfe in der gleichen Zeile, Spalte oder Diagonale beide das gleiche Aufschrift "X" oder "O" wie der Spieler haben (bevor dessen Inhalts-Text für den nächsten Zug gewechselt wird). Deshalb wird auf .equals(spieler) abgefragt.



Übungs-Aufgaben zu P4

  1. Vervollständigen Sie den Programmtext, d.h. schreiben Sie noch die Methoden für die sieben hier nicht gezeigten Knöpfe!
  2. Testen Sie Ihr Spiel durch Probeläufe, d.h. intensives Spielen!
  3. Erklären Sie, warum beim Erkennen einer Gewinnstellung die Variable zug auf 10 gesetzt wird. Wären statt 10 auch andere Werte möglich? Und könnte diese Zuweisung auch direkt vor der Ausgabe der Sieg-Meldung stehen statt unmittelbar danach (aber im selben { }-Paar) ?
  4. Im angegebenen Text steht der Aufruf der Methode spielerWechseln im else-Fall der Gewinnkontrolle. Überlegen Sie, ob das nötig ist, oder ob dieser Aufruf nicht einfach außerhalb der Kontrollstruktur am Ende der ActionPerformed-Methode stehen kann, d.h. immer ausgeführt wird: Bei Gewinn oder Unentschieden stört es doch nicht, wenn der Spieler danach noch gewechselt wird, weil er doch nicht mehr dran kommt (und die Sieg- [oder Unentschieden-]Meldung ja schon vor dem Wechsel für den richtigen Gewinner geschrieben wurde), oder?
  5. Zeichnen Sie für den Programmtext eines Knopfes ein Struktogramm!


zum Seitenanfang / zum Seitenende

Zusammenfassungs-Blatt und Ausblick



Gebeten, das Wichtigste fürs Programmieren schriftlich festzuhalten (es wird kein Buch verwendet), habe ich für meinen Kurs ein zweiseitiges Blatt mit einer Zusammenfassung heraus gegeben, das (bei installiertem pdf-Reader) hier mit Linksklick in einem neuen Fenster gelesen werden oder nach Rechtsklick auf den eigenen Computer herunter geladen werden kann:

Java-Programme IF EF-Bi 2017.pdf (ca 80 kB)

Dort findet man als abgebildete Beispiel-Oberfläche schon ein Programm, das viele Grüße in einem mehrzeiligen Ausgabefeld vom Typ JTextArea zulässt. Mit diesem Programm sollen die auf dem Blatt bereits aufgeführten Wiederholungen als weitere Kontrollstrukturen eingeführt werden. Mit Wiederholungen bieten sich viele schöne weitere Programmier-Möglichkeiten an, z.B. ein Kassenautomat mit Wechselgeldrückgabe, ein Quiz-Programm im 'Wer-wird-Millionär'-Format oder natürlich wieder diverse Autorennen. Dazu aber mehr auf meiner kommenden Seite if-java-b2_2017.htm




zurück zur Informatik-Hauptseite


zum Anfang dieser Seite
Willkommen/Übersicht  -  Was ist neu?  -  Software  -  Mathematik  -  Physik  -  Informatik  -   Schule: Lessing-Gymnasium und -Berufskolleg  -  Fotovoltaik  -  & mehr  -  Kontakt: e-Mail,  News-Abo, Gästebuch, Impressum  -  Grußkarten, site map, Download und Suche

Diese Seite ist Teil des Webangebots http://www.r-krell.de. Sie können diese Seite per e-Mail weiter empfehlen (tell a friend).