Fragen zum Programmierstiel

Status
Nicht offen für weitere Antworten.

zero-2-one

Mitglied
Hallo, ich steige gerade (malwieder) in Java ein (habe aber wirklich fast garkeine Ahnung mehr davon).

Als Einstieg wollte ich mir nen kleinen Minesweeperclone basteln. Weit bin ich zwar noch nicht aber ich wollte einfach mal grundsätzlich fragen ob mein Stiel einigermaßen ok ist. Ich hätte sozusagen gerne dass ihr meinen Code zerreist ;)

Kurz vorweg noch: Mir ist schon aufgefallen, dass ich die Verwaltung der Felder etwas anders lösen sollte. Zur zeit mach ich das über eine ArrayList und ich denk mal, dass ich mir da eine Klasse ArrayField basteln werde.

Ansonsten würden mich auch ein paar Tipps in Bezug auf den ActionListener freuen, weil ich mir das nur irgendwie zusammengebastelt hab und noch nicht ganze verstehe warum es so kompliziert sein muss einen Button zu überwachen - Also immer her mit besseren Varianten (wenn möglich mit ner kleinen Erläuterung).

Dann hier jetzt mal der code:

Code:
import java.util.ArrayList;
import java.util.List;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.lang.Math.*;


public class MinenFeld
{
   final static int dimX = 10;   //soll die Anzahl an Feldern in x-Richtung angeben
   final static int dimY = 10;   //soll die Anzahl an Feldern in y-Richtung angeben
   final static int buttonGroesse = 55;
   final static Dimension bDim = new Dimension(buttonGroesse,buttonGroesse); //die Breite bzw. Hoehe der Buttons
   final static double partOfBombs = 0.16;        // 16% des Spielfeldes enthalten Bomben ist allerdings nochimmer zufällig

   private static List<Target> tList = new ArrayList<Target>();    //das Feld in dem die Minen verwaltet werden sollen

   static class Target extends JButton    // Ein Button, der mit einigen Eigenschaften wie "istMine", "entschaerft", der Position im Spielfeld etc. erweitert werden soll
   {
     int x = 0; //beschreibt die Position auf dem Spielfeld
     int y = 0;
     private boolean isBomb = false;

     Target(int x, int y)
     {
       this.x = x;
       this.y = y;

       this.addActionListener(new ActionListener()
       {
         public void actionPerformed(ActionEvent evt)
         {
           onKlick(evt);
         }
       });
     }
     
     public void setBomb(boolean bomb)
     {
       this.isBomb = bomb;
     }
     
     public void onKlick(ActionEvent event)
     {
       if (this.isBomb) this.setText("X");      //hier soll aber irgendwann angezeigt werden ob eine Mine da war oder die Anzahl der benachbarten Minen
         else this.setText("O");
     }

   }

  private static void Spielfeld()      // ist für den Aufbau der Gui bzw. eines Minenfeldes verantwortlich
   {
      JFrame f = new JFrame("Minenfeld");
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.setSize((dimX*buttonGroesse),(dimY*buttonGroesse));
      Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
      f.setLocation( ((d.width - f.getSize().width) / 2), ((d.height - f.getSize().height) / 2) );
      f.setResizable(false);

      JPanel p = new JPanel(new GridLayout(dimX,dimY));

      int help = 0; //soll die bereits vergebenen Bomben mitzaehlen

      for (int i = 0; i < dimX; i++){                   // erzeugen und positionieren der MinenButtons und Verteilung der Bomben
        for (int j = 0; j < dimY; j++) {
          Target t = new Target(i,j);
          t.setSize(bDim);
          t.setLocation(i*buttonGroesse,j*buttonGroesse);
          p.add(t);
          if (Math.random() < partOfBombs)
          {
            t.setBomb(true);
          }
          tList.add(t);
          t.setText(t.x + "/" + t.y);
        }
      }
      
      f.getContentPane().add(p);
      f.setVisible(true);

   }

   public static void main(String[] args)
   {
     Spielfeld();

   }
}

Und schonmal Danke an alle die sich hier Mühe machen.

zero
 

Tobias

Top Contributor
OK,

1.) nach den Sun Coding Conventions schreibt man Konstanten durchgängig groß, Einzelwörter werden durch Unterstriche getrennt. Konstanten erkennst du an "static final".

2.) Komm weg von der static-Seuche und programmier vernünftiges OOP. Aus deiner Methode SpielFeld() (Methoden beginnen übrigens IMMER mit einem kleinem Buchstaben und einem Verb [hier also z.B. zeichneSpielfeld()]) kann man prima einen Konstruktor der Klasse Minenfeld machen, den man in der main() aufruft. Schon spart man sich das ganze static-Gesocks bei Target etc.

3.) Schreibst du deine Briefe und Emails auch in einem deutsch-englisch-Mischmasch? Nein? Warum machst du das dann bei Programmcode? Durchgängig englisch halte ich für die einzige akzeptable Sprachwahl.

4.) Zu ActionListener: Der kommt dir nur so komplex vor, weil du fortgeschrittene Syntax (eine anonyme, innere Klasse) benutzt. Das Prinzip dahinter ist ganz simpel und wird in der FAQ unter "Listener und Events" erklärt.

