使用GridBagLayout使用太多空间行包装JTextArea

时间:2014-05-22 09:49:25

标签: java swing jscrollpane gridbaglayout

我一直试图让一个可滚动的JTextArea出现在JList的右边,其中JTextArea占用了大部分空间,但为JList留下了很好的部分(JTextArea的帧的3/4) ,JList为1/4)。问题是当JTextArea上的LineWrap设置为true时,似乎忽略了约束的权重。

没有换行,JTextArea占据了帧的大约3/4,而JList占用了另外1/4,这就是我想要的。但是当打开换行时,JTextArea会尝试占用尽可能多的空间并将JList压缩到它包含的字符串的宽度。有趣的是,只有在调整窗口大小时才会出现这种情况(最初看起来很好),如果在JTextArea中输入任何内容,它会慢慢扩展,推回JList。这至少让我感到困惑。

我制作了一个屏幕截图,显示了在调整窗口大小后没有换行和换行的情况: Example

这里有一些示例代码,向您展示我的意思。删除换行语句,它看起来很好,但保留它们,你会看到在调整大小时,JList被压扁。

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

import javax.swing.*

public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel(new GridBagLayout());

        JTextArea area = new JTextArea();
        DefaultListModel<String> model = new DefaultListModel<>();
        JList<String> list = new JList<String>(model);
        JScrollPane scroll = new JScrollPane(area,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

        for (int i = 0; i < 5; i++)
            model.addElement("Example" + i);

        area.setLineWrap(true);
        area.setWrapStyleWord(true);

        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.fill = GridBagConstraints.BOTH;
        c.weighty = 1;
        c.weightx = 0.3;
        panel.add(scroll, c);

        c = new GridBagConstraints();
        c.gridx = 1;
        c.fill = GridBagConstraints.BOTH;
        c.weighty = 1;
        c.weightx = 0.1;
        panel.add(list, c);

        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500, 300);
        frame.setVisible(true);

    }
}

4 个答案:

答案 0 :(得分:2)

您可以使用ipadx定义最小可能宽度

    c.weightx = 0.1;
    c.ipadx=desiredPixelsWidthForTheList;
    panel.add(list, c);

更新

此外,您可以将它们放在JSplitPane中并定义所需的比例。

答案 1 :(得分:2)

简短的回答是文本区域的宽度超出了你想要的宽度,因为它的首选宽度远大于列表的宽度。

请注意, weightx 不会确定组件占用的空间百分比,而是确定添加到组件大小或从组件大小中删除的比例空间 。在这种情况下,例如,“额外”空间是您明确设置为500的框架宽度(或更准确地说,其内容窗格的宽度)与文本区域和列表的组合宽度之间的差异。换句话说,滚动窗格/文本区域和列表都将以其优选大小显示,加上文本区域的剩余空间的75%和列表的25%。同样,由于文本区域的首选大小一开始就很大,它占据屏幕的大部分比你想要的大。

正如一些人已经指出的那样,获得所需结果的一种简单方法是明确指定文本区域的行数和列数。另一方面,您应该避免明确设置大小,首选或其他方式,如this之类的问题所述。

就神秘缩小的列表而言,我怀疑GridBagLayout中存在一个错误。它似乎最初忽略了JList的最大大小,但是当它因为帧大小调整而放置组件时会尊重它,这就是它突然缩小然后再也不会变大的原因。这通常不是问题,因为像JTextArea一样,JList通常包含在滚动窗格中,这是您应该考虑的事情。

答案 2 :(得分:0)

尝试使用.setPreferredSize()到组件

答案 3 :(得分:0)

我修改了你的代码。刚刚指定了textarea的大小并列出了这样的

list.setPreferredSize(new Dimension(frame.getWidth()/4, frame.getHeight()));
area.setPreferredSize(new Dimension(frame.getWidth()*(3/4), frame.getHeight()));

检查以下完整代码:

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel(new GridBagLayout());

        JTextArea area = new JTextArea();
        DefaultListModel model = new DefaultListModel();
        JList list = new JList(model);
        JScrollPane scroll = new JScrollPane(area,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

        for (int i = 0; i < 5; i++)
            model.addElement("Example" + i);
        frame.setSize(500, 300);

        list.setPreferredSize(new Dimension(frame.getWidth()/4, frame.getHeight()));
        area.setPreferredSize(new Dimension(frame.getWidth()*(3/4), frame.getHeight()));
        area.setLineWrap(true);
        area.setWrapStyleWord(true);

        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.fill = GridBagConstraints.BOTH;
        c.weighty = 1;
        c.weightx = 0.3;


        panel.add(scroll, c);

        c = new GridBagConstraints();
        c.gridx = 1;
        c.fill = GridBagConstraints.BOTH;
        c.weighty = 1;
        c.weightx = 0.1;
        panel.add(list, c);

        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }
}