10

I have a JList with very long item names that cause the horizontal scroll-bar to appear in scroll-pane.

Is there anyway that I can word wrap so that the whole whole item name appears in 2 rows yet can be selected in one click? I.E it should still behave as a single item but be displayed in two rows.


Here is what I did after seeing the example below

I added a new class to my project MyCellRenderer and then I went added MyList.setCellRenderer(new MyCellRenderer(80)); in the post creation code of my List. Is there anything else I need to do?

Elrond_EGLDer
  • 47,430
  • 25
  • 189
  • 180
koool
  • 13,917
  • 11
  • 43
  • 60
  • I seem to recall someone (was it Andrew) using a JLabel, HTML and simple style sheets to solve something like this. – Hovercraft Full Of Eels Nov 19 '11 at 21:00
  • Yes, of course, it was Andrew: [is-there-some-word-wrap-property-of-jlabel-exist](http://stackoverflow.com/questions/7861724/is-there-some-word-wrap-property-of-jlabel-exist/7861833#7861833). I do believe that this concept can also be used in your custom cell renderer. – Hovercraft Full Of Eels Nov 19 '11 at 21:05
  • Another alternative (why is everybody looking at me funny?) is to use a tool-tip for the long name and "Value is..." for the label itself. Of course this would not work very well with the one concrete example given in HFoEs answer. I would hate to have to mouse-over the list to distinguish between every guy called "Mohamed". – Andrew Thompson Nov 20 '11 at 01:07

3 Answers3

20

Yep, using Andrew's code, I came up with something like this:

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

public class JListLimitWidth {
   public static void main(String[] args) {
      String[] names = { "John Smith", "engelbert humperdinck",
            "john jacob jingleheimer schmidt" };
      MyCellRenderer cellRenderer = new MyCellRenderer(80);
      JList list = new JList(names);
      list.setCellRenderer(cellRenderer);
      JScrollPane sPane = new JScrollPane(list);
      JPanel panel = new JPanel();
      panel.add(sPane);
      JOptionPane.showMessageDialog(null, panel);

   }
}

class MyCellRenderer extends DefaultListCellRenderer {
   public static final String HTML_1 = "<html><body style='width: ";
   public static final String HTML_2 = "px'>";
   public static final String HTML_3 = "</html>";
   private int width;

   public MyCellRenderer(int width) {
      this.width = width;
   }

   @Override
   public Component getListCellRendererComponent(JList list, Object value,
         int index, boolean isSelected, boolean cellHasFocus) {
      String text = HTML_1 + String.valueOf(width) + HTML_2 + value.toString()
            + HTML_3;
      return super.getListCellRendererComponent(list, text, index, isSelected,
            cellHasFocus);
   }

}
Hovercraft Full Of Eels
  • 276,051
  • 23
  • 238
  • 346
  • 2
    It wasn't my smarts that did this but this one here: [Andrew's post](http://stackoverflow.com/questions/7861724/is-there-some-word-wrap-property-of-jlabel-exist/7861833#7861833). I can't upvote his answer more than once, but I encourage anyone who thinks that my answer was helpful to upvote the link. – Hovercraft Full Of Eels Nov 19 '11 at 21:27
  • (as you all know, including @Andrew Thompson, I dont like html tricksing overly much, especially not if mis-used for hard-coded sizing ) so, why not use the actual with of the list instead of the fixed? – kleopatra Nov 20 '11 at 11:52
  • Thanks a lot for the example!! I really appreciate it!! – koool Nov 20 '11 at 18:18
  • Hey @HovercraftFullOfEels I just tried this code ... it doesnt seem to work for me.... I am not developing anything on browser it is a pure java appication and it doesnot wrap the text ... could you help me out. Here is what I did I added a new class to my project MyCellRenderer and then I went added MyList.setCellRenderer(new MyCellRenderer(80)); in the post creation code of my List. Is there anything else I need to do? Thanks for you help and paitence – koool Nov 20 '11 at 18:39
0

It can be done even easier. You can create JList by consatructor with ListModel. In CustomListModel extends AbstractListModel, getElementAt() method can returns String with same html-formatted text. So this way do the same without cell renderer modification.

-1

You can also compute dynamically the width (instead of a fixed value):

String text = HTML_1 + String.valueOf(**list.getWidth()**) + HTML_2 + value.toString() + HTML_3;

So if the panel resizes the list, wrapping remains correct.

Update

And the result looks like this: enter image description here

Jason
  • 10,225
  • 8
  • 57
  • 79
steph
  • 1
  • This does not work. If the JList is resized the height of the row will not be adjusted and funny visual things happen. See my attached image... I added green and red to help illustrate. – Jason Mar 18 '16 at 19:25