mpG
Tobias
 

zero-2-one

Mitglied
Das ist doch mal ein guter Anfang :)

Hab mir schon gedacht, dass da der Wurm drin ist. Na dann werd ich mir die Sachen mal zu Herzen nehmen (bzw. erst mal schauen, dass ich versteh was genau du meinst).

Für weitere Kommentare bin ich weiterhin Dankbar

Edit: Achja, was genau meinst du mit "static-Seuche"? Wie gesagt, es ist schon etwas länger her und ich habe damals noch nie OO programmiert - ist also absolutes neuland.
 

foobar

Top Contributor
zero-2-one hat gesagt.:
Edit: Achja, was genau meinst du mit "static-Seuche"? Wie gesagt, es ist schon etwas länger her und ich habe damals noch nie OO programmiert - ist also absolutes neuland.

Damit ist gemeint, daß du den static-Modifier mit mehr Zurückhaltung einsetzen solltest. Versuch mal dein Programm in Klassen aufzuteilen wie MainFrame, PlayGround, GameLogic etc.
Anstatt in einer statischen Methode einen Frame zusammen zu bauen, kannst du auch eine eigene Klasse von JFrame ableiten, die das Grundgerüst deiner Anwendung darstellt den MainFrame.
 

zero-2-one

Mitglied
Ok, da muss ich mich glaub ich noch bedeutend mehr reinlesen - wenn ich ehrlich bin versteh ich noch nicht allzuviel von euren Ratschlägen bezüglich OOP und dem Verzicht auf static, aber ich hab grad in der FAQ ein bischen was dazu gelernt :)

Jetzt aber noch ein paar kurze Fragen... Wenn ich mein Programm in mehrere Klassen aufteile (z.B. MainFrame, PlayGround, GameLogic), soll ich die Klassen dann auch in verschiedene Datein Speichern? Oder ist das bei einem so kleinen Projekt nicht nötig?

Und zu der untergliederung hätte ich noch ein paar Fragen.

1) Seh ich das richtig, dass MainFrame dann nur dazu gedacht wäre mir ein Fenster zu erzeugen, dass ich noch nach belieben anpassen kann (z.B Einstellungsmöglichkeiten und den ganzen Kram den mal halt kennt "Datei", "Bearbeiten",... - irgend einen Rahmen für mein eigentliches Programm eben)

2) PlayGround wäre dann ein JPanel das ich in meinem MainFrame platziere (wie das geht weiß ich zwar noch nicht aber mal schaun) und auf dem ich dann alles liegen habe was direkt mit dem Spiel zu tun hat (in meinem Fall eigentlich nur die Buttons) Dafür wird dann mein Objekt GameLogic als Schablone verwendet, oder wie?

3)GameLogic wäre dann "nur" die Verwaltung der Daten auf die PlayGround zugreifen müsste, oder?
Das wäre bei mir dann ja eigentlich nur ein Feld bei dem ich für jeden Eintrag mehrere Angaben machen kann.

PlayGround ist also nur eine visuelle verwirklichung von GameLogic und GameLogic besitzt eigentlich ausschließlich die komplette Funktionalität, die nicht direkt was mit anklicken zu tun hat.

Hoffe mal, dass ich mich nicht zu konvus ausgedrückt habe aber wie gesagt... mir geht es halt darum mir nicht von Anfang an irgendwelche dummen Eigenheiten anzugewöhnen, die mich später bei komplexeren Problemen völlig aus der Bahn werfen.
 

Marco13

Top Contributor
Wenn ich mein Programm in mehrere Klassen aufteile (z.B. MainFrame, PlayGround, GameLogic), soll ich die Klassen dann auch in verschiedene Datein Speichern?
Ja

Oder ist das bei einem so kleinen Projekt nicht nötig?

Ja :wink:
Es ist nicht nötig (nie!), aber man sollte es machen - je größer das Projekt wird, desto sinnvoller wird es.


Du könntest man im Web nach "Model-View-Controller" suchen. Ob das bei so einem kleinen Spiel die "sinnvollste" Lösung ist, ist erstmal nicht so klar, aber es trägt dazu bei, sich Gedanken darüber zu machen, wie man seine Klassen vernünftig aufteilt.


1) Seh ich das richtig, dass MainFrame dann nur dazu gedacht wäre mir ein Fenster zu erzeugen, dass ich noch nach belieben anpassen kann
So ein Hauptframe ist sicher nicht verkehrt...


2) PlayGround wäre dann ein JPanel das ich in meinem MainFrame platziere (wie das geht weiß ich zwar noch nicht aber mal schaun) und auf dem ich dann alles liegen habe was direkt mit dem Spiel zu tun hat (in meinem Fall eigentlich nur die Buttons) Dafür wird dann mein Objekt GameLogic als Schablone verwendet, oder wie?


Wie du das mit der "Schablone" jetzt meinst, ist mir nicht ganz klar. Aber der nächste Punkt klingt schon recht sinnvoll:

