我正在使用 aJScrollPane
和 a BoxLayout
(a Box
,尽管我也尝试过 a GridLayout
),它显示了一个分页元素列表,每个页面有 5 个元素,每个元素有 5 个可视组件。实现元素的数据是从 Web 服务中检索的,在每次页面更改时加载,删除列表中的当前元素并添加新元素(我知道这可以优化,但这就是我现在所拥有的)。
这里奇怪的是,无论是在加载时还是在更改页面时,垂直滚动条都会移动到中间的某个位置,而不是顶部,不是底部,也不是确切的中心。添加组件后,我尝试以编程方式将其向上移动,但是在数据表示方法完成后,滚动又被放置在该位置。然后,我可以正常使用滚动条,直到下一页更改。
实际上,我已经附加了一个AdjustmentListener
,JScrollBar
并且我可以计数 25 次(5 * 5,duh!)AdjustmentEvent
触发将滚动条移动到该位置的事件 - 是的,如果我添加更少的组件,则触发事件的次数更少.
在移动滚动条之前,我尝试在窗口上调用revalidate()
和repaint()
,但似乎没有任何效果,每个添加的组件它都会移动到该特定位置一次。
有任何想法吗?很抱歉没有发布一些代码,但它有点乱,很难提取可能导致问题的基本部分。
非常感谢。
更新
回应@kleopatra,我将尝试编写一些类似于我正在做的代码,尽管也许我正在跳过一些导致奇怪行为的东西。
public class MyUI extends JPanel {
List<Data> data;
JPanel dataItemsPanel;
JScrollPane scrollPane;
// ...
/**
* Method to build the UI.
*/
void createUI() {
this.setLayout(new BorderLayout());
// ...
JPanel left = new JPanel();
JPanel right = new JPanel(new BorderLayout());
// ...
dataItemsPanel = new JPanel(new GridLayout(0, 1));
// this is the scroll pane that behaves weird
scrollPane = new JScrollPane(dataItemsPanel);
//...
right.add(scrollPane, BorderLayout.CENTER);
JSplitPane splitPane = new JSplitPane(JSPlitPane.HORIZONTAL_SPLIT,
left, right);
splitPane.setResizeWeight(0);
splitPane.setOneTouchExpandable(true);
splitPane.setContinuousLayout(true);
this.add(splitPane, BorderLayout.CENTER);
// ...
loadPage(0);
}
/**
* Method to load a data page. Called when the program starts (to load
* the first page) and whenever the data page is changed.
*/
void loadPage(int page) {
data = retrievePageDataFromWebService(page);
// remove previous data
dataItemsPanel.removeAll();
// add new data
for (Data d : data) {
// build complex data item representation
JPanel description = new JPanel(new FlowLayout(FlowLayout.LEFT));
description.add(new JEditorPane(/*...*/));
JPanel options = new JPanel(new FlowLayout(FlowLayout.LEFT));
options.add(new JButton(/*...*/));
options.add(new JButton(/*...*/));
JPanel leftDataPanel = new JPanel(new BorderLayout());
leftDataPanel.add(new JEditorPane(/*...*/));
JPanel rightDataPanel = new JPanel(new BorderLayout());
rightDataPanel.add(new JEditorPane(/*...*/));
rightDataPanel.add(options, BorderLayout.CENTER);
JPanel data = new JPanel(new GridLayout(1, 2));
data.add(leftDataPanel);
data.add(rightDataPanel);
JPanel dataItemContainer = new JPanel(new BorderLayout());
dataItemContainer.add(description, BorderLayout.NORTH);
dataItemContainer.add(data, BorderLayout.CENTER);
// finally add it to the data panel
dataItemsPanel.add(dataItemContainer);
}
/*
After this method finishes, an AdjustmentEvent is called once per
added component (25 times). Trying to set the scroll bar position
at this point has no effect, as the events are triggered after the
method. I have tried to call revalidate() and repaint() here and
then move the scroll bar but the result is the same.
*/
}
}