【问题标题】:JScrollPane words wrapJScrollPane 自动换行
【发布时间】:2012-04-30 02:00:18
【问题描述】:

我有问题。在 JScrollPane 中,我使用 JPanel 的继承者作为 viewPort。继承者可以包含标签、单选按钮、复选框和其他元素(取决于实现)。在 JScrollPane 中设置 HORIZONTAL_SCROLLBAR_​​NEVER。 JPanel 的继承者中的内容需要在垂直和水平滚动时换行。在标签中显示长文本时(特别是 html 标签)没有自动换行,尽管 HORIZONTAL_SCROLLBAR_​​NEVER。如果不使用 JScrollPane(JPanel 的继承者有具体大小)的话要被包裹,但我需要垂直滚动。

尝试设置侦听器以调整 JScrollPane 的大小并为内部 JPanel 设置必要的大小。不工作。设置侦听器以调整内部 JPanel 的大小。设置宽度后发生另一个变化(显然非常重要)。

我怎么解决这个问题?需要在垂直和水平自动换行中滚动。提前致谢。对不起,我的英语)。

例子(不好,后面更好)

import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.EmptyBorder;

public class Test extends JFrame
{

    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    Test frame = new Test();


                    JScrollPane scrollPane =  new JScrollPane();
                    scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
                    JPanel panel = new JPanel();
                    panel.add(new JLabel("<html>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</html>"));
                    scrollPane.setViewportView(panel);
                    frame.add(scrollPane);
                    frame.setVisible(true);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public Test()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);
    }

}

好例子

屏幕链接:http://s44.radikal.ru/i104/1204/4d/72ea56d685ee.png

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.JScrollPane;

