Вызов setValueAt не отправляет событие TableModel

Я написал личку TableModel, которая берет данные из db. Проблема в том, что когда я изменяю данные в таблице, я могу видеть эффект в таблице, но ни одно событие таблицы не завершается успешно. Кажется, что метод setValueAt не создает событие, но я вижу, что он обновляет ячейку таблицы. Очевидно добавляю в основную программу эти коды.

Я добавил их, чтобы показать, что это не работает

Stabili.java (источник данных из db)

package entity;

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;

@Entity
@Table(catalog = "", schema = "ROOT")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Stabili.findAll", query = "SELECT s FROM Stabili s"),})
public class Stabili implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(nullable = false)
private Long id;
@Basic(optional = false)
@Column(nullable = false, length = 50)
private String indirizzo;

public Stabili() {
}

public Stabili(Long id) {
    this.id = id;
}

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getIndirizzo() {
    return indirizzo;
}

public void setIndirizzo(String indirizzo) {
    this.indirizzo = indirizzo;
}
@Override
public int hashCode() {
    int hash = 0;
    hash += (id != null ? id.hashCode() : 0);
    return hash;
}

@Override
public boolean equals(Object object) {
    if (!(object instanceof Stabili)) {
        return false;
    }
    Stabili other = (Stabili) object;
    if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
        return false;
    }
    return true;
}

@Override
public String toString() {
    return "entity.Stabili[ id=" + id + " ]";
}
}

// модель таблицы StabiliTableModel.java

package prova;

import entity.Stabili;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.swing.event.EventListenerList;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

public class StabiliTableModel implements TableModel, TableModelListener{

protected EventListenerList listenerList = new EventListenerList();
private final EntityManager em;
private final TypedQuery<Stabili> qry;
private final List<Stabili> results;

public StabiliTableModel(EntityManager em){
    this.em = em;
    qry = em.createNamedQuery("Stabili.findAll",Stabili.class);
    results = qry.getResultList();
}

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

@Override
public int getColumnCount() {
    return 2;
}

@Override
public String getColumnName(int columnIndex) {
    switch (columnIndex){
        case 0:
            return "Id";
        case 1:
            return "Indirizzo";
    }
}

@Override
public Class<?> getColumnClass(int columnIndex) {
    return getValueAt(0, columnIndex).getClass();
}

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

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    switch (columnIndex){
                case 0:
                    return results.get(rowIndex).getId();
                case 1:
                    return results.get(rowIndex).getIndirizzo();
    }
}

@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    switch (columnIndex){
        case 1:
            results.get(rowIndex).setIndirizzo(aValue.toString());
    }
    fireTableCellUpdated(rowIndex,columnIndex);
}

@Override
public void addTableModelListener(TableModelListener l) {
}

@Override
public void removeTableModelListener(TableModelListener l) {
}

@Override
public void tableChanged(TableModelEvent e) {
    System.out.println(e.getColumn());
}

public void fireTableDataChanged(){
  fireTableChanged(new TableModelEvent(this, 0, Integer.MAX_VALUE));
}
public void fireTableStructureChanged(){
   fireTableChanged(new TableModelEvent(this, TableModelEvent.HEADER_ROW));
}

public void fireTableRowsInserted(int firstRow, int lastRow){
      fireTableChanged(new TableModelEvent(this, firstRow, lastRow,
                                           TableModelEvent.ALL_COLUMNS,
                                           TableModelEvent.INSERT));
}

public void fireTableRowsUpdated(int firstRow, int lastRow){
    fireTableChanged(new TableModelEvent(this, firstRow, lastRow,
                                       TableModelEvent.ALL_COLUMNS,
                                       TableModelEvent.UPDATE));
}


public void fireTableRowsDeleted(int firstRow, int lastRow)
{
  fireTableChanged(new TableModelEvent(this, firstRow, lastRow,
                                       TableModelEvent.ALL_COLUMNS,
                                       TableModelEvent.DELETE));
}


public void fireTableCellUpdated(int row, int column)
{
  fireTableChanged(new TableModelEvent(this, row, row, column));
}

public void fireTableChanged(TableModelEvent event){
    int    index;
    TableModelListener listener;
    Object[] list = listenerList.getListenerList();
    for (index = 0; index < list.length; index += 2){
      listener = (TableModelListener) list [index + 1];
      listener.tableChanged(event);
    }
}

}

// и, наконец, основной

package prova;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
 import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;


public class Prova extends JFrame{

private JTable mainTable,fixedTable;
private JScrollPane scrollPane;
private JTableHeader mainTableHeader;
private TableColumnModel originalColumnModel,mainColumnModel,fixedColumnModel;
private TableColumn[] columns;
private int ncols,counter;
private EntityManager em;

public Prova(){

    EntityManagerFactory emf = Persistence.createEntityManagerFactory("provaPU");
    em = emf.createEntityManager();

    StabiliTableModel mainTableModel = new StabiliTableModel(em);

    scrollPane = new JScrollPane();

    mainTable = new JTable(mainTableModel);

    mainTableModel.addTableModelListener(mainTableModel);
    scrollPane.setViewportView(mainTable);
    add(scrollPane, BorderLayout.CENTER);
    pack();
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
@Override
        public void run() {
    new Prova().setVisible(true);
        }
});
}
}

person Andrea    schedule 15.10.2015    source источник
comment
Возможный дубликат; расширить AbstractTableModel и запустить соответствующее событие в setValueAt(), как предлагается здесь.   -  person trashgod    schedule 15.10.2015
comment
Это не дубликат !!! Проблема в том, что я не ХОЧУ расширять AbtractTableModel, мне нужно реализовать TableModel. Ваше не является объяснением, потому что я думаю, что проблема в setValueAt, я переписал ее, но, вероятно, нет чего-то, что запускает событие ... но я не знаю что ..   -  person Andrea    schedule 16.10.2015


Ответы (1)


Как было предложено здесь, предпочтительный подход - расширить _ 1_ и активировать подходящий TableModelEvent в вашей реализации setValueAt(). DefaultTableModel является примером.

Я не хочу продлевать AbtractTableModel.

Некоторые альтернативы:

  • Делегируйте подкласс AbtractTableModel в вашем StabiliTableModel.

  • Добавьте экземпляр EventListenerList как член StabiliTableModel и запускайте собственные события, используя схему, описанную в EventListenerList API.

Нет ничего, что могло бы вызвать это событие, но я не знаю что.

Точно; вам нужно будет использовать существующий механизм событий или создать свой собственный.

person trashgod    schedule 16.10.2015
comment
Спасибо за ответ, не могли бы вы сделать мне пример этого - Делегирование подкласса AbtractTableModel в вашей StabiliTableModel. ИЛИ Добавьте экземпляр EventListenerList в качестве члена StabiliTableModel и запускайте свои собственные события, используя схему, описанную в EventListenerList API. - person Andrea; 17.10.2015
comment
Вот несколько примеров делегатов, ; jfreechart широко использует EventListenerList в своих наборах данных. - person trashgod; 18.10.2015
comment
К сожалению, я не могу решить эту проблему. Я попытался изменить StabiliTableModel и сделать его расширением AbstractTableModel, но это тоже не работает. - person Andrea; 18.10.2015
comment
Чтобы помочь изолировать проблему, отредактируйте свой вопрос, включив в него полный автономный пример, в котором основное внимание уделяется таблице и демонстрируется проблема. вы описываете. - person trashgod; 18.10.2015
comment
Ваша реализация setValueAt() должна запускать соответствующее событие для пример. - person trashgod; 20.10.2015