Kniffel programmieren - Code-Beurteilung

Hallo zusammen,

ich würde gerne mal von Eu ich meinen Code reviewen lassen.
Zum einen möchte ich wissen, ob der Code (der bisher besteht) ordentlich (sprich objektorientiert) gemacht ist.

Ferner habe ich noch ein Problem.

Ich habe eine Klasse KeyListenerHelper gebaut, die die Tastendrücke auswertet. Ich weiß nicht, wie ich das verdrahte, wenn die Taste Space gedrückt wird ein neuer Wurf geworfen wird.

Manchmal fehlt es mir noch an der richrtigen ojektorientierten Denke glaube ich.

Anbei mein Code…
Ich habe einfach mal drauf los programmiert, würde aber gern mal ein Klassendiagramm dazu malen habe da aber irgendwie keinen richtigen Ansatz.
Ich glaube auch, daß ich mir dadurch manchmal Steine in den Weg lege, wenn ich das vorher nicht durchstrukturiert habe. Aber irgendwie fehlt mir da der Ansatz…

	static Würfel w1 = new Würfel();
	static Würfel w2 = new Würfel();
	static Würfel w3 = new Würfel();
	static Würfel w4 = new Würfel();
	static Würfel w5 = new Würfel();

	public static void main(String Args[]) {
		final int INT_RUNDEN = 0; // Bis zu 13 Runden
		final int INT_SPIELZUEGE = 1; // 3 Runden max.
		System.out.println("Kniffel
");

		Oberfläche oberfläche = new Oberfläche(w1, w2, w3, w4, w5);
		Spiel spiel = new Spiel(w1, w2, w3, w4, w5);
		

		for (int i = 0; i <= INT_RUNDEN; i++) {
			for (int j = 1; j <= INT_SPIELZUEGE; j++) {
				
				System.out.println("Unsortiert");

				
				spiel.neuerWurf();
				
				oberfläche.aktualisierenOberfläche(w1, w2, w3, w4, w5);

				//				int[] a = { w1.getErgebnis(), w2.getErgebnis(),
//						w3.getErgebnis(), w4.getErgebnis(), w5.getErgebnis() };
				// System.out.println(a.length);
//				int[] b = Hilfsklasse.bubblesort(a);
				// w1.setErgebnis(b[0]);
				// w2.setErgebnis(b[1]);
				// w3.setErgebnis(b[2]);
				// w4.setErgebnis(b[3]);
				// // w5.setErgebnis(b[4]);
				// System.out.println("
nach Sortieren");
				// System.out.println(b[0]);
				// System.out.println(b[1]);
				// System.out.println(b[2]);
				// System.out.println(b[3]);
				// System.out.println(b[4]);

			}
		}

	}

	

}



