我正在使用JScrollPane
与BoxLayout
(Box
,虽然我也试过了GridLayout
,但它显示了一个分页元素列表,每个页面有5个元素,每个元素有5个可视组件。完成元素的数据是从Web服务检索的,每次页面更改时加载,删除列表中的当前元素并添加新元素(我知道这可以优化,但这就是我现在所拥有的)。
这里奇怪的是,无论是在加载还是更换页面时,垂直滚动条都会移动到中间的某个位置,而不是顶部,而不是底部,而不是精确的中心。我尝试在添加组件后以编程方式将其移动,但在数据显示方法完成后,滚动再次放在该位置。然后,我可以正常使用滚动条,直到下一页更改。
实际上,我已将AdjustmentListener
附加到JScrollBar
,我可以计算25次(5 * 5,呃!)将{1}}事件移动到滚动条的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.
*/
}
}