【问题标题】:JScrollPane automatically sets ViewPort position to (0,0)JScrollPane 自动将 ViewPort 位置设置为 (0,0)
【发布时间】:2013-08-09 08:38:24
【问题描述】:

我有一个JScrollPane,其视口是JPanel 的子类。该面板使用BoxLayout 进行布局,并且在用户交互时,组件的水平宽度可以改变。当有足够的组件需要滚动条时,更改组件的水平大小,然后在 JPanel 子类(视口视图)上调用 revalidate() 将始终导致滚动窗格重置为 (0,0 )。

我想保留当前视图,所以我设置了一个组件侦听器,并在componentMoved() 上将值存储在getLocation()(这都在 JPanel 子类或视口视图中)。在调用revalidate() 之后,我立即使用存储的位置(在事件调度线程上)调用setLocation()。但是,这会导致视图位置设置为 (0,0) 的跳跃,然后立即跳转到存储的位置。有没有办法阻止JScrollPane 回到(0,0)?有没有更好的方法来告诉它它的视口视图的大小已经改变?

我试图通过子类化JScrollBar 并覆盖setValue() 并放置一个断点来找出(0,0) 的来源,但它没有被击中(但当我移动滚轮时)所以我认为它是在内部设置的。有谁知道会发生什么?

【问题讨论】:

  • 为了尽快获得更好的帮助,请将您的代码发布为SSCCE,以证明您的问题。这允许用户复制/粘贴和重现您的问题。
  • 我会的,但我为这个问题开发的 SSCCE 没有显示问题。似乎因为它太小了,“比赛条件”没有发生(我永远看不到跳跃)。我的项目太大了,我不能只发布它,所以我希望我的描述足够好:(

标签: java swing jscrollpane jviewport


【解决方案1】:

尝试另一种方式在revalidate() buf 之后在repaint() 之前调用代码。

scrollPane.getViewport().setViewPosition(new Point(x,y));

您也可以尝试拨打panel.scrollRectToVisible(Rectangle)

【讨论】:

  • 谢谢,我会试一试。当您说“在 repaint() 之前”时,您的意思是在我直接调用 repaint() 之前? revalidate() 在重新布局其组件后最终不会调用 repaint() 吗?在 revalidate() 之后我实际上并没有自己调用 repaint(),也许我需要(我不是因为我可以看到屏幕更新,所以我认为它是在 repaint() 中的某个地方调用的)。
  • 好的,我试过你说的,还是不行。但这让我思考。在尝试了一大堆其他事情(删除一些电话,改变一些等等)之后,我回去完全按照你说的做。我选择了“revalidate();repaint();”它奏效了!唯一不同的是我没有调用 setSize() 。我认为我需要这样做,因为组件的大小发生了变化,但是只要让 getPreferredSize() 返回正确的大小就可以让一切正常。 TL;DR:确保我唯一的调用是 revalidate();和重绘();事件不需要记住位置并设置它
猜你喜欢
  • 2012-10-24
  • 2010-12-30
  • 1970-01-01
  • 1970-01-01
  • 2013-07-25
  • 1970-01-01
  • 1970-01-01
  • 2015-04-08
  • 1970-01-01
相关资源
最近更新 更多