getSize() - Echte Höhe bestimmen

Hallöle Crian,

das ist das, was ich zu Anfang des Themas suchte, vielen Dank! :slight_smile:
Ich werde mir das abspeichern, ich werde es sicherlich für nachfolgende Projekte benötigen. :slight_smile:
Aber das Thema ist vorangeschritten. Ist aktuell nicht von nötigen. Ich bastle aktuell an einem GridLayout nach bestimmten Vorgaben, die ich weiter oben schrieb. Mal sehen was daraus wird, ich poste Ergebnisse, wenn ich das irgendwann mal verstanden habe, die Tage dann. :wink:

Gruß
Lukas

======
Ich probiere mich als aller erstes einmal daran ein Layout nach folgender Vorgabe zu machen:
Drei Spalten. Links und Rechts jeweils vertikal in zwei Zeilen eingeteilt. Die Mittlere Spalte komplett senkreicht 100% einnehmend soll dann weiter unterteilt werden können, beispielsweise in 4 mal 4 Labels. (siehe der Beitrag von EikeB #33)

Hallöle,

jetzt muss ich mal nachfragen. Ich habe mich versucht mit GridBagLayout auseinanderzusetzen und folgenden Quelltext kreiert:

   
    public CafeMain() throws IOException {
        spielframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        spielframe.setLocationRelativeTo(null);
        spielframe.setPreferredSize(new Dimension(600, 600));
        spielframe.setLocation((Toolkit.getDefaultToolkit().getScreenSize().width - spielframe.getSize().width) / 2, (Toolkit.getDefaultToolkit().getScreenSize().height - spielframe.getSize().height) / 2);
        spielframe.setIconImage(Toolkit.getDefaultToolkit().getImage("./src/spiel/demo_DE.jpg"));
        Container contentPane = spielframe.getContentPane();
        contentPane.setLayout(gridlayout);
        //======
        Random rand = new Random();
        
        GridBagConstraints linksConstraints = new GridBagConstraints();
        linksConstraints.fill = GridBagConstraints.BOTH;
        JLabel labellinks = new JLabel("LINKSOBEN");
        labellinks.setBackground(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)));
        linksConstraints.gridx = 0;
        linksConstraints.gridy = 0;
        linksConstraints.gridwidth = 1;
        linksConstraints.gridheight = 1;
        
        GridBagConstraints linksConstraints2 = new GridBagConstraints();
        linksConstraints2.fill = GridBagConstraints.BOTH;
        JLabel labellinks2 = new JLabel("LINKSUNTEN");
        labellinks2.setBackground(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)));
        linksConstraints2.gridx = 0;
        linksConstraints2.gridy = 1;
        linksConstraints2.gridwidth = 1;
        linksConstraints2.gridheight = 1;
        
        GridBagConstraints rechtsConstraints = new GridBagConstraints();
        rechtsConstraints.fill = GridBagConstraints.BOTH;
        JLabel labelrechts = new JLabel("RECHTSOBEN");
        labelrechts.setBackground(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)));
        rechtsConstraints.gridx = 2;
        rechtsConstraints.gridy = 0;
        rechtsConstraints.gridwidth = 1;
        rechtsConstraints.gridheight = 1;
        
        GridBagConstraints rechtsConstraints2 = new GridBagConstraints();
        rechtsConstraints2.fill = GridBagConstraints.BOTH;
        JLabel labelrechts2 = new JLabel("RECHTSUNTEN");
        labelrechts2.setBackground(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)));
        rechtsConstraints2.gridx = 2;
        rechtsConstraints2.gridy = 1;
        rechtsConstraints2.gridwidth = 1;
        rechtsConstraints2.gridheight = 1;

        GridBagConstraints mitteConstraints = new GridBagConstraints();
        mitteConstraints.fill = GridBagConstraints.BOTH;
        JLabel labelmitte = new JLabel("MITTE");
        labelmitte.setBackground(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)));
        mitteConstraints.gridx = 1;
        mitteConstraints.gridy = 0;
        mitteConstraints.gridwidth = 1;
        mitteConstraints.gridheight = 2;

        spielframe.add(labellinks,linksConstraints);
        spielframe.add(labellinks2,linksConstraints2);
        spielframe.add(labelrechts,rechtsConstraints);
        spielframe.add(labelrechts2,rechtsConstraints2);
        spielframe.add(labelmitte,mitteConstraints);
         
        spielframe.pack();
    }```


Dies ist nach dem von mir erzählten Modell angeordnet:
Es gibt drei Spalten und zwei Zeilen. In Spalte 1 und 3 gibt es nach unten hin jeweils zwei verschiedene JLabel. In der mittleren Spalte ist dies ein JLabel, was sich über alles hinweg zieht.

Das Endergebnis sieht so aus:


Kann mir einer verraten, warum 1) das setBackground nicht funktioniert hat, wie ich es mir vorgestellt habe.
Und wie ich 2) das ganze so einstellen kann, dass die gesamte Fensterfläche von diesen von mir definierte Eigenschaften eingenommen wird.

Vielen Lieben Dank
Lukas

Eins vorweg: Das kannst du dir sparen :wink: setLocationRelativeTo(null); macht genau das gleiche.

JLabels sind per default nicht opaque (also durchsichtig). Du musst per erst per setOpaque(true) dafür sorgen, dass du den Hintergrund siehst.

Mit dem GridBagLayout hast du dir gleich mal einen der kompliziertesten LayoutManager ausgesucht :wink: Vermutlich bekommt man das durch verschachteln auch etwas unkomplizierter hin. Dein Problem ist folgendes:
Deine Komponenten wachsen momentan in ihrer Größe nicht mit. Dafür gibts in den Contraints noch weightx/weighty die du setzen musst. In deinem Fall auf 1, was dazu führt dass jede Komponente gleichviel Platz einnimmt.

Okay, das setOpaque funktioniert, vielen Dank, das wusste ich nicht.

Zu dem Layoutmanager: Das ist jetzt ein Fall ins Kalte Wasser, ich versuche irgendwie krampfhaft mit allem, was mir das Internet vorschlägt, wie man das macht meinen Vorschlag umzusetzen.

Einfach nur folgende Idee:
Die Sache mit den Drei Spalten. Erste und Dritte Spalte jeweils in zwei Zeilen.
Und die Mittlere ist dann komplett eins, aber verschachtelt sich innen drin.

Mal ein schematisches Bild in Excel, wie ich das meine:

Und das Teil da in der Mitte als ein Element soll nochmal unterteilt werden, beispielsweise jede Einzelne Zelle, 8 mal 8 Labels.

Wenn ich das die tage irgendwie hinkriege, dann steht mein Konzept, dann kann ich weiterverfahren. Dahin ist das aber noch ein weiter Weg.

Das ist nen gutes Beispiel für verschachtelte Layouts. Das Grundgerüst lässt sich bspw. mit nem GridBagLayout erstellen, so wie du es auch schon gemacht hast.
Die Mitte wiederum ist ein JPanel mit GridLayout. Ich habe außerdem deinen Code etwas bereinigt, vieles davon kann man bequem in Methode auslagern, was den ganzen Code übersichtlicher macht:

Könnte dann bspw. so aussehen:

public class CafeMain {
    private JFrame spielframe = new JFrame("Test");

    public CafeMain() {
        spielframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        spielframe.setPreferredSize(new Dimension(600, 600));
        spielframe.setLocationRelativeTo(null);
        Container contentPane = spielframe.getContentPane();
        contentPane.setLayout(new GridBagLayout());

        // add the labels
        spielframe.add(Helper.createRandomBackgroundLabel("LINKSOBEN"), Helper.createGridBagConstraints(0, 0, 1, 1, 1, 1));
        spielframe.add(Helper.createRandomBackgroundLabel("LINKSUNTEN"), Helper.createGridBagConstraints(0, 1, 1, 1, 1, 1));
        spielframe.add(Helper.createRandomBackgroundLabel("RECHTSOBEN"), Helper.createGridBagConstraints(2, 0, 1, 1, 1, 1));
        spielframe.add(Helper.createRandomBackgroundLabel("RECHTSUNTEN"), Helper.createGridBagConstraints(2, 1, 1, 1, 1, 1));

        // add the game panel
        GamePanel gamePanel = new GamePanel(4, 4);
        spielframe.add(gamePanel, Helper.createGridBagConstraints(1, 0, 1, 2, 3, 3));

        spielframe.pack();
        spielframe.setVisible(true);
    }



    public static void main(String[] args)
    {
        new CafeMain();
    }
}

class GamePanel extends JPanel
{
    public GamePanel(int rows, int columns) {
        setLayout(new GridLayout(rows, columns));

        // fill the panel with labels
        for (int i = 0; i < rows * columns; i++) {
            add(Helper.createRandomBackgroundLabel(String.valueOf(i)));
        }
    }
}

class Helper
{
    public static GridBagConstraints createGridBagConstraints(int x, int y, int width, int height, int weightX, int weightY)
    {
        GridBagConstraints constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.BOTH;
        constraints.gridx = x;
        constraints.gridy = y;
        constraints.gridwidth = width;
        constraints.gridheight = height;
        constraints.weightx = weightX;
        constraints.weighty = weightY;

        return constraints;
    }

    public static JLabel createRandomBackgroundLabel(String text)
    {
        Random rand = new Random();
        JLabel label = new JLabel(text);
        label.setBackground(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)));
        label.setOpaque(true);

        return label;
    }
}

Hallöle,

vielen Dank für diese Codeidee.

Dass man das ganze in Methoden mit mehreren Integern auslagern kann, ist mir bewusst, das hab ich erst einmal bewusst nicht gemacht, damit ich erstmal kompakt und an einer Codestelle mir das Arbeiten mit dem GridBagLayout erlernen kann. :wink: Ich werde das aber nun fortan umsetzen, ich glaube verstanden zu haben, wie das ganze funktioniert.

Ich habe Deinen Code eingebaut und es funktioniert hervorragend, mein Testprojekt, vielen Dank!

Ich habe nur noch ein paar Änderungen vorgenommen, um es besser in meine eigene Philosophie anzugliedern.
Beispielsweise hab ich ein paar Klassen und Methoden umbenannt, da ich das Projekt immer eher in Deutsch als in Englisch programmiere. Wenn ich versuchen würde Englische Worte mit meiner Sprache einzubauen, wäre die Blamage perfekt. :slight_smile:

Also das ganze sieht nun vorerst so aus, Korrekturen in Lesbarkeit und Codeverbesserung werden noch folgen.
Meine Hauptklasse CafeMain:

 
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
 
public class CafeMain {
   
    // System
    protected static String OS = System.getProperty("os.name").toLowerCase();
    protected static String dateipfad = new File("").getAbsolutePath();
    protected static String programmname = "Café International";
    protected static JFrame spielframe = new JFrame(programmname);
   
    // Spieler
    protected static int spieler = 1;
    protected static String[] spielername = new String[2];
    protected static int[] punktespieler = new int[2];
    protected static List<Gastkarte> kartenspieler1 = new ArrayList<Gastkarte>();
    protected static List<Gastkarte> kartenspieler2 = new ArrayList<Gastkarte>();
   
    // Spielkarten
    protected static List<Gastkarte> gastkarten = new ArrayList<Gastkarte>();
    protected static List<Laenderkarte> laenderkarten = new ArrayList<Laenderkarte>();
   
    // Spielfeld
    protected static List<Tisch> tische = new ArrayList<Tisch>(12);
    protected static List<Stuhl> stuehle = new ArrayList<Stuhl>(24);
    protected static int[] tischex = new int[12];
    protected static int[] tischey = new int[12];
    protected static int anzahlbarplaetze = 21;
   
    // Sonstiges
    protected static boolean spielernamenkorrekt = false;
    protected static GridBagLayout gridlayout = new GridBagLayout();
   
    public CafeMain() throws IOException {
        spielframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        spielframe.setLocationRelativeTo(null);
        //Spielfeld spielfeld = new Spielfeld();
        //spielframe.add(spielfeld);
        spielframe.setPreferredSize(new Dimension(600, 600));
        //spielframe.setSize(600,600);
        spielframe.setResizable(false);
        spielframe.setIconImage(Toolkit.getDefaultToolkit().getImage("./src/spiel/demo_DE.jpg"));
        spielframe.setVisible(false);
        
        //======
        Container contentPane = spielframe.getContentPane();
        contentPane.setLayout(gridlayout);
        //======
        spielframe.add(AufbauHilfe.createRandomBackgroundLabel("LINKSOBEN"), AufbauHilfe.createGridBagConstraints(0, 0, 1, 1, 1, 1));
        spielframe.add(AufbauHilfe.createRandomBackgroundLabel("LINKSUNTEN"), AufbauHilfe.createGridBagConstraints(0, 1, 1, 1, 1, 1));
        spielframe.add(AufbauHilfe.createRandomBackgroundLabel("RECHTSOBEN"), AufbauHilfe.createGridBagConstraints(2, 0, 1, 1, 1, 1));
        spielframe.add(AufbauHilfe.createRandomBackgroundLabel("RECHTSUNTEN"), AufbauHilfe.createGridBagConstraints(2, 1, 1, 1, 1, 1));
 
        Spielfeld spielpanel = new Spielfeld(4, 4);
        spielframe.add(spielpanel, AufbauHilfe.createGridBagConstraints(1, 0, 1, 2, 3, 3));
         
        spielframe.pack();
        
        ablauf();
    }
   
   
   
    public static void ablauf() {
       
        /*do{
        Spielstart.namensfrage();
        } while(spielernamenkorrekt == false);*/
        Spielstart.gastkartenmischen();
        Spielstart.laenderkartenmischen();
        Spielstart.spielfeldgenerieren();
        spielframe.setVisible(true);
    }
 
    public static void main(String[] args) throws IOException {
        new CafeMain();
    }
 
 
}```

