# Methoden werden zwar ausgeführt führen aber nicht zum Ergebnis



## V0g3l (11. Sep 2014)

Hi Leute,
ich wollte eigentlich mit einem einfachen Spiel beginne nachdem ich zig Tutorials durchgeführt habe. Meine erste idee war ein Textbasiertes Rollenspiel, was  sich aber als schwieriger erwies als gedacht. Darum nahm ich mir vor zunächst ein  Würfelspiel zu programmieren. In einer Konsolenvariante hatte ich das ganze schon perfekt. Jetzt wollte ich es in einer GUI unterbringen, habe also von neuem begonnen. Allerdings scheitere ich wie auch beim ersten Versuch des textbasierten Rollenspiels an folgender Stelle:

Meine Methoden werden ausgeführt (habe ich mit System.out.println("")) überprüft aber es kommt nicht zu einem Ergebnis. Das GUI habe ich über NetBeans mit einer neuen Swing GUI JFrame file erstellt, was sich als sehr bequem erwiesen hat. Den daraus generierten Code habe ich markiert.


```
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Spiel1;

import java.util.Random;

/**
 *
 * @author Thomas
 */
public class Frame extends javax.swing.JFrame {

    /**
     * Creates new form Frame
     */
    public Frame() {
        initComponents();
    }
    int Augenzahl;
    int gewuerfelt = 0;
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")

// Ab hier ist der generierte Code
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        Feld = new javax.swing.JTextArea();
        Button = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        Feld.setColumns(20);
        Feld.setRows(5);
        jScrollPane1.setViewportView(Feld);

        Button.setText("Wuerfeln");
        Button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(Button))
                .addContainerGap(224, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 159, Short.MAX_VALUE)
                .addComponent(Button)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>                        


// Diese Methode hingegen verändert den Text auf dem Feld.

 private void ButtonActionPerformed(java.awt.event.ActionEvent evt) {                                       
        Random random = new Random();
        
        if (gewuerfelt == 0)
        {
        Augenzahl = 1 + random.nextInt(6);
        Feld.setText("Ihr habt eine " + Augenzahl + " gewürfelt.");
        gewuerfelt = 1;
        }
    }                             

// Diese Methoden funktionieren nicht wie sie es sollen
 public int getAugenzahl()
    {
        return Augenzahl;
    }
    
    public int getgewuerfelt()
    {
        return gewuerfelt;
    }
    public void resetgewuerfelt()
    {
        gewuerfelt = 0;
        Feld.setText("TEST");
    }
    
    
    /*public void Update()
    {
        String tmp = Feld.getText();
        Feld.setText(tmp + " 1 ");
        
    }
    */
    
    /**
     * @param args the command line arguments
     */
    public static void start() {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see [url=http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html]How to Set the Look and Feel (The Java™ Tutorials > Creating a GUI With JFC/Swing > Modifying the Look and Feel)[/url] 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Frame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    public javax.swing.JButton Button;
    public javax.swing.JTextArea Feld;
    private javax.swing.JScrollPane jScrollPane1;
    // End of variables declaration                   
}
```

Zusätzlich existiert noch die kleine Klasse Background in der ich alle Prozesse berechnen lassen wollte. Es würde zwar alles einfacher gehen, dass weiss ich. Ich wollte aber speziell so den besseren Umgang mit den Klassenmodellen lernen, außerdem würde es mein Problem bei dem anderen spiel auch lösen. 


```
public class Background {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
        Frame Ebene = new Frame();
        Ebene.start();
        
        while(true)
        {
            
            if (Ebene.gewuerfelt == 1)
            {
                Ebene.resetgewuerfelt();
            }
        }
    }
```


Die rot markierte Methode(n) sind generiert. 
Blau sind die Methoden die nicht das ausführen was sie sollen 
und Grün ist ein Button bei dem allerdings die setText methode funktioniert. :bahnhof:

edit: Ich seh gerade dass die farbigen unterlegungen in einem code nicht funktionieren. Daher habe ich diese mit kommentaren versehen.

Ich hoffe ihr könnt mir helfen, danke im vorraus.


----------



## Joose (11. Sep 2014)

Soweit ich am Code erkennen kann gibt es noch große Verständnisprobleme mit den Grundlagen.
Es wird static und nonstatic vermischt. Du erstellst 2x ein Objekt der Klasse Frame, sprich hier wäre schonmal eine Fehlerquelle!