3)GameLogic wäre dann "nur" die Verwaltung der Daten auf die PlayGround zugreifen müsste, oder?
Die Anführungszeichen bei "nur" sind berechtigt: Im Idealfall gibt es die GameLogic (oder das GameModel). Und das funktioniert, und damit kann man spielen.

Sinngemäß(!) und NUR zur Verdeutlichung: Man könnte es mit einem Programm steuern, indem man die Methoden aufruft...
Code:
gameModel.open(3,4);
if (gameModel.thereWasABomb()) return;
if (gameModel.getNumberOn(4,4) == 1) 
{
    gameModel.open(4,2);
}
...
(wenn man z.B. eine KI schreiben will...)
oder es an der Konsole spielen lassen, indem der Benutzer die Feldkoordinaten eingibt
Code:
int x, y;
while (!gameModel.isGameOver())
{
    x = userInput();
    y = userInput();
    gameModel.open(x,y);
    print(gameModel);
}
oder - was du vorhast - das ganze mit einem richtigen GUI steuern lassen
Code:
class GUI ... implements ActionListener
{
    private GameModel gameModel; 
    
    ...
    public void actionPerformed(ActionEvent e)
    {
        int x = ... bestimme geklickten Button
        int y = ... bestimme geklickten Button
        gameModel.open(x,y);
        ....
    }
}
Und das ganze könnte so sein, dass das Modell "nicht weiß, von wem es gesteuert wird". Es bietet nur die minimale Menge von Methoden, mit denen man 1. alles notwendige über das Modell erfahren kann, und 2. das Modell steuern kann. Das ist dann (teilweise) die "Kunst": Sich zu überlegen, woraus das Spiel in seinem Kern eigentlich besteht, und was notwendig ist, um es spielen zu können:
- Man muss Felder aufdeken können
- Man muss erfahren können, ob das Spiel zuende ist
- Man muss abfragen können, welche Zahl auf einem Feld steht..
- ...

Wenn man das hat (und man braucht es nichtmal fertig implementiert zu haben - eine "dummy-Implementierung" der Methoden reicht schon) kann man sich überlegen, wie man das GUI machen will. Das kann dann z.B.
- Buttons verwenden, an denen ActionListener hängen, und deren Aufschrift die Anzahl der Bomben angibt
- einen Canvas verwenden, wo ein MouseListener dranhängt, in dem man ein schönes, "gerendertes" Minenfeld aus kleinen Images reinzeichnet, und man rechnet aus, welches Feld angeklickt wurde
- ... oder oder oder...
 

zero-2-one

Mitglied
Mit dem Stiel muss ich dir wohl recht geben ;)

So, ansonsten hab ich den Code jetzt mal total umgestellt und würde gerne wissen, ob das jetzt so besser ist.

Code:
package Minesweeper;

import Minesweeper.data.*;
import Minesweeper.gui.*;

public class Minesweeper
{
  private static final int ROWS = 10;
  private static final int COLUMNS = 10;

  public static GameLogic game_logic; // ist das so sauber? oder sollte die komunikation zwischen GameLogic und MyButton anders verwirklicht werden?

  public static void main(String[] args)
  {
    game_logic = new GameLogic(COLUMNS,ROWS);
    MainFrame mf = new MainFrame(COLUMNS,ROWS);
    mf.setVisible(true);
  }
}

Code:
package Minesweeper.data;

import java.math.*;

public class GameLogic
{
  static final double PART_OF_BOMBS = 0.16; // ~16% of the field are setted with bombs
  private Target[][] battlefield;
  private int x,
              y;

  public GameLogic(int x, int y)
  {
    this.x = x;
    this.y = y;

    // for checking surrounding bombs the real battlefield is surrounded by an "invisible" border of targets without bombs
    battlefield = new Target[x+2][y+2];
    for (int i = 0; i < (battlefield.length); i++)
    {
      battlefield[i][0] = new Target(i,0);  // first row
      battlefield[i][battlefield[0].length-1] = new Target(i,battlefield[0].length-1); //last row
    }
    for (int j = 0; j < battlefield[0].length; j++)
    {
      battlefield[0][j] = new Target(0,j); // first column
      battlefield[battlefield.length-1][j] = new Target(battlefield.length-1,j); //last column
    }
    
    //sets bombs randomly at the battelfield
    for (int k = 1; k <= y; k++)
      for (int l = 1; l <= x; l++)
      {
        boolean bomb = (Math.random() <= PART_OF_BOMBS ? true : false);
        battlefield[l][k] = new Target(l,k,bomb);
      }
  }
  
  public void setTarget(Target target, int i, int j)
  {
    if ( ( (0 < i) && (i < (x+1)) ) && ( (0 < j) && (j < (y+1)) ) )
      battlefield[i][y] = target;
  }
  
  public Target getTarget(int i, int j)
  {
    if ( ( (0 < i) && (i < (x+1)) ) && ( (0 < j) && (j < (y+1)) ) )
      return battlefield[i][j];
    return null;
  }
  