Ist eben noch ein kleines bisschen anderes Zeuchs drin, alles an Code, was noch nie in diesem Thema erwähnt wurde, ist jetzt zu vernachlässigen. ;)

Deine beiden Hilfsklassen, wo die Methoden drinstecken habe ich einfach ausgelagert in die Datei Spielfeld, wo früher mal mein altes JPanel drin war, was ich nicht mehr brauche.
```package spiel;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.util.Random;

import javax.swing.JLabel;
import javax.swing.JPanel;

class Spielfeld extends JPanel {
    public Spielfeld(int rows, int columns) {
        setLayout(new GridLayout(rows, columns));
 
        for (int i=0; i<rows*columns; i++) {
            add(AufbauHilfe.createRandomBackgroundLabel(String.valueOf(i)));
        }
    }
}
 
class AufbauHilfe {
    public static GridBagConstraints createGridBagConstraints(int x, int y, int width, int height, int weightX, int weightY) {
        GridBagConstraints constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.BOTH;
        constraints.gridx = x;
        constraints.gridy = y;
        constraints.gridwidth = width;
        constraints.gridheight = height;
        constraints.weightx = weightX;
        constraints.weighty = weightY;
 
        return constraints;
    }
 
    public static JLabel createRandomBackgroundLabel(String text) {
        Random rand = new Random();
        JLabel label = new JLabel(text);
        label.setBackground(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)));
        label.setOpaque(true);
 
        return label;
    }
}```

