Ho un pannello in cui posiziono diversi mini-pannelli, affiancati, con dimensioni e colori diversi, e dovrebbero occupare l'intero pannello genitore (orizzontalmente).JPanel non si allungano completamente per occupare lo spazio disponibile
Per questo utilizzo BorderLayout (per il pannello padre) e BoxLayout per un pannello secondario in cui posiziono tutti i mini-pannelli (vedere il codice seguente). Funziona e si comporta correttamente con il ridimensionamento e tutto. Tuttavia, poiché il numero di mini-pannelli diventa più grande, si verifica uno strano comportamento: lo spazio vuoto appare alla fine del pannello genitore.
penso che ho trovato che questo è un bug streching nei gestori di layout, perché per strech i pannelli, il gestore di layout tenta di aggiungere un singolo pixel per ogni mini-pannello. Tuttavia, quando il numero di mini-pannelli è ampio, l'aggiunta di un singolo pixel a ognuno comporterà l'aggiunta di molti pixel e oltre la dimensione del genitore. Pertanto, il gestore di layout non aggiunge alcun pixel a nessun mini-pannello, risultando nello spazio vuoto.
Ecco il mio SSCCE: (provare a eseguire, e streching la finestra, per capire il 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);
}
}
Come posso evitare questo comportamento? Voglio che i miei pannelli occupino l'intero contenitore.
EDIT: I mini-pannelli sono destinati ad avere (una volta che questo è stato risolto) ascoltatori del mouse. Pertanto, le soluzioni di verniciatura sono sfortunatamente evitabili.
molto bello SSCCE +1 – mKorbel
interessante ... cosa vuoi succedere? La soluzione più semplice (probabilmente non la migliore :-) sarebbe quella di dare tutto lo spazio di arrotondamento all'ultimo ... – kleopatra
Voglio che i mini pannelli riempiano completamente lo spazio disponibile. Dare il rimanente all'ultimo non è un'opzione, dal momento che i rapporti delle dimensioni delle partizioni devono essere rispettati. – Anoyz