Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JScrollPane和JList自动滚动_Java_Swing_Jscrollpane_Jlist_Autoscroll - Fatal编程技术网

Java JScrollPane和JList自动滚动

Java JScrollPane和JList自动滚动,java,swing,jscrollpane,jlist,autoscroll,Java,Swing,Jscrollpane,Jlist,Autoscroll,我有下一个代码: listModel = new DefaultListModel(); listModel.addElement(dateFormat.format(new Date()) + ": Msg1"); messageList = new JList(listModel); messageList.setLayoutOrientation(JList.VERTICAL); messageScrollList = new JScrollPan

我有下一个代码:

    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());  
        }
    }); 
它会自动向下滚动。但是,如果我试图向上滚动以重新阅读邮件,则会强制向下滚动。
我该如何解决这个问题?

我想你要做的是,当你向消息列表中添加内容时,让它向下滚动,而不是调整。因此,您的代码可以如下所示:

Adjustable sb = messageScrollList.getVerticalScrollBar()
boolean onBottom = sb.getValue() == sb.getMaximum();
//
// add your message to the JList.
//
if(onBottom)  sb.setValue(sb.getMaximum());
否则,您需要知道调整是由模型更改引起的,还是由鼠标引起的,并且查看API文档,我不确定是否有办法轻松做到这一点。虽然您可以看到在这些情况下是否返回不同的值,但如果是这样,那么您可以在匿名内部类中使用if语句


您可以尝试的另一件事是在某个地方设置一个布尔变量,当您向列表中添加某些内容时,该变量将被设置。然后,在处理程序中检查变量是否已设置。如果是这样,则进行调整(并取消设置变量),否则忽略它。这样,添加到列表中的每个项目只有一次向下滚动。

添加新邮件时,请使用与邮件窗格首选大小相同的尺寸在上调用。给定垂直方向,可以方便地将的首选大小设置为消息窗格高度的整数倍。另见:


附录:这一引人注目的讨论可能也很有帮助。

我发现这一点非常有用:
this.list = blah blah... 
this.list.setSelectedValue(whatever);   
final JScrollPane sp = new JScrollPane(this.list); // needs to be after the parent is the sp 
this.list.ensureIndexIsVisible(this.list.getSelectedIndex());
(由“inopia”发布)
它工作得很好

正如他所说:
“这里的问题是,在更新ListModel、JList和JScrollPane之后,要找到触发的事件可能会有点困难。”

要自动滚动,我使用了一个非常简单的静态变量和list.makeVisible(int index)概念


@询问者。请从更改您的代码

messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {  
    public void adjustmentValueChanged(AdjustmentEvent e) {  
        e.getAdjustable().setValue(e.getAdjustable().getMaximum());  
    }
});

也就是说,将
getMaximum()
更改为
getValue()
,然后它可以根据需要工作
getMaximum()
使滚动条达到最大值;而
getValue()
会在事件发生的任何地方使用它

如果只放一行代码,就可以避免完全使用这段代码

messageScrollList.setViewportView(messageList);

这就像jList的
add(component)
,并获得其固有行为。

我使用
JScrollPane
JTextArea
一起使用。我通过仅在
JScrollBar max
值更改时滚动来避免强制向下滚动:

JScrollPane scrollPane=新的JScrollPane(jTextArea);
verticalScrollBarMaximumValue=scrollPane.getVerticalScrollBar().getMaximum();
scrollPane.getVerticalScrollBar().addAdjustmentListener(
e->{
如果((垂直滚动条最大值-e.getAdjustable().getMaximum())==0)
返回;
e、 getAdjustable().setValue(例如getAdjustable().getMaximum());
verticalScrollBarMaximumValue=scrollPane.getVerticalScrollBar().getMaximum();
}
);

我想,有更好的解决方案可以过滤没有额外变量的事件,如果有人发布它,我们将不胜感激。

在这两种情况下,adjustmenttype是相同的。我尝试过在添加消息时向下滚动。但如果我这样做,最后添加的消息将不可见。它向下滚动不够。我该怎么解决呢?嗯。。。嗯,你可以做的一件事是在某个地方设置一个布尔变量,当你向列表中添加一些东西时,它会被设置。然后,在处理程序中检查变量是否已设置。如果是这样,则进行调整(并取消设置变量),否则忽略它。这样,添加到列表中的每个项目只有一个向下滚动。链接已关闭。你能刷新一下吗?
messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {  
    public void adjustmentValueChanged(AdjustmentEvent e) {  
        e.getAdjustable().setValue(e.getAdjustable().getValue());
    }
}); 
messageScrollList.setViewportView(messageList);