java - JTable 不会更新 fireXXXXX() 事件

标签 java swing model-view-controller user-interface

我的项目中发生了一些错误的事情。抱歉,这里有很大一部分代码:

public abstract class RowTableModel<T> extends AbstractTableModel {
protected List<T> modelData;
protected List<String> columnNames;
@SuppressWarnings("rawtypes")
protected Class[] columnClasses;
protected Boolean[] isColumnEditable;
@SuppressWarnings("rawtypes")
private Class rowClass = Object.class;
private boolean isModelEditable = true;

@SuppressWarnings("rawtypes")
protected RowTableModel(Class rowClass) {
    setRowClass(rowClass);
}

protected RowTableModel(List<String> columnNames) {
    this(new ArrayList<T>(), columnNames);
}

protected RowTableModel(List<T> modelData, List<String> columnNames) {
    setDataAndColumnNames(modelData, columnNames);
}

@SuppressWarnings("rawtypes")
protected RowTableModel(List<T> modelData, List<String> columnNames, Class rowClass) {
    setDataAndColumnNames(modelData, columnNames);
    setRowClass(rowClass);
}

protected void setDataAndColumnNames(List<T> modelData, List<String> columnNames) {
    this.modelData = modelData;
    this.columnNames = columnNames;
    columnClasses = new Class[getColumnCount()];
    isColumnEditable = new Boolean[getColumnCount()];
    fireTableStructureChanged();
}

@SuppressWarnings("rawtypes")
protected void setRowClass(Class rowClass) {
    this.rowClass = rowClass;
}

@SuppressWarnings({"rawtypes", "unchecked"})
public Class getColumnClass(int column) {
    // Class columnClass = null;
    //
    // if (column < columnClasses.length)
    // columnClass = columnClasses[column];
    //
    // // Get the default class
    //
    // if (columnClass == null)
    // columnClass = super.getColumnClass(column);
    //
    // return columnClass;
    Class columnClass = getValueAt(0, column).getClass();
    if (columnClass != null) {
        return columnClass;
    } else {
        return String.class;
    }

}
public int getColumnCount() {
    return columnNames.size();
}

public String getColumnName(int column) {
    Object columnName = null;

    if (column < columnNames.size()) {
        columnName = columnNames.get(column);
    }

    return (columnName == null) ? super.getColumnName(column) : columnName.toString();
}

public int getRowCount() {
    return modelData.size();
}

public boolean isCellEditable(int row, int column) {
    Boolean isEditable = null;

    // Check is column editability has been set

    if (column < isColumnEditable.length)
        isEditable = isColumnEditable[column];

    return (isEditable == null) ? isModelEditable : isEditable.booleanValue();
}

public void addRow(T rowData) {
    insertRow(getRowCount(), rowData);
}

public T getRow(int row) {
    return modelData.get(row);
}

@SuppressWarnings("unchecked")
public T[] getRowsAsArray(int... rows) {
    List<T> rowData = getRowsAsList(rows);
    T[] array = (T[]) Array.newInstance(rowClass, rowData.size());
    return (T[]) rowData.toArray(array);
}

public List<T> getRowsAsList(int... rows) {
    ArrayList<T> rowData = new ArrayList<T>(rows.length);

    for (int i = 0; i < rows.length; i++) {
        rowData.add(getRow(rows[i]));
    }

    return rowData;
}

public void insertRow(int row, T rowData) {
    modelData.add(row, rowData);
    fireTableRowsInserted(row, row);
}

public void insertRows(int row, List<T> rowList) {
    modelData.addAll(row, rowList);
    fireTableRowsInserted(row, row + rowList.size() - 1);
}

public void insertRows(int row, T[] rowArray) {
    List<T> rowList = new ArrayList<T>(rowArray.length);

    for (int i = 0; i < rowArray.length; i++) {
        rowList.add(rowArray[i]);
    }

    insertRows(row, rowList);
}

public void moveRow(int start, int end, int to) {
    if (start < 0) {
        String message = "Start index must be positive: " + start;
        throw new IllegalArgumentException(message);
    }

    if (end > getRowCount() - 1) {
        String message = "End index must be less than total rows: " + end;
        throw new IllegalArgumentException(message);
    }

    if (start > end) {
        String message = "Start index cannot be greater than end index";
        throw new IllegalArgumentException(message);
    }

    int rowsMoved = end - start + 1;

    if (to < 0 || to > getRowCount() - rowsMoved) {
        String message = "New destination row (" + to + ") is invalid";
        throw new IllegalArgumentException(message);
    }

    // Save references to the rows that are about to be moved

    ArrayList<T> temp = new ArrayList<T>(rowsMoved);

    for (int i = start; i < end + 1; i++) {
        temp.add(modelData.get(i));
    }

    // Remove the rows from the current location and add them back
    // at the specified new location

    modelData.subList(start, end + 1).clear();
    modelData.addAll(to, temp);

    // Determine the rows that need to be repainted to reflect the move

    int first;
    int last;

    if (to < start) {
        first = to;
        last = end;
    } else {
        first = start;
        last = to + end - start;
    }

    fireTableRowsUpdated(first, last);
}

public void removeRowRange(int start, int end) {
    modelData.subList(start, end + 1).clear();
    fireTableRowsDeleted(start, end);
}

public void removeRows(int... rows) {
    for (int i = rows.length - 1; i >= 0; i--) {
        int row = rows[i];
        modelData.remove(row);
        fireTableRowsDeleted(row, row);
    }
}

public void replaceRow(int row, T rowData) {
    modelData.set(row, rowData);
    fireTableRowsUpdated(row, row);
}

@SuppressWarnings("rawtypes")
public void setColumnClass(int column, Class columnClass) {
    columnClasses[column] = columnClass;
    fireTableRowsUpdated(0, getColumnCount() - 1);
}

public void setColumnEditable(int column, boolean isEditable) {
    isColumnEditable[column] = isEditable ? Boolean.TRUE : Boolean.FALSE;
}

public void setModelEditable(boolean isModelEditable) {
    this.isModelEditable = isModelEditable;
}

public static String formatColumnName(String columnName) {
    if (columnName.length() < 3)
        return columnName;

    StringBuffer buffer = new StringBuffer(columnName);
    boolean isPreviousLowerCase = false;

    for (int i = 1; i < buffer.length(); i++) {
        boolean isCurrentUpperCase = Character.isUpperCase(buffer.charAt(i));

        if (isCurrentUpperCase && isPreviousLowerCase) {
            buffer.insert(i, " ");
            i++;
        }

        isPreviousLowerCase = !isCurrentUpperCase;
    }

    return buffer.toString().replaceAll("_", " ");
}

}

