ArrayList to JList - более одного элемента объекта

Я использую Eclipse, программирую на Java. Эта проблема:

Вот как я хочу, чтобы мой JList отображался:

1 - Dante
2 - William
3 - Jaime
etc...

Теперь числа - это идентификаторы объектов, а имена - это, ну, имена.

ArrayList называется TraitList.

Это то, что я получаю, когда я помещаю это как свойство "model" в JList из Window Builder в Eclipse:

TraitL.setModel(new AbstractListModel() {
        String [] values = new String[] {"1 - Dante", "2 - William", "3 - Jaime"};
        public int getSize() {
            return values.length;
        }
        public Object getElementAt(int index) {
            return values[index];
        }
    });

Поэтому я изменил это для:

TraitL.setModel(new AbstractListModel() {
        String [] values = new String [];
        for (int jln = 0; jln < TraitList.size(); jln++){
            values [jln] = (TraitList.get(jln).id + " - " + TraitList.get(jln).Name);
        }
        public int getSize() {
            return values.length;
        }
        public Object getElementAt(int index) {
            return values[index];
        }
    });

Это не сработало. Я перепробовал десятки вариантов. Никто не работал. Итак, как мне сделать, чтобы несколько элементов объекта отображались в этом списке? Мне все равно, если это DefaultListModel или AbstractListModel, или даже ListModel. Заранее спасибо.

РЕДАКТИРОВАТЬ: ошибки всех строк с тем, что я пробовал, на следующем рисунке: ошибки

БОНУСНЫЙ ВОПРОС: Как сделать щелчок в элементе этого списка "actionPerformed", чтобы что-то происходило после того, как я щелкнул по нему?

4 ответа

Решение
new AbstractListModel() {
    String [] values = new String [];
    for (int jln = 0; jln < TraitList.size(); jln++){
        values [jln] = (TraitList.get(jln).id + " - " + TraitList.get(jln).Name);
    }
    public int getSize() {
        return values.length;
    }
    public Object getElementAt(int index) {
        return values[index];
    }
}

Это неверное определение анонимного класса, у вас есть код, плавающий в теле класса.

Это можно исправить, переместив инициализацию в закрытый метод:

String [] values = initTraitList();
private String[] initTraitList() {
    String [] values = new String [TraitList.size()];
    for (int jln = 0; jln < TraitList.size(); jln++){
        values [jln] = (TraitList.get(jln).id + " - " + TraitList.get(jln).Name);
    }
    return values;
}

или с помощью блока инициализации экземпляра:

String [] values = new String [TraitList.size()];
{
    for (int jln = 0; jln < TraitList.size(); jln++){
        values [jln] = (TraitList.get(jln).id + " - " + TraitList.get(jln).Name);
    }
}

Я думаю, что линия

String [jln] = (TraitList.get(jln).id + " - " + TraitList.get(jln).Name);

должно быть

values[jln] = (TraitList.get(jln).id + " - " + TraitList.get(jln).Name);

право?

Не должно быть необходимости копировать ваш список в локальную переменную. Вы можете, если хотите, но это не обязательно. Вот пример доступа к исходному списку непосредственно в вашей модели:

public static void main(String[] args) {
    List<String> values = Arrays.asList("A", "B", "C");
    JList list = new JList(new AbstractListModel() {
        public int getSize() {
            return values.size();
        }

        public Object getElementAt(int index) {
            return index + " - " + values.get(index);
        }
    });
    list.addListSelectionListener(e -> 
            System.out.println("Clicked " + list.getSelectedValue()));
    JFrame frame = new JFrame("List Test");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(list);
    frame.pack();
    frame.setVisible(true);
}

Если вы особенно хотите это в массиве внутри модели с индексами, встроенными в значение, то:

String[] valueCopy = IntStream.range(0, values.size())
    .mapToObj(i -> i + " - " + values.get(i))
    .toArray(new String[0]);
public int getSize() {
    return valueCopy.length;
}

public Object getElementAt(int index) {
    return valueCopy[index];
}

Это может быть достигнуто без модели:

String [] values = new String[] {"1 - Dante", "2 - William", "3 - Jaime"};
JList jlist = new JList(values);
scrollpane = new JScrollPane(jlist);
scrollpane.setViewportView(jlist);
Другие вопросы по тегам