【问题标题】:How to scroll to a specific location in a JScrollPane如何滚动到 JScrollPane 中的特定位置
【发布时间】:2012-08-19 14:49:30
【问题描述】:

我有一个 JScrollPane,其中包含一个高度较大的 JPanel,这个大 JPanel 中包含更多 Jpanel,如图像中所示。其中一些面板包含我用来显示标题的 JLabel。在顶部,有 JLabels,其编号与标题标签中的标题编号相匹配。我需要做的是,当我从顶部标签列表中单击一个标签时,JScrollBar 应该滚动到该标签所在的位置。

我不知道这是否可能,但如果有人知道如何滚动到 JScrollPane 中的特定位置,请帮助我。

【问题讨论】:

  • 我找到了一个解决方案,效果很好我所做的是,我得到了我需要的标题标签的 Y 位置,然后调用 JScrollPane 的以下方法,jScrollPane.getViewport().setViewPosition( new Point(0, [页眉标签的Y位置]));

标签: java swing jscrollpane


【解决方案1】:

假设您希望包含作为标题的标签的整个面板可见:

Container parent = titleLabel.getParent();
parent.scrollRectToVisible(parent.getBounds());

没有必要访问包含的视口/scrollPane 除了(总是有一个例外,不是吗:-)

  • 调用 scrollRectToVisible 的组件具有自定义实现(如 f.i. 文本组件
  • 如果该方法到达的默认位置不符合您的喜好

编辑

@MadProgrammer 的代码 sn-p :-) - 但懒得删除 SwingX 的所有痕迹,所以我们开始吧:

final JLabel last = new JLabel("I'm the last");

int maxRow = 20;
int maxColumn = 10;

JComponent content = new JPanel(new GridLayout(maxRow, maxColumn));
for (int row = 0; row < maxRow; row++) {
    for (int column = 0; column < maxColumn; column++) {
        JComponent parent = new JPanel();
        JLabel label = new JLabel("i'm in " + row + "/" + column);
        if (row == (maxRow - 1) && column == (maxColumn - 1)) {
            label = last;
            last.setBorder(BorderFactory.createLineBorder(Color.RED));
        }
        parent.add(label);
        content.add(parent);
    }
}
JXFrame frame = wrapWithScrollingInFrame(content, "scroll");
Action action = new AbstractAction("scrollLastVisible") {

    @Override
    public void actionPerformed(ActionEvent e) {
        last.scrollRectToVisible(last.getBounds());
    }
};
addAction(frame, action);
show(frame, frame.getPreferredSize().width / 2, frame.getPreferredSize().height / 2);

【讨论】:

  • 啊,我明白了,绝对是白痴。我假设矩形是相对于滚动窗格的。 - 我会把它添加到我的小黑书里。谢谢(现在我想删除我的答案:P)
  • ps 我知道你不需要它,但是 +1 - 可惜我不能投票支持更多 ;)
  • 这是不正确的。 Container parent = titleLabel.getParent(); parent.scrollRectToVisible(parent.getBounds()); Container 类上没有名为 scrollRectToVisible 的方法。
  • @searchengine27 是的,你是对的:这是 JComponent 上的一个方法,需要一个类型转换(这很安全,因为我们知道我们将它添加到了 JPanel)。感谢您的提醒,请随时进行更正:)
【解决方案2】:

这是可行的。

您需要在标题中引用 JLabel 以及它在您的视图中链接到的位置 (JPanel)。获得此链接后,您可能需要确定 JLabel 在“JPanel”中的位置。

您可以使用JViewport.scrollRectToVisible(Rectangle) 方法滚动到该位置。

JLabel labelInPane = //... reference lookup
Rectangle bounds = labelInPane.getBounds();
// You may need to convert the point to meet the requirements of the parent container...
// bounds.setLocation(SwingUtilities.convertPoint(labelInPane, bounds.getPoint(), topLevelParentPaneInScrollPane));

scrollPane.getViewport().scrollRectToVisible(bounds);

【讨论】:

  • 或将 Rectangle 直接更改为 JLabels 边界
  • @mKorbel 你是对的......在我的脑海中,它可能有可能移动视口,以便标签出现在滚动窗格的底部......但显然这是只是疯狂的谈话:P
  • -1 表示过于复杂(tsss ...又一个极其棘手的错误;):只需要 label.scrollRectToVisible(label.getBounds()) ..
  • @kleopatra 当然,我们都假设有问题的标签位于 JViewport 内的顶级容器上,如果是这样,那么是的,你都是正确的,我同意,但如果标签被包含在一个或多个其他子容器中,我不相信它会,因此关于转换点的组件但是,您不需要视口可见边界
  • 不是一个信仰问题 - 这是一个事实,在默认实现中处理了grand-how-deep-children ;-)
【解决方案3】:

scrollRectToVisible 不适合我。 但是,我是这样解决的:

AbstractNode a = pkmap.get(0);
scroll.getVerticalScrollBar().setValue(a.getY());
scroll.getHorizontalScrollBar().setValue(a.getX());

【讨论】:

    猜你喜欢
    • 2011-12-14
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多