  public int getSurroundingBombs(int i, int j)
  {
    if ( ( (0 < i) && (i < (x+1)) ) && ( (0 < j) && (j < (y+1)) ) )
    {
      int count = 0;
      for(int k = -1; k <= 1; k++)
      {
        for(int l = -1; l <= 1; l++)
        {
          if (!(k == 0 && l == 0))
            if (battlefield[i+k][j+l].getBomb())
              count++;
        }
      }
      return count;
    }
    return 9; //nine neighbourd bombs are impossible
  }
  
  public int getWidth()
  {
    return this.x;
  }
  
  public int getHeight()
  {
    return this.y;
  }
  
}

Code:
package Minesweeper.data;

public class Target
{
  private int pos_x, pos_y;
  private int[] pos = new int[2];
  private boolean has_bomb;
  
  public Target(int x, int y, boolean has_bomb)
  {
    this.pos_x = x;
    this.pos_y = y;
    this.has_bomb = has_bomb ;
    this.pos[0] = x;
    this.pos[1] = y;
  }
  
  public Target(int x, int y)
  {
    new Target(x,y,false);
  }
  
  public void setBomb()
  {
    this.has_bomb = true;
  }
  
  public boolean getBomb()
  {
    return has_bomb;
  }
  
  public int[] getPos()
  {
    return pos;
  }
}

Code:
package Minesweeper.gui;

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

public class MainFrame extends JFrame
{

  public MainFrame(int columns, int rows)
  {
    super("Minesweeper");
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    setSize(columns*MyButton.size, rows*MyButton.size);

    setLocationByPlatform(true);
    setResizable(false);

    // create a field of Buttons
    PlayGround play_ground = new PlayGround(columns,rows);
    getContentPane().add(play_ground);
    add(play_ground);
  }

}

Code:
package Minesweeper.gui;

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

public class PlayGround extends JPanel
{
  public PlayGround(int x, int y)
  {
    this.setLayout(new GridLayout(x, y));

    for (int i = 1; i <= x; i++)
    {
      for (int j = 1; j <= y; j++)
      {
        MyButton b = new MyButton(i,j);
        add(b);
      }
    }
  }
  
}

Code:
package Minesweeper.gui;

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

class MyButton extends JButton
{
  public static final int size = 70;

  private int x, y;
  private GameLogic gl = Minesweeper.game_logic; // ist das so sauber? oder sollte die komunikation zwischen GameLogic und PlayGround anders verwirklicht werden?

  public MyButton(int x, int y)
  {

    this.x = x;
    this.y = y;
    
    setText(gl.getTarget(x,y).getBomb() ? "X" : "O");     //returns "O" if there is no bomb on position (x,y) else it returns "X"
    // setText(x + " / " + y);

    setSize(size,size);

    addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent evt)
      {
        onKlick(evt);
      }
    });
  }

  public void onKlick(ActionEvent event)
  {
    if (gl.getTarget(x,y).getBomb()) this.setText("X");      // X is Symbol for a bomb
      else this.setText("" + gl.getSurroundingBombs(x,y));
  }

}

so das wars bis jetzt mal. Leider bin ich mir nicht ganz im Klaren darüber wie man es sauber löst, dass meine MyButton auf die Daten von GameLogic zugreift. Am Anfang wollte ich direkt in der GameLogic ein public static Array mit allen (in meinem Fall nur ein einziges) GameLogic-Instanzen machen, durch die man dann Zugriff auf alle Instanzen hätte. Dann habe ich mir gedacht, dass ich die eine Instanz die ich benötige ja auch einfach in der Minesweeperklasse public machen könnte. Was ist den jetzt der sinvollere / korrektere Weg? Eher die Klasse selbst die Objekte verwalten lassen oder eher die Übergordnete Klasse die Verwaltung übernehmen lassen oder ganz was anderes?
 

Marco13

Top Contributor
Hmja, MainFrame fehlt noch ... So beim ersten drübersehen: GameLogic enthält alles wesentliche (und insbesondere KEINE GUI-spezifischen Sachen). Ok. Target liefert bei getPos() eine Referenz auf den internen Array. Das ist gefährlich.
Code:
void createInconsistentStateWhichWillCauseAnErrorSoonerOrLater()
{
    target.getPos()[0] = -666; // Knirsch!
}

Das mit der statischen GameLogic ist in der Tat nicht so schön. Ob die Klasse MyButton in dieser Form überhaupt existieren sollte, ist auch fraglich. Das ist nicht 100% "sauber" (d.h. es gäbe noch eine aufwändigere Möglichkeit, die u.U. eine noch stärkere Trennung ermöglichen würde) aber man könnte sowas machen wie
Code:
class PlayGround extends JPanel
{
    private GameLogic gameLogic;

    public PlayGround(final GameLogic gameLogic, ...)
    {
        this.gameLogic = gameLogic;
        ....

        for (int i = 1; i <= x; i++)
        {
          for (int j = 1; j <= y; j++)
          {
            final int ii = i;
            final int jj = j;
            JButton b = new JButton(gameLogic.getTarget(ii,jj).getBomb() ? "X" : "O");
            b.addActionListener(new ActionListener()
            {
                 public void actionPerformed(ActionEvent e)
                 { 
                     if (gameLogic.getTarget(ii,jj).getBomb()) b.setText("X");      // X is Symbol for a bomb
                     else b.setText("" + gameLogic.getSurroundingBombs(ii,jj));
                 }
            })
            add(b);
          }
        }
    }
}
"Besser" wäre es, wenn man zwischen das GUI und die GameLogic nochmal einen Controller schalten würde, damit der PlayGround die GameLogic nicht direkt kennen muss, sondern nur auf einer Controller-Klasse arbeitet, die die Befehle geeignet an die GameLogic weiterreicht, aber ... leg' das jetzt nicht zu sehr auf die Goldwaage - über die genaue Struktur müßte man sich (i.s. "ich mir") auch erstmal Gedanken machen...
 

