JScrollPane 和 JList 自动滚动
我有下一个代码:
listModel = new DefaultListModel();
listModel.addElement(dateFormat.format(new Date()) + ": Msg1");
messageList = new JList(listModel);
messageList.setLayoutOrientation(JList.VERTICAL);
messageScrollList = new JScrollPane(messageList);
messageScrollList.setPreferredSize(new Dimension(500, 200));
messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
e.getAdjustable().setValue(e.getAdjustable().getMaximum());
}
});
它自动向下滚动。但是,如果我尝试向上滚动以重新阅读消息,它会强制向下滚动。 我该如何解决这个问题?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我发现这非常有用:
http://forums.sun.com/thread.jspa?threadID=623669 ('inopia' 发表)
正如
他所说:
“这里的问题是,在 ListModel、JList 和 JScrollPane 都更新后,找到触发的事件可能会变得有点困难。”
I found this really useful:
http://forums.sun.com/thread.jspa?threadID=623669 (post by 'inopia')
It works perfectly
As he says:
"The problem here is that it can become a bit difficult to find an event that fires after both the ListModel, JList and JScrollPane have been updated."
@问题询问者。请将您的代码从 更改
为
将
getMaximum()
更改为getValue()
然后它会按要求工作。getMaximum()
将滚动条调至最大值;而getValue()
在事件发生的任何地方都会获取它。可以完全避免使用这段代码。
如果您放置一行类似于 jList 的
add(component)
的代码并获取其固有行为,则@question enquirer. Please change your code from
to
That is change
getMaximum()
togetValue()
Then it works as required.getMaximum()
takes the scroller to its maximum; whilegetValue()
takes it wherever event happens.You can avoid using this piece of code altogether if you put one line
That works like
add(component)
for jList and gets its inherent behaviour.我将
JScrollPane
与JTextArea
一起使用。我仅在JScrollBar max
值发生变化时才通过滚动来避免强制向下滚动:我想,有更好的解决方案来过滤事件而无需额外的变量,如果有人发布它,我将不胜感激。
I used
JScrollPane
withJTextArea
. I avoided force scroll down by scrolling only whenJScrollBar max
value changed:I suppose, there is better solution to filter events without extra variables, and would appreciate if somebody post it.
我认为你想要做的是在向消息列表添加内容时让它向下滚动,而不是在调整时滚动。因此,您的代码可能如下所示:
否则,您需要判断调整是由模型更改还是由鼠标引起,并查看 API 文档,我不确定是否有办法轻松做到这一点。尽管您可以看到
AdjustmentEvent.getAdjustmentType()
在这些情况下返回不同的值,如果这是真的,那么您可以在匿名内部类中使用 if 语句。您可以尝试的另一件事是在某处设置一个布尔变量,当您向列表添加某些内容时,该变量会被设置。然后,在处理程序中检查变量是否已设置。如果是这样,则进行调整(并取消设置变量),否则,忽略它。这样,添加到列表中的每个项目只会有一次向下滚动。
I think what you want to do is have it scroll down when you add stuff to your messageList, rather then on adjustment. So your code could look like this:
Otherwise you would need to tell if the adjustment was caused by a model change, or by the mouse, and looking through the API docs I'm not sure if there's a way to do that easily. Although you could see if the
AdjustmentEvent.getAdjustmentType()
returns different values in those cases, if that's true then you could just have an if statement in your anonymous inner class.Another thing you could try would be to have a boolean variable somewhere that gets set when you add something to the list. Then, in your handler you check to see if the variable is set. If so, you do the adjustment (and unset the variable) otherwise, you ignore it. That way, there will be only one scroll-down per item being added to the list.
为了自动滚动,我使用静态变量和 list.makeVisible(int index) 的非常简单的概念
To auto scroll I am using a very simple concept of static variable and list.makeVisible(int index)
添加新消息时,调用 scrollRectToVisible() rel="noreferrer">
JList
使用矩形
其尺寸与消息窗格的首选尺寸相同。给定垂直方向,设置JScrollPane
的JViewport
消息窗格高度的整数倍。另请参阅:如何使用滚动窗格 。附录:关于文本区域滚动的引人注目的讨论 可能也会有帮助。
When adding a new message, invoke
scrollRectToVisible()
on theJList
using aRectangle
having the same dimensions as your message pane's preferred size. Given a vertical orientation, it may be convenient to make the preferred size of theJScrollPane
'sJViewport
an integral multiple of the message pane's height. See also: How to Use Scroll Panes.Addendum: This compelling discussion of Text Area Scrolling may be helpful, too.