Il problema nasce dal fatto che un JPanel inserito all'interno di uno JScrollPane perde la sua capacità di gestire correttamente il FlowLayout... e girando su altri forum ho trovato la soluzione adottando questo layout personalizzato:

codice:
package immagineX;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.util.LinkedList;

/**
 * A layout manager similar to FlowLayout but that will not cause the container to
 * grow in width.
 * @author pgi
 */
public class TableLayout implements LayoutManager {

    /** Creator */
    public static TableLayout newInstance() {
        return new TableLayout();
    }

    /** Default empty constructor, not used. */
    protected TableLayout() {
    }

    /**
     * Unused
     * @param name
     * @param comp
     */
    public void addLayoutComponent(String name, Component comp) {
    }

    /**
     * Unused
     * @param comp
     */
    public void removeLayoutComponent(Component comp) {
    }

    /**
     * The preferred layout size depends upon the actual width of the container.
     * The size is the width and the minumum height sufficient to display all
     * the children of the container along their preferred size.
     * @param parent
     * @return the preferred size for the parent container.
     */
    public Dimension preferredLayoutSize(Container parent) {
        synchronized (parent.getTreeLock()) {
            int width = parent.getWidth();
            int height = parent.getHeight();
            Insets margins = parent.getInsets();
            int availableWidth = width - margins.left - margins.right;
            Component[] children = parent.getComponents();

            RowBuilder rowBuilder = new RowBuilder(availableWidth);
            for (Component c : children) {
                rowBuilder.push(c);
            }

            Dimension dim = rowBuilder.computeSize();
            dim.width += margins.left + margins.right;
            dim.height += margins.top + margins.bottom;
            return dim;
        }
    }

    /**
     * Returns the preferred layout size.
     * @param parent the component to layout
     * @return the minimum layout size.
     */
    public Dimension minimumLayoutSize(Container parent) {
        return preferredLayoutSize(parent);
    }

    /**
     * Assign bounds to the child of the given container.
     * @param parent the container to layout
     */
    public void layoutContainer(Container parent) {
        synchronized (parent.getTreeLock()) {

            int width = parent.getWidth();
            int height = parent.getHeight();
            Insets margins = parent.getInsets();

            int availableWidth = width - margins.left - margins.right;
            int availableHeight = height - margins.top - margins.bottom;

            RowBuilder rowBuilder = new RowBuilder(availableWidth);

            for (Component c : parent.getComponents()) {
                rowBuilder.push(c);
            }

            rowBuilder.assignBounds(margins.left, margins.top);
        }
    }

    private static class RowBuilder {

        private LinkedList<Row> rows = new LinkedList<Row>();
        private int currentX;
        private final int width;
        private Row currentRow = new Row();

        private RowBuilder(int width) {
            this.width = width;
            rows.add(currentRow);
        }

        void push(Component c) {
            Dimension dim = c.getPreferredSize();
            if (currentX + dim.width >= width) {
                currentRow = new Row();
                rows.add(currentRow);
                currentX = 0;
            }
            currentX += dim.width;
            currentRow.add(c);
        }

        void assignBounds(int originX, int originY) {
            int y = originY;
            for (Row r : rows) {
                r.assignBounds(originX, y);
                y += r.getHeight();
            }
        }

        Dimension computeSize() {
            Dimension dim = new Dimension();
            for (Row r : rows) {
                dim.width = Math.max(dim.width, r.getWidth());
                dim.height += r.getHeight();
            }
            return dim;
        }
    }

    private static class Row {

        private LinkedList<Component> components = new LinkedList<Component>();
        private int height = 0;
        private int width = 0;

        void assignBounds(int originX, int originY) {
            int x = originX;
            for (Component c : components) {
                Dimension dim = c.getPreferredSize();
                c.setBounds(x, originY, dim.width, dim.height);
                x += dim.width;
            }
        }

        void add(Component c) {
            Dimension dim = c.getPreferredSize();
            components.add(c);
            height = Math.max(height, dim.height);
            width += dim.width;
        }

        int getWidth() {
            return width;
        }

        int getHeight() {
            return height;
        }
    }
}