包装JTextArea的空间不足,无法窃取空间

时间:2019-04-28 11:34:12

标签: java swing

似乎包装纸(setLineWrap(true)JTextArea没有足够的空间,因此被切掉了:
JTextArea cut off

两次将父级布局制作为其子级似乎可以解决此问题:
JTextArea proper size

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Collectors;

import javax.swing.JFrame;
import javax.swing.JTextArea;

public class JTextAreaTest {
    public static void main(String[] args) throws InvocationTargetException, InterruptedException {
        SwingUtilities.invokeAndWait(() -> {
            Arrays.asList(true, false).forEach(packTwice -> {
                testWrappingCutOff(packTwice);
            });
        });
    }

    private static void testWrappingCutOff(boolean packTwice) {
        JFrame frame = new JFrame("packTwice: " + packTwice);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JTextArea wrapping = new JTextArea();
        wrapping.setLineWrap(true);
        wrapping.setText(Collections.nCopies(10, "wrapping").stream().collect(Collectors.joining(" ")));
        frame.add(wrapping);

        frame.pack();
        // Second call to pack() solves the problem
        if (packTwice) {
            frame.pack();
        }

        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
}

另外,当它与其他组件一起使用时,会“窃取”它们之间的空间。即当其他组件位于JScrollPane内时,即使它们的公共父组件可以被放大以适合这两个组件,它们也会获得滚动条:
JTextArea stealing space

两次调用pack()可以再次解决此问题:
Both components properly layed out

将父母安排两次是很不方便的,而且不一定总是可行。

  • 我使用了不正确的课程吗?
  • 这是已知限制吗,因为只有在知道有多少可用空间后才能进行包装?
  • 这是Swing的(尚未报告)错误吗?
  • 还是还有其他问题?

1 个答案:

答案 0 :(得分:1)

摆动组件确定自己喜欢的尺寸。通常通过执行以下操作来完成此操作:

JTextArea textArea = new JTextArea(5, 20);

因此,文本区域可以调整大小,以显示5行数据和20个“ W”字符。通常,然后将JTextArea添加到JScrollPane以在需要时显示滚动条。

但是,我猜这不是您真正想要的。您正在尝试使文本完全适合JTextArea。问题在于文本区域不知道如何计算自己的首选大小,因为它不知道该文本区域要使用什么宽度。

第一个pack()将导致框架的宽度为标题栏组件的宽度,这意味着将调整文本区域的大小以填充内容窗格的宽度。现在,对于第二个pack(),文本区域可以知道其当前宽度来计算其首选高度。

您可以通过使用类似以下内容的文本区域提示来避免使用第二个pack():

wrapping.setSize(200, 1);

现在,文本区域的大小在第一个pack()之后。