Search code examples
javascrollword-wrapjlistjscrollpane

JList with JScrollPane and prototype cell value wraps element names (replaces with dots instead of showing horizontal scrollbar), why?


I've got a Jlist inside a JScrollPane and I've set a prototype value so that it doesn't have to calculate the width for big lists, but just uses this default width.

Now, the problem is that the Jlist is for some reason replacing the end of an element with dots (...) so that a horizontal scrollbar will never be shown.

How do I disable with "wrapping"? So that long elements are not being replaced with dots if they are wider than the Jlist's width?

I've reproduced the issue in a small example application. Please run it if you don't understand what I mean:

import javax.swing.*;
import java.awt.*;

public class Test
{
    //window
    private static final int windowWidth = 450;
    private static final int windowHeight = 500;

    //components
    private JFrame frame;
    private JList classesList;
    private DefaultListModel classesListModel;

    public Test()
    {
        load();
    }

    private void load()
    {   
        //create window
        frame = new JFrame("Test");
        frame.setSize(windowWidth, windowHeight);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setUndecorated(true);
        frame.getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);

        //classes list
        classesListModel = new DefaultListModel();
        classesList = new JList(classesListModel);
        classesList.setPrototypeCellValue("prototype value");
        classesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        classesList.setVisibleRowCount(20);
        JScrollPane scrollClasses = new JScrollPane(classesList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);     

        for (int i = 0; i < 200; i++)
        {
            classesListModel.addElement("this is a long string, does not fit in width");
        }

        //panel
        JPanel drawingArea = new JPanel();
        drawingArea.setBackground(Color.white);

        drawingArea.add(scrollClasses);
        frame.add(drawingArea);

        //set visible
        frame.setVisible(true);
    }
}

Even if you force horizontal scrollbar, you still won't be able to scroll because the element is actually not wider than the width because of the dot (...) wrapping.

Thanks in advance.


Solution

  • Scrollbars appear automatically when the preferred size of the component added to the scrollpane is greater than the size of the scrollpane.

    By using the setPrototypeCellValue(...) method you are affecting the way the list calculates its preferred size, which means you are responsible for providing the proper value that ensures the strings will not be truncated.

    So the simple solution is not not use that method, but in addition you will need to set the preferred size of the scrollpane to be whatever you want. Then the horizontal scrollbars will appear if required.