简而言之,我想使用swing实现这种布局:

注意两个主要目标:
- JPanels 表现为文本,它们被包裹到窗口的宽度,并且在空间不足的情况下,它们被包裹到 JPanel 的下一个“行”。 
- 没有水平滚动,但存在垂直滚动以提供查看窗口中所有可能元素的访问权限。 
Nick Rippe 在下面提供了一个几乎完成的解决方案,在这里可以将其视为独立的 java 程序,其中包含我更新的更随机的最内层 textarea 字符串和左对齐。
最后一步是修复 CPanel 中文本区域的每一行顶部对齐:
((WrapLayout)getLayout()).setAlignOnBaseline( true );
完整的解决方案:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.Border;
public class APanel extends JScrollPane {
    int width = 0;
    public static String getRandomMultilineText() {
        String filler = "";
        int words = (int) (Math.random() * 7) + 1;
        for ( int w = 0 ; w < words ; w++ ) {
            int lettersInWord = (int) (Math.random() * 12) + 1;
            for ( int l = 0 ; l < lettersInWord ; l++ ) {
                filler += "a";
            }
            filler += "\n";
        }
        return filler.trim();
    }
    public APanel() {
        super();
        setAlignmentX( LEFT_ALIGNMENT );
        setAlignmentY( TOP_ALIGNMENT );
        final Box B = Box.createVerticalBox();
        B.setAlignmentX( LEFT_ALIGNMENT );
        B.setAlignmentY( TOP_ALIGNMENT );
        for ( int i = 0 ; i < 4 ; i++ ) {
            B.add( new CPanel() {
                //Important!!! Make sure the width always fits the screen
                public Dimension getPreferredSize() {
                    Dimension result = super.getPreferredSize();
                    result.width = width - 20; // 20 is for the scroll bar width
                    return result;
                }
            } );
        }
        setViewportView( B );
        //Important!!! Need to invalidate the Scroll pane, othewise it
        //doesn't try to lay out when the container is shrunk
        addComponentListener( new ComponentAdapter() {
            public void componentResized( ComponentEvent ce ) {
                width = getWidth();
                B.invalidate();
            }
        } );
    }
    // nothing really very special in this class - mostly here for demonstration
    public static class CPanel extends JPanel {
        public CPanel() {
            super( new WrapLayout( WrapLayout.LEFT ) );
            ((WrapLayout)getLayout()).setAlignOnBaseline( true);
            setOpaque( true );
            setBackground( Color.gray );
            setAlignmentY( TOP_ALIGNMENT );
            setAlignmentX( LEFT_ALIGNMENT );
            int wordGroups = (int) (Math.random() * 14) + 7;
            //Adding test data (TextAreas)
            for ( int i = 0 ; i < wordGroups ; i++ ) {
                JTextArea ta = new JTextArea( getRandomMultilineText() );
                ta.setAlignmentY( TOP_ALIGNMENT );
                ta.setAlignmentX( LEFT_ALIGNMENT);
                add( ta );
            }
            Border bx = BorderFactory.createTitledBorder( "Lovely container" );
            setBorder( bx );
        }
    }
    public static void main( String[] args ) {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.add( new APanel() );
        frame.pack();
        frame.setSize( 400 , 300 );
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );
    }
}