import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KeyListenerHelper implements KeyListener {
	Würfel w1, w2, w3, w4, w5;
	Spiel spiel = new Spiel(w1, w2, w3, w4, w5);

	public KeyListenerHelper(Würfel w1, Würfel w2, Würfel w3, Würfel w4,
			Würfel w5) {
		this.w1 = w1;
		this.w2 = w2;
		this.w3 = w3;
		this.w4 = w4;
		this.w5 = w5;
	}

	@Override
	public void keyPressed(KeyEvent e) {
		System.out.println("


Es wurde eine Taste gedrückt...");
		int key = e.getKeyCode();
		if (key == e.VK_F1) {

			if (w1.blnHaltenWürfel == false) {
				w1.blnHaltenWürfel = true;
			} else
				w1.blnHaltenWürfel = false;
		}
		System.out.println("w1" + w1.blnHaltenWürfel);
		//
		//
		//
		//
		//
		if (key == e.VK_F2) {

			if (w2.blnHaltenWürfel == false) {
				w2.blnHaltenWürfel = true;
			} else
				w2.blnHaltenWürfel = false;
		}
		System.out.println("w2" + w2.blnHaltenWürfel);
		//
		//
		//
		//
		//
		if (key == e.VK_F3) {

			if (w3.blnHaltenWürfel == false) {
				w3.blnHaltenWürfel = true;
			} else
				w3.blnHaltenWürfel = false;
		}
		System.out.println("w3" + w3.blnHaltenWürfel);
		//
		//
		//
		//
		//
		if (key == e.VK_F4) {

			if (w4.blnHaltenWürfel == false) {
				w4.blnHaltenWürfel = true;
			} else
				w4.blnHaltenWürfel = false;
		}
		System.out.println("w4" + w4.blnHaltenWürfel);
		//
		//
		//
		//
		//

		if (key == e.VK_F5) {

			if (w5.blnHaltenWürfel == false) {
				w5.blnHaltenWürfel = true;
			} else
				w5.blnHaltenWürfel = false;
		}
		System.out.println("w5" + w5.blnHaltenWürfel);

		if (key == e.VK_SPACE) {
			System.out.println("neuer Wurf");
			
			spiel.neuerWurf();
			
		}

	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub

	}

}



import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.*;

public class Oberfläche {
	Würfel w1, w2, w3, w4, w5;
	JFrame f;
	JTextField tf1 = new JTextField("Würfel 1");
	JTextField tf2 = new JTextField("Würfel 2");
	JTextField tf3 = new JTextField("Würfel 3");
	JTextField tf4 = new JTextField("Würfel 4");
	JTextField tf5 = new JTextField("Würfel 5");
	JButton b1 = new JButton("1");
	JButton b2 = new JButton("2");
	JButton b3 = new JButton("3");
	JButton b4 = new JButton("4");
	JButton b5 = new JButton("5");
	JButton b6 = new JButton("neuer Wurf");

	Oberfläche(final Würfel w1, final Würfel w2, final Würfel w3,
			final Würfel w4, final Würfel w5) {
		f = new JFrame();

		KeyListenerHelper kl = new KeyListenerHelper(w1, w2, w3, w4, w5);

		f.add(tf1);
		f.add(tf2);
		f.add(tf3);
		f.add(tf4);
		f.add(tf5);

		f.add(b1);
		f.add(b2);
		f.add(b3);
		f.add(b4);
		f.add(b5);
		f.add(b6);
		f.addKeyListener(kl);
		
		aktualisierenOberfläche(w1, w2, w3, w4, w5);
		

		f.setLayout(new FlowLayout(FlowLayout.LEFT));
		f.setSize(300, 400);
		f.setVisible(true);
		f.setFocusable(true);
		f.requestFocusInWindow();

	}
	
	void aktualisierenOberfläche(Würfel w1, Würfel w2, Würfel w3, Würfel w4, Würfel w5) {
		tf1.setText(String.valueOf(w1.ergebnis));
		tf2.setText(String.valueOf(w2.ergebnis));
		tf3.setText(String.valueOf(w3.ergebnis));
		tf4.setText(String.valueOf(w4.ergebnis));
		tf5.setText(String.valueOf(w5.ergebnis));
		
	}
}


public class Würfel {
	int intAugenzahl;
	int ergebnis;
	boolean blnHaltenWürfel=false;

	Würfel() {
		
	}

	int rollenWürfel() {
		ergebnis = (int) ((Math.random()) * 6 + 1);
		return ergebnis;
	}

	int getErgebnis() {

		return ergebnis;
	}

	void setErgebnis(int ergebnis) {
		this.ergebnis=ergebnis; 
	}
}



public class Spiel {
	static Würfel w1;
	static Würfel w2;
	static Würfel w3;
	static Würfel w4;
	static Würfel w5;

	Spiel(Würfel w1, Würfel w2, Würfel w3, Würfel w4, Würfel w5) {
		this.w1 = w1;
		this.w2 = w2;
		this.w3 = w3;
		this.w4 = w4;
		this.w5 = w5;
	}

	public void neuerWurf() {
		if (w1.blnHaltenWürfel == false)
			w1.rollenWürfel();
		if (w2.blnHaltenWürfel == false)
			w2.rollenWürfel();
		if (w3.blnHaltenWürfel == false)
			w3.rollenWürfel();
		if (w4.blnHaltenWürfel == false)
			w4.rollenWürfel();
		if (w5.blnHaltenWürfel == false)
			w5.rollenWürfel();

	}
}

Auch was das Zerlegen gemäß MVC (Model View Controller) angeht bitte ich mal ein paar Sätze zu schreiben…
Danke.

Gruss

Matthias
Manchmal denke ich einen Knoten in den Kopf…

niemals Code wiederholen wenn vermeidbar,
diese einfache Grundregel, die sich von selber ergibt, sorgt für die Vermeidung der meisten Probleme,
ergibt meist automatisch brauchbaren Code,

objektoriertiert natürlich für sich auch wichtig, aber kommt fast von selber, Alternative Methoden mit vielen Parametern,

praktisch alles in deinem Code ist 5fach da, da kann man ja an nichts anderes denken,
lohnt sich für kompletten Umbau, den ich dann für Vergleich auch mal selber gleich mache,

das setzt dann Verwendung von Listen oder Arrays voraus, was für sich neue Probleme bringt, vor allem wenn noch nicht bekannt,
muss nicht zweifelsfrei als besser angesehen werden, andererseits auch wichtiges Feld das zu lernen ist


wobei ich nun natürlich auch diverse andere Schwierigkeiten sehe,
in Oberfläche gibt es Variablen für die Würfel, aber sie werden nicht gefüllt, stattdessen in Methoden die Würfel als Parameter,
das ist ja nun klar offene Baustelle, muss das erst wer anders sagen? :wink:
jeder Code/ jede Variable muss begründeten Sinn und Verwendung haben, bei 300 Zeilen kann man das doch noch alles überblicken

wie du schon ansprichst haben die Button keine Aktion, das kann man doch nach Lehrbuch lernen, ActionListener,
KeyListener hilft da nicht viel

Vorsicht mit dem Einsatz von static, nur wenn wirklich nötig, was ein Spiel als Konstruktor-Parameter bekommt ist nur für diese Spiel-Instanz,
nur ein Objekt gedacht, ein zweites sollte eigene Parameter haben,
wenn in static gespeichert dann habe alle Spiel-Objekte dieselben Daten, die die zuletzt gespeichert wurden

im Moment gibt es auch zwei Spiel-Objekte, in main und vom Listener aus erzeugt,
wenn eins reicht dann darauf achten, lieber von main als Parameter durchreichen

boolean-Operationen sind auch noch bedenklich, ist ja auch verständlich,
bVal = !bVal;
ist ein einfaches Mittel, einen boolean zu kippen, nicht if/ else

besser generell nie mit == true oder == false vergleichen, wobei die Meinungen vielleicht variieren,
es gibt recht unstrittig if(bVal) oder für false if(!bVal)


nun noch kurz ein paar Änderungen von mir zur Anschauung, ohne Anspruch das Spiel lauffähig zu bekommen, dafür viel zu viel an allen Ecken offen

beachte wie keine einzelnen großen Würfel-Variablen mehr, stattdessen Liste,

in Würfel neben sinnvoller Nummer nun auch das TextFeld und der Button mit drin,
grundsätzlich etwas fragwürdig zusammen’gewürfelt’, aber wenn nicht dort dann noch eine neue Klasse ‚GuiForWürfel‘ oder so und davon eine Liste,
wertvoll hier alles zusammen zu haben, das ergibt gute Möglichkeiten,

der ActionListener zum Button könnte sofort den eigenen Würfel bearbeiten, ohne zu wissen in welcher statischen Variable oder Index-Position in welcher Liste,
das ist Vorteil von Objektorierierung,
auch könnte gleich das Textfeld aktualisiert werden,

weder braucht es allgemeinen großen Listener über alles noch aktualisierenOberfläche() in der GUI, wobei hier noch dabei

der Vergleich mit den F-Tasten-Konstanten ist bisschen hakelig, weil die als einzelne Variablen vorgegeben sind,
falls irgendwann F nicht mehr gebraucht, nur mit Buttons gesteuert, dann hoffentlich weg

class Kniffel
{
    public static void main(String Args[])
    {
        System.out.println("Kniffel
");

        List<Würfel> wList = new ArrayList<>();
        for (int nr = 1; nr <= 5; nr++)
        {
            wList.add(new Würfel(nr));
        }
        new Oberfläche(wList);
    }


}


class KeyListenerHelper
    implements KeyListener
{
    static int[] VKF =
        {KeyEvent.VK_F1, KeyEvent.VK_F2, KeyEvent.VK_F3, KeyEvent.VK_F4, KeyEvent.VK_F5};
    List<Würfel> wList;
    Spiel spiel;

    public KeyListenerHelper(List<Würfel> wList)
    {
        this.wList = wList;
        this.spiel = new Spiel(wList);
    }

    @Override
    public void keyPressed(KeyEvent e)
    {
        System.out.println("


Es wurde eine Taste gedrückt...");
        int key = e.getKeyCode();
        for (int i = 0; i < VKF.length; i++)
        {
            if (key == VKF**)
            {
                Würfel w = wList.get(i);
                w.blnHaltenWürfel = !w.blnHaltenWürfel;
                System.out.println("w" + w.nr + " " + w.blnHaltenWürfel);
            }
        }

        if (key == e.VK_SPACE)
        {
            System.out.println("neuer Wurf");
            spiel.neuerWurf();
        }

    }

    @Override
    public void keyReleased(KeyEvent e)
    {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyTyped(KeyEvent e)
    {
        // TODO Auto-generated method stub

    }

}


class Oberfläche
{
    List<Würfel> wList;
    JFrame f;
    JButton bWurf = new JButton("neuer Wurf");

    Oberfläche(final List<Würfel> wList)
    {
        this.wList = wList;
        f = new JFrame();

        KeyListenerHelper kl = new KeyListenerHelper(wList);
        for (Würfel w : wList)
            f.add(w.tf);
        for (Würfel w : wList)
            f.add(w.b);

        f.add(bWurf);
        f.addKeyListener(kl);

        aktualisierenOberfläche();


        f.setLayout(new FlowLayout(FlowLayout.LEFT));
        f.setSize(300, 400);
        f.setVisible(true);
        f.setFocusable(true);
        f.requestFocusInWindow();
    }

    void aktualisierenOberfläche()
    {
        for (Würfel w : wList)
        {
            w.tf.setText(String.valueOf(w.ergebnis));
        }
    }
}


class Würfel
{
    int nr;
    int intAugenzahl;
    int ergebnis;
    boolean blnHaltenWürfel = false;
    public JTextField tf;
    public JButton b;

    Würfel(int nr)
    {
        this.nr = nr;
        tf = new JTextField("Würfel " + nr);
        b = new JButton("" + nr);
        b.addActionListener(new ActionListener()
            {

                @Override
                public void actionPerformed(ActionEvent e)
                {
                    System.out.println("Aktion in Würfel " + nr);

                }
            });
    }

    int rollenWürfel()
    {
        ergebnis = (int)((Math.random()) * 6 + 1);
        return ergebnis;
    }

    int getErgebnis()
    {

        return ergebnis;
    }

    void setErgebnis(int ergebnis)
    {
        this.ergebnis = ergebnis;
    }
}


class Spiel
{
    List<Würfel> wList;

    Spiel(List<Würfel> wList)
    {
        this.wList = wList;
    }

    public void neuerWurf()
    {
        for (Würfel w : wList)
        {
            if (!w.blnHaltenWürfel) w.rollenWürfel();
        }
    }
}

Lass die ungarische Notation bitte weg, das ist letztes Jahrtausend - inzwischen haben wir statische Typsysteme und IDEs.

Vorschlag für die Würfel-Klasse:

import java.util.Random;

public class Würfel {

    private static final Random RANDOM = new Random();

    private boolean halten;

    private int ergebnis;

    public void würfeln() {
        if (! halten) {
            ergebnis = RANDOM.nextInt(6) + 1;
        }
    }

    public int getErgebnis() {
        return ergebnis;
    }

    public boolean isHalten() {
        return halten;
    }

    public void changeHalten() {
        this.halten = ! halten;
    }

}

Vorteil: Man kann “würfeln” aufrufen, ohne auf halten prüfen zu müssen. Damit vereinfacht sich Spiel zu

public class Spiel {
    private Würfel w1;
    private Würfel w2;
    private Würfel w3;
    private Würfel w4;
    private Würfel w5;

    Spiel(Würfel w1, Würfel w2, Würfel w3, Würfel w4, Würfel w5) {
        this.w1 = w1;
        this.w2 = w2;
        this.w3 = w3;
        this.w4 = w4;
        this.w5 = w5;
    }

    public void neuerWurf() {
        w1.würfeln();
        w2.würfeln();
        w3.würfeln();
        w4.würfeln();
        w5.würfeln();
    }
}

Vorschlag KeyListenerHelper:

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;

public class KeyListenerHelper extends KeyAdapter {
    private Map<Integer, Würfel> würfel = new HashMap<>();

    public KeyListenerHelper(Würfel w1, Würfel w2, Würfel w3, Würfel w4,
                             Würfel w5) {

        würfel.put(KeyEvent.VK_F1, w1);
        würfel.put(KeyEvent.VK_F2, w2);
        würfel.put(KeyEvent.VK_F3, w3);
        würfel.put(KeyEvent.VK_F4, w4);
        würfel.put(KeyEvent.VK_F5, w5);
    }

    @Override
    public void keyPressed(KeyEvent e) {
        System.out.println("


Es wurde eine Taste gedrückt...");
        int key = e.getKeyCode();
        if (würfel.containsKey(key)) {
            würfel.get(key).changeHalten();
        }
    }

}

Die XyzAdapter-Klassen sind dein Freund, wenn du nicht alle XyzListener-Methoden implementieren willst.

Ansonsten müsste man sehen, wie du dir das weiter vorgestellt hast.

Um mal was Positives zu sagen: es ist Gut, dass Du deine Klassen nicht von JFrame erben lässt und der KeyListener eine eigene Klasse bekommen hat.

@Slater hat ja schon auf einige hingewiesen.

Aber an einer telle muss ich ihn berichtigen (Zeile 108):[quote=SlaterB]for (Würfel w : wList) { w.tf.setText(String.valueOf(w.ergebnis)); }[/quote]Was hier passiert heißt “Feature envy”:
Die GUI holt sich etwas aus dem Würfel-Objekt und dies mit einem anderen Datum aus dem selben Würfel-Objekt zu ändern.
Die Zeile 18 sollte also komplett in der Würfelklasse stehen:public void updateGui(){ this.tf.setText(String.valueOf(this.ergebnis)); } und die Zeile 108 ind der GUI sollte dann nur noch so aussehen:for (Würfel w : wList) { w.updateGui(); }

Andererseits habe wir hier das Problem, das GUI und Modell zu stark vermischt sind. Die ModellKlasse Würfel sollte keine GUI-Klassen (wie Texfelfd) kennen. Dafür sollte es ein interface geben mit dem sich ein Interessent über das Ergebnis eines Wurfs benachrichtigen lassen kann:```public interface WuerfelListener {
void geworfenWurde(int ergebnis);
}
public class Würfel {
boolean würfelGehalten = false;
private WuerfelListener wuerfelListener; // ist meist eine Liste

public void setWuerfelListener(WuerfelListener wuerfelListener) {
    this.wuerfelListener = wuerfelListener;
}

void rollenWürfel() {
    if (!würfelGehalten) {
        int ergebnis = (int) ((Math.random())
                * 6
                + 1);
        wuerfelListener.geworfenWurde(ergebnis);
    }
}

}die anderen Klassen sähen bei mir so aus:import java.util.Arrays;
import java.util.List;

public class Kniffel {
public static void main(String Args[]) {
final int INT_RUNDEN = 0; // Bis zu 13 Runden
final int INT_SPIELZUEGE = 1; // 3 Runden max.
System.out.println("Kniffel
");
List<Würfel> würfels = Arrays.asList(new Würfel(), new Würfel(), new Würfel(), new Würfel(), new Würfel());

    new Oberfläche(würfels); //startet sich selbst
    Spiel spiel = new Spiel(würfels);

    for (int i = 0; i <= INT_RUNDEN; i++) {
        for (int j = 1; j <= INT_SPIELZUEGE; j++) {
            System.out.println("Unsortiert");
            spiel.neuerWurf();
        }
    }
}

}

import java.awt.event.ActionEvent;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Oberfläche {
JFrame f;

Oberfläche(final List<Würfel> würfelList) {
    f = new JFrame();
    f.setLayout(new FlowLayout(FlowLayout.LEFT));
    f.setSize(300, 400);
    for (int i = 0; i < 5; i++) {
        JCheckBox haltenCheckBox = new JCheckBox();
        JLabel egebnisAnzeiger = new JLabel(String.format("Würfel %s", i));
        konfiguriereGuiElemente(würfelList, i, haltenCheckBox, egebnisAnzeiger);
        f.add(egebnisAnzeiger);
        f.add(haltenCheckBox);
    }
    f.add(createRollenButton(würfelList));

    f.setVisible(true);
    f.setFocusable(true);
    f.requestFocusInWindow();

}

private JButton createRollenButton(final List<Würfel> würfelList) {
    String actionName = "rollen";
    AbstractAction rollenAction = new AbstractAction(actionName) {
        @Override
        public void actionPerformed(ActionEvent e) {
            for (Würfel würfel : würfelList) {
                würfel.rollenWürfel();
            }
        }
    };
    JButton rollen = new JButton(rollenAction);
    return rollen;
}

protected void konfiguriereGuiElemente(final List<Würfel> würfelList,
        int i,
        JCheckBox haltenCheckBox,
        JLabel egebnisAnzeiger) {
    Würfel würfel = würfelList.get(i);
    AbstractAction checkBoxAction = new AbstractAction("halten") {
        @Override
        public void actionPerformed(ActionEvent e) {
            würfel.würfelGehalten = haltenCheckBox.isSelected();
        }
    };
    haltenCheckBox.setAction(checkBoxAction);
    f.add(haltenCheckBox);
    würfel.setWuerfelListener(new WuerfelListener() {
        @Override
        public void geworfenWurde(int ergebnis) {
            egebnisAnzeiger.setText(String.valueOf(ergebnis));
        }
    });
}

}

import java.util.List;

public class Spiel {

private final List<Würfel> _würfels;

Spiel(List<Würfel> würfels) {
    _würfels = würfels;
}

public void neuerWurf() {
    for (Würfel würfel : _würfels) {
        würfel.rollenWürfel();
    }
}

}```
Um die HotKeays habe ich mich jetzt nicht gekümmert, aber das Spiel lässt sich ja auch so über die Tastatur bedienen…
Dafür gibt es die Klasse KeyListenerHelper nicht mehr.

bye
TT

Vielleicht könnte auch eine Klasse der Art Würfelsatz helfen. In dieser könnten durchaus fünf fest verdrahtete Würfel vorliegen, für ein Spiel mit genau 5 Würfeln ja nicht falsch. Dennoch könnte man sie so schreiben, dass von außen darauf iteriert werden könnte und spezielle Tastencodes könnte man auch gleich dort hinterlegen. Das würde den Code des Spielablaufes entschlacken.

[quote=Crian]Vielleicht könnte auch eine Klasse der Art Würfelsatz helfen.[/quote]Welchen konkreten Vorteil hätte so eine Extra-Klasse gegenüber einer Collection von Würfeln?

bye
TT

Den von Objektorientierung allgemein: Daten und verabreitende Methoden sind in einer Datei versammelt. Allerdings habe ich in meiner angefangenen Kniffel-Version - von diesem Thread inspiriert - die einzeln abgelegten Würfel-Objekte noch nicht gebraucht, sondern immer mit der (bisher zusätzlich vorhandenen) Liste von Würfeln gearbeitet.

Weiß nicht, was schon gesagt wurde, aber ich hab deinen Code mal ein bisschen verbessert, @aquarium1974 / Matthias :

import java.awt.event.*;
import javax.swing.*;

/**
 */
public class Kniffel {

    static Würfel w1 = new Würfel();
    static Würfel w2 = new Würfel();
    static Würfel w3 = new Würfel();
    static Würfel w4 = new Würfel();
    static Würfel w5 = new Würfel();

    public static void main(String Args[]) {
        final int INT_RUNDEN = 0; // Bis zu 13 Runden
        final int INT_SPIELZUEGE = 1; // 3 Runden max.
        System.out.println("Kniffel
");

        Oberfläche oberfläche = new Oberfläche(w1, w2, w3, w4, w5);
        Spiel spiel = new Spiel(w1, w2, w3, w4, w5);

        for (int i = 0; i <= INT_RUNDEN; i++) {
            for (int j = 1; j <= INT_SPIELZUEGE; j++) {

                System.out.println("Unsortiert");

                spiel.neuerWurf();

                oberfläche.aktualisierenOberfläche(w1, w2, w3, w4, w5);

                //              int[] a = { w1.getErgebnis(), w2.getErgebnis(),
                //                      w3.getErgebnis(), w4.getErgebnis(), w5.getErgebnis() };
                // System.out.println(a.length);
                //              int[] b = Hilfsklasse.bubblesort(a);
                // w1.setErgebnis(b[0]);
                // w2.setErgebnis(b[1]);
                // w3.setErgebnis(b[2]);
                // w4.setErgebnis(b[3]);
                // // w5.setErgebnis(b[4]);
                // System.out.println("
nach Sortieren");
                // System.out.println(b[0]);
                // System.out.println(b[1]);
                // System.out.println(b[2]);
                // System.out.println(b[3]);
                // System.out.println(b[4]);
            }
        }

    }

}

class KeyListenerHelper implements KeyListener {

    Würfel w1, w2, w3, w4, w5;
    Spiel spiel = new Spiel(w1, w2, w3, w4, w5);

    KeyListenerHelper(Würfel w1, Würfel w2, Würfel w3, Würfel w4, Würfel w5) {
        this.w1 = w1;
        this.w2 = w2;
        this.w3 = w3;
        this.w4 = w4;
        this.w5 = w5;
    }

    @Override
    public void keyPressed(KeyEvent e) {
        System.out.println("


Es wurde eine Taste gedrückt...");
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_F1) {

            if (w1.blnHaltenWürfel == false) {
                w1.blnHaltenWürfel = true;
            } else {
                w1.blnHaltenWürfel = false;
            }
        }
        System.out.println("w1" + w1.blnHaltenWürfel);
        //
        //
        //
        //
        //
        if (key == KeyEvent.VK_F2) {

            if (w2.blnHaltenWürfel == false) {
                w2.blnHaltenWürfel = true;
            } else {
                w2.blnHaltenWürfel = false;
            }
        }
        System.out.println("w2" + w2.blnHaltenWürfel);
        //
        //
        //
        //
        //
        if (key == KeyEvent.VK_F3) {

            if (w3.blnHaltenWürfel == false) {
                w3.blnHaltenWürfel = true;
            } else {
                w3.blnHaltenWürfel = false;
            }
        }
        System.out.println("w3" + w3.blnHaltenWürfel);
        //
        //
        //
        //
        //
        if (key == KeyEvent.VK_F4) {

            if (w4.blnHaltenWürfel == false) {
                w4.blnHaltenWürfel = true;
            } else {
                w4.blnHaltenWürfel = false;
            }
        }
        System.out.println("w4" + w4.blnHaltenWürfel);
        //
        //
        //
        //
        //

        if (key == KeyEvent.VK_F5) {

            if (w5.blnHaltenWürfel == false) {
                w5.blnHaltenWürfel = true;
            } else {
                w5.blnHaltenWürfel = false;
            }
        }
        System.out.println("w5" + w5.blnHaltenWürfel);

        if (key == KeyEvent.VK_SPACE) {
            System.out.println("neuer Wurf");

            spiel.neuerWurf();

        }

    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }

}

class Oberfläche {

    Würfel w1, w2, w3, w4, w5;
    JFrame f;
    JTextField tf1 = new JTextField("Würfel 1");
    JTextField tf2 = new JTextField("Würfel 2");
    JTextField tf3 = new JTextField("Würfel 3");
    JTextField tf4 = new JTextField("Würfel 4");
    JTextField tf5 = new JTextField("Würfel 5");
    JButton b1 = new JButton("1");
    JButton b2 = new JButton("2");
    JButton b3 = new JButton("3");
    JButton b4 = new JButton("4");
    JButton b5 = new JButton("5");
    JButton b6 = new JButton("neuer Wurf");

    Oberfläche(final Würfel w1, final Würfel w2, final Würfel w3,
            final Würfel w4, final Würfel w5) {
        f = new JFrame();

        KeyListenerHelper kl = new KeyListenerHelper(w1, w2, w3, w4, w5);

        f.add(tf1);
        f.add(tf2);
        f.add(tf3);
        f.add(tf4);
        f.add(tf5);

        f.add(b1);
        f.add(b2);
        f.add(b3);
        f.add(b4);
        f.add(b5);
        f.add(b6);
        f.addKeyListener(kl);

        aktualisierenOberfläche(w1, w2, w3, w4, w5);

        f.setLayout(new FlowLayout(FlowLayout.LEFT));
        f.setSize(300, 400);
        f.setVisible(true);
        f.setFocusable(true);
        f.requestFocusInWindow();

    }

    final void aktualisierenOberfläche(Würfel w1, Würfel w2, Würfel w3, Würfel w4, Würfel w5) {
        tf1.setText(String.valueOf(w1.ergebnis));
        tf2.setText(String.valueOf(w2.ergebnis));
        tf3.setText(String.valueOf(w3.ergebnis));
        tf4.setText(String.valueOf(w4.ergebnis));
        tf5.setText(String.valueOf(w5.ergebnis));

    }
}

class Würfel {

    int intAugenzahl;
    int ergebnis;
    boolean blnHaltenWürfel = false;

    Würfel() {

    }

    int rollenWürfel() {
        ergebnis = (int) (Math.random() * 6) + 1;
        return ergebnis;
    }

    int getErgebnis() {

        return ergebnis;
    }

    void setErgebnis(int ergebnis) {
        this.ergebnis = ergebnis;
    }
}

class Spiel {

    Würfel w1;
    Würfel w2;
    Würfel w3;
    Würfel w4;
    Würfel w5;

    Spiel(Würfel w1, Würfel w2, Würfel w3, Würfel w4, Würfel w5) {
        this.w1 = w1;
        this.w2 = w2;
        this.w3 = w3;
        this.w4 = w4;
        this.w5 = w5;
    }

    void neuerWurf() {
        if (w1.blnHaltenWürfel == false) {
            w1.rollenWürfel();
        }
        if (w2.blnHaltenWürfel == false) {
            w2.rollenWürfel();
        }
        if (w3.blnHaltenWürfel == false) {
            w3.rollenWürfel();
        }
        if (w4.blnHaltenWürfel == false) {
            w4.rollenWürfel();
        }
        if (w5.blnHaltenWürfel == false) {
            w5.rollenWürfel();
        }

    }
}```

1. am Anfang nur Paket-Sichtbarkeit
2. Würfel müssen nicht static sein
3. über KeyEvent kommst du an KeyCode
4. Würfel in eine Liste packen
5. du hast Semi-Logik im Konstruktor
6. final Parameter - why?  [edit SlaterB: weiter hier: http://forum.byte-welt.net/java-forum/allgemeine-themen/17773-final-parameter.html]
7. zu lang, zu spät, schreiben morgen weiter

Grüße