Das ganze sieht nun so aus:


Ich hab bewusst mal den ganzen Bildschirm genommen, weil sich noch ein weiteres Problem ergibt. Der setzt mein Fenster nicht mehr in die Mitte des Bildschirms. Es muss irgendetwas geben, was mein `spielframe.setLocationRelativeTo(null);` erfolgreich aushebelt. Hab ich schon öfter mal nach Codeänderungen gehabt, kann ich nicht nachvollziehen, wieso das so ist, wie es ist.


======
Der Rest sieht erstmal korrekt aus.
Jeder dieser 5 Bereiche ist nun ein Einzelbereich, wo ich weitere Elemente hinzufügen werde. Mein Focus liegt erstmal im Mittleren Bereich, wo jetzt das 4 mal 4 hinkommt, soll irgendwann einmal das hier entstehen:


Die weißen sind ohne Funktion und die Roten sowie Orangenen haben je die gleiche Funktion mit ActionListener beim Anklicken.
Ich schau mal, wie ich das Codetechnisch am besten hinbekommen sollte zu generieren. Ergibt sich sicherlich die Tage.

======
Letzte Sache, mal so zum Verständnis:
```constraints.gridx = x;
        constraints.gridy = y;
        constraints.gridwidth = width;
        constraints.gridheight = height;
        constraints.weightx = weightX;
        constraints.weighty = weightY;```

