在 JScrollPane 中绘制视口外的列表

发布于 2024-07-04 16:06:23 字数 963 浏览 6 评论 0原文

我有一个列表,其中每个项目都有几个内容,包括一个可以更新很多的 JProgressBar 。 每次其中一项更新其 JProgressBar 时,列表上的 ListDataListener 都会尝试使用“

/*
 * This makes the updating content item automatically scroll
 * into view if it is off the viewport.
 */
public void contentsChanged(final ListDataEvent evt) {
    if (!EventQueue.isDispatchThread()) {
        /**
          * Make sure the scrolling happens in the graphics "dispatch" thread.
          */
        EventQueue.invokeLater(new Runnable() {
            public void run()  {
               contentsChanged(evt);
            }
        });
    }
    if (playbackInProgress) {
        int index = evt.getIndex0();
        currentContentList.ensureIndexIsVisible(index);
    }
}

请注意,我正在尝试确保滚动”将 其滚动到可见范围在调度线程中完成,因为我认为问题可能是它在重新绘制时滚动。 然而,我仍然有一个问题,如果事情真的很活跃,一些列表项会在视口之外绘制,覆盖 JScrollPane 之外的内容。 强制曝光事件会重新绘制这些东西,但这很烦人。

我还需要注意什么才能阻止这些东西在剪切区域之外绘画吗?

I have a list, each item of which has several things in it, including a JProgressBar which can be updated a lot. Each time one of the items updates its JProgressBar, the ListDataListener on the list tries to scroll it to the visible range using

/*
 * This makes the updating content item automatically scroll
 * into view if it is off the viewport.
 */
public void contentsChanged(final ListDataEvent evt) {
    if (!EventQueue.isDispatchThread()) {
        /**
          * Make sure the scrolling happens in the graphics "dispatch" thread.
          */
        EventQueue.invokeLater(new Runnable() {
            public void run()  {
               contentsChanged(evt);
            }
        });
    }
    if (playbackInProgress) {
        int index = evt.getIndex0();
        currentContentList.ensureIndexIsVisible(index);
    }
}

Note that I'm trying to make sure the scrolling is done in the dispatch thread, since I thought maybe the problem was it being scrolled while it was repainting. And yet, I still have a problem where if things are really active, some of the list items paint outside of the viewport, overwriting what's outside the JScrollPane. Forcing an exposure event will repaint those things, but it's annoying.

Is there anything else I need to look out for to stop these things painting outside of their clipping area?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

睫毛上残留的泪 2024-07-11 16:06:23

您是否尝试过在 JList 和/或其正在绘制的组件上显式启用双缓冲? (带有:setDoubleBuffered(boolean aFlag))

另一种想法是,您可能需要在委托给 EDT 后立即退出该函数。 根据代码的编写方式,如果从非 EDT 线程调用 ContentChanged,则更新似乎会在两个线程中发生。 登录第一个 if (或在 if 中设置断点 - 但在可运行的 not 中 - 应该有助于确定这是否是您的问题。

例如:

public void contentsChanged(final ListDataEvent evt)
{
    if (!EventQueue.isDispatchThread())
    {
        log.debug("Delegating contentsChanged(...) to EDT");

        EventQueue.invokeLater(new Runnable() 
        {
            public void run() 
            {
                contentsChanged(evt);
            }
        });
        // don't run ensureIndexIsVisible twice:
        return;
     }

     if (playbackInProgress)
     {
         int index = evt.getIndex0();
         currentContentList.ensureIndexIsVisible(index);
     }
}

Have you tried explicitly enabling double-buffering on the JList and/or the components that it is drawing over? (with:setDoubleBuffered(boolean aFlag))

Another thought is that you might need to exit the function immediately after delegating to the EDT. The way your code is written, it looks like the update will happen in both threads if ContentChanged is invoked from a non-EDT thread. Logging in the first if (or set a breakpoint in the if -- but not in the runnable -- should help determine if that is your problem.

eg:

public void contentsChanged(final ListDataEvent evt)
{
    if (!EventQueue.isDispatchThread())
    {
        log.debug("Delegating contentsChanged(...) to EDT");

        EventQueue.invokeLater(new Runnable() 
        {
            public void run() 
            {
                contentsChanged(evt);
            }
        });
        // don't run ensureIndexIsVisible twice:
        return;
     }

     if (playbackInProgress)
     {
         int index = evt.getIndex0();
         currentContentList.ensureIndexIsVisible(index);
     }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文