java 更改 JList 内部时使 JScrollPane 显示滚动条

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/818163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 13:55:27  来源:igfitidea点击:

Make JScrollPane display scrollbars when JList inside is changed

javaswing

提问by VolkA

I'm trying to change a JList inside a JScrollPane dynamically, using

我正在尝试动态更改 JScrollPane 内的 JList,使用

myList.setListData(someArray);

After this I would expect the JScrollPane to show Scrollbars as needed, but this doesn't happen. Googling the issue was not very helpful. I tried various combinations of the following methods, with little success (basically poking through the api docs):

在此之后,我希望 JScrollPane 根据需要显示滚动条,但这不会发生。谷歌搜索这个问题并不是很有帮助。我尝试了以下方法的各种组合,但收效甚微(基本上是浏览 api 文档):

myScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
myList.validate(); myScrollPane.validate();
myScrollPane.setPreferredSize(Dimension someDimension);
myScrollPane.setViewportView(moduleList);
myScrollPane.setLayout(...);

When using the first method a scrollbar appears, but it doesn't get activated by the model change. I also hooked into the PropertyChangeEvent and validated that the JList fires and event when the model changed. What am I missing here? What method do I have to use to make this work, or even better what property would make this work out of the box?

使用第一种方法时,会出现滚动条,但不会因模型更改而激活。我还连接到 PropertyChangeEvent 并验证 JList 是否在模型更改时触发和事件。我在这里错过了什么?我必须使用什么方法来完成这项工作,或者更好的是什么属性可以使这项工作开箱即用?

回答by evanx

if the preferredSize is set on JList, even if (0, 0), then JScrollPane doesn't work - ensure that it is unset, setPreferredSize(null) if necessary

如果在 JList 上设置了 preferredSize,即使 (0, 0),JScrollPane 也不起作用 - 确保它未设置,如有必要, setPreferredSize(null)

see mrtextmineras follows

mrtextminer如下

The solution to this problem is to not setting the preferredSize of the JList (removing the setting statement). In Netbeans IDE 5.5.1, unsetting the preferredSize of the JList can be achieved by right clicking on the preferredSize property of the JList and then selecting “restoring default value”.

In conclusion, set preferredSize of the JScrollPane only. Do not set the preferredSize of the JList.

解决这个问题的办法是不设置JList的preferredSize(去掉设置语句)。在Netbeans IDE 5.5.1中,可以通过右键单击JList的preferredSize属性,然后选择“恢复默认值”来取消设置JList的preferredSize。

总之,只设置 JScrollPane 的 preferredSize。不要设置 JList 的 preferredSize。

回答by r?ph

just wrote a little sample app to test this behaviour, and it works out of the box. when you modify the list data, vertical and horizontal scrollbars are added to the scrollpane as needed by default.

刚刚编写了一个小示例应用程序来测试这种行为,它开箱即用。当您修改列表数据时,默认情况下会根据需要将垂直和水平滚动条添加到滚动窗格中。

public class Frametest {

private JList list;

public Frametest() {
    JFrame f = new JFrame("Scrollable JList");
    f.setSize(200, 300);
    JScrollPane jsp = new JScrollPane();        
    list = new JList();
    jsp.getViewport().add(list);
    f.getContentPane().setLayout(new BorderLayout());
    f.getContentPane().add(jsp, BorderLayout.CENTER);
    JButton button = new JButton("update");
    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            Object[] objects = new Object[20];
            for(int i=0; i<20; i++) {
                objects[i] = "foo foo foo foo foo foo foo foo foo foo foo foo "+i;
            }
            list.setListData(objects);
        }
    });
    f.getContentPane().add(button, BorderLayout.SOUTH);
    f.setVisible(true);     
}

public static void main(String[] args) {
    new Frametest();
}}

回答by coobird

Have you tried calling the validateor revalidatemethod of the JListupon making changes to the list data?

您是否尝试过在更改列表数据时调用 的validaterevalidate方法JList

myList.setListData(someArray);
myList.revalidate();

Just for your information, I just did a quick investigation of the difference between validateand revalidateand it seems to be that validatewill the layout for the component the method was called on and its children, while revalidatewill go all the way up to its highest parent and then perform layout changes and such to all its children.

只是为了您的信息,我只是做之间的差异的快速调查validate,并revalidate和它似乎是validate将用于该组件的布局方法被调用并且它的孩子,而revalidate会去一路攀升到最高父级,然后对其所有子项执行布局更改等。

Calling revalidateon myListwill not only validate the list itself, but it will also validate the scroll pane as well, therefore, affecting the visibility of the scroll bar depending on the items being drawn in the list.

调用revalidateonmyList不仅会验证列表本身,还会验证滚动窗格,因此,会根据列表中绘制的项目影响滚动条的可见性。

回答by coobird

This looks wrong:

这看起来不对:

jsp.getViewport().add(list);

Instead use:

而是使用:

jsp.setViewportView(list);

or

或者

new JScrollPane(list);

and the list will be added correctly to the scrollpane. Adding it this way tells the scrollpane to listen to it for changes.

并且列表将正确添加到滚动窗格中。以这种方式添加它会告诉滚动窗格监听它的变化。

回答by Anders

if you still need this try removing the validate methods and if you have a setpreferredsize on the list remove it, that was how mine got messed up

如果你仍然需要这个尝试删除验证方法,如果你在列表中有一个 setpreferredsize 删除它,那就是我的搞砸了

I removed

我删除了

resultList.setPreferredSize(resultList.getPreferredSize());

and it's done

它完成了