如何在垂直滚动窗格中布局组件?

时间:2009-08-08 12:09:45

标签: java swing

我有一个复杂的问题我无法在任何地方找到答案。

这是一个例子:

public static void main(final String[] args) {
    final JFrame frame = new JFrame("test");
    final JPanel bigPane = new JPanel(new GridLayout(0, 1));
    frame.setContentPane(new JScrollPane(bigPane, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
            ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER));
    bigPane.add(new JTextField("reterterter ertertrert erterter ert"));
    bigPane.add(new JTextField(" ertertrert erterter ert"));
    bigPane.add(new JTextField("reterterter ertertrert  ert"));
    bigPane.add(new JTextField("reterterter ertertrert erterter "));
    frame.pack();
    frame.setSize(frame.getSize().width/2, frame.getSize().height);
    frame.setVisible(true);
}

在这里,显然文本字段被剪切了。更准确地说,bigPane被削减了。但我希望文本字段可以调整大小而不是剪切,所以我们仍然可以使用它们。

由于禁止出现水平滚动条,我希望布局忘记视图(bigPane)的首选宽度,并始终强制视图的宽度与视口的宽度相匹配。就像没有水平方向的虚拟视口一样,只有垂直方向。

如果你能提供帮助,我无法找到解决方案,甚至不是黑客攻击。

尼科。

PS:看起来ViewportLayout的代码不包含任何代码

PS2:以上代码http://www.nraynaud.com/kilombo/testLayout.png的结果上限见右侧。

3 个答案:

答案 0 :(得分:4)

我认为“正确”的方法是使用Scrollable接口:

public class ScrollPaneWidthTrackingPanel extends JPanel implements Scrollable {
    private static final long serialVersionUID = 1L;

    public ScrollPaneWidthTrackingPanel(LayoutManager layoutManager) {
        super(layoutManager);
    }

    public Dimension getPreferredScrollableViewportSize() {
        return getPreferredSize();
    }

    public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
        return Math.max(visibleRect.height * 9 / 10, 1);
    }

    public boolean getScrollableTracksViewportHeight() {
        return false;
    }

    public boolean getScrollableTracksViewportWidth() {
        return true;
    }

    public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
        return Math.max(visibleRect.height / 10, 1);
    }
}

然后必须将两行代码更改为:

final ScrollPaneWidthTrackingPanel bigPane = new ScrollPaneWidthTrackingPanel(new GridLayout(0, 1));
frame.setContentPane(new JScrollPane(bigPane));

组件应始终填充JScrollPane的整个宽度,无论框架的大小如何。此更改具有副作用,即组件现在不会填充JScrollPane的高度。要解决此问题,请将以下代码添加到getScrollableTracksViewportHeight方法的顶部:

if (getParent() instanceof JViewport) {
    JViewport viewport = (JViewport) getParent();
    return component.getPreferredSize().height < viewport.getHeight();
}

答案 1 :(得分:1)

使用以JTextField为参数的int构造函数。这是文本字段中可见字符的数量。然后,您可以使用setText初始化字段的内容(如果需要)。

或者,正确设置文本字段的最大和首选尺寸setMaximumSizesetMinimumSize)。

答案 2 :(得分:1)

来自JavaDoc:

  

<强>参数:
      text - 要显示的文本,或null       columns - 用于计算首选宽度的列数;如果列设置为零,则首选宽度将是组件实现自然产生的任何宽度

因为你正在调用0构造函数,所以你得到了“无论结果如何”的实现,它实现了你的太长字符串的长度。只需调用列构造函数,非零将为您解决此问题。试试这些:

bigPane.add(new JTextField("reterterter ertertrert erterter ert",3));
bigPane.add(new JTextField(" ertertrert erterter ert",3));
bigPane.add(new JTextField("reterterter ertertrert  ert",3));
bigPane.add(new JTextField("reterterter ertertrert erterter ",3));

以下是生成的窗格的屏幕截图:

alt text
(来源:mcglashan.net