【问题标题】:How to layout a components in vertical only scrollpane?如何在仅垂直的滚动窗格中布局组件?
【发布时间】:2009-08-08 12:09:44
【问题描述】:

我有一个复杂的问题,我在任何地方都找不到答案。

这是一个例子:

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 的结果的上限,见右侧。

【问题讨论】:

  • “我想剪切文本字段中的文本”是什么意思?你想限制文本的长度吗?
  • 这就是我想要的:nraynaud.com/kilombo/textcut.png(我通过移除滚动窗格来做到这一点)这是我得到和不想要的:nraynaud.com/kilombo/textfieldcut.png 使得文本字段无法使用。
  • 我不明白对这两个答案的反对票。他们都做你想做的事。
  • 不是真的,因为它们是狭窄的黑客,在现实生活中我的列中有其他组件,我希望能够在某些情况下使用首选大小等。我转换了点数,因为,在我的示例的确切情况下,它们有效。但这几乎不是一个解决方案。
  • “在我的示例的确切情况下,它们有效。但这几乎不是一个解决方案” - 嗯。如果您要鼓励人们提供帮助,那么对可行的解决方案投反对票并不是一个好主意!

标签: java swing


【解决方案1】:

我认为“正确”的做法是使用 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();
}

【讨论】:

  • 我真的读得太快了 Scrollable javadoc。显然,我想要的是 public boolean getScrollableTracksViewportWidth() { return true; } 非常感谢。
  • 从技术上讲,我的项目中已经使用了 swingx,我将使用 JXPanel 并调用 panel.setScrollableTracksViewportHeight(false);在上面。这将避免其余的自定义代码。
【解决方案2】:

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

或者,设置文本字段的最大和首选大小setMaximumSizesetMinimumSize)。

【讨论】:

  • 我认为这些解决方案都不能解决我的问题。我希望垂直部分的当前行为保持不变,因此这排除了用手触摸任何尺寸。设置列号根本不会改变布局行为,它只是间接改变了preferredSize。
  • 我不能说我明白你想要什么。究竟是什么问题,你所说的“削减”是什么意思?框架是否显得太宽?不够宽?有什么问题?
  • 缩小框架时,字段被剪切而不是调整大小。这是我得到的:nraynaud.com/kilombo/textfieldcut.png 这是我想要的:nraynaud.com/kilombo/textcut.png
  • 很抱歉,我仍然不确定您的意思! “剪切”字段和调整大小的字段有什么区别?我在您的两张图片之间看到的唯一区别是您的文本字段的垂直大小......也许您是说您希望整个字段更小(包括字体大小等)?如果是这种情况,您将需要,嗯,更改字体大小。这不是典型的行为 - 如果我将浏览器缩小,我最终不会得到网页的微型缩略图!
  • 看右边的图片。也许你会看到不同。用图片向你展示行为很复杂。
【解决方案3】:

来自 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));

这是生成的窗格的屏幕截图:


(来源:mcglashan.net

【讨论】:

  • 我想我已经回答过了。这将破坏首选大小的目的,例如破坏 JFrame.pack() 意图。我不想(手动)更改首选尺寸,我希望在这种特殊情况下计算视图宽度时忽略首选宽度。
猜你喜欢
  • 2013-05-13
  • 1970-01-01
  • 2019-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多