在 JScrollPane 上设置滚动条

Posted

技术标签:

【中文标题】在 JScrollPane 上设置滚动条【英文标题】:Setting Scroll Bar on a JScrollPane 【发布时间】:2010-11-13 01:22:55 【问题描述】:

我有这个由htmlEditorKit 支持的JTextPane(包裹在JScrollPane 中)。 JTextPane 的内容是简单的 HTML,其中包含一些使用 img 标签嵌入的图像(本地文件)。问题是当你加载JTextPane 时,加载需要一瞬间,然后它会在页面底部出现滚动条。如果我这样做:

JTextPane text = new JTextPane();
JScrollPane scroll = new JScrollPane(text);
// do some set up...
scroll.getVerticalScrollBar().setValue(0);

它会暂时设置滚动条,然后另一个头(可能是负责加载图像的)出现并将滚动条撞回底部。我尝试添加:

((AbstractDocument)text.getDocument()).setAsynchronousLoadPriority(-1);

但这并没有解决问题。有什么方法可以从text.getDocument()text 获取事件,当窗格完成加载时会通知我,以便我可以设置滚动条?另一种方法是我设置另一个线程等待一秒钟左右,然后设置滚动条,但这是一个糟糕的 hack。

你的建议?

【问题讨论】:

【参考方案1】:

您的应用是单线程的吗?如果是,您可以请求正在运行的线程列表并在它们完成时收到通知,然后设置滚动条值。这是一个选择吗?

或者您可以为每个加载的图像提供一个 ImageObserver,并在报告加载所有图像时设置滚动条的位置?

【讨论】:

Swing 应用程序依靠一个称为事件调度线程的线程来控制所有 GUI 操作。如果需要,您可以解决这个问题,但我现在所做的所有工作都在 Event Dispatch Thread 上。这可以被视为一种选择,但可能与我在问题中提出的一样糟糕。不过我会记住的。【参考方案2】:

您是否尝试过使用 invokeLater?

final JScrollPane scroll = new JScrollPane(text);
javax.swing.SwingUtilities.invokeLater(new Runnable() 
   public void run()  
       scroll.getVerticalScrollBar().setValue(0);
   
);

如果这不起作用,那么深入研究图像视图非常困难,所以我的下一步是追踪滚动条发生变化的原因:

scroll.setVerticalScrollbar(new JScrollBar() 
    public void setValue(int value) 
        new Exception().printStackTrace();
        super.setValue(value);
     
);

您还可以在 setValue() 方法中使用调试器,而不仅仅是打印堆栈跟踪。

【讨论】:

第一个解决方案有效,谢谢。为什么地球上没有无需调用 SwingUtilities 的方法来设置它? 不知道。我认为它的设计方式是您必须创建 JScrollPane,将其添加到屏幕,然后 然后 设置值。对我来说毫无意义。【参考方案3】:

经过 50 分钟的绝望后,以下内容为我解决了问题:

JTextPane.grabFocus();
JTextPane.setCaretPosition(20);

【讨论】:

以上是关于在 JScrollPane 上设置滚动条的主要内容,如果未能解决你的问题,请参考以下文章

Swing自定义JScrollPane的滚动条设置,重写BasicScrollBarUI方法

java中JScrollPane不显示水平滚动条的解决办法

java swing JPanel添加在JScrollPane上,有垂直的滚动条,可是滚动条拉到底,只显示了JPanel的一部分。

java 怎么在JtextArea里设置滚动条

如何在 JScrollPane 中居中垂直和水平滚动条?

JScrollPane 上面放 JPanel 怎么让 JScrollPane 在适当的时候显示滚动条