如何通过FormLayout缩小带有自动换行的JTextArea?

时间:2016-10-31 23:04:49

标签: java swing layout-manager jtextarea word-wrap

我需要一个不可编辑的可自行编排的文本标签/字段/区域,没有滚动条,它的父级调整大小而没有滚动条。它将用于显示各种大小的文本,但“总是”有足够的空间来显示全文。在极少数情况下,用户调整窗口的大小以至于它不适合,我希望它能够截断行/垂直。

我一直在搜索很多并阅读我在这里找到的任何相关问题,而没有找到问题的根源。由于其自动换行功能,我选择了JTextArea。我也尝试了JLabel的自定义扩展,但问题仍然存在,所以我想我也可以坚持JTextArea。由于多种原因,HTML方法是我真正想要避免的。这不是我第一次碰到这个问题,我之前通过妥协布局(以不同的方式设计表格)解决了这个问题。这肯定不是我最后一次面对这个问题,所以我认为我需要找到一种方法而不是继续妥协。

问题在于,虽然这最初按预期工作,并且当窗口调整为水平放大时,水平缩小窗口不会更新自动换行,因此JTextArea会被水平截断。

我的测试表明,这仅适用于某些布局管理器,但我不确定问题实际存在于“什么级别”。我还在某处读过这个问题只存在于Windows上,但我还没有验证/测试过。我正在使用Windows进行开发,所以我所知道的就是问题出在我身边,并且存在于Java 7和Java 8中。

测试不同的布局管理器已显示:

  • FormLayout:缩小时不会重新换行。
  • MigLayout:收缩时不会重新换行。
  • GridBagLayout:它在缩小时重新换行,但不正确,因此隐藏了一些文本。
  • BorderLayout:按预期工作。
  • BoxLayout:如果axis设置为Y_AXIS,则按预期工作。设置为X_AXIS时的行为类似于FormLayout或MigLayout。
  • GridLayout:按预期工作。
  • CardLayout:按预期工作。

现有的应用程序广泛使用FormLayout,如果没有进行大量的重写,我无法改变它。只需在层次结构中进一步使用其中一个“已损坏”布局时,将JTextAreaJPanel一起包含其中一个工作布局(例如BorderLayout)就无济于事。似乎有一些信号丢失而且没有到达孩子们,所以我陷入困境,因为我无法真正摆脱FormLayout一直到层次结构的顶部。

这里有几个非常相似的问题,但很多问题与JTextAreaJScrollPane或其他一些细微差异有关,而且没有一个能帮助我找到有效的解决方案。通过尽可能缩小问题范围并提供有效的SCCEE,我希望不要作为副本被拒绝。

SCCEE:

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.RowSpec;
import javax.swing.JTextArea;



public class MainFrame {

    private JFrame frame;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            public void run() {
                try {
                    MainFrame window = new MainFrame();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public MainFrame() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                final JPanel panel = new JPanel(new FormLayout(
                    new ColumnSpec[] {ColumnSpec.decode("pref:grow"),},
                    new RowSpec[] {RowSpec.decode("pref:grow"),}
                ));
                frame.getContentPane().add(panel, BorderLayout.CENTER);
                final JTextArea textArea = new JTextArea();
                panel.add(textArea, "1, 1, fill, fill");
                textArea.setLineWrap(true);
                textArea.setText("Lorem ipsum dolor sit amet, ut eum assum debet tacimates, mei nisl electram moderatius ei, veri semper cotidieque eu pri. In quot noster vocent usu, ne augue voluptaria quo. Ex per malis vocibus. Consequat mediocritatem no vel.");
    }
}

1 个答案:

答案 0 :(得分:1)

您可以设置列大小...但您也可以将文本区域的setPreferredSize设置为0,0

import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;

public class Test extends JFrame {
    final JPanel panel;
    final JTextArea textArea;
    final FormLayout fl;
    public Test() {
        this.setBounds(100, 100, 450, 300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        fl = new FormLayout(
                new ColumnSpec[] {ColumnSpec.decode("pref:grow"), 
//                      ColumnSpec.decode("pref:grow")
                        },
                new RowSpec[] {RowSpec.decode("pref:grow"), 
//                      RowSpec.decode("pref:grow")
                        }
            );
        panel = new JPanel(fl);
        this.getContentPane().add(panel, BorderLayout.CENTER);
        textArea = new JTextArea();
        textArea.setPreferredSize(new Dimension());

        panel.add(new JPanel().add(textArea), "1, 1, fill, fill");
//        panel.add(new JPanel().add(new JLabel("test")), "1, 2, fill, fill");
//        panel.add(new JPanel().add(new JLabel("test")), "2, 1, fill, fill");
        textArea.setLineWrap(true);
//        textArea.setWrapStyleWord(true);
        textArea.setText("Lorem ipsum dolor sit amet, ut eum assum "
                + "debet tacimates, mei nisl electram moderatius ei, veri semper cotidieque eu pri. In quot noster vocent usu, "
                + "ne augue voluptaria quo. Ex per malis vocibus. Consequat mediocritatem no vel.");
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Test().setVisible(true);
            }
        });
    }
}