Das war wohl der Grund, warum ich da immer noch nicht so ganz durchgesehen habe.
Kann mir einer sagen, ob folgender Gedankengang richtig ist?
`x` und `y` stellen einfach die Position im Raster fest, wobei oben Links 0,0 ist und das dann nach links und unten weiterzählt.

`width` & `height` legt die "Positionslänge" fest. Also ich meine, das Teil in der Mitte ist beispielsweise nur ein einzelnes X, aber erstreckt sich senkrecht über gleich 2 Ypsilon. Also 1,2.
`weightX` & `weightY` sind irgendetwas mit Extraplatz, was ich aber noch nicht so nachvollziehen kann.


Schöne Grüße und Danke im Voraus für die Beantwortung meiner Fragen.

Gruß
Lukas

Man muss es nur an der richtigen Stelle aufrufen. Wenn der Code selbst noch nicht „weiß“ wie groß das Fenster überhaupt ist/wird, wie soll er dazu die passende Position berechnen?

Sowas kann man ganz einfach in der API nachschauen. Dort steht zu weightX/Y:

In deinem ersten Beispiel hattest du die weight nicht gesetzt und alle Komponenten hatten nur ihre Mindestgröße. Durch das setzen der weight auf 1 wird der überschüssige Platz gleichmäßig an alle Komponenten verteilt.

[QUOTE=EikeB]Sowas kann man ganz einfach in der API nachschauen. Dort steht zu weightX/Y:

In deinem ersten Beispiel hattest du die weight nicht gesetzt und alle Komponenten hatten nur ihre Mindestgröße. Durch das setzen der weight auf 1 wird der überschüssige Platz gleichmäßig an alle Komponenten verteilt.[/QUOTE]

Vielen Dank für die Erklärung! :slight_smile: Jetzt ist es verstanden.

Ich mache mich nun an die generelle Spielfläche mit ActionListenern, mal gucken, wie ich das umsetze. Habe schon eine Idee, aber die gefällt mir Codetechnisch nicht. Ich poste das mal die Tage hier. :slight_smile:

hat noch jemand eine Idee zu meinem Problem mit der Bildschirmmitte?

Naja in die Bildschirmmitte kannst du dann ja einfach ein Panel geben, dem du ein GridLayout zuweist.

Hallöle,

kleines Missverständnis. :slight_smile:
Ich meine nicht mein Problem mit dem mittleren Bereich. Das baue ich mir die Tage zusammen.
Ich meine das Problem, dass mein Fenster immer unten Rechts auf dem Bildschirm angezeigt wird, obwohl ich spielframe.setLocationRelativeTo(null); gesetzt habe.

Da die Position schon beim Aufrauf von setLocationRelativeTo() berechnet wird muss bekannt sein wie groß das JFrame sein wird. Dazu müssen alle Komponenten hinzugefügt und layoutet sein.
Schieb den Aufruf hinter das pack(), dann ist dein JFrame zentriert.

