Tengo un panel donde coloco varios mini paneles, uno al lado del otro, con diferentes tamaños y colores, y deben ocupar todo el panel principal (horizontalmente).JPanels no se extienden por completo para ocupar el espacio disponible
Para esto utilizo BorderLayout (para el panel padre), y BoxLayout para un subpanel donde coloco todos los mini paneles (vea el código a continuación). Funciona y se comporta correctamente al cambiar el tamaño y todo. Sin embargo, a medida que aumenta el número de mini paneles, se produce un comportamiento extraño: aparece espacio vacío al final del panel principal.
Creo que he encontrado que esto es un error estiramiento en los controladores de distribución, porque a fin de estirar los paneles, el controlador de distribución intenta añadir un solo píxel de cada mini-panel. Sin embargo, cuando el número de mini paneles es grande, agregar un solo píxel a cada uno dará como resultado la adición de muchos píxeles y más allá del tamaño del elemento principal. Por lo tanto, el administrador de diseño termina sin agregar píxeles a ningún mini panel, lo que resulta en el espacio vacío.
Aquí es mi SSCCE: (intente ejecutar, y streching la ventana, para entender el problema)
package com.myPackage;
import java.awt.*;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ColoredPanels extends JPanel
{
/* Content information. */
private Vector<Integer> partitions;
private Vector<Color> colors;
/* Panel where the content panels will go. */
private JPanel contentHolder;
private final int defaultHeight = 20;
public ColoredPanels(Vector<Integer> partitions, Vector<Color> colors)
{
assert partitions != null;
assert !partitions.isEmpty();
assert colors != null;
assert !colors.isEmpty();
assert colors.size() == partitions.size();
this.partitions = partitions;
this.colors = colors;
/* Set layout manager. */
setLayout(new BorderLayout());
/* Create the content holder. */
contentHolder = new JPanel();
contentHolder.setLayout(new BoxLayout(contentHolder, BoxLayout.X_AXIS));
this.add(contentHolder, BorderLayout.NORTH);
/* Fill content holder with colored panels. */
createPanels();
}
private void createPanels()
{
assert partitions != null;
assert !partitions.isEmpty();
assert colors != null;
assert !colors.isEmpty();
assert colors.size() == partitions.size();
for (int i = 0; i < partitions.size(); i++)
{
JPanel newPanel = new JPanel();
newPanel.setBackground(colors.get(i));
newPanel.setPreferredSize(new Dimension(partitions.get(i), defaultHeight));
newPanel.setMinimumSize(new Dimension(1, defaultHeight));
contentHolder.add(newPanel);
}
}
public static void main(String[] in)
{
Vector<Integer> sizes = new Vector<Integer>();
Vector<Color> cols = new Vector<Color>();
/* Make 100 random sizes, and use two colors. */
for (int i = 0; i < 100; i++)
{
int size = (int)Math.round(1 + Math.random() * 10);
sizes.add(size);
cols.add((i%2 == 0)? Color.red : Color.green);
}
ColoredPanels panels = new ColoredPanels(sizes, cols);
panels.setBorder(BorderFactory.createLineBorder(Color.yellow, 1));
JFrame newFrame = new JFrame();
newFrame.getContentPane().add(panels);
newFrame.pack();
newFrame.setVisible(true);
}
}
¿Cómo puedo evitar este comportamiento? Quiero que mis paneles ocupen todo el contenedor.
EDIT: Los mini paneles tienen la intención de tener (una vez que esto se resuelva) los oyentes del mouse. Por lo tanto, las soluciones de pintura son desafortunadamente evitables.
muy bonito SSCCE +1 – mKorbel
interesante ... ¿qué quieres que suceda? El camino más fácil (probablemente no el mejor :-) sería dar todo el espacio de redondeo al último ... – kleopatra
Quiero que los mini paneles llenen por completo el espacio disponible. Dar lo último a lo último no es una opción, ya que se deben respetar las proporciones de tamaño de la partición. – Anoyz