zero-2-one

Mitglied
ok dazu hätte ich grad nochmal ein paar kurze Fragen (nachdem ich gerade mit dem Post fertig bin, muss ich zugeben, dass die Fragen garnicht sooo kurz sind)...

Was meinst du mit "MainFrame" fehlt noch? Die Klasse ist doch als viertes aufgeführt, oder?

Das mit der getPos() ist wohl wahr - da die Methode eigentlich auch nicht genutzt wurde habe ich das Teil jetzt einfach mal rausgeworfen. Aber mal davon abgesehen... Wie sollte man sowas ansonsten lösen? Sollte man das so machen wie du in deiner abgewandelten PlayGround? Also erst die gefragte Klassenvariable an eine final "Variable" übergeben und dann diese mit return zurückgeben. Warum macht man das dann nicht bei jeder get-Methode so? Oder sollte man das eigentlich immer tun und ich hab das bisher einfach nur nicht beachtet?

Warum würdest du die MyButton als unsauber bezeichnen? Mir ist es zwar auch schon so vorgekommen als wäre die PlayGround mit dieser Auslagerung fast überflüssig aber da ich mich mit dem Actionlistener nochnicht so genau auseinander gesetzt habe wollte ich es einfach mal so probieren (Aber deine Lösunge gefällt mir von der Idee her auch besser). Außerdem muss ich der GUI nach deinem Schema auch nicht soviele Daten von der GameLogic aufhalsen bzw. dort nochmal speichern, sondern reagiere ja nur auf die Daten die dort bereits drinnen stehen - meintest du das mit unsauber, weil ich eigentlich für die GUI irrelevante Daten trotzdem dort nocmals speichere?

nun zu deinem Aufruf von PlayGround mit einer Instanz von meiner GameLogic im Konstruktor: Dann müsste ich diese Instanz ja auch schon von meiner Minesweeper (dort wird ja die Instanz von GameLogic erstellt) mit in die MainFrame schleppen um Sie dort an PlayGround weiter zu reichen - allerdings hat die GameLogic ja nichts in der MainFrame verloren, oder? Außerdem würde mich interessieren was dieses final im Konstruktor von deiner PlayGround bewirkt (oder wird dort dann einfach eine Kopie und keine Referenz erzeugt?)

Was ich auch nicht ganz verstehe ist warum es Sinn macht in den Schleifen diese final-Varianten der Laufvariablen zu erzeugen oder macht man das einfach so, weil in dem ganzen ActionListener-Gedöhns ja etwas böses mit den Variablen passieren könnte (So wie ich das verstehe tut es das ja aber nicht) und ich mir damite meine Schleifen zerschießen könnte?

Und zuletzt noch... das mit dem Controler hört sich interessant an - kann mir zwar noch nicht so 100% was drunter vorstellen aber es klingt nach einer sauberen Trennung der Daten. Wo kann ich mich darüber ein bischen schlau machen oder gibt es irgendwo einfache compilierbare Beispiele wo ich mir die Idee dazu mal anschauen kann? Ich denke mal du stellst dir da so eine Art InterfaceKlasse vor, die eine Komunikation zwischen meinen zwei Klassen regelt.

Sorry malwieder für die vielen Fragen - würde mich aber freuen, wenn ich zumindest ein paar davon beantwortet bekomme :)
 

Marco13

Top Contributor
Was meinst du mit "MainFrame" fehlt noch? Die Klasse ist doch als viertes aufgeführt, oder?

Hoppla :shock: die ist mir beim Rauskopieren vorhin wohl entwischt... ???:L



Das mit der getPos() [...] Wie sollte man sowas ansonsten lösen? Sollte man das so machen wie du in deiner abgewandelten PlayGround? Also erst die gefragte Klassenvariable an eine final "Variable" übergeben und dann diese mit return zurückgeben. Warum macht man das dann nicht bei jeder get-Methode so? Oder sollte man das eigentlich immer tun und ich hab das bisher einfach nur nicht beachtet?

Nee ... den Array final zu machen würde nichts am Problem ändern: Sein Inhalt wäre dann immernoch nicht final :wink: Die Alternative wäre ganz banal: getX() und getY() ....


Warum würdest du die MyButton als unsauber bezeichnen?

Das unsauberste war die statische GameLogic, die da rumflog. Die Klasse an sich ... war nicht "unsauber" (bis auf einen Punkt, kommt weiter unten noch)