Du leitest von JFrame obwohl, du diese Klasse nicht erweiterst. Du nennst die Klasse Frame obwohl dies zu Verwirrung mit der Java Framework Klasse Frame (AWT) führen könnte. Die Formatierung des Codes sowie die nicht vorhanden Einheitlichkeit bei den Namen von Attributen und Methoden (lowerCamelCase für Methoden und Attribute, sowie UpperCamelCase für Klassen) macht es schwer den Code zu lesen.
Dann hast du Attribute, welche von 2 Threads aus abgefragt und vl geändert werden aber keine Synchornisation -> Fehlerquelle.

Probiere den Code strukturierter aufzubauen. Schaue zuerst das du GUI funtkioniert, wenn das passt
kannst du den Hintergrund thread zu resetten des gewürfelten Wertes einbauen.


----------



## V0g3l (11. Sep 2014)

Das GUI wird von Netbeams generiert und läuft soweit flüssig. Das einzige was ich hinzugefügt habe war der Inhalt des Buttons, die Methoden getGewuerfelt, getAugenzahl und resetgewuerfelt.

Uff also ich will ehrlich sein, die hälfte von dem was du beschrieben hast habe ich nicht verstanden  .
Also das mit dem Namen habe ich nicht beachtet und werde das mal überarbeiten und hoffen ob das schonmal hilft. 

 " Die Formatierung des Codes sowie die nicht vorhanden Einheitlichkeit bei den Namen von Attributen und Methoden (lowerCamelCase für Methoden und Attribute, sowie UpperCamelCase für Klassen) macht es schwer den Code zu lesen.
Dann hast du Attribute, welche von 2 Threads aus abgefragt und vl geändert werden aber keine Synchornisation -> Fehlerquelle."

Also da verstehe ich echt nur Bahnhof... Was genau meinst du mit lowerCamelCase bzw upperCamelCase? Die Begriffe vielen in den Tutorials bisher noch nie. 
Der Punkt mit der Synchronisation könnte vermutlich der Auslöser sein, sofern ich das richtig verstanden habe. Die Synchronisation sorgt dafür das die beiden Threads miteinander "Kommunizieren" und sozusagen von einander abhängigkeiten austauschen, richtig?
Ich werde mir den Bereich nochmal ansehen, gibts da eventuell noch weitere Schlagwörter die wichtig sind?

Eine Frage am Rande: Ist es sinnvoller das GUI komplett selber zu schreiben oder kann man diesen generierten Code aus der Netbeans, Datei problemlos übernehmen?


----------



## Joose (11. Sep 2014)

V0g3l hat gesagt.:


> Das GUI wird von Netbeams generiert und läuft soweit flüssig. Das einzige was ich hinzugefügt habe war der Inhalt des Buttons, die Methoden getGewuerfelt, getAugenzahl und resetgewuerfelt.



Und wie steht es generell um dein Wissen in Java?
Grundlagen der OOP sind durchgearbeitet und wurden verstanden?

Vielleicht sind für den Anfang der GUI Programmierung ein TicTacToe, Sudoko oder ein Taschenrechner besser geeignet als etwas mit einem Hintergrund Thread usw.




V0g3l hat gesagt.:


> Uff also ich will ehrlich sein, die hälfte von dem was du beschrieben hast habe ich nicht verstanden  .
> Also das mit dem Namen habe ich nicht beachtet und werde das mal überarbeiten und hoffen ob das schonmal hilft.



Helfen wird es dir nur bedingt, aber der Code wird dadurch für dich und vor allem andere (die dir ja dann helfen sollen) besser lesbar.



V0g3l hat gesagt.:


> " Die Formatierung des Codes sowie die nicht vorhanden Einheitlichkeit bei den Namen von Attributen und Methoden (lowerCamelCase für Methoden und Attribute, sowie UpperCamelCase für Klassen) macht es schwer den Code zu lesen.
> Dann hast du Attribute, welche von 2 Threads aus abgefragt und vl geändert werden aber keine Synchornisation -> Fehlerquelle."
> 
> Also da verstehe ich echt nur Bahnhof... Was genau meinst du mit lowerCamelCase bzw upperCamelCase? Die Begriffe vielen in den Tutorials bisher noch nie.



Bezüglich "lowerCamelCase" und "UpperCamelCase" schaue hier vorbei What is Camelcase (und halt auch Wikipedia)

In Java werden Klassennamen in UpperCamelCase und Methodennamen und Attribute in lowerCamelCase geschrieben.
Das Ganze dient wieder nur der Lesbarkeit vom Code.



V0g3l hat gesagt.:


> Der Punkt mit der Synchronisation könnte vermutlich der Auslöser sein, sofern ich das richtig verstanden habe. Die Synchronisation sorgt dafür das die beiden Threads miteinander "Kommunizieren" und sozusagen von einander abhängigkeiten austauschen, richtig?
> Ich werde mir den Bereich nochmal ansehen, gibts da eventuell noch weitere Schlagwörter die wichtig sind?



