JPanels auf gleicher Höhe (Y-Achse) in einem FlowLayout platzieren

Exolution

Mitglied
Guten Abend zusammen,

ich komme derzeit bei diesem doch recht "lächerlichem" Problem nicht weiter und möchte hiermit um eure Hilfe bitten.

Zum Problem:
Ich habe mehrere JPanels, alle von denen haben eine unterschiedliche Größe, da jedes JPanel eine unterschiedliche Anzahl an JLabels hat.
Wenn ich diese JPanels jetzt einem JPanel zuordne, welches als Layout den FlowLayout nutzt, dann reihen sich alle schön zentiert in der X-Achse ein, soweit so gut.
Da aber die JPanels alle eine unterschiedliche Größe besitzten, kommt es zum Problem:
Die kleineren JPanels zentrieren sich in der Y-Achse mittig zum größten JPanel im FlowLayout, jedoch möchte ich, dass die kleineren JPanels sich alle oben anordnen, genauso wie der größte JPanel.

Ich habe zwei Bild angehangen, einmal der IST-Zustand und der SOLL-Zustand.
Ich hätte gerne das die Labels trotz unterschiedlicher Größe auf gleicher Höhe sind (Siehe Bild 2), wie erziele ich das gewünschte Ergebnis?

MfG Exolution

Der Code:

Java:
public class Problem {

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        frame.setSize(1300, 700);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.getContentPane().setBackground(Color.RED);
        
            JPanel maincontent = new JPanel();
            maincontent.setBorder(BorderFactory.createEmptyBorder(25, 25, 25, 25));
            maincontent.setBackground(Color.GREEN);
            maincontent.setSize(1275, 675);
            maincontent.setLayout(new GridLayout());
        
                JPanel mainpanel = new JPanel();
                mainpanel.setLayout(new FlowLayout(FlowLayout.CENTER, 30, 0));
        
                JPanel content1 = new JPanel();
                content1.setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = 0;
                gbc.anchor = gbc.NORTHWEST;
                for (int i = 0; i < 10; i++) {
                    gbc.gridy = i;
                    content1.add(new JLabel("Label: " + (i+1)), gbc);
                }
                
            mainpanel.add(content1);
        
                JPanel content2 = new JPanel();
                content2.setLayout(new GridBagLayout());
                GridBagConstraints gbc2 = new GridBagConstraints();
                gbc2.gridx = 0;
                gbc2.anchor = gbc2.NORTHWEST;
                for (int i = 0; i < 15; i++) {
                    gbc2.gridy = i;
                    content2.add(new JLabel("Label: " + (i+1)), gbc2);
                }
                
            mainpanel.add(content2);
        
        maincontent.add(mainpanel);
        
    frame.getContentPane().add(maincontent);
    frame.setVisible(true);

    }

}
 

Anhänge

  • Screenshot (272).png
    Screenshot (272).png
    20,6 KB · Aufrufe: 4
  • Screenshot (273).png
    Screenshot (273).png
    16,4 KB · Aufrufe: 9

Blender3D

Top Contributor
Dein Code ein wenig umgebaut funktioniert. Statt FlowLayout mit GridBagLayout.
[CODE lang="java" title="StartProblem"]import java.awt.Color;
import javax.swing.JFrame;

public class StartProblem {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(1300, 700);
frame.add(new Problem(1275, 675));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.getContentPane().setBackground(Color.RED);
frame.pack();
frame.setVisible(true);
}
}[/CODE]

[CODE lang="java" title="Problem" highlight="17-26"]import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Problem extends JPanel {
public Problem(int width, int height) {
setPreferredSize(new Dimension(width, height));
setBorder(BorderFactory.createEmptyBorder(25, 25, 25, 25));
setBackground(Color.GREEN);
setLayout(new GridLayout());
JPanel mainpanel = new JPanel();
mainpanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.PAGE_START;
gbc.gridx = 0;
gbc.weighty = 1;
gbc.ipadx=20;
mainpanel.add(new LabelListPanel(10),gbc);
gbc.gridx = 1;
mainpanel.add(new LabelListPanel(15),gbc);
add(mainpanel);
}
}[/CODE]
[CODE lang="java" title="LabelListPanel vermeidet doppelten Code"]import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class LabelListPanel extends JPanel {
public LabelListPanel(int num) {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.anchor = GridBagConstraints.NORTHWEST;
for (int i = 0; i < num; i++) {
gbc.gridy = i;
add(new JLabel("Label: " + (i + 1)), gbc);
}
}
}[/CODE]
 

