В моем приложении Vaadin (v.23.2.6) я создаю компонент класса Book. Этот компонент имеет набор тегов. Теги извлекаются из базы данных и содержат два свойства — tagName и tagDescription. В моей форме пользовательского интерфейса я указал MultiSelectComboBox для тегов.
this.tagsField = new MultiSelectComboBox<>("Tags");
this.tagsField.setAllowCustomValue(true);
this.tagsField.setAutoOpen(false);
this.tagsField.setItemLabelGenerator(Tag::getTagName);
Это работает, но я хочу отображать значение tagDescription, когда курсор находится над tagName в списке выбора. Какой прослушиватель событий я могу использовать для этой цели? Должен ли я использовать уведомление или есть что-то еще, что может помочь мне с этой реализацией? Пожалуйста, порекомендуйте.
Хотя это технически возможно, вы не хотите прослушивать события наведения (наведения мыши) на сервере. Это излишне и приведет к большому количеству ненужного сетевого трафика. Вместо этого вы можете позаботиться об этом в клиенте с помощью Renderer. Например, используя стандартный атрибут HTML title
:
tagsField.setRenderer(LitRenderer.<Tag>of(
"<span title='${item.description}'>${item.name}</span>")
.withProperty("description", Tag::getTagDescription)
.withProperty("name", Tag::getTagName)
);
Виноват. Я заглянул в исходный код LitRenderer и понял, почему он выдает NPE. Я поместил код в конструктор, где задавал свойства всех полей. Неудивительно, что UI.getCurrent() возвращает null. Кстати, я думаю, что это ошибка, и строка litRendererCount = UI.getCurrent().getElement() .getProperty("__litRendererCount", 0); должен быть заменен на litRendererCount = (UI.getCurrent() == null)? 0 : UI.getCurrent().getElement() .getProperty("__litRendererCount", 0); Тем временем я переопределяю метод open() и переношу туда код. Сейчас это работает.
Можно ли использовать это решение для чего-то другого, кроме поля со списком? Я использовал его для присвоения тегов книгам. Теперь мне нужно отображать информацию о книге, включая теги. Я хочу показать их, как здесь, в SO (см. выше в вопросе).
Вы можете использовать VirtualList, который поддерживает рендереры: vaadin.com/docs/latest/components/virtual-list
Не думаю, что VirtualList здесь применим. Я думаю о чем-то вроде горизонтальной линии меток, отображающей tagName и отображающей tagDescription при наведении на нее указателя мыши. Тегов будет 2-3 (не более 5 точно). Кстати, будет ли исправлена ошибка в LitRenderer в ближайшее время?
Я добавил рекомендованный вами код: this.tagsField.setRenderer(LitRenderer.<Tag>of("<span title='${item.description}'>${item.name}</span>") .withProperty( "описание", Tag::getTagDescription).withProperty("name", Tag::getTagName)); Теперь он вызывает NPE: вызвано: java.lang.NullPointerException: null at com.vaadin.flow.data.renderer.LitRenderer.<init>(LitRenderer.java:80) ~[vaadin-renderer-flow-23.2. 6.jar:na] at com.vaadin.flow.data.renderer.LitRenderer.of(LitRenderer.java:128) ~[vaadin-renderer-flow-23.2.6.jar:na]