Hmm… wenn es hier immer noch Probleme bei der Größe gibt, würde ich mal (zumindest unter Windows) mit “setResizable()” experimentieren. Das hat dort nämlich noch nie richtig funktioniert, weil nicht skalierbare Fenster je nach gewähltem Windows-Design 1 bis 10 Pixel in Höhe und Breite kleiner waren. Witzigerweise scheint das nie wirklich jemanden interessiert zu haben.

Schätze mal das liegt daran, dass nicht skalierbare JFrames so gut wie nie verwendet werden. Wenn dann höchstens ein Dialog. Das schöne am GridBagLayout vom TO ist ja jetzt, dass sich sein Spielfeld automatisch an die Größe des Fensters anpassen kann. Ist ja auch viel schöner, wenn man sich das Fenster großziehen kann.

Hallöle,

ich habe das Projekt mal zwei Wochen Ruhen lassen, um mich mit anderen Dingen zu befassen und meine Javakenntnisse direkt zu vertiefen.
Bin nun wieder hierhin eingestiegen und hätte eine Frage.

Meine Klasse sieht ja nun so aus:

 
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
 
public class CafeMain {
   
    // System
    protected static String OS = System.getProperty("os.name").toLowerCase();
    protected static String dateipfad = new File("").getAbsolutePath();
    protected static String programmname = "Café International";
    protected static JFrame spielframe = new JFrame(programmname);
   
    // Spieler
    protected static int spieler = 1;
    protected static String[] spielername = new String[2];
    protected static int[] punktespieler = new int[2];
    protected static List<Gastkarte> kartenspieler1 = new ArrayList<Gastkarte>();
    protected static List<Gastkarte> kartenspieler2 = new ArrayList<Gastkarte>();
   
    // Spielkarten
    protected static List<Gastkarte> gastkarten = new ArrayList<Gastkarte>();
    protected static List<Laenderkarte> laenderkarten = new ArrayList<Laenderkarte>();
   
    // Spielfeld
    protected static List<Tisch> tische = new ArrayList<Tisch>(12);
    protected static List<Stuhl> stuehle = new ArrayList<Stuhl>(24);
    protected static int[] tischex = new int[12];
    protected static int[] tischey = new int[12];
    protected static int anzahlbarplaetze = 21;
   
    // Sonstiges
    protected static boolean spielernamenkorrekt = false;
    protected static GridBagLayout gridlayout = new GridBagLayout();
   
    public CafeMain() throws IOException {
        spielframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        spielframe.setPreferredSize(new Dimension(600, 600));
        spielframe.setResizable(false);
        spielframe.setIconImage(Toolkit.getDefaultToolkit().getImage("./resources/demo_DE.jpg"));
        spielframe.setVisible(false);
        
        //======
        Container contentPane = spielframe.getContentPane();
        contentPane.setLayout(gridlayout);
        //======
        spielframe.add(AufbauHilfe.createRandomBackgroundLabel("LINKSOBEN"), AufbauHilfe.createGridBagConstraints(0, 0, 1, 1, 1, 1));
        spielframe.add(AufbauHilfe.createRandomBackgroundLabel("LINKSUNTEN"), AufbauHilfe.createGridBagConstraints(0, 1, 1, 1, 1, 1));
        spielframe.add(AufbauHilfe.createRandomBackgroundLabel("RECHTSOBEN"), AufbauHilfe.createGridBagConstraints(2, 0, 1, 1, 1, 1));
        spielframe.add(AufbauHilfe.createRandomBackgroundLabel("RECHTSUNTEN"), AufbauHilfe.createGridBagConstraints(2, 1, 1, 1, 1, 1));
 
        Spielfeld spielpanel = new Spielfeld(4, 4);
        spielframe.add(spielpanel, AufbauHilfe.createGridBagConstraints(1, 0, 1, 2, 3, 3));
         
        spielframe.pack();
        spielframe.setLocationRelativeTo(null);
        
        ablauf();
    }
   
   
   
    public static void ablauf() {
        Spielstart.gastkartenmischen();
        Spielstart.laenderkartenmischen();
        Spielstart.spielfeldgenerieren();
        spielframe.setVisible(true);
    }
 
    public static void main(String[] args) throws IOException {
        new CafeMain();
    }
 
}```

Und die Klasse Spielfeld sieht so aus:
```package spiel;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.util.Random;

import javax.swing.JLabel;
import javax.swing.JPanel;

class Spielfeld extends JPanel {
    public Spielfeld(int rows, int columns) {
        setLayout(new GridLayout(rows, columns));
 
        for (int i=0; i<rows*columns; i++) {
            add(AufbauHilfe.createRandomBackgroundLabel(String.valueOf(i)));
        }
    }
}
 
class AufbauHilfe {
    public static GridBagConstraints createGridBagConstraints(int x, int y, int width, int height, int weightX, int weightY) {
        GridBagConstraints constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.BOTH;
        constraints.gridx = x;
        constraints.gridy = y;
        constraints.gridwidth = width;
        constraints.gridheight = height;
        constraints.weightx = weightX;
        constraints.weighty = weightY;
 
        return constraints;
    }
 