nun zu deinem Aufruf von PlayGround mit einer Instanz von meiner GameLogic im Konstruktor: Dann müsste ich diese Instanz ja auch schon von meiner Minesweeper (dort wird ja die Instanz von GameLogic erstellt) mit in die MainFrame schleppen um Sie dort an PlayGround weiter zu reichen - allerdings hat die GameLogic ja nichts in der MainFrame verloren, oder?

Nicht unbedingt - das war das, was ich mit dem letzten Absatz angedeutet hatte. Man kann es auf die Spitze treiben und der View (also dem MainFrame oder dem Playground) nur eine Referenz auf ein Interface geben, das das Modell repräsentiert (und dann eben von GameLogic implementiert wird). Aber man hätte hier jezt keinen unmittelbaren Vorteil (nur mehr Arbeit). Es würde nur erlauben, später die "GameLogic" auszutauschen, ohne dass sich am GUI was ändern muss. In bestimmten Fällen kann sowas sinnvoll sein.

Aber es ist nicht unüblich, dass die View das Modell kennt (oder ein Interface, das das Modell repräsentiert). Von dem holt es sich ja die Sachen, die es anzeigen soll.



Was ich auch nicht ganz verstehe ist warum es Sinn macht in den Schleifen diese final-Varianten der Laufvariablen zu erzeugen...

Das final braucht man, damit man in der inneren, anonymen Klasse verwenden kann. Aber das mußt du jetzt nicht alles 1:1 abtippen. Es sollte nur verdeutlichen, dass man diese Button-Klasse eigentlich nicht braucht. Aber wenn du in diese Klasse noch etwas wichtiges einbauen wolltest, hätte sie vielleicht eine Existenzberechtigung.



Und zuletzt noch... das mit dem Controler hört sich interessant an - kann mir zwar noch nicht so 100% was drunter vorstellen aber es klingt nach einer sauberen Trennung der Daten. Wo kann ich mich darüber ein bischen schlau machen oder gibt es irgendwo einfache compilierbare Beispiele wo ich mir die Idee dazu mal anschauen kann?

Der Controller verbindet die View (GUI) mit dem Modell (GameLogic). Häufig ist der Controller aber in gewisser Form mit der View verbunden (z.B. durch anonyme Listener, die von der View aus direkt das Modell beeinflussen). Das ist nämlich noch eine wichtige Sache, die jetzt noch nicht direkt bei dir vorgesehen ist, aber mit der vorletzten Frage zusammenhängt: Wie Model und View miteinander verbunden sind. Im Moment änderst du die Button-Aufschrift, wenn der Button geklickt wird. Das ist aber nicht unbedingt etwas, was man "aktiv" machen sollte. Stattdessen sollte dieses actionPerformed nur dem Controller bescheid sagen, dass das Modell verändert werden soll (oder in diesem Fall ggf. direkt das Model oder Model-Interface verändern) Das Modell sollte dann eine Nachricht an alle seine "Listener" oder Observer rausschicken. Die GUI sollte einer dieser Listener sein, diese Nachricht erhalten und sich dann vom Modell den neuen Zustand zum Zeichnen abholen.

Mehr Infos gibt's dazu natürlich hier http://en.wikipedia.org/wiki/Model-view-controller oder hier http://java.sun.com/blueprints/patterns/MVC-detailed.html , aber die sind beide nicht sooo toll. Insbesondere die Wikipedia-Seite ist IMHO ziemlich schwach. Vermutlich liegt das aber auch daran, dass MVC ein sehr allgemeines Konzept ist, bei dessen Auslegung man (wenn man die Grundidee einhält) ein paar Freieheitgerade hat.

Deswegen würde ich dir http://pclc.pace.edu/~bergin/mvc/mvcgui.html empehlen: Dort ist mit einem SEHR einfachen, aber vollständigen und sehr anschaulichen Java-Beispiel das MVC-Pattern erklärt, und es kommt IMHO ganz gut rüber, wie man das grundsätzlich angehen kann.
 

zero-2-one

Mitglied
das ist mal service :) Danke für die weiteren Erklärungen!

Hab zwar heute und morgen keine Zeit mir die Links durchzulesen aber das ist doch schonmal ein guter Anhaltspunkt für mich.

Ansonsten hab ich mein game_logic jetzt wirklich mal bis zur PlayGround durchgereicht und das static rausgenommen. Außerdem hab ich die MyButton aufgelöst. Du hast zwar gemeint, dass die ggf. doch berechtigt sein könnte bei einer Erweiterung (die in jedem Fall kommt, weil ich ja irgendwann noch auf einen Rechtsklick reagieren will, etc.), allerdings hätte ich sonst ja die game_logic noch einmal weiterreichen müssen - und das zusätzlich noch in meinen zwei Schleifen (denke mal das wäre nicht so gut gewesen).

das ist zwar jetzt nicht so wichtig aber noch ne kleine Frage zur anonymen Klasse in den for-Schleifen:

