# GridLayout verändert festgesetzte Größe der Komponenten



## Lexi (25. Mrz 2009)

Folgendes Problem:

Ich habe ein Panel, welches 10x10 Buttons enthält.
Diese Buttons liegen auf einem Panel dessen Layout ein GridLayout ist.
Das Panel mit den Buttons liegt, zusammen mit einem weiteren Panel auf der contentPane, die eine BorderLayout hat.
(ButtonPanel BorderLayout.CENTER | anderesPanel BorderLayout.SOUTH)

Die Buttons sind eine aus JButton abgeleitete Klasse, in der ich getPrefferedSize, getMinimumSize() und getMaximumSize() überschrieben habe. Alle 3 Methoden liefern den gleichen Wert zurück.

Sobald ich von dem ButtonPanel jetzt alle Buttons entferne und danach wieder z.B 16x16 oder 20x20 Buttons draufmache, werden die Buttons alle um einwenig kleiner dargestellt als sie eigentlich laut der "Size-Methoden" dürften.

Sollte Code-Bedarf bestehen, bitte kurz anmerken..


----------



## Marco13 (25. Mrz 2009)

Naja, wenn 10x10 in der richtigen Größe angezeigt werden, dann... passen nicht 12x12 in der gleichen Größe drauf...?! (Wenn du noch ein hauptFrame.pack(); hinterherschieben würdest, würde sich das Fenster ggf. anpassen, aber ... was soll das Programm machen?...)


----------



## Lexi (25. Mrz 2009)

pack() rufe ich dann selbstverständlich auf...
Das ganze ist ein Minesweeper Spiel, bei dem man die Möglichkeit haben soll die Größe des Spielfeldes bzw die Anzahl der einzelnen Felder zu variieren...


----------



## Ebenius (26. Mrz 2009)

Quelltext wäre wohl ganz gut. Wenn möglich zusammengeschrumpft aber in sich vollständig.

Ebenius


----------



## Lexi (26. Mrz 2009)

Wenn euch da ncohwas fehlt, bitte bescheid geben :

