GridBagLayout macht mich wahnsinnig :-(

HarryR

Mitglied
Hallo Leute,

folgender einfacher Code soll zwei (gleichgroße) recheckige JFrames in einem JFrame erzeugen.
Damit man was sieht habe ich die Hintergründe eingefärbt:
Java:
public void addComponentsToPane(Container pane)
{
  // pane =     JFrame
  pane.setLayout(new GridBagLayout());
  pane.setBackground(Color.cyan);
  GridBagConstraints c = new GridBagConstraints();

            
   JPanel left = new JPanel();
   left.setBackground(Color.green);
   c.gridx = 0;
   c.gridy = 0;
            
   pane.add(left,c);       

            

   JPanel right = new JPanel();
   right.setBackground(Color.red);

   c.gridx = 1;
   c.gridy = 0;
   pane.add(right,c);
}

Was dabei herauskommt seht ihr im Screenshot, eine cyan-Fläche

Erwartet habe ich eine grüne Fläche links, eine rote rechts ..

Was mache ich falsch, so schwer ist das doch nicht, oder ?


Viele Grüße
 

Anhänge

  • GridBagLayout-Demo.png
    GridBagLayout-Demo.png
    12,9 KB · Aufrufe: 0
Das Problem dürfte sein, dass standardmäßig kein Fill und weigthx/y gesetzt ist.

Standardmäßig skalieren die Elemente nicht und der verbleibende Platz wird am Rand zugeschlagen. Siehe: https://docs.oracle.com/javase/7/docs/api/java/awt/GridBagLayout.html
Used to determine how to distribute space, which is important for specifying resizing behavior. Unless you specify a weight for at least one component in a row (weightx) and column (weighty), all the components clump together in the center of their container. This is because when the weight is zero (the default), the GridBagLayout object puts any extra space between its grid of cells and the edges of the container.
Wenn du willst, dass der Platz gleichmäßig verteilt wird, weise der Constraint bei weigthx und weightx den gleichen Wert (z.B. 1.0) zu und fill den Wert GridBagConstraints.BOTH damit auch in beide Richtungen (horizontal / vertikal) skaliert wird.
 
Du willst doch eigentlich dem Layout etwas hinzufügen und nicht dem pane.
Von dem Layout hast du keine Variable. Um dem was hinzuzufügen.
 
Du willst doch eigentlich dem Layout etwas hinzufügen und nicht dem pane.
Von dem Layout hast du keine Variable. Um dem was hinzuzufügen.
Nein, das macht er schon richtig so. Hierzu muss noch gesagt werden, dass es hier um LayoutMANAGER geht.

Demit beiden den selben Flächen gleich groß inwerden, müssen beide das selbe Gewicht >0 in X haben. Sie müssen außerdem ein Gewicht in y haben. Dieses darf sich unterscheiden, da hier sonst nichts vorhanden ist. Zu guter Letzt Außerdem musst du ihnen noch sagen, dass sie die reservierte Fläche füllen sollen.
Java:
    public static void addComponentsToPane(Container pane) {
        // pane =     JFrame
        pane.setLayout(new GridBagLayout());
        pane.setBackground(Color.cyan);
        GridBagConstraints c = new GridBagConstraints();

        JPanel left = new JPanel();
        left.setBackground(Color.green);
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1;
        c.weighty = 1;
        c.fill = GridBagConstraints.BOTH;

        pane.add(left, c);
        JPanel right = new JPanel();
        right.setBackground(Color.red);

        c.gridx = 1;
        pane.add(right, c);
    }

Das hier ist übrigens einer der Fälle, wo ich GridBagLayout NICHT empfehlen würde. Abhängig vom Inhalt dieser beiden Flächen können sie nämlich verschieden groß werden. Das hier ist ein Beispiel, wo das GridLayout besser wäre, da es Breite und Höhe in fixe Bereiche einzeilt, unabhängig vom Inhalt.
Java:
    public static void addComponentsToPane2(Container pane) {
        pane.setLayout(new GridLayout(0, 2));

        JPanel left = new JPanel();
        left.setBackground(Color.green);
        pane.add(left);

        JPanel right = new JPanel();
        right.setBackground(Color.red);
        pane.add(right);
    }
 
ps: Gewichte und / oder Breiten lassen sich übrigens auch über den Layoutmanager selbst setzen, dann muss man es nicht für alle Komponenten einzeln machen.
Hier ein Beispiel für das Layout einer einfachen Konfigurationsliste. Abstand oben und links = 14 Pixel, der Text hat dann eine Mindestbreite von 250, die dritte Spalte beinhaltet die Eingabedaten, füllt die gesamte Restbreite aus. Rechts wird dann nochmal ein Abstand von 14 gehalten.
Beim Design muss man jetzt nur noch die Komponenten in die richtige Spalte setzen (beginnend mit Zeile 1) und sie linksbündig ausrichten.
Java:
        GridBagLayout gbl = new GridBagLayout();
        gbl.columnWidths = new int[]{14, 250, 0, 14}; //die zweite Spalte mit den Texten hat eine fixe Breite, es sei denn, die Texte sind länger, dann wird sie automatisch verbreitert.
        gbl.columnWeights = new double[]{0, 0, 1};//die dritte Spalte schnappt sich in der Breite alles, was nicht reserviert ist.
        gbl.rowHeights = new int[]{14}; //Die erste Zeile ist fix 14 Pixel groß, um oben einen Abstand zu haben.
        pane.setLayout(gbl);

        //ganz unten sollte noch ein Filler eingefügt werden, der den übrigen Platz einnimmt und eine Mindesthöhe von 14 hat, damit man auch hier garantiert einen Abstand hat.
Komponenten können natürlich auch mehr als eine Spalte oder Zeile einnehmen, man kann sie auch so konfigurieren, dass sie bis ganz nach rechts oder bis zur nächsten Komponente in der selben Zeile gehen. Viel Spaß beim Experimentieren.

Falls du irgendwann mal begreifst, wie man anständig mit "Internal Paddings" (ipadx,ipady des GridbagConstraints) arbeitet, hast du mehr verstanden als ich. Ich lass die immer auf 0, verwende insets zum Vergrößern der Fläche, welche durch eine Komponente eingenommen wird.
 

Zurück
Oben