5

我有一个 JTable,需要对用户可以输入文本的单元格进行单元格验证。当用户输入无效文本时,单元格的边框变为红色。

如果每个单元格是否有错误,我已经设法让这个工作关联一个二维数组来标记。

问题是用户必须能够重新排序表(按列)。我必须将错误标志存储在表模型中,而不是单独存储。任何人都有想法如何做到这一点?

4

2 回答 2

7

还要考虑一个 custom TableCellEditor,见这里和下面。添加一个InputVerifier,如此处所示是一个不错的选择。

由于用户必须能够按列重新排序表:

JTable提供从模型坐标转换为视图坐标的方法 -convertColumnIndexToViewconvertRowIndexToView- 以及从视图坐标转换为模型坐标的方法 -convertColumnIndexToModelconvertRowIndexToModel.

图片

于 2013-04-26T11:25:22.010 回答
4

我尝试了一种方法。我们可以使用 aTableCellRenderer并检查单元格中的数据,如果数据有错误,则只需将其显示在RED. 在这里,我有一个StudentTableModel将数据放到表中的方法。

错误检查

重新排序后

如果单元格包含特殊字符,则该表显示单元格 RED '@', '#', '$'。您仍然可以reorder使用表格,但渲染仍然会处理它。实现这一点不需要 AFAIK 标志。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

import com.amarnath.DragDrop.StudentTableModel;

public class TableErrorCheck {

    private JFrame frame;
    private JTable table;


    private void createUI() {

        frame = new JFrame();
        table = new JTable();
        table.setModel(new StudentTableModel());
        table.getColumnModel().getColumn(1).setCellRenderer(new ErrorCellRenderer());

        frame.setLayout(new BorderLayout());
        frame.add(new JScrollPane(table), BorderLayout.CENTER);
        frame.setTitle("Table Error Check.");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                new TableErrorCheck().createUI();
            }
        };

        EventQueue.invokeLater(r);
    }

}

class ErrorCellRenderer extends DefaultTableCellRenderer {

    private static final long serialVersionUID = 1L;

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
        Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
                row, column);

        if(value.toString().contains("@") || value.toString().contains("$") || value.toString().contains("#")) {
            component.setBackground(Color.RED);
        } else {
            component.setBackground(Color.WHITE);
        }

        return component;
    }
}


import java.util.ArrayList;
import java.util.List;

import javax.swing.table.AbstractTableModel;

public class StudentTableModel extends AbstractTableModel {

    private static final long serialVersionUID = 1L;

    private List<StudentDO> data;

    private List<String> columnNames;

    public StudentTableModel() {
        data = getTableData();
        columnNames = getTableColumnNames();
    }

    public List<StudentDO> getData() {
        return data;
    }

    public void setData(List<StudentDO> data) {
        this.data = data;
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        switch (columnIndex) {
        case 0:
            return Boolean.class;
        case 1:
            return String.class;
        case 2:
            return String.class;
        default:
            return String.class;
        }
    }

    @Override
    public String getColumnName(int column) {
        return columnNames.get(column);
    }

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

    @Override
    public int getRowCount() {
        if(data == null) {
            return 0;
        }
        return data.size();
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        if(columnIndex == 0 || columnIndex == 1) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        switch (columnIndex) {
        case 0:
            return data.get(rowIndex).isSelect();
        case 1:
            return data.get(rowIndex).getName();
        case 2:
            return data.get(rowIndex).getAge();
        default:
            return null;
        }
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        switch (columnIndex) {
        case 0:
            data.get(rowIndex).setSelect((Boolean) aValue);
            break;
        case 1:
            data.get(rowIndex).setName(aValue == null ? null : aValue.toString());
            break;
        case 2:
            data.get(rowIndex).setAge(aValue == null ? new Integer(0) : Integer.parseInt(aValue.toString()));
            break;
        default:
            break;
        }
    }

    /**
     * Add a row.
     * @param index
     * @param studentDO
     */
    public void addRow(int index, StudentDO studentDO) {
        data.add(index, studentDO);
        fireTableDataChanged();
    }

    private List<StudentDO> getTableData() {
        List<StudentDO> list = new ArrayList<StudentDO>();

        for(int i = 0; i< 5; i++) {
            StudentDO student = new StudentDO();
            student.setSelect(false);
            student.setName("Stu " + i);
            student.setAge(10 + i);
            student.setIdentifier("ToapTable");

            list.add(student);
        }

        return list;
    }

    private List<String> getTableColumnNames() {
        List<String> columnNames = new ArrayList<String>();
        columnNames.add("Select");
        columnNames.add("Name");
        columnNames.add("Age");

        return columnNames;
    }
}

public class StudentDO {

    private boolean select;
    private String name;
    private int age;
      // Removed Getters and Setters .
}

PS:请让我知道这是否是好方法。

于 2013-04-26T09:18:07.977 回答