Exolution

Mitglied
Danke für eure Antwort!

Leider benötige ich das FlowLayout, da das Fenster im eigentlichen Projekt resizeable ist und die Labels dann abgeschnitten sind, wenn das Fenster zu klein wird.

Wie realisiere ich das am besten?
 

Blender3D

Top Contributor
Leider benötige ich das FlowLayout, da das Fenster im eigentlichen Projekt resizeable ist und die Labels dann abgeschnitten sind
Wie willst du mittels FlowLayout bei einem zu kleinem Fenster verhindern, dass die Labels abgeschnitten werden?
Normalerweise arbeitet man da mit einer minimalen Größe die nicht unterschritten wird und ScrollPanes, um den Zugriff des Users auf alle Steuerelemente zu gewährleisten.
 

Exolution

Mitglied
Wie willst du mittels FlowLayout bei einem zu kleinem Fenster verhindern, dass die Labels abgeschnitten werden?
Normalerweise arbeitet man da mit einer minimalen Größe die nicht unterschritten wird und ScrollPanes, um den Zugriff des Users auf alle Steuerelemente zu gewährleisten.
Genau, ich habe eine Mindestgröße des JFrames festgelegt und wenn es mehrere Panels werden, würde ich ScrollPane nutzen.

Wenn ich aber jetzt das Fenster verkleinere, schneidet das JFrame in Inhalt links und rechts ab, hätte ich ein FlowLayout würden alle weiteren JPanels sich untereinander anordnen, dann könnte man hier mittels JScrollPane den gesamten Inhalt anzeigen lassen.

Ich weiß nicht ob mein Text und Problem verständlich ist :/
 

mihe7

Top Contributor
Wie realisiere ich das am besten?
Mit einem passenden LayoutManager. Entweder suchst Du Dir einen fertigen oder Du schreibst Dir einen.

Du willst die Komponenten mit ihrer Preferred Size linksbündig nebeneinander setzen und umbrechen, wenn der Platz nicht reicht. Das ist nicht wirklich kompliziert, hier mal ein Ansatz:

Java:
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.util.function.Function;

public class ReactiveLayout implements LayoutManager {

    private final int hGap;
    private final int vGap;

    public ReactiveLayout() {
        this.hGap = 0;
        this.vGap = 0;
    }

    public ReactiveLayout(int hGap, int vGap) {
        this.hGap = hGap;
        this.vGap = vGap;
    }

    @Override
    public Dimension minimumLayoutSize(Container parent) {
        return calculateLayoutSize(parent, c -> c.getMinimumSize());
    }

    @Override
    public Dimension preferredLayoutSize(Container parent) {
        return calculateLayoutSize(parent, c -> c.getPreferredSize());
    }

    private Dimension calculateLayoutSize(Container parent, Function<Component, Dimension> compSize) {
        int width = 0;
        int height = 0;

        for (Component c : parent.getComponents()) {
            if (c.isVisible()) {
                Dimension size = compSize.apply(c);
                width += size.width + (width > 0 ? hGap : 0);
                height = Math.max(height, size.height);
            }
        }

        Insets insets = parent.getInsets();
        width += insets.left + insets.right;
        height += insets.top + insets.bottom;

        return new Dimension(width, height);
    }

    @Override
    public void layoutContainer(Container parent) {
        Insets insets = parent.getInsets();
        int x = insets.left;
        int y = insets.top;
        int rowHeight = 0;
        Dimension parentSize = parent.getSize();
        int maxWidth = parentSize.width - insets.left - insets.right;

        for (Component c : parent.getComponents()) {
            if (c.isVisible()) {
                Dimension size = c.getPreferredSize();
                if (x + size.width > maxWidth) {
                    x = insets.left;
                    y += rowHeight + vGap;
                    rowHeight = 0;
                }
                c.setBounds(x, y, size.width, size.height);
                rowHeight = Math.max(rowHeight, size.height);
                x += size.width + hGap;
            }
        }
    }

