Java和JScrollPane:在哪里调用setPreferredSize?

Java和JScrollPane:在哪里调用setPreferredSize?,java,swing,jscrollpane,Java,Swing,Jscrollpane,我使用的是JScrollPane,在viewportView.doLayout内部,我调用的是viewportView.setPreferredSize。这似乎是错误的,因为JScrollPane的滚动条总是根据doLayout之前的最后一个setPreferredSize更新。因此,在重新验证的情况下,JScrollPane首先根据首选大小更新滚动条,然后调用doLayout 我能改变这种行为吗?或者我应该在哪里调用setPreferredSize?或者我应该把布局子组件的代码放在哪里 我想

我使用的是
JScrollPane
,在
viewportView.doLayout
内部,我调用的是
viewportView.setPreferredSize
。这似乎是错误的,因为
JScrollPane
的滚动条总是根据
doLayout
之前的最后一个
setPreferredSize
更新。因此,在重新验证的情况下,
JScrollPane
首先根据首选大小更新滚动条,然后调用
doLayout

我能改变这种行为吗?或者我应该在哪里调用
setPreferredSize
?或者我应该把布局子组件的代码放在哪里


我想出了一个可行的办法:

调用
this.setPreferredSize
this.setSize
内部
viewportView.doLayout

我留下这个问题,因为我真的不明白为什么这样做有效(如果我删除其中一个也不行),我想知道


好的,这是有效的,因为它生成了一个无止境的循环,也就是说,它总是将一些重新验证请求推送到事件循环中,当然这就解决了问题。然而,这并不是真正的解决办法

我现在有这个:

// In viewportView of the JScrollPane:
@Override public void doLayout() {
    // ... layout childs ...
    // size.x/size.y being the size I want to have for the viewportView
    if(size.x != getPreferredSize().width || size.y != getPreferredSize().height) {
        setPreferredSize(new Dimension(size.x, size.y));
        if(getParent() != null) getParent().validate();
    }
}
这似乎现在很管用


仍然想知道是否有人可以澄清这是否是正确的方法,如果不是,它将是什么。

如果您想要
JScrollPane
的内容(例如
JPanel
)大小将其设置为内容。如果需要
JScrollPane
的大小,请将其设置为
JScrollPane
。无需调用viewPortView的方法。

但我的viewPortView是我的内容。而且,问题不是我应该调用什么,而是我应该在哪里调用。我不太确定,但是afaik调用setSize是应该在doLayout方法内部执行的操作。此外,滚动条反映了组件的实际大小,而不是它的首选大小,尽管可能存在松散的依赖关系。当您尝试重新发明轮子时,这些就是您遇到的问题。您不必重写doLayout()。你不认为Swing的设计师们对布局管理应该如何工作考虑了很多吗?Albert在昨天的另一篇帖子()中被建议使用自定义布局管理器,而不是覆盖所有这些方法。@camickr:你能解释一下“所有这些方法”是什么意思吗?我只是重写了一个方法,并在其中添加了一些非常简单的代码。