    public static JLabel createRandomBackgroundLabel(String text) {
        Random rand = new Random();
        JLabel label = new JLabel(text);
        label.setBackground(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)));
        label.setOpaque(true);
 
        return label;
    }
}```

Das Spielpanel in der Mitte als Beispiel mit den 4 mal 4 Feldern funktioniert auch.

Nun würde ich das ganze einmal umbauen und benötige dazu Hilfe.

Ich möchte dieses 4 mal 4 Zeuchs durch das hier ersetzen:


Also wie man sehen kann sozusagen ein 11 mal 11 Block.
Hierbei sind die weißen Felder einfach nur klassische JLabel, ohne jegliche Funktion.
Die Roten und Orangenen Felder haben entsprechende Funktionen.
Sie haben alle eine Nummer und jedes Rote funktioniert gleich (mal abgesehen von der ihm bekannten Nummer).
Gleiches gilt für das Orangene.

Nun würde ich gerne einmal wissen, wie man das machen könnte.
Das Problem, welches ich hierbei sehe ist das folgende:
Ich generiere hier zwar jedes Feld einzeln korrekt, aber es besteht mir irgendwie nicht die richtige Möglichkeit, sie korrekt anzusprechen.
Also ich habe hier einmalig das hier:
```Spielfeld spielpanel = new Spielfeld(4, 4);```
Also kann ich spielpanel ansprechen. Aber ich kann jetzt nicht irgendwie sagen, Feld (2;3) in Spielpanel, mache dies, Feld (3;1) tu das.


Vielen Dank im Voraus für eure Hilfe.

Gruß
Lukas

=====
Also so sieht mein bisheriger Versuch aus:
Erstmal für die 11 mal 11 Labels, und um sie direkt ansprechen zu können:
So meine Spielfeldklasse:
```class Spielfeld extends JPanel {
	
	JLabel spielfeldlabel[][] = new JLabel[11][11];
	
	public Spielfeld() {
		Random rand = new Random();
		setLayout(new GridLayout(11,11));
		for(int n=0;n<11;n++) {
			for(int i=0;i<11;i++) {
				spielfeldlabel[n]** = new JLabel(n+","+i);
				spielfeldlabel[n]**.setBackground(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)));
				spielfeldlabel[n]**.setOpaque(true);
                                add(spielfeldlabel[n]**);
			}
		}
	}
	
}```

Und beim direkten generieren:
``` Spielfeld spielpanel = new Spielfeld();
        spielframe.add(spielpanel, AufbauHilfe.createGridBagConstraints(1, 0, 1, 2, 3, 3));```

Er zeigt schon einmal alles korrekt an, knorke!
Ich kümmere mich jetzt nur noch um die ActionListener...

Dafür kannst du dir in der Spielfeld-Klasse doch entsprechende Methoden definieren.
In der Spielfeld Klasse solltest du dir die Roten bzw. Orangenen Felder in einer Liste oder einem Array speichern. Darüber hättest du dann direkten Zugriff auf das gewünschte Feld.

Hallöle,

sorry ich war meiner Zeit ein wenig voraus. Das Problem hat sich schneller geklärt als ich dachte. Ich konnte nur den Beitrag hier nicht wieder löschen. :wink:

Ich habe das jetzt so geregelt:

	
	JLabel spielfeldlabel[][] = new JLabel[11][11];
	ArrayList<JLabel> spielfeldlabeltisch = new ArrayList<JLabel>(12);
	ArrayList<JLabel> spielfeldlabelstuhl = new ArrayList<JLabel>(24);
	
	public Spielfeld() {
		//Random rand = new Random();
		setLayout(new GridLayout(11,11));
		for(int n=0;n<11;n++) {
			for(int i=0;i<11;i++) {
				spielfeldlabel[n]** = new JLabel(n+","+i);
				
				spielfeldlabel[n]**.setBackground(new Color(255,255,255));
				spielfeldlabel[n]**.setOpaque(true);
				add(spielfeldlabel[n]**);
			}
		}
		spielfeldlabeltisch.add(spielfeldlabel[4][3]);
		spielfeldlabeltisch.add(spielfeldlabel[5][2]);
		spielfeldlabeltisch.add(spielfeldlabel[6][3]);
		spielfeldlabeltisch.add(spielfeldlabel[7][4]);
		spielfeldlabeltisch.add(spielfeldlabel[8][5]);
		spielfeldlabeltisch.add(spielfeldlabel[7][6]);
		spielfeldlabeltisch.add(spielfeldlabel[6][7]);
		spielfeldlabeltisch.add(spielfeldlabel[5][8]);
		spielfeldlabeltisch.add(spielfeldlabel[4][7]);
		spielfeldlabeltisch.add(spielfeldlabel[3][6]);
		spielfeldlabeltisch.add(spielfeldlabel[2][5]);
		spielfeldlabeltisch.add(spielfeldlabel[3][4]);
		for(JLabel a:spielfeldlabeltisch) {
			a.setBackground(Color.ORANGE);
		}
		for(JLabel b:spielfeldlabelstuhl) {
			b.setBackground(Color.RED);
		}
	}
	
}```