Ist die sichtbarkeit der final Variablen ii und jj nur auf den Schleifenbereich und die innere Klasse beschränkt oder sind die dann auch in der gesammten Klasse PlayGround sichtbar? Außerdem vermute ich mal, dass ich den JButton b auch noch als Referenz an "final bb" übergeben muss, oder? Auch wenn es einfach vom Compiler so gefordert wird verstehe ich nicht so ganz warum das so ist... wenn ich doch in der inneren Klasse über die referenz des eigentlichen Buttonobjekts an die Methoden des Buttons rankomme (was ich ja auch will) macht doch final garkeinen Sinn mehr, oder?
Naja, wie gesagt das hier ist jetzt nicht so wichtig gewesen ist mir aber eben so durch den Kopf gegangen.
 

Marco13

Top Contributor
Ausprobieren :wink: Die finalen Referenzen sind nur innerhalb der { } sichtbar, in denen sie deklariert werden.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
Zrebna Fragen zu einem Klassendiagramm Java Basics - Anfänger-Themen 8
H Fragen zu Wrapperklassen Java Basics - Anfänger-Themen 29
S Best Practice Fragen zu Projektstruktur einer Datenbank-Abfrage-App (MVC) Java Basics - Anfänger-Themen 13
A Bei VierGewinnt fragen ob man gegen CPU oder Menschen spielen will. Java Basics - Anfänger-Themen 7
A Bei VierGewinnt vorher fragen, ob man gegen den Computer spielen möchte oder gegeneinander. Java Basics - Anfänger-Themen 1
A Bei VierGewinnt fragen, ob man gegen den Computer spielen möchte oder gegeneinander Java Basics - Anfänger-Themen 1
sserio Wie kann man nach einer Klasse fragen? Java Basics - Anfänger-Themen 12
G Fragen zu Kompelierfehler in Aufgabe. Java Basics - Anfänger-Themen 25
E Bäume/ allgemeine Fragen Java Basics - Anfänger-Themen 21
O Falsche Antworten zu Fragen Java Basics - Anfänger-Themen 4
S Diverse Fragen vor Schulaufgabe ;) Java Basics - Anfänger-Themen 4
S Fragen zu Ausgabe double und float Java Basics - Anfänger-Themen 3
B fragen zu Aufbau eines UML-Klassendiagramm Java Basics - Anfänger-Themen 1
C 3 Fragen rund um Klassenattribute Java Basics - Anfänger-Themen 8
L Erste Schritte Log4J Fragen Java Basics - Anfänger-Themen 5
NeoLexx Fragen zu diversen Elementen der Javabibliothek Java Basics - Anfänger-Themen 5
D Budget Manager fragen zur Umsetzung Java Basics - Anfänger-Themen 9
N Fragen zur Datenspeicherung Java Basics - Anfänger-Themen 45
T Java Anfänger mit konkreten Fragen Java Basics - Anfänger-Themen 2
CT9288 Fragen zu Java Java Basics - Anfänger-Themen 16
W Fragen zu Generics Java Basics - Anfänger-Themen 14
T ObjectInput/OutputStream Fragen zur Funktionsweise Java Basics - Anfänger-Themen 3
J Fragen zu einer Methode Java Basics - Anfänger-Themen 3
J Fragen zum Code aus dem Buch "Schrödinger programmiert Java 2.te Ausgabe" Java Basics - Anfänger-Themen 6
Z Fragen zu Exception (Throws/throw) Java Basics - Anfänger-Themen 7
J Fragen zu Input/Output Java Basics - Anfänger-Themen 3
J Erste Schritte Oracle Tutorials zu Java 8 - Fragen dazu Java Basics - Anfänger-Themen 1
H Java Quereinsteiger Roadmap und Fragen Java Basics - Anfänger-Themen 29
H fragen Java Basics - Anfänger-Themen 15
M Samelsarium Grundlegender Fragen 2 Java Basics - Anfänger-Themen 9
M Sammelsarium an Grundlagen Grundlagen Fragen Java Basics - Anfänger-Themen 11
B Java ist / wird kostenpflichtig. Ein paar Fragen Java Basics - Anfänger-Themen 1
J Fragen zu synrchonized und kritischen Abschnitten Java Basics - Anfänger-Themen 5
S Fragen zu einem Rechentrainer Java Basics - Anfänger-Themen 2
B Java Vererbung Fragen (zu Code Beispiel) Java Basics - Anfänger-Themen 3
J Wo kann man Fragen zu ireport stellen. Java Basics - Anfänger-Themen 0
M Fragen zum Anlegen und Benutzen von Listen Java Basics - Anfänger-Themen 9
G Ein paar Anfänger Fragen zu StdDraw Java Basics - Anfänger-Themen 4
D Fragen zur Klassen Java Basics - Anfänger-Themen 4
Aprendiendo Zwei Fragen und ein geerbtes "protected"-Attribut Java Basics - Anfänger-Themen 2
J Interface Fragen bezüglich "Sauberkeit" von Code Java Basics - Anfänger-Themen 5
D Objekte-Fragen Java Basics - Anfänger-Themen 1
V Erste Schritte Habe Fragen zu der For und While Schleife als auch Inkrement und Dekrement Java Basics - Anfänger-Themen 4
D Anfänger-Fragen(Parameter einer Methode) Java Basics - Anfänger-Themen 7
K Zwei Fragen zu Graphics/Graphics2D Java Basics - Anfänger-Themen 5
R Fragen über den Konstruktor Java Basics - Anfänger-Themen 0
Azazel Ein paar Fragen zu Methodenaufrufen(java.awt) Java Basics - Anfänger-Themen 2
S Erste Schritte Fragen zur For-Schleife Java Basics - Anfänger-Themen 9
C Interface Fragen zum Interface Java Basics - Anfänger-Themen 7
GreenTeaYT Exception und zur OOP fragen? Java Basics - Anfänger-Themen 3
C Fragen zum Spigot Plugin (1.8) Java Basics - Anfänger-Themen 6
J Fragen zu Exceptions Java Basics - Anfänger-Themen 24
N Quiz- Fragen zufällig anzeigen lassen Java Basics - Anfänger-Themen 7
J Verschieden Fragen über Java Programmierung Java Basics - Anfänger-Themen 3
L Viele Fragen zu den Grundlagen Java Basics - Anfänger-Themen 5
B Fragen zu ZIP-File Java Basics - Anfänger-Themen 9
L fragen zu arrays Java Basics - Anfänger-Themen 8
L Fragen zu selbstgeschriebenem Programm Java Basics - Anfänger-Themen 5
M Fragen zum Auslesen von HTML Seiten Java Basics - Anfänger-Themen 5
J Threading-Aufgabe. Totale Noob Fragen, aber bitte trotzdem beantworten ;) Java Basics - Anfänger-Themen 7
S Java Fragen Konstruktor & Statische Methoden Java Basics - Anfänger-Themen 4
K Erste Schritte Frage Antwort Spiel - Fragen zur Planung Java Basics - Anfänger-Themen 2
C Java Applet Fragen: Serialisierung, Excel import Java Basics - Anfänger-Themen 2
Anfänger2011 2 kleine Fragen zu ArrayListen Java Basics - Anfänger-Themen 5
S Fragen zu Ausdrücken&Bedingungen Java Basics - Anfänger-Themen 5
A 2 kurze Anfänger fragen Java Basics - Anfänger-Themen 6
H grundlegende Fragen Java Basics - Anfänger-Themen 3
V Interface ich schäme mich das zu fragen, aber ich schaff nicht ein Text zu zentrieren :( [javaFX] Java Basics - Anfänger-Themen 6
N Programm: Fragen beantworten Java Basics - Anfänger-Themen 6
C Anfänger Anfänger Fragen Java Basics - Anfänger-Themen 8
Z Compiler-Fehler LinkedList Fragen Java Basics - Anfänger-Themen 4
D Rekursion Allgemeine Fragen Java Basics - Anfänger-Themen 2
D [Fragen] zu Methoden Java Basics - Anfänger-Themen 2
S Fragen zur Implementierung eines Binärbaums Java Basics - Anfänger-Themen 3
T Ein paar Fragen zu OOP und Java. Java Basics - Anfänger-Themen 16
J Allgemeine Fragen zur GUI Java Basics - Anfänger-Themen 1
johnnydoe Erste Schritte Erster Blick - erste Fragen Java Basics - Anfänger-Themen 11
DStrohma Grundsätzliche Fragen zu Drag & Drop Java Basics - Anfänger-Themen 1
N Klassen fragen zur getter und setter methode Java Basics - Anfänger-Themen 11
S 3 Fragen, Verzeichnis, GridLayout psoitionieren, Werte für JSpinner Java Basics - Anfänger-Themen 2
T Fragen zu Set / Relationen verknüpfen Java Basics - Anfänger-Themen 4
S 2 Fragen Java Basics - Anfänger-Themen 4
S Hallo und Fragen zu Arbeitsverzeichnis und Menü Java Basics - Anfänger-Themen 8
N Java Fragen... Java Basics - Anfänger-Themen 10
F ExecutorService Fragen! Java Basics - Anfänger-Themen 2
O HashMap Fragen Java Basics - Anfänger-Themen 8
C Fragen zu Arrays Java Basics - Anfänger-Themen 19
T viele "kleine" Fragen... Java Basics - Anfänger-Themen 3
S Fragen zur Implementierung eines Adressbuches Java Basics - Anfänger-Themen 20
S Fragen zu Arrays Java Basics - Anfänger-Themen 6
K Diverse Fragen zum Fehlerlogging Java Basics - Anfänger-Themen 9
N StringReader - Fragen Java Basics - Anfänger-Themen 8
C Einige Fragen zu Frames Java Basics - Anfänger-Themen 7
M Erste Schritte Allgemeine Fragen Java Basics - Anfänger-Themen 4
PaulG Fragen zu Binärbaum Java Basics - Anfänger-Themen 21
P Methoden Aquarium (Fragen zum Scanner) Java Basics - Anfänger-Themen 5
T Erste Schritte Fragen zu meinen kleinen Programm Java Basics - Anfänger-Themen 9
D 2 Fragen: Position ändern vs. LayoutManager / Bilder einfügen im Vordergrund Java Basics - Anfänger-Themen 3
O Zwei Fragen zu Methoden Aufrufen Java Basics - Anfänger-Themen 5
B fragen zur for-schleife und arrays Java Basics - Anfänger-Themen 8

Ähnliche Java Themen

Neue Themen


Oben