[HIGHLIGHT="Java"]import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Oberfläche
extends JFrame
implements ActionListener
{
    private Spiel spiel;
    private KachelButton felder[][];

    private final JButton btNeu;
    private final JComboBox cbKacheln, cbFrustFaktor;
    private JPanel kachelPanel;

    public Oberfläche()
    {
       super("Minesweeper - Lexi");
       Container cp = getContentPane();
       addWindowListener( new WindowAdapter(){
                             //...
                         );
       cp.setLayout(new BorderLayout());
       kachelPanel = new JPanel(){
                        @Override
                        protected void paintComponent(Graphics g)
                        {
                            super.paintComponent(g);
                            //...Hier werden nur g.drawString und g.fillOval aufgerufen
                    }
                };
       addKachelButtons();

       //Comboboxen zur Größen und Schwierigkeits Einstellung
       JPanel menuPanel = new JPanel();
       JPanel dropDownPanel = new JPanel();
       dropDownPanel.setLayout(new GridLayout(1,2));
       String[] frustFaktoren = { "Sehr Leicht",
                                  "Leicht",
                                  "Normal",
                                  "Schwer",
                                  "Sehr Schwer" };
       cbFrustFaktor = new JComboBox(frustFaktoren);
       cbFrustFaktor.setEditable(false);
       dropDownPanel.add(cbFrustFaktor);
       String[] kachelAnzahl = { "10x10","16x16","20x20" };
       cbKacheln = new JComboBox(kachelAnzahl);
       cbKacheln.setEditable(false);
       dropDownPanel.add(cbKacheln);
       menuPanel.add(dropDownPanel);

       btNeu = new JButton("Neues Spiel");
       btNeu.addActionListener(this);
       menuPanel.add(btNeu);

       cp.add(kachelPanel,BorderLayout.NORTH);
       cp.add(menuPanel,BorderLayout.SOUTH);
       setVisible(true);
       pack();
    }

    @Override
    public void actionPerformed(ActionEvent ae)
    {
      if(ae.getSource().equals(btNeu)) // Neues Spiel
      {
          //Hier werden die BUttons neu aufs Panel gemacht
          kachelPanel.removeAll();
          addKachelButtons();
          pack();
          kachelPanel.repaint();
      }
    }    

    class MyMouseListener
    extends MouseAdapter
    {
        @Override
        public void mousePressed(MouseEvent me)
        {
          //... 
        }
    }

    private void addKachelButtons()
    {
        felder = new KachelButton[feldGroesse][feldGroesse];
        kachelPanel.setLayout(new GridLayout(feldGroesse,feldGroesse));
        for(int j = 0; j < feldGroesse; j++)         
          for(int i = 0;i < feldGroesse; i++){
            felder_[j] = new KachelButton(i+1,j+1);
            felder[j].addMouseListener(new MyMouseListener());
            felder[j].setMargin(new Insets(0,0,0,0));
            kachelPanel.add(felder[j]);
       }
    }
}[/HIGHLIGHT]


EDIT: Habe noch 2 Screenshots angehängt._


----------



## Marco13 (26. Mrz 2009)

Mit "in sich vollständig" ist i.a. gemeint: Etwas, was man mit Copy&Paste rauskopieren und compilieren kann, und wo man dann auf einen Button klickt und den Fehler sieht.

Lieber 50 Zeilen mehr Code und Compilierbar, als 50 Zeilen weniger und irgendwelche Obskuren Klassen dabei, von denen man nicht weiß, wie sie implementiert sind, und die auf die Funktion einfluß haben könn(t)en....


----------



## Marco13 (26. Mrz 2009)

Setzt du vielleicht (in dem Teil, den du nicht gepostet hast) die PreferredSize vom KachelPanel oder irgendeiner anderen Component (außer den KachelButtons) auf irgendeinen festen Wert?


----------



## Lexi (26. Mrz 2009)

> Die Buttons sind eine aus JButton abgeleitete Klasse, in der ich getPrefferedSize, getMinimumSize() und getMaximumSize() überschrieben habe. Alle 3 Methoden liefern den gleichen Wert zurück.



Ja das hab ich gemacht.

[HIGHLIGHT="Java"]import javax.swing.*;
import java.awt.*;

public class KachelButton
extends JButton
{
    private final Dimension groesse = new Dimension(30,30);

    public KachelButton()
    {
        super();
    }

    @Override
    public Dimension getPreferredSize()
    {
        return groesse;
    }

    @Override
    public Dimension getMinimumSize()
    {
        return groesse;
    }

    @Override
    public Dimension getMaximumSize()
    {
        return groesse;
    }

}[/HIGHLIGHT]


----------



## Marco13 (26. Mrz 2009)

Marco13 hat gesagt.:


> Setzt du vielleicht (in dem Teil, den du nicht gepostet hast) die PreferredSize vom KachelPanel oder irgendeiner anderen Component *(außer den KachelButtons)* auf irgendeinen festen Wert?



Bei den KachelButtons ist das OK. Auch wenn eine eigene Klasse dafür nicht angebracht ist, aber vielleicht können sie in Wirklichkeit ja noch mehr.

Die Frage war, ob du irgendwo sowas machst wie
kachelPanel.setPreferredSize(new Dimension(300,300));
oder so.


----------



## Lexi (26. Mrz 2009)

Marco13 hat gesagt.:


> Bei den KachelButtons ist das OK. Auch wenn eine eigene Klasse dafür nicht angebracht ist, aber vielleicht können sie in Wirklichkeit ja noch mehr.
> 
> Die Frage war, ob du irgendwo sowas machst wie
> kachelPanel.setPreferredSize(new Dimension(300,300));
> oder so.



Nein.


----------



## Marco13 (26. Mrz 2009)

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

public class Oberflache
extends JFrame
implements ActionListener
{
    public static void main(String args[])
    {
        new Oberflache();
    }

    private final JButton btNeu;
    private JPanel kachelPanel;
    private int feldGroesse=5;

    public Oberflache()
    {
       super("Minesweeper - Lexi");
       Container cp = getContentPane();
       cp.setLayout(new BorderLayout());

       kachelPanel = new JPanel();

       btNeu = new JButton("Neues Spiel");
       btNeu.addActionListener(this);

       cp.add(kachelPanel,BorderLayout.NORTH);
       cp.add(btNeu,BorderLayout.SOUTH);
       setVisible(true);
       pack();
    }

    @Override
    public void actionPerformed(ActionEvent ae)
    {
          kachelPanel.removeAll();
          feldGroesse+=2;
          addKachelButtons();
          pack();
          kachelPanel.repaint();
    }

    private void addKachelButtons()
    {
        kachelPanel.setLayout(new GridLayout(feldGroesse,feldGroesse));
        for(int j = 0; j < feldGroesse; j++)
          for(int i = 0;i < feldGroesse; i++){
            JButton b = new JButton(i+","+j);
            b.setMargin(new Insets(0,0,0,0));
            kachelPanel.add(b);

       }
    }
}
```


----------



## Ebenius (27. Mrz 2009)

Lexi hat gesagt.:


> Ja das hab ich gemacht.
> 
> [HIGHLIGHT="Java"]@Override
> public Dimension getPreferredSize()
> ...


Anmerkung am Rande: Mach sowas nicht; die Werte der Dimension-Klasse sind veränderbar. Immer eine selbständige Instanz zurückgeben: [HIGHLIGHT="Java"]@Override
public Dimension getPreferredSize()
{
    return new Dimension(groesse);
}[/HIGHLIGHT]
Ebenius


----------



## Marco13 (27. Mrz 2009)

Noch kleinere Anmerkung: Sowas löst man i.a. nicht durch das Erstellen einer abgeleiteten Klasse und Überschreiben der Methoden (was ich ja schon hinterfragt hatte), sondern dadurch, dass man schlicht und einfach "button.setPreferredSize(...)" aufruft.... So ein Überschreiben kann (wenn man nicht genau weiß, was man da tut) SEHR unschöne Seiteneffekte haben...


----------