Ich habe jetzt sozusagen zwei ArrayLists für die Roten und für die Orangenen und lege einmal in dem großen AddBlock da fest (die Stühle mach ich noch), welche hinzugefügt werden.
Dann färbe ich sie in einer for-each Schleife um und werde ihnen später ActionEvents zuordnen.


Vielen Lieben Dank allen für ihre Hilfe!

Gruß
Lukas

*** Edit ***

Hallöle,

meine letzte Erledigung, die ich treffen möchte ist folgendes:
Ich würde gerne, wenn man auf ein Rotes Feld klickt die Index-Nummer in der "roten" Liste ausgeben lassen, und wenn man auf ein orangenes Feld klickt, die Index-Nummer in der orangenen Liste angeben.

Mein Quellcode sieht bis dato so aus:
```package spiel;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JLabel;
import javax.swing.JPanel;

class Spielfeld extends JPanel implements MouseListener {
	
	JLabel spielfeldlabel[][] = new JLabel[11][11];
	ArrayList<JLabel> spielfeldlabeltisch = new ArrayList<JLabel>(12);
	ArrayList<JLabel> spielfeldlabelstuhl = new ArrayList<JLabel>(24);
	
	public Spielfeld() {
		setLayout(new GridLayout(11,11));
		for(int i=0;i<11;i++) {
			for(int n=0;n<11;n++) {
				spielfeldlabel[n]** = new JLabel(n+","+i);
				
				spielfeldlabel[n]**.setBackground(new Color(255,255,255));
				spielfeldlabel[n]**.setOpaque(true);
				add(spielfeldlabel[n]**);
			}
		}
		feldmalen();
	}
	
	public void feldmalen() {
		spielfeldlabeltisch.add(spielfeldlabel[4][3]);
		spielfeldlabeltisch.add(spielfeldlabel[5][2]);
		spielfeldlabeltisch.add(spielfeldlabel[6][3]);
		spielfeldlabeltisch.add(spielfeldlabel[7][4]);
		spielfeldlabeltisch.add(spielfeldlabel[8][5]);
		spielfeldlabeltisch.add(spielfeldlabel[7][6]);
		spielfeldlabeltisch.add(spielfeldlabel[6][7]);
		spielfeldlabeltisch.add(spielfeldlabel[5][8]);
		spielfeldlabeltisch.add(spielfeldlabel[4][7]);
		spielfeldlabeltisch.add(spielfeldlabel[3][6]);
		spielfeldlabeltisch.add(spielfeldlabel[2][5]);
		spielfeldlabeltisch.add(spielfeldlabel[3][4]);
		
		spielfeldlabelstuhl.add(spielfeldlabel[4][4]);
		spielfeldlabelstuhl.add(spielfeldlabel[5][1]);
		spielfeldlabelstuhl.add(spielfeldlabel[6][2]);
		spielfeldlabelstuhl.add(spielfeldlabel[7][3]);
		spielfeldlabelstuhl.add(spielfeldlabel[8][4]);
		spielfeldlabelstuhl.add(spielfeldlabel[7][5]);
		spielfeldlabelstuhl.add(spielfeldlabel[6][6]);
		spielfeldlabelstuhl.add(spielfeldlabel[5][7]);
		spielfeldlabelstuhl.add(spielfeldlabel[4][6]);
		spielfeldlabelstuhl.add(spielfeldlabel[3][5]);
		spielfeldlabelstuhl.add(spielfeldlabel[2][4]);
		spielfeldlabelstuhl.add(spielfeldlabel[3][3]);
		spielfeldlabelstuhl.add(spielfeldlabel[4][2]);
		spielfeldlabelstuhl.add(spielfeldlabel[5][3]);
		spielfeldlabelstuhl.add(spielfeldlabel[6][4]);
		spielfeldlabelstuhl.add(spielfeldlabel[9][5]);
		spielfeldlabelstuhl.add(spielfeldlabel[8][6]);
		spielfeldlabelstuhl.add(spielfeldlabel[7][7]);
		spielfeldlabelstuhl.add(spielfeldlabel[6][8]);
		spielfeldlabelstuhl.add(spielfeldlabel[5][9]);
		spielfeldlabelstuhl.add(spielfeldlabel[4][8]);
		spielfeldlabelstuhl.add(spielfeldlabel[3][7]);
		spielfeldlabelstuhl.add(spielfeldlabel[2][6]);
		spielfeldlabelstuhl.add(spielfeldlabel[1][5]);
		
		for(JLabel a:spielfeldlabeltisch) {
			a.setBackground(Color.ORANGE);
			a.addMouseListener(this);
		}
		for(JLabel b:spielfeldlabelstuhl) {
			b.setBackground(Color.RED);
			b.addMouseListener(this);
		}
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		System.out.println("Klick");
	}

	@Override
	public void mousePressed(MouseEvent e) {
		System.out.println("Gedrückt");
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		System.out.println("Klick beendet");
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		System.out.println("Berührung");
	}

	@Override
	public void mouseExited(MouseEvent e) {
		System.out.println("Verlassen");
	}
	
}
 
class AufbauHilfe {
    public static GridBagConstraints createGridBagConstraints(int x, int y, int width, int height, int weightX, int weightY) {
        GridBagConstraints constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.BOTH;
        constraints.gridx = x;
        constraints.gridy = y;
        constraints.gridwidth = width;
        constraints.gridheight = height;
        constraints.weightx = weightX;
        constraints.weighty = weightY;
 
        return constraints;
    }
 
    public static JLabel createRandomBackgroundLabel(String text) {
        Random rand = new Random();
        JLabel label = new JLabel(text);
        label.setBackground(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)));
        label.setOpaque(true);
 
        return label;
    }
}```

