添加组件时,JScrollPane触发奇怪的AdjustmentEvent

时间:2013-03-27 16:26:08

标签: java swing jscrollpane

我正在使用JScrollPaneBoxLayoutBox,虽然我也试过了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.
         */
    }
}

0 个答案:

没有答案