# Schiffe Versenken - GUI mit Scene Builder



## battleship (4. Aug 2018)

Guten Tag Community,
Wir sitzen gerade an der Erstellung eines GUI für das Spiel Schiffe Versenken, wofür wir den Scene builder verwenden. Die Schwierigkeit besteht gerade darin, wie man es im Scene Builder hinbekommt, seine Schiffe ins GridPane zu setzen. Unsere Idee war es, das GridPane (10x10) mit Buttons zu belegen und die Schiffe per drag&drop zu platzieren, um so die Buttons zu 'aktivieren', damit sie auch getroffen werden können. Die Umsetzung des Ganzen gestaltet sich allerdings problematisch, da wir noch nicht einmal drauf kommen, wie wir die Schiffobjekte umsetzen sollen, welche dann auch noch sowohl vertikal als auch horizontal ausgelegt werden können, sprich drehbar sind und sich dabei nicht überschneiden, sondern höchstens benachbart sind. Das wäre wohl genug für den Anfang.
Wenn jemand einen Link zu einem passenden Tutorial hätte, wären wir auch schon dafür sehr dankbar, da unsere Suche bisher leider nicht erfolgreich verlief.
LG,
battleships.


----------



## horstiii1 (4. Aug 2018)

Muss es denn unbedingt "drag&drop" sein? Dabei gibt es einige Tücken


----------



## battleship (4. Aug 2018)

Es muss nicht drag&drop sein, wir dachten uns aber es wäre schick das so zu machen, wenn das Spiel dann wirklich von jemandem gespielt wird.
Selbstverständlich sind auch neue Ideen und Vorschläge willkommen.


----------



## horstiii1 (4. Aug 2018)

Man klickt auf ein Schiffsmuster und dann wählt man im GridPane das Button, auf den die obere linke Position des Schiffsmuster gezeichnet werden soll.


----------



## Xyz1 (5. Aug 2018)

Ganz simpel:

```
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Schiffe {

    public static void main(String[] args) {
        MouseListener[][] a = new MouseListener[3][3];
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                final int ii = i;
                final int jj = j;
                a[i][j] = new MouseAdapter() {
                    @Override
                    public void mouseReleased(MouseEvent e) {
                        System.out.println("Auf " + ii + " " + jj + " wurde etwas fallengelassen .... ");
                    }
                };
            }
        }
        JFrame fame = new JFrame();
        fame.setLayout(new GridLayout(1, 2, 0, 100));
        fame.add(new Board(3, 3, a));
        fame.add(new Board(1, 3, a));
        fame.setSize(600, 400);
        fame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        fame.setVisible(true);
    }

}

class Board extends JPanel implements MouseListener {

    int x, y;
    MouseListener[][] a;
    int b = 0;

    Board(int x, int y, MouseListener[][] a) {
        this.x = x;
        this.y = y;
        this.a = a;
        this.addMouseListener(this);
    }

    @Override
    public void paint(Graphics g) {
        int w = this.getWidth(), h = this.getHeight();
        for (int i = 0; i < x; i++) {
            for (int j = 0; j < y; j++) {
                g.drawRect(i * (w / x), j * (h / y), w / x, h / y);
            }
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
    }

    @Override
    public void mousePressed(MouseEvent e) {
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        if (b == 1) {
            b = 0;
            a[Board.this.getMousePosition().x / (this.getWidth() / this.x)][Board.this.getMousePosition().y / (this.getHeight() / this.y)].mouseReleased(e);
        }
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        if (b == 0 && e.getModifiersEx() == MouseEvent.BUTTON1_DOWN_MASK) {
            b = 1;
        }
    }

    @Override
    public void mouseExited(MouseEvent e) {
        if (b == 1) {
            b = 0;
        }
    }

}
```

`Board.this.getMousePosition().x` und `Board.this.getMousePosition().y` liefert allerdings immer die Position zur Ursprung Komponente zurück wahrscheinlich Sicherheitsgründe ....
Kurz: drag&drop ist in Java nicht dafür gedacht, es selber zu schreiben .... 

vielleicht hat da noch jemand eine Idee?  @Flown


----------



## mihe7 (5. Aug 2018)

@DerWissende ich glaube, die reden von JavaFX.

Was DnD betrifft:
In JavaFX: https://docs.oracle.com/javafx/2/drag_drop/jfxpub-drag_drop.htm
In Swing: https://docs.oracle.com/javase/tutorial/uiswing/dnd/intro.html
und java.awt.dnd.*; 

@battleship in Swing würde ich keine Buttons nehmen sondern einfach eine eigene Komponente für das Spielfeld schreiben. Wie das in JavaFX aussieht, weiß ich nicht.

Was (nicht nur) das Platzieren betrifft: modelliert das Spiel mal ganz ohne UI(-Komponenten). Das UI hat im besten Fall nur die Aufgabe, das Modell grafisch darzustellen und mit dem Benutzer zu interagieren, um Änderungen am Modell vorzunehmen (googelt mal nach MVC - model view controller).


----------



## Xyz1 (5. Aug 2018)

mihe7 hat gesagt.:


> ich glaube, die reden von JavaFX


*Scene Builder* hätte es mich erahnen lassen können....
Dann das von Dir genannte DnD einfach adaptieren....

@battleship wie weit seit ihr schon schon Land bei euch in Sicht  (Sorry für das schlechte Wortspiel)


----------



## battleship (5. Aug 2018)

Zu aller Erst danke für eure Hilfe und die Tipps.

@DerWissende Nein, Land in Sicht ist noch lange nicht  Das wird ein ordentliches Stück Arbeit, denn trotz guter Mitarbeit während des Semesters (falls man dies an der Note festmachen darf) ist unser Wissensstand nicht wirklich besser als "nicht vorhanden". Bekanntlich soll die Übung aber den Meister machen, also wird es noch. Ich melde mich, sobald es Neuigkeiten gibt und bis dahin einen schönen Sonntag!


----------

