Java Качели:Установить элемент, который отображается в JListBox

StackOverflow https://stackoverflow.com/questions/2253222

Вопрос

Существует ли сопоставимый механизм с .NET "set DisplayMember" для компонента JListBox Swing?

Переопределение toString() метода недостаточно, потому что я также хочу иметь возможность изменять элемент отображения во время выполнения.

Я также изучил возможность реализации своего собственного ListCellRenderer, но нашел это не очень удобным.

Есть ли более простой или элегантный подход?

Спасибо, что уделили мне время.

Это было полезно?

Решение 2

Я пришел к удовлетворительному решению, основанному на реализации пользовательского ListCellRenderer.

import java.awt.Component;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JList;
import javax.swing.ListCellRenderer;

public class DynamicCellRenderer implements ListCellRenderer {
    private final ListCellRenderer listCellRenderer;
    private String displayMember;

    public DynamicCellRenderer(String displayMember) {
        this(displayMember, new DefaultListCellRenderer());
    }

    public DynamicCellRenderer(String displayMember, ListCellRenderer wrapped) {
        listCellRenderer = wrapped;
        this.displayMember = displayMember;
    }

    @Override
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        Object displayMemberValue = getDisplayMemberValue(value);
        return listCellRenderer.getListCellRendererComponent(list, displayMemberValue, index, isSelected, cellHasFocus);
    }

    private Object getDisplayMemberValue(Object value) {
        // value is the domain class
        // only works if display member is a method, TODO: fallback to field
        // displayMember is something like "getName" -> value.getName() gets called
        try {
            return value.getClass().getMethod(displayMember).invoke(value);
        } catch (Exception ex) {
            // if anything went wrong it is the programmers fault -> propagate exception
            throw new RuntimeException(ex);
        }
    }

    public String getDisplayMember() {
        return displayMember;
    }

    public void setDisplayMember(String displayMember) {
        this.displayMember = displayMember;
    }

}

В вашем клиентском графическом коде вы можете сделать что-то вроде этого:

jListBox1.setCellRenderer(new DynamicCellRenderer("getName"));
...
...
// and later at some point
((DynamicCellRenderer) jListBox1.getCellRenderer()).setDisplayMember("getEmail");

Другие советы

Вам следует создать класс-оболочку вокруг вашего бизнес-объекта, который переопределяет toString().Таким образом, вы сохраняете свой собственный объект в чистоте и можете во время выполнения менять местами оболочки.

public class MyWrapper()
{
    private MyBusinessObject object;

    public String toString()
    {
        return object.getImportantString();
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top