Java Swing中类似文本的JPanel包装 [英] Text-like JPanel wrapping in Java Swing

查看:36
本文介绍了Java Swing中类似文本的JPanel包装的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In short, I want to achieve this layout using swing:

注意两个主要目标:

  • JPanels 表现为文本,它们被包裹到窗口的宽度,如果空间不足,它们将被包装到下一个行"JPanels.

  • JPanels behaves as text, they are wrapped to width of a window, and in case of lack of space, they are wraped to next "lines" of JPanels.

没有水平滚动,但存在垂直滚动拥有查看窗口中所有可能元素的权限.

There is no horizontal scorll, but vertical scroll is present to privide access to view all possible elements in window.

Nick Rippe 提供了一个几乎完成的解决方案下面,可以看出此处 作为独立的 Java 程序,其中包含我更新的更随机的最内部文本区域字符串和左对齐.

Nick Rippe provided an almost done solution below, it can be seen here as standalone java program with my updated more-random innermost textarea strings and left aligment.

最后一步是在CPanel中修复textareas的每行顶部对齐:

The last step is to fix each-row top alignment of textareas in 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 的首选尺寸.这个首选尺寸需要被覆盖(对于宽度)并包含默认高度.

Your problem is your calculation of your preferredSize of panel C. This preferred size needs to both be overridden (for the width) and contain the default height.

我已经整理了一个演示,以便您了解如何做到这一点:

I've put together a demonstration so you can see how this would be done:

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 Swing中类似文本的JPanel包装的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