Переопределение getValueAt в AbstractTableModel для привязки Map к JTable

У меня есть следующий код:

    class Files {       
    private static String files;
    private static String duration;
    private static String status;

    public Files(String files, String duration, String status) {
        this.files = files;
        this.duration = duration;
        this.status = status;
    }

    public static String getfiles() {
        return files;
    }

    public static String getduration() {
        return duration;
    }

    public static String getstatus() {
        return status;
    }
}

    Map<Files, String> hmap = new HashMap<Files,String>();

    private void AddFiles(String addfile,String addurr,String addstatus, String addpath){       
    Files f = new Files(addfile, addurr, addstatus);                
    hmap.put(f, addpath);       
}
    final JTable table = new JTable();
    table.setBounds(26, 27, 664, 274);
    table.setModel(new MyTableModel());

Итак, я создаю новую таблицу и переопределяю «getValueAt».

        class MyTableModel extends AbstractTableModel {    
        @Override
        public int getColumnCount() {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public int getRowCount() {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
             switch (columnIndex) {
             case 0:
                    return Files.getfiles(); 
             case 1:
                    return Files.getduration();
             case 2:
                    return Files.getstatus();
             default:
                    throw new IndexOutOfBoundsException();
             }
        }
    }

Тем не менее, я не могу загрузить переменные из класса «Файлы» HashMap в JTable. Может ли кто-нибудь сказать мне, что я делаю неправильно? Я в основном застрял в течение 3 дней и был бы очень признателен за помощь.


person Omid    schedule 06.04.2013    source источник


Ответы (3)


Есть много вещей неправильных.

Во-первых, почему все поля и методы в Files статичны. Это означает, что экземпляр Files на самом деле вообще не имеет состояния и что все экземпляры Files используют одни и те же файлы, продолжительность и статус. Эти поля и методы, безусловно, должны быть вместо этого полями и методами экземпляра (т.е. вы должны удалить модификатор static).

Затем ваша модель реализует getColumnCount() и getRowCount(), возвращая 0. Это означает, что ваша таблица содержит 0 строк и 0 столбцов. Поэтому я не вижу смысла в использовании таблицы, если вы не собираетесь иметь в ней никакой ценности.

Метод getValueAt(), с другой стороны, подразумевает, что все строки содержат одни и те же значения, поскольку вы возвращаете одни и те же значения независимо от того, что содержит аргумент rowIndex.

Наконец, Вы говорите, что у вас есть Map<Files, String>, но не говорите, какой должна быть связь между этой картой и таблицей. Вы нигде не используете эту карту в своей модели, а поскольку код как таковой не имеет смысла, трудно догадаться, что на самом деле содержит карта и что на самом деле должна отображать таблица.

person JB Nizet    schedule 06.04.2013
comment
Спасибо за ваш вклад. довольно новичок в Java. Итак, я хочу, чтобы 3 переменные в файлах (файлы, продолжительность и статус) отображались в виде трех столбцов в JTable. - person Omid; 06.04.2013
comment
А какая связь с картой? Вы хотите отобразить один файл в таблице, которая, таким образом, будет иметь 1 строку и 3 столбца? Вы начали исправлять свой код на основе указаний, которые я вам уже дал? - person JB Nizet; 06.04.2013
comment
да, 1 строка и 3 столбца. Но как только значения будут добавлены на карту, они также будут добавлены в JTable. Да, я удалил всю статику. - person Omid; 06.04.2013
comment
Карту нельзя наблюдать. Вам придется вручную добавлять элемент в модель таблицы каждый раз, когда вы добавляете его на карту. Используйте List‹Files› для хранения строк вашей модели таблицы и реализуйте getRowCount() и getValueAt(), получая размер и элемент в заданном индексе строки соответственно. Прочтите docs.oracle.com/javase/tutorial/uiswing/components / - person JB Nizet; 06.04.2013
comment
согласился с List‹Whatever› вместо XxxMap, я бы предложил начать с DefaultTableModel на основе Vector == pretty new to Java - person mKorbel; 06.04.2013
comment
но мне нужна система пар ключ-значение, чтобы я мог получить значение для каждого элемента списка. - person Omid; 06.04.2013
comment
@mKorbel: я согласен с удобством DefaultTableModel, но AbstractTableModel может позволить меньше копировать данные. - person trashgod; 06.04.2013
comment
@trashgod эта абстракция не проста для понимания, ваши с JB Nizets знания и опыт так далеки..., :-) - person mKorbel; 06.04.2013
comment
Я близок к решению этого, скоро опубликую - person Omid; 06.04.2013

Мне нужна пара ключ/значение.

Для справки: EnvTableTest создает AbstractTableModel из существующего Map. Он использует keySet() карты для нулевого столбца и использует каждый ключ для получения значения для этой строки.

person trashgod    schedule 06.04.2013
comment
getenv не работает, когда ключ карты является классом. Как таковой: private final Map‹Files, String› list = System.getenv(); - person Omid; 06.04.2013
comment
@Omid: Верно, это просто похожий пример для сравнения. - person trashgod; 06.04.2013

Хорошо, только что нашел решение:

private final Map<Files, String> list = new LinkedHashMap<Files,String>();

class MyTableModel extends AbstractTableModel {

private String[] columnNames = {"File","Duration","Status"};

public void addElement(String addfile,String addurr,String addstatus, String addpath) {             
Files f = new Files(addfile, addurr, addstatus);                
list.put(f, addpath); // edit
fireTableRowsInserted(list.size()-1, list.size()-1);   
}

@Override
public int getColumnCount() {
return columnNames.length;
}

@Override
public int getRowCount() {
return list.size();
}

@Override
public String getColumnName(int col) {
return columnNames[col];
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {

List<Entry<Files,String>> randAccess = new ArrayList<Entry<Files,String>>(list.entrySet());

switch (columnIndex) {
case 0:
return randAccess.get(rowIndex).getKey().getfiles();
case 1:
return randAccess.get(rowIndex).getKey().getduration();
case 2:
return randAccess.get(rowIndex).getKey().getstatus();
default:
throw new IndexOutOfBoundsException();
        }
    }
}
person Omid    schedule 06.04.2013