Die Synchronisation zwischen Thread sorgt nur dafür das 2 Threads nicht gleichzeitig den Wert einer Variable ändern zum Beispiel.
Beispiel: 2 Threads wollen in die gleiche Datei schreiben, wenn beide gleichzeitig schreiben könnten und würden, wäre der Inhalt irgendwas unlesbares. Daher wird synchronisiert damit sie entweder abwechselnd schreiben oder erst der eine dann dere andere.

Aber das ist ein ziemlich komplexes Thema mit dem man sich vor der Spieleprogrammierung auseinander setzen sollte.



V0g3l hat gesagt.:


> Eine Frage am Rande: Ist es sinnvoller das GUI komplett selber zu schreiben oder kann man diesen generierten Code aus der Netbeans, Datei problemlos übernehmen?



Pass auf mit dieser Frage kannst du einen kleinen Forenkrieg starten 
Viele sagen es ist sinnvoller die Zeit nicht mit GUI händisch schreiben zu verschwenden und das GUI Builder guten lesbaren Code produzieren.
Wiederum viele andere sagen (zu denen gehöre ich auch): Bevor man einen GUI Builder verwendet um sich diese "stupide" zusammenzuklicken, sollte man mal eine Zeit lang die GUI selber schreiben.

Vorteile beim selber schreiben:

Du setzt dich mit den eigentlichen Klassen auseinander
verstehst den Code deiner GUI auf Anhieb
du kannst doppelten Code sofort vereinfachen bzw. optimieren
es wird ersichtlicher warum sich LayoutManager so verhalten wie sie sich verhalten 

Nachteile:

Es dauert natürlich länger sich die GUI zu schreiben
oft muss man hier und da mal mit den Abständen oder ähnlichen nachbessern
aber je öfter man selber schreibt umso schneller wird man

Vorteile beim zusammenklicken: 

Es geht schnell
man sieht teilweise auch wie die GUI dann ausschaut

Nachteile: 

Es wird viel viel Code produziert
ähnlicher Code kommt doppelt vor
im GUI Builder schaut vl alles gut aus, aber viele sind dann überrascht wenn sich das Layout beim Resize total verschiebt usw.
Wenn ich im generierten Code etwas anpassen will, kann es sein das danach der GUI Builder die Datei nciht mehr richtig interpretieren kann
Wechsel ich von GUIBuilder A zu GUIBuilder B kann es ebenfalls sein dass die Dateien nicht lesbar sind weil der neue GUI Builder etwas anderes generiert

Also wie du siehst es hat beides Vor- und Nachteile. 
Persönlich tendiere ich zum Selber schreiben: Geht mit der Übung recht flott, alles kann ich persönlich optimieren, wenn ich aus welchen Grund auch immer den GUI Builder nciht verfügbar habe kann ich trotzdem Änderungen vornehmen


EDIT: Eine Ausnahme mache ich wenn ich mal schnell das Verhalten einer Komponente testen will wenn der und der Zustand eintritt. Oder Komponenten von Drittanbietern testen will


----------



## V0g3l (11. Sep 2014)

Danke für die ausführlich Antwort. 
Also bisher habe ich von meinen früheren Kenntnissen gebrauch gemacht und diese mithilfe der Tutorials  von 
https://www.youtube.com/channel/UCgfw1u4W7eMqsZd4rHl_mSw
und von 
https://www.youtube.com/channel/UC-3thK6H2pfxxGAa7qljipQ

Jeweils die Java Grundlagentutorials habe ich durchgekaut. Dabei habe ich natürlich alles selber geschrieben und auch versucht verständnis anzueignen. Ich bin aber noch nicht mit allen Videos komplett durch. Ich wollte mit einem kleinen Würfelspiel /besagtes Rollenspiel überprüfen wie weit ich alles verstanden habe. Bei dem ersten bin ich bei einem der letzten Videos und bei dem anderen bin ich mittendrin eingestiegen beim Thema Threads, da sich ja auch vieles überschneidet.

Okay CamelCase kannte ich jetzt nicht unter einem speziellen Begriff . Werde in Zukunft dran denken das auch mal anzuwenden. 

Tic Tac Toe, klingt nicht schlecht als noch einfacheren Einstieg. 
Werde mich hier im Forum melden wenn der Code dazu fertig ist vielleicht schaut dann auch nochmal jemand drüber =)


----------



## Joose (11. Sep 2014)

Kein Problem! 
Aber ich wollte dich jetzt nicht von deinem Würfelspiel abbringen  
Dachte mir nur bei TicTacToe wird abwechselnd gespielt, das geht auch ohne Threads.


----------

