Перенос слов в элементах JList

У меня есть JList с очень длинными именами элементов, из-за которых горизонтальная полоса прокрутки появляется на панели прокрутки.

Могу ли я каким-либо образом перенести слова так, чтобы все имя элемента отображалось в 2 строки, но при этом его можно было выбрать одним щелчком мыши? Т.е. он по-прежнему должен вести себя как один элемент, но отображаться в двух строках.


Вот что я сделал, увидев пример ниже

Я добавил новый класс в свой проект MyCellRenderer, а затем добавил MyList.setCellRenderer(new MyCellRenderer(80)); в код создания сообщения моего списка. Есть ли что-нибудь еще, что мне нужно сделать?


person koool    schedule 19.11.2011    source источник
comment
Кажется, я припоминаю, что кто-то (это был Эндрю) использовал JLabel, HTML и простые таблицы стилей для решения чего-то подобного.   -  person Hovercraft Full Of Eels    schedule 20.11.2011
comment
Да, конечно, это был Андрей: -существует-существование-свойства-переноса-слов-jlabel. Я верю, что эту концепцию также можно использовать в вашем пользовательском рендерере ячеек.   -  person Hovercraft Full Of Eels    schedule 20.11.2011
comment
Другая альтернатива (почему все так странно на меня смотрят?) — использовать всплывающую подсказку для длинного имени, а Value is... для самой метки. Конечно, это не очень хорошо сработает с одним конкретным примером, приведенным в ответе HFoE. Мне бы очень не хотелось наводить курсор мыши на список, чтобы отличить каждого парня по имени Мохамед.   -  person Andrew Thompson    schedule 20.11.2011


Ответы (3)


Да, используя код Эндрю, я придумал что-то вроде этого:

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);
   }

}
person Hovercraft Full Of Eels    schedule 19.11.2011
comment
Это сделал не мой ум, а вот этот: Запись Андрея. Я не могу проголосовать за его ответ более одного раза, но я призываю всех, кто считает мой ответ полезным, проголосовать за ссылку. - person Hovercraft Full Of Eels; 20.11.2011
comment
(как вы все знаете, в том числе @Andrew Thompson, мне не очень нравятся html-обманки, особенно если они неправильно используются для жестко закодированного размера ‹g›), так почему бы не использовать фактическое with из списка вместо фиксированного? - person kleopatra; 20.11.2011
comment
Большое спасибо за пример!! Я очень ценю это!! - person koool; 20.11.2011
comment
Эй, @HovercraftFullOfEels, я только что попробовал этот код ... он у меня не работает .... Я ничего не разрабатываю в браузере, это чисто приложение Java, и оно не переносит текст ... не могли бы вы мне помочь. Вот что я сделал. Я добавил новый класс в свой проект MyCellRenderer, а затем добавил MyList.setCellRenderer(new MyCellRenderer(80)); в коде создания сообщения моего списка. Есть ли что-нибудь еще, что мне нужно сделать? Спасибо за помощь и терпение - person koool; 20.11.2011

Это можно сделать еще проще. Вы можете создать JList конструктором с помощью ListModel. В CustomListModel расширяет AbstractListModel, метод getElementAt() может возвращать строку с тем же текстом в формате html. Таким образом, сделайте то же самое без модификации модуля рендеринга ячеек.

person Dmitry V    schedule 09.01.2018
comment
Обертывание - это пользовательский интерфейс, а не модель. Изменение модели для адаптации к пользовательскому интерфейсу — это плохо. - person SurfMan; 09.01.2018

Вы также можете динамически вычислять ширину (вместо фиксированного значения):

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

Таким образом, если панель изменяет размер списка, перенос остается правильным.

Обновить

И результат выглядит так: введите здесь описание изображения

person steph    schedule 07.08.2012
comment
Это не работает. Если размер JList изменен, высота строки не будет изменена, и будут происходить забавные визуальные эффекты. Смотрите мое прикрепленное изображение... Я добавил зеленый и красный, чтобы проиллюстрировать. - person Jason; 18.03.2016