public class Test extends JFrame
{

private JPanel contentPane;

/**
 * Launch the application.
 */
public static void main(String[] args)
{
    EventQueue.invokeLater(new Runnable()
    {
        public void run()
        {
            try
            {
                Test frame = new Test();
                frame.setVisible(true);

            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public Test()
{
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    GridBagLayout gbl_contentPane = new GridBagLayout();
    gbl_contentPane.columnWidths = new int[] { 0, 0 };
    gbl_contentPane.rowHeights = new int[] { 0, 0 };
    gbl_contentPane.columnWeights = new double[] { 1.0, Double.MIN_VALUE };
    gbl_contentPane.rowWeights = new double[] { 1.0, Double.MIN_VALUE };
    contentPane.setLayout(gbl_contentPane);

    JScrollPane scrollPane = new JScrollPane();
    GridBagConstraints gbc_scrollPane = new GridBagConstraints();
    gbc_scrollPane.fill = GridBagConstraints.BOTH;
    gbc_scrollPane.gridx = 0;
    gbc_scrollPane.gridy = 0;
    contentPane.add(scrollPane, gbc_scrollPane);

    JPanel panel = new JPanel();
    scrollPane.setViewportView(panel);
    scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);        
    GridBagLayout gbl_panel = new GridBagLayout();
    gbl_panel.columnWidths = new int[]{0, 0};
    gbl_panel.rowHeights = new int[]{0, 0};
    gbl_panel.columnWeights = new double[]{0.0, Double.MIN_VALUE};
    gbl_panel.rowWeights = new double[]{0.0, Double.MIN_VALUE};
    panel.setLayout(gbl_panel);

    JLabel lblNewLabel = new JLabel("<html>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</html>");
    GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
    gbc_lblNewLabel.gridx = 0;
    gbc_lblNewLabel.gridy = 0;
    panel.add(lblNewLabel, gbc_lblNewLabel);
}

 }

使用 `tag html` 在 JLabel 中换行的示例:

屏幕链接:http://s019.radikal.ru/i628/1204/75/d14b8fa81f15.png

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class Test extends JFrame
{

private JPanel contentPane;

/**
 * Launch the application.
 */
public static void main(String[] args)
{
    EventQueue.invokeLater(new Runnable()
    {
        public void run()
        {
            try
            {
                Test frame = new Test();
                frame.setVisible(true);

            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public Test()
{
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    GridBagLayout gbl_contentPane = new GridBagLayout();
    gbl_contentPane.columnWidths = new int[] { 0, 0 };
    gbl_contentPane.rowHeights = new int[] { 0, 0 };
    gbl_contentPane.columnWeights = new double[] { 0.0, Double.MIN_VALUE };
    gbl_contentPane.rowWeights = new double[] { 0.0, Double.MIN_VALUE };
    contentPane.setLayout(gbl_contentPane);

    JLabel lblNewLabel = new JLabel(
            "<html>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</html>");
    GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
    gbc_lblNewLabel.weightx = 1.0;
    gbc_lblNewLabel.fill = GridBagConstraints.BOTH;
    gbc_lblNewLabel.gridx = 0;
    gbc_lblNewLabel.gridy = 0;
    contentPane.add(lblNewLabel, gbc_lblNewLabel);
}

  }

【问题讨论】:

  • 请附上sscce 说明问题。
  • 简单地说。我需要在垂直和水平换行的 JScrollPane 中滚动内容。我使用 HORIZONTAL_SCROLLBAR_​​NEVER,但单词不换行。我在标签中使用 html 标签。
  • @gshadrin,正如我之前所说,请包括sscce
  • @gshadrin 请阅读 SSCCE 文档并发布 SSCCE 而不是代码 sn-ps!
  • @AndrewThompson,我发布了示例。

标签: java swing jscrollpane


【解决方案1】:

import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class Test extends JFrame {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Test frame = new Test();

                    JTextArea message = new JTextArea("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
                        ,6,40);
                    // make it look & act like a label
                    message.setWrapStyleWord(true);
                    message.setLineWrap(true);
                    message.setEditable(false);
                    message.setFocusable(false);
                    message.setOpaque(false);

                    JScrollPane scrollPane =  new JScrollPane(message,
                        ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                        ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
                        );
                    frame.add(scrollPane);
                    frame.pack();
                    frame.setVisible(true);
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public Test() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationByPlatform(true);
    }
}

【讨论】:

  • 谢谢。我理解你的例子。您限制列数。在我添加的问题中,如果使用html tag,JLabel 也可以自动换行,但不滚动。我可以使用 JLAbel 吗?如果我使用带有长文本的 JRadioButton 并且需要自动换行?
  • 虽然JLabel 可以使用 HTML 进行包装,但使用 HTML 会产生一些奇怪的结果,就像您观察到的那样。至于JRadioButton - “这是选择吗?”应该没有长文本。
  • 当它是 JScrollPane 的视口时,我认为内部 JPanel 的大小(我的 2 个示例“好示例”)会导致什么奇怪的结果。虽然使用 HORIZONTAL_SCROLLBAR_​​NEVER,但这个尺寸显然很大。使用滚动时显然是一个很大的原因。我想限制实际值的内部 JPanel 的大小(如 3 示例)。这是我的主要问题。内部 JPanel 的内容可以是任何内容(不仅是长文本)。
  • 如果使用JTextArea,则大小限制列数
【解决方案2】:

我认为你需要实现 Scrollable 接口。其实JTextArea也实现了Scrollable。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Rectangle;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.Scrollable;
import javax.swing.border.EmptyBorder;

public class TestScrollLabel extends JFrame
{

private JPanel contentPane;

/**
 * Launch the application.
 */
public static void main(String[] args)
{
    EventQueue.invokeLater(new Runnable()
    {
        public void run()
        {
            try
            {
                TestScrollLabel frame = new TestScrollLabel();
                JScrollPane scrollPane =  new JScrollPane();
                scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
                JPanel panel = new MyPanel();
                //BorderLayout is a good choice here
                panel.setLayout(new BorderLayout());
                panel.add(new JLabel("<html>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</html>"));
                scrollPane.setViewportView(panel);
                frame.add(scrollPane);
                frame.setVisible(true);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    });
}

static class MyPanel extends JPanel implements Scrollable{

    @Override
    public Dimension getPreferredScrollableViewportSize() {

        return this.getPreferredSize();
    }

    @Override
    public int getScrollableUnitIncrement(Rectangle visibleRect,
            int orientation, int direction) {
        return 50;
    }

    @Override
    public int getScrollableBlockIncrement(Rectangle visibleRect,
            int orientation, int direction) {
        return 80;
    }

    /*
     * (non-Javadoc)
     * @see javax.swing.Scrollable#getScrollableTracksViewportWidth()
     */
    @Override
    public boolean getScrollableTracksViewportWidth() {
        return true;
    }

    @Override
    public boolean getScrollableTracksViewportHeight() {
        return false;
    }

}

/**
 * Create the frame.
 */
public TestScrollLabel()
{
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);
}

}

【讨论】:

    【解决方案3】:

    JLabel 没有自动换行功能。您可以通过创建JTextArea 来模拟这种效果,使用setEditable(false) 将其设为只读,然后调用setWrapStyleWord(true) 以启用自动换行。

    我认为您也可以使用setBorder() 使其看起来更扁平,更像是一个普通的标签,但这可能会根据外观和感觉在不同平台上产生不同的效果。

    【讨论】:

    • 我添加示例。 JLabel 中的单词用 html tag 换行
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 2011-01-29
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多