    @Override
    public void addLayoutComponent(String name, Component comp) {}

    @Override
    public void removeLayoutComponent(Component comp) {}    
}
 

Neumi5694

Top Contributor
Vielleicht kommst du ja so zum Ziel?
Die Zeilen 7-9 und 20 sind der wichtige Teil daran, der Rest dient nur zum Aufbau des Beispiels
[CODE lang="java" title="Flowlayout" highlight="7,8,9,20"]public class FlowLayoutTopAlignment {

private static Component buildPanel(int nlabels) {
nlabels = Math.max(1, nlabels);
JPanel panel = new JPanel(new GridLayout(nlabels, 1)) {
@Override
public int getBaseline(int width, int height) {
return 0;
}
};

for (int i = 0; i < nlabels; i++) {
panel.add(new JLabel(String.format("Label %d", counter++)));
}
return panel;
}

public static void main(String[] args) {
FlowLayout fl = new FlowLayout();
fl.setAlignOnBaseline(true);
JPanel holder = new JPanel(fl);
holder.add(buildPanel(2));
holder.add(buildPanel(1));
holder.add(buildPanel(4));
holder.add(buildPanel(2));
holder.add(buildPanel(1));
holder.add(buildPanel(6));
holder.add(buildPanel(4));
holder.add(buildPanel(2));
JFrame frame = new JFrame("title");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(holder);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static int counter = 1;
}
[/CODE]

Du bist aber nicht der erste mit diesem Problem, da haben sich schon massig Webdesigner den Kopf darüber zerbrochen. Mach dich per Google mal etwas schlau, ob es nicht schon vorgefertigte bessere Lösungen als diesen rudimentären Ansatz gibt. Einen externen Layoutmanager mit einzubinden, dürfte das kleinste aller möglichen Probleme sein.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Probleme beim aktualisieren eines JPanels Java Basics - Anfänger-Themen 7
V Alle Komponenten eines JPanels Java Basics - Anfänger-Themen 14
L Threads Laufbild Erzeugen Problem mit Aktualisieren des JPanels Java Basics - Anfänger-Themen 2
W 2 JPanels in 2Klasse in einem JFrame zusammenfügen Java Basics - Anfänger-Themen 12
D Methoden Implementieren von einer Zoomfunktion innerhalb eines JPanels mit null-Layoutmanager Java Basics - Anfänger-Themen 1
N Probleme beim entfernen eines JPanels Java Basics - Anfänger-Themen 4
L "Graphik" JPanels übereinander legen Java Basics - Anfänger-Themen 5
M JPanels verschachteln Java Basics - Anfänger-Themen 23
J Cannot find Symbol Variable mit JPanels Java Basics - Anfänger-Themen 2
M dynamische JPanels/Component Java Basics - Anfänger-Themen 3
M Überschreiben von JPanels funktioniert nicht! Java Basics - Anfänger-Themen 9
U Neuzeichnen eines JPanels Java Basics - Anfänger-Themen 17
A Mehere JPanels und JLabels - Warum Fehler? Java Basics - Anfänger-Themen 5
G Gesamten clickCount mehrerer JPanels herausfinden Java Basics - Anfänger-Themen 5
M JPanels vergleichen Java Basics - Anfänger-Themen 3
A Matisse oder Java Problem: JPanels werden riesig ? Java Basics - Anfänger-Themen 3
B LayoutManager Anorden von verschiedenen JPanels Java Basics - Anfänger-Themen 5
Q ActionListener event bei JPanels Java Basics - Anfänger-Themen 5
P Schriftgröße eines JPanels ändern Java Basics - Anfänger-Themen 2
T JPanels austauschen? Java Basics - Anfänger-Themen 4
T Fehlermeldung beim Klonen eines JPanels Java Basics - Anfänger-Themen 8
W JPanels löschen und neu konstruieren Java Basics - Anfänger-Themen 4
R Größter zusammenhängender Block gleicher Zeichen im String Java Basics - Anfänger-Themen 1
K Java gleicher Wert von Zahlen? Java Basics - Anfänger-Themen 5
B bei 2 Arrays Anzahl gleicher Elemente vergleichen? Java Basics - Anfänger-Themen 49
M In gleicher zeile hinter ausgabe noch etwas ausgeben Java Basics - Anfänger-Themen 1
L Best Practice Code Refactoring für Methoden mit fast gleicher Aufbau Java Basics - Anfänger-Themen 6
E gleicher Name in der Basisklasse und in der Subklasse Java Basics - Anfänger-Themen 45
L Zwei sortierte Subarrays mit gleicher Länge zusammenfügen Java Basics - Anfänger-Themen 2
J Unterschiedliche Ordnerstrukturen trotz gleicher Entwicklungsumgebungen Java Basics - Anfänger-Themen 3
H Würfelspiel, stop bei gleicher Zahl Java Basics - Anfänger-Themen 4
K Anzahl gleicher Elemente in Array Java Basics - Anfänger-Themen 32
B Gleicher Prozess starten und stoppen (Problem beim Stoppen) Java Basics - Anfänger-Themen 5
B Klassen HashMap Zwei Objekte, gleicher Key Java Basics - Anfänger-Themen 4
N Compiler findet array in gleicher methode nicht Java Basics - Anfänger-Themen 4
D Ermitteln der Anzahl gleicher Nachkommastellen 2er Zahlen Java Basics - Anfänger-Themen 9
? Algo gleicher Buchstabe in 2 Wörtern suchen Java Basics - Anfänger-Themen 16
A Klasse importieren wenn 2 mal gleicher Name Java Basics - Anfänger-Themen 2
I Array und variable gleicher wert, wird jedoch nicht erkannt Java Basics - Anfänger-Themen 4
R Anzahl gleicher Elemente in ArrayList Java Basics - Anfänger-Themen 5
G Gleicher Klassenname in API Java Basics - Anfänger-Themen 2
G in Verzeichnis auf gleicher Ebene wechseln Java Basics - Anfänger-Themen 4
G Abstrakte Methode in gleicher Klasse aufrufen Java Basics - Anfänger-Themen 5
V mehrere Instanzen gleicher Name möglich? Java Basics - Anfänger-Themen 3
G XML nächstes Child element (gleicher name) Java Basics - Anfänger-Themen 5
J Jedes Element in 2 Arrays mit gleicher Position addieren Java Basics - Anfänger-Themen 12
X trotz gleicher variablen nicht equal Java Basics - Anfänger-Themen 5
krgewb Breite und Höhe eines Bildes in base64 auslesen Java Basics - Anfänger-Themen 3
BeginnerJava "Weihnachtsbäume" anzeigen: Höhe als Parameter Java Basics - Anfänger-Themen 1
H Höhe eines binäurbaums. Java Basics - Anfänger-Themen 7
B Wie kann ich die Buchstaben sortieren nach der Höhe der Zahlen Java Basics - Anfänger-Themen 14
P Shape Zeichnen klappt nicht - einlesen der Breite/Höhe schon Java Basics - Anfänger-Themen 1
I HTML Tabelle nur so lange erzeugen bis Höhe erreicht Java Basics - Anfänger-Themen 9
H Höhe einer Komponente an Textinhalt anpassen Java Basics - Anfänger-Themen 4
K JComboBox hat volle Höhe uber das gesamte JPane, warum? Java Basics - Anfänger-Themen 2
B Binärbaum höhe herausfinden Java Basics - Anfänger-Themen 12
R Höhe eines B-Baums Java Basics - Anfänger-Themen 3
L variable <div> höhe Java Basics - Anfänger-Themen 6
N Rekursive Berechnung der Höhe eines binären Baumes Java Basics - Anfänger-Themen 4
dummy2 Negative Höhe / Breite bei Figuren Java Basics - Anfänger-Themen 2
dummy2 Breite / Höhe Java Basics - Anfänger-Themen 4
M Binärer Suchbaum Höhe Java Basics - Anfänger-Themen 6
L Höhe eines Baumes Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben