Ячейка JTable не отражает изменений, хотя и доступна для редактирования

Для пользовательской TableModel я переопределяю isCellEditable, который всегда возвращает значение true.

Я также переопределяю setValueAt, но не знаю, как использовать этот метод, чтобы JTable отражал изменения, сделанные путем редактирования.

Ниже приведен модифицированный код для PersonTableModel:

class PersonTableModel extends AbstractTableModel{

    public int getRowCount(){
        return 10 ;
    }

    public int getColumnCount(){
        return 1 ;
    }

    public String getColumnName(int c){
        return "Name" ;
    }

    public Object getValueAt(int r, int c){
        return "Person " + ++r ;
    }

    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return true ; 
    }

    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        //what goes here
    }
}

С уважением, Ритс.


Редактировать:

Как было предложено членами формы, ниже приведен код, в котором я использую PersonTableModel: -

public class CustomTableModel{

    @SuppressWarnings("deprecation")
    public static void main(String[] args){
        JFrame frame = new PersonFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ;
        frame.show();
    }
}

class PersonFrame extends JFrame{

    @SuppressWarnings("deprecation")
    public PersonFrame(){
        setTitle("PersonTable");
        setSize(600, 300);

        TableModel model = new PersonTableModel() ;
        JTable table = new JTable(model);

        getContentPane().add(new JScrollPane(table), "Center") ;
        show() ;
    }
}

person mogli    schedule 24.10.2010    source источник


Ответы (2)


Расширьте DefaultTableModel, и тогда вам нужно будет только переопределить метод isCellEditable(...). Модель таблицы по умолчанию уже реализует метод setValueAt() в дополнение к другим полезным методам.

Если вы действительно хотите знать, что происходит в методе setValueAt(...), посмотрите исходный код DefaultTableModel, чтобы увидеть, как setValueAt() уведомляет представление об изменении модели, вызывая соответствующий метод fireXXX.

person camickr    schedule 24.10.2010
comment
Я изменил класс PersonTableModel, расширяющий AbstractTableModel, на класс PersonTableModel, расширяющий DefaultTableModel, а также удалил метод setValueAt из моего класса PersonTableModel. Но и тогда изменения не отражаются. - person mogli; 24.10.2010
comment
Тогда у вас есть еще одна проблема с вашим кодом. Вот почему вы должны начать с создания SSCCE (sscce.org). Затем вы можете опубликовать SSCCE, если у вас есть проблемы. - person camickr; 24.10.2010
comment
Я пробовал то, что вы предложили, но ячейка не обновляется, когда я ее редактирую. - person mogli; 25.10.2010
comment
Вы не используете DefaultTableModel. По умолчанию все ячейки доступны для редактирования, поэтому вам даже не нужно переопределять метод isCellEditable(), как я предлагал ранее. И вы до сих пор не опубликовали SSCCE, поэтому я не могу помочь. - person camickr; 25.10.2010

Я бы сказал, что ваша первая версия PersonTableModel уже очень близка. Я предполагаю, что вы хотите иметь таблицу с одним столбцом с заголовком «Имя», а затем в каждой строке имя, которое можно редактировать.
Причина, по которой ваши изменения не отображаются, заключается в том, что у вас нет базовой структуры данных для их сохранения. . Я бы предложил добавить массив строк для сохранения имен. Тогда код для вашей TableModel должен выглядеть так:

class PersonTableModel extends AbstractTableModel{

String[] data;

// I would add a constructor which fills the column initially with the
// values you want to have. Like "Person 1" "Person 2" and so on.
// You can also think about passing a size value here which determines
// the capacity of the table and therefore also the rows in the table. 
// (But this would require you to change the getRowCount method).
public PersonalTableModel(){
    data = new String[10]
    for(int i = 0; i<10; i++){
        data[i] = "Person "+i;
    }
}


public int getRowCount(){
    return 10 ;
}

public int getColumnCount(){
    return 1 ;
}

public String getColumnName(int c){
    return "Name" ;
}

// Since you dont have multiple columns you only need to pass the row here
public Object getValueAt(int r){
    // Simply get the corresponding String out of the data array
    return data[r];
}

public boolean isCellEditable(int rowIndex, int columnIndex) {
    return true ; 
}

// Here you also dont need to pass the column index
public void setValueAt(Object aValue, int rowIndex) {
    // Save the new name into the array
    data[rowIndex] = aValue.toString(); 
}

}

Надеюсь это поможет.

person gaussd    schedule 31.10.2010