java - Java Swing 中类似文本的 JPanel 换行

标签 java swing user-interface

总之,我想用swing来实现这样的布局:

enter image description here

注意两个主要目标:

  • JPanel 表现得像文本,它们被包裹到窗口的宽度, 如果空间不足,它们会被包装到下一个“行” JPanels。

  • 没有水平滚动,但有垂直滚动 授予查看窗口中所有可能元素的权限。

Nick Rippe 提供了一个几乎完成的解决方案 below ,可见here作为独立的 java 程序,带有我更新的更随机的最内层文本区域字符串和左对齐。

最后一步是修复 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 );
    }
}

最佳答案

您的问题是计算面板 C 的首选尺寸。此首选尺寸需要被覆盖(宽度)并包含默认高度。

我制作了一个演示,以便您可以了解如何完成此操作:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class APanel extends JScrollPane {

    int width = 0;

    public APanel(){
        super();        

        final Box B = Box.createVerticalBox();

        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{

        //Test Data - not necessary
        static StringBuffer fillerString;
        static {
            fillerString = new StringBuffer();
            int i = 0;
            for(char c = '0'; c < 'z'; c++){
                fillerString.append(c);
                if(i++ %10 == 0){
                    fillerString.append('\n');
                }
            }
        }

        public CPanel(){
            super(new WrapLayout());
            setOpaque(true);
            setBackground(Color.gray);

            //Adding test data (TextAreas)
            for(int i = 0; i < 9; i++){
                JTextArea ta = new JTextArea(fillerString.toString());
                ta.setAlignmentX(LEFT_ALIGNMENT);
                add(ta);
            }

            setBorder(BorderFactory.createTitledBorder("Lovely container"));
        }
    }

    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);
    }

}

关于java - Java Swing 中类似文本的 JPanel 换行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13250043/

相关文章:

java - 赋予一个类以扩展一个Java的值(value)

java - JTextPane - 获取组件值

java - 添加自定义 JComponent 时未调用 paintComponent

java - 为什么我会收到 InvalidDnDOOperationException?

android - ScrollView 内的图像网格

ios - 正在调用我的委托(delegate)函数,但我的 UI 仍然没有相应更新

java - 使用java删除另一个双引号内的双引号

java - 如何解析 OpenWeatherMap 16 天 json?

java - 在 JTable 中监听 KeyEvent - 如何在编辑单元格时执行此操作?

python-3.x - Pyqt5 方法关闭或删除小部件并根据命令重新设置它