#java #swing #jlist
#java #swing #jlist
Вопрос:
Я работаю с JList и столкнулся с несколькими проблемами проектирования. что я хочу, так это графический интерфейс, который представляет список и позволяет пользователю добавлять или удалять из него значения.
Итак, я создал класс, который получает список
List<? exteds IDisplayable>
- IDisplayable — это простой интерфейс, который имеет строку DisplayString() . каждый объект, который хочет отображаться в списке, должен реализовать IDIsplayable.
Когда загружается моя форма с графическим интерфейсом, я перебираю список и выполняю
MylistModel.addElement(iDisplayable.getDisplayString()
Это потому, что я не хочу, чтобы он отображал toString () . Итак, я добавил метод.
Теперь мой вопрос заключается в том, как вернуть список в форму gui, которая его вызвала. Должен ли я повторить это и сравнить по имени? Это звучит ужасно.
Я думаю, что мне нужно поместить в мою ListModel объект, но отобразить другую toString. Должен ли я создать новую listmodel? Я даже не могу расширить AbstractListModel, потому что он использует toString.
Это единственное решение?
Комментарии:
1. вам следует прочитать руководство 😉
Ответ №1:
Как уже упоминалось, xxRenderer — это соавтор, который принимает решение обо всем визуальном представлении элемента, отображаемого в «компоненте коллекции» (таком как JList, JTable и т.д.). Если придерживаться базовой поддержки Swing, то лучше всего реализовать пользовательский рендерер. SwingX поддерживает более упрощенный подход, позволяя подключать отображение строк (и визуальные оформления, но это другая история): реализуйте пользовательское строковое значение (SwingX говорит о преобразователе строк) и передавайте его в средство визуализации SwingX, например
StringValue sv = new StringValue() {
@Override
public String getString(Object value) {
if (value instanceof MyObject) {
return .... // use MyObject properties to build a suitable rep
}
return TO_STRING.getString(value);
}
}
list.setCellRenderer(new DefaultListRenderer(sv));
// a bit of beauty: same rep is re-usable in other collection components
table.setCellRenderer(MyObject.class, new DefaultTableRenderer(sv);
comboBox.setRenderer(list.getCellRenderer());
tree.setTreeCellRenderer(new DefaultTreeRenderer(sv));
Другими словами: SwingX поддерживает унифицированное строковое представление во всех своих компонентах коллекции. Вся мощь этого подхода проявляется при сортировке / фильтрации / поиске: вся эта функциональность автоматически использует это пользовательское строковое представление, то есть пользователи по умолчанию сортируют / фильтруют / ищут по тому, что они видят — никаких дополнительных усилий, требуемых разработчиком 🙂
Ответ №2:
Вы могли бы создать объект-оболочку, который содержит IDisplayable объект и реализует метод toString(), который просто вызывает getDisplayString() для IDisplayable. Может быть, это не так приятно, но может быть лучше, чем создавать свою собственную модель списка.
Редактировать: Не уверен, почему это не появилось сначала. Но, похоже, ListCellRenderer
это действительно то, что вам нужно: http://download.oracle.com/javase/tutorial/uiswing/components/list.html
Комментарии:
1. то же примечание здесь — listmodel возвращает объект для getElementAt, и я все еще сталкиваюсь с той же проблемой toString (). Я должен сказать, что предложенное вами решение, хотя и akward, является довольно хорошим решением (тем не менее, swing не о чем писать дома).
2. @user450602, я думаю, вам также следует заглянуть в ListCellRenderer, я обновил свой ответ.
3. И это правильный ответ . Совсем забыл об этом. Ненавижу swing :-). 10x
4. комментарии @user450602 типа «Я ненавижу xx» обычно произносятся разработчиками, которые не слишком много знают о xx 😉
Ответ №3:
Должен ли я повторить это и сравнить по имени? звучит ужасно.
Это ужасно. Вы можете запросить индекс выбранного элемента, поэтому вам не нужно сравнивать, но вы можете сразу получить нужный объект. Вопрос в том, достаточно ли хорош этот быстрый и грязный подход. Как вы уже упоминали, новая модель списка была бы «чистым» решением.
Комментарии:
1. Да, но — getElementAt возвращает объект . Итак, у меня все еще есть проблема, когда он использует объект toString . и я не хочу, чтобы он это делал. Я хочу, чтобы он отображал мой метод DisplayString () . он отображает что-то еще.