Layoutprobleme JPanel

ich habe mal wieder ein problem. dieses mal geht ein jpanel in dem ich mehrere andere jpanels einfüge.
ich habe ein jscrollpane, in dieses füge ich ein jpanel ein. nun möchte ich daten zeilenweise darstellen. und für jede datei brauch ich ein jradiobutton für die selektion und 2 jbutton (zum editieren und löschen).
wie auf dem bild zu sehen ist werden die panels über die ganze höhe angezeigt, das möchte ich nicht die sollen so hoch wie die buttons sind, evtl bissle höher.

dafür habe ich eine klasse, die stellt ein eintrag dar.


	private JPanel btnPanel = null;
	private JButton del = null;
	private JButton edit = null;
	private JRadioButton sel = null;
	private final ImageIcon trashicon = new ImageIcon(
			"src/main/resources/icons/trash-icon.png");
	private final ImageIcon editicon = new ImageIcon(
			"src/main/resources/icons/edit-icon.png");

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public FWConPanel(JRadioButton radiobtn, int width) {
		this.sel = radiobtn;
		btnPanel = new JPanel();
		btnPanel.setLayout(new GridLayout(1, 2));
		btnPanel.setBackground(Color.WHITE);
		del = new JButton();
		del.setIcon(trashicon);
		del.setPreferredSize(new Dimension(24, 24));
		edit = new JButton();
		edit.setPreferredSize(new Dimension(24, 24));
		edit.setIcon(editicon);
		btnPanel.add(edit);
		btnPanel.add(del);
		this.setLayout(new BorderLayout());
		this.add(sel, BorderLayout.CENTER);
		this.add(btnPanel, BorderLayout.EAST);
		this.setBackground(Color.WHITE);
		this.setPreferredSize(new Dimension(width, 30));
	}

}```

aufruf und einfügen der einträge sieht so aus:
```	private void createRadioButtons() {
		// TODO Auto-generated method stub
		btnpanel.setLayout(new BoxLayout(btnpanel, BoxLayout.Y_AXIS));
		btnpanel.setPreferredSize(new Dimension(330, 24 * fwconfigs.size()));
		for (int i = 0; i < fwconfigs.size(); i++) {
			JRadioButton tmpbtn = new JRadioButton(fwconfigs.get(i).getName());
			tmpbtn.addItemListener(it);
			tmpbtn.setBackground(Color.WHITE);
			btngrp.add(tmpbtn);
			btnpanel.add(new FWConPanel(tmpbtn, btnpanel.getWidth()));

		}
		btnpanel.revalidate();
		btnpanel.repaint();
	}```

das setzen von preferredsize bringt leider nichts auch setsize bringt keine feste höhe der eingefügen jpanels.

habe das ganze auch schon mit einer jlist und eigenem renderer versucht, dann habe ich aber probleme mit den buttons (da diese ja dann nur angezeigt werden, aber net wirklich aktiv beim klick)

hat jmd eine idee wie man dies lösen könnte habe es auch shcon mit dem Gridlayout versucht, aber das hatte den selben effekt.


ein ausführbare beispiel (man muss noch die FWConPanel-Klasse erstellen und von oben kopieren):

```public class KSKKB extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private final JPanel contentPane, panel;
	private final ButtonGroup btngrp = new ButtonGroup();
	private final String[] names = { "test", "test2", "test3" };

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				try {
					KSKKB frame = new KSKKB();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public KSKKB() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 475);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);

		JScrollPane scrollPane = new JScrollPane();
		contentPane.add(scrollPane, BorderLayout.CENTER);

		panel = new JPanel();
		panel.setBackground(Color.WHITE);
		scrollPane.setViewportView(panel);
		panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
		createRadioButtons();
	}

	private void createRadioButtons() {
		// TODO Auto-generated method stub
		panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
		panel.setPreferredSize(new Dimension(330, 24 * names.length));
		for (int i = 0; i < names.length; i++) {
			JRadioButton tmpbtn = new JRadioButton(names**);
			tmpbtn.setBackground(Color.WHITE);
			btngrp.add(tmpbtn);
			panel.add(new FWConPanel(tmpbtn, panel.getWidth()));

		}
		panel.revalidate();
		panel.repaint();
	}

}```

Da Du das Ganze in den CENTER Bereich eines BorderLayouts einfügst wird das JScrollPane und damit auch dessen Viewport auf die gesamte verfügbare Höhe aufgezogen. Hilfreich wäre da sicherlich ein flexibleres Layout evlt. GridBagLayout. (z.B. Panel mit Box/GridLayout mit den Komponenten füllen, dieses Panel in ein Panel mit GridBagLayout (Ausrichtung PAGE_START) und letzteres wiederum in die JScrollPane.

Alternativ wäre auch ein JTable denkbar. Hier dürfte aber die Abbildung der Funktionalität einer Buttongroup aufwändiger werden.

das BorderLayout benutze ich für das kleine jpanel, welches die buttons und radiobutton enthält. diese jpanels füge ich in ein jpanel ein welches mit dem boxlayout arbeitet und diese panel mit dem boxlayout ist im viewport meiner jscrollpane. daher dürfte doch das nichts aus machen? meine jscrollpane sieht ja nur das jpanel mit dem boxlayout.

Ich meinte das BorderLayout im Frame, in das die JScrollPane eingefügt wird. Das in der Komponente passt ja.

aso das ist aber nur in dem ausführbaren beispiel, in meinem eigentlichen programm habe ich die scrollpane in einem panel das mit null-layout arbeitet (ja ich weis - böse, aber ist wieder mit dem gui-builder erstellt und ich habe nur noch bis freitag, daher habe ich keine zeit um mich tiefer in die layouts einzuarbeiten)

Das einfachste ist meiner Meinung das von mir im ersten Post vorgeschlagenen Vorgehen mit GridBagLayout (s. ab Zeile 20):

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 450, 475);

JPanel listPanel = new JPanel(new GridLayout(0, 1));
ButtonGroup group = new ButtonGroup();
for (int i=0; i<5; i++) {
	JPanel panel = new JPanel(new BorderLayout());
	panel.setBackground(Color.WHITE);
	AbstractButton comp;
	panel.add(comp = new JRadioButton("test " + i), BorderLayout.CENTER);
	group.add(comp);
	comp.setOpaque(false);
	panel.add(comp = new JButton("o"), BorderLayout.EAST);
	comp.setOpaque(false);
	listPanel.add(panel);
}

//insert the list component in a GridBagLayout
JPanel viewPort = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.PAGE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = 1;
gbc.weightx = 1d;
gbc.weighty = 1d;
viewPort.add(listPanel, gbc);

frame.add(new JScrollPane(viewPort));
frame.setVisible(true);```

ok danke für deine hilfe, nur noch ein frage was ist dieses ld in zeile 25 und 26 ?

Nicht “klein L” sondern 1 (eins) und d (= double). Damit wird die Zahl als double Wert markiert, da das Attribute weight… als double deklariert ist - ist hier aber nicht unbedingt notwendig.

aso :smiley: ok dann spiel ich mal mit dem gridbaglayout rum, vielen dank

Die ganzen manuellen Berechnungen von Preferred Sizes sind alle für die Katz. Wenn du einen Layoutmanager hast, wirft der das meistens über den Haufen. Das einzige wo das was bringt, ist bei den untersten Komponenten in der Hierarchie, wie den Buttons und auch da funktioniert das nur wenn der Layoutmanager mitspielt. Das verschachteln von Panels bringt dann auch meistens mehr Probleme und noch mehr Unübersichtlichkeit.

Probier mal den Code, ich hab leider deine Icons nicht aber ich denke so sollte das aussehen:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class KSKKB extends JFrame
{
	class FWConPanel extends JPanel
	{
		
		private JPanel btnPanel = null;
		private JButton del = null;
		private JButton edit = null;
		private JRadioButton sel = null;
		private final ImageIcon trashicon = new ImageIcon("src/main/resources/icons/trash-icon.png");
		private final ImageIcon editicon = new ImageIcon("src/main/resources/icons/edit-icon.png");
		
		/**
            *
            */
		private static final long serialVersionUID = 1L;
		
		public FWConPanel(JRadioButton radiobtn)
		{
			this.sel = radiobtn;
			del = new JButton();
			del.setIcon(trashicon);
			del.setPreferredSize(new Dimension(24, 24));
			edit = new JButton();
			edit.setPreferredSize(new Dimension(24, 24));
			edit.setIcon(editicon);
			this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
			this.add(sel);
			this.add(Box.createHorizontalGlue());
			this.add(del);
			this.add(edit);
			this.setBackground(Color.WHITE);
			
		}
		
	}
	
	/**
    *
    */
	private static final long serialVersionUID = 1L;
	private final JPanel contentPane, panel;
	private final ButtonGroup btngrp = new ButtonGroup();
	private final String[] names = { "test", "test2", "test3" };
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args)
	{
		EventQueue.invokeLater(new Runnable()
			{
				@Override
				public void run()
				{
					try
					{
						KSKKB frame = new KSKKB();
						frame.setVisible(true);
					} catch (Exception e)
					{
						e.printStackTrace();
					}
				}
			});
	}
	
	/**
	 * Create the frame.
	 */
	public KSKKB()
	{
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 475);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
		
		JScrollPane scrollPane = new JScrollPane();
		contentPane.add(scrollPane, BorderLayout.CENTER);
		
		panel = new JPanel();
		panel.setBackground(Color.WHITE);
		scrollPane.setViewportView(panel);
		panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
		createRadioButtons();
		panel.add(Box.createVerticalGlue());
	}
	
	private void createRadioButtons()
	{
		// TODO Auto-generated method stub
		panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
		for (int i = 0; i < names.length; i++)
		{
			JRadioButton tmpbtn = new JRadioButton(names**);
			tmpbtn.setBackground(Color.WHITE);
			btngrp.add(tmpbtn);
			panel.add(new FWConPanel(tmpbtn));
			
		}
		panel.revalidate();
		panel.repaint();
	}
	
}

Eventuell kannst du ja auch beim BoxLayout mit Box.createGlue(); etwas erreichen.
Ist sicher nicht schick aber wenns ma schnell gehen muss nen Versuch wert.

Und warum nicht einfach 'ne [JAPI]JTable[/JAPI] mit 'nem passenden [JAPI]TableModel[/JAPI]?

bye
TT

Weil Buttons in einer JTable ganz andere Probleme aufwerfen und so ohne weiteres nicht funktionieren.