JavaSwingJList and ListModel: Scrolling


Scrolling

The code presented here makes use of the general scrolling methods in Scrolling.java and adds little but calls to JList.getCellBounds().

All code presented (slightly augmented) and the code omitted here is available in JListScrolling.java.

This does not handle the 1.4 "list" wrapping features of JList yet.

Paranoia: After changing the ListModel (or row heights), the JList may not immediately have its new size updated. The scrolling code should be wrapped in SwingUtilities.invokeLater(). I don't really think it is necessary with BasicListUI, unlike JTable, which will only calculate its column widths later.

Making cells visible

Single rows can be made visible with list.ensureIndexIsVisible(index); which is equivalent to list.scrollRectToVisible(list.getCellBounds(index, index)); except that it ignores wrong values for index.

To make multiple cells visible, you can use list.scrollRectToVisible(list.getCellBounds(first, last));

The use of the scrollVertically() methods in Scrolling may make the intent clearer, and allows biases.

public static void ensureIndexIsVisible(JList list, int index)
{
    Scrolling.scrollVertically(list, list.getCellBounds(index, index));
}
public static void ensureIndicesAreVisible(JList list, int first, int last, int bias)
{
    Scrolling.scrollVertically(list, list.getCellBounds(first, last), bias);
}

Making cells centered

public static void ensureIndexIsCentered(JList list, int index)
{
    Scrolling.centerVertically(list, list.getCellBounds(index, index), false);
}
public static void ensureIndicesAreCentered(JList list, int first, int last)
{
    Scrolling.centerVertically(list, list.getCellBounds(first, last), false);
}

Testing whether cells are visible

Horizontal visibility isn't handled here. Either the list's visible rectangle's width is equal to the list's width, then all cells are completely visible horizontally, or not; so this isn't something that's different on a cell basis.

Test for (vertically) partial visibility can be done with getFirst/LastVisibleIndex().

public static boolean areIndicesPartlyVisible(JList list, int first, int last)
{
    int listFirst = list.getFirstVisibleIndex();
    return listFirst != -1 && first >= listFirst && last <= list.getLastVisibleIndex();
}

For complete visibility, the Rectangle calculations in Scrolling can be used:

public static boolean areIndicesVisible(JList list, int first, int last)
{
    return Scrolling.isVerticallyVisible(list, list.getCellBounds(first, last));
}

(C) 2001-2009 Christian Kaufhold (swing@chka.de)