这是抽象表模型,我对其进行了如下扩展:

public class ProfessorTableModel extends RowTableModel<Professor> {

public ProfessorTableModel(List<Professor> modelData,
        List<String> columnNames) {
    super(modelData, columnNames);
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    Professor professor = super.getRow(rowIndex);
    switch (columnIndex) {
    case 0: {
        return professor.getId();
    }
    case 1: {
        return professor.getSurname();
    }
    case 2:{
        return professor.getName();
    }
    case 3:{
        return professor.getPatronymic();
    }
    case 4:{
        return professor.getMail();
    }
    case 5:{
        return professor.getPhone();
    }
    case 6:{
        return professor.getDays();
    }
    default:
        return null;
    }
}

@Override
public boolean isCellEditable(int row, int column) {
    return false;
}

像这样:

public class LessonTableModel extends RowTableModel<Lesson>{
    public LessonTableModel(List<Lesson> modelData,
            List<String> columnNames) {
        super(modelData, columnNames);
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Lesson lesson = super.getRow(rowIndex);
        switch (columnIndex) {
        case 0: {
            return lesson.getId();
        }
        case 1: {
            return lesson.getProfessor();
        }
        case 2:{
            return lesson.getCourse();
        }
        case 3:{
            return lesson.getGroup();
        }
        case 4:{
            return lesson.isLab();
        }
        default:
            return null;
        }
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        return false;
    }
}

因此,在模型的第一种情况下,我进行以下编辑:

int[] selectedIndexes = professorTable.getSelectedRows();
            if (selectedIndexes.length == 1) {
                int selectedIndex = professorTable.convertRowIndexToModel(professorTable.getSelectedRow());
                Professor professor = professorTableModel.getRow(selectedIndex);
                ProfessorFrame professorFrame = ProfessorFrame.show(professor);
                if (professorFrame.getDialogResult() == DialogResult.OK) {
                    professorTableModel.replaceRow(selectedIndex, professorFrame.getProfessor());
                }
            }   

在第二种情况下我几乎做同样的事情:

int[] selectedIndexes = lessonTable.getSelectedRows();
                    if (selectedIndexes.length == 1) {
                        int selectedIndex = lessonTable.convertRowIndexToModel(lessonTable.getSelectedRow());
                        Lesson lesson = lessonTableModel.getRow(selectedIndex);
                        LessonFrame lessonFrame = LessonFrame.show(lesson);
                        if (lessonFrame.getDialogResult() == DialogResult.OK) {
                            lessonTableModel.replaceRow(selectedIndex, lessonFrame.getLesson());
                        }
                    }

但在第一种情况下,表会正确更新,而在第二种情况下,会在单击表后应用更新。我知道有大量的代码字符串,但我真的希望有人可以提供帮助。 (尝试用 fireTableDataChanged 替换 fireTableRowInserted,但没有任何改变)

预先感谢大家,非常感谢您的帮助!

最佳答案

问题出在框架的形态上。 ProfessorFrame 是模态的,而 LessonFrame 不是。这就是为什么正确应用第一种情况下的更改会导致编辑的值被 Hook ,而在第二种情况下,代码执行时没有暂停(模态暂停),并且没有新值被 Hook 。感谢@HovercraftFullOfEels 的帮助和建议。

关于java - JTable 不会更新 fireXXXXX() 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10572006/

相关文章:

java - 根据 JTable 的列坐标定位组件

java - 从SecurityContextHolder获取电子邮件地址 spring java MVC

java - Spring Roo : difference between [controller scaffold --class] and [web mvc scaffold --class ]

Java SimpleDateFormat解析之谜

java - 安装补丁后Websphere丢失配置

java - 我应该如何为 JSF + Hibernate 应用程序中的简单 CRUD 操作设计类?

JSP - 如何查找名称 (Tomcat/MVC)

java - 在 Java 中多次使用相同的 ResultSet

java - Java 格式的 JFileChooser 路径

java - (Java) 类里面的困难