Da sind jetzt 5 MouseListener verwendet worden. Ich brauche eigentlich nur den ersten, die anderen vier sind erstmal irrelevant und werden wieder entfernt. Wichtig ist MouseClicked.

Ich habe jetzt in der for-Schleife, welche für jedes Element die Farbe festlegt gleich die passenden ActionListener hinzugefügt:
```for(JLabel a:spielfeldlabeltisch) {
			a.setBackground(Color.ORANGE);
			a.addMouseListener(this);
		}
		for(JLabel b:spielfeldlabelstuhl) {
			b.setBackground(Color.RED);
			b.addMouseListener(this);
		}```

Jedoch haben die ja dann beide den gleichen MouseListener.
Ich möchte erreichen, dass die Tische und die Stühle verschiedene MouseListener haben.

Deshalb würde ich gerne mein entsprechendes Element in etwa so erweitern:
```@Override
	public void mouseClicked(MouseEvent e) {
		if(this.equals(spielfeldlabelstuhl)) {
			System.out.println("Ich bin ein Stuhl");
		} else if (this.equals(spielfeldlabelstuhl)) {
			System.out.println("Ich bin ein Tisch");
		}
	}```

Also wenn es sich um einen Stuhl handelt, dann sag "Ich bin ein Stuhl" und wenn nicht, dann sage: "Ich bin ein Tisch".
Bei `spielfeldlabelstuh` und `spielfeldlabeltisch` handelt es sich aber um Arrays, das heißt das einfache equals ist hie gänzlich falsch und würde nie true ergeben.
War jetzt nur ne Schematische Darstellung für das, was ich möchte. ;)

Und noch eine zweite Frage: Kann ich dann irgendwie erreichen, dass der ActionListener weiß, welchen Index das Element in seiner Liste hat?
damit möchte ich weiterrechnen können, dass das Programm weiß, da ist Stuhl #8 angeklickt worden und nicht irgendwas.

Schönes Wochenende!
Lukas :)

Du kannst den MouseListener (bzw. besser: MouseAdapter, da du ja nur die mouseClicked brauchst) auch als anonyme Klasse umsetzen, das könnte dann so aussehen:

for (int i = 0; i < spielfeldlabeltisch.length; i++) {
  JLabel tisch = spielfeldlabeltisch**;
  tisch.setBackground(Color.ORANGE);
  tisch.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent e) {
      System.out.println("Tisch " + i + " wurde gedrückt!");
    }
  });
}

Am einfachsten ist wohl, du passt das name Attribut der jeweiligen JLabels an. Z.B spielfeldlabel[n]**.setName(“Stuhl Nr. 3”);
Wenn Stuhl und Tisch aber eine gravierend unterschiedliche Behandlung benötigen kannst du auch für Stuhl und Tisch eigene Klassen machen die eben von JLabel erben.

Ansonsten kannst du mit Hilfe der contains Methode rausfinden ob ein Label Tisch oder Stuhl ist:

MouseListener mouseListener = new MouseListener
{
@Override
public void mouseClicked(MouseEvent e)
{
if(arrayListeMitTischen.contains(e.getSource())
{//Ich bin ein Tisch}
...

Hallöle und vielen Dank beiden für eine Antwort,
@bERt0r

	public void mouseClicked(MouseEvent e) {
		// TODO Automatisch generierter Methodenstub
		if(spielfeldlabelstuhl.contains(e.getSource())) {
			System.out.println("Stuhl");
		} else if(spielfeldlabeltisch.contains(e.getSource())) {
			System.out.println("Tisch");
		}
	}```

So klappt das, perfekt. getSource ist das Zauberwort. Habe ich bei allen Recherchen darüber immer sehen und wusste nie, was das bedeutet... Danke! :)
  @EikeB 
Hierbei stellt sich aber noch eine Frage, was das i angeht:
Der kann das i als Zahlenvariable weiterhin nicht verarbeiten, da mir Eclipse meldet, in inneren Klassen kann man das nicht ohne weiteres weiterverwenden.