views:

268

answers:

3

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.

+2  A: 

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.

camickr
How would I set the preferred size then? I thought that's what the setPrototypecellValue does?
Tom
Got it now using scrollClasses.setPreferredSize(new Dimension(100, 400));. Thanks.
Tom
See my answer below. Also, if you don't call setPrototypecellValue() it will automatically adjust the size of the JList to accommodate the widest item. setPrototypecellValue() is only useful if you have a very long list and you don't want Java to go through each entry to find the width requirements.
Alinium
I indeed don't want Java to go through each entry to find the width requirements, that's why I used it. I hope scrollClasses.setPreferredSize(width, height) has the same effect. Does it?
Tom
+1  A: 

When you call classesList.setPrototypeCellValue("prototype value") you are telling the JList classesList to limit its maximum width to the length of the string "prototype value". (See javadocs)

Then later on when you populate the list with the strings "this is a long string, does not fit in width", no wonder it does not fit in the width! Because the width of the prototype you gave it is smaller than the width of the string you are filling the list with.

The JScrollPane will automatically show the scrollbars and you usually don't need to adjust their behavior. The JList will also automatically adjust its width to try and show the maximum width item in the list. The problem occurs when you tell the JList to fix its width by calling the setPrototypeCellValue().

If you comment out

classesList.setPrototypeCellValue("prototype value");

or replace it with

classesList.setPrototypeCellValue("this is a long string, does not fit in width");

then it will function as you expected it to.

Alinium
Thanks, camickr was a bit faster but you deserve an upvote for extra elaboration! I did read the docs by the way, but I think I misunderstood it. :)
Tom
A: 

My answer to that question is that first find the longest element in the list then use setPrototype method on that elements

Farrukh