JTable中的单元validation

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

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

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

还可以考虑一个自定义的TableCellEditor ,可以在这里和下面看到。 如此处所示,添加InputVerifier是一个不错的选择。

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

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

图片

我试过一种方法。 我们可以使用TableCellRenderer并检查单元格中的数据,如果数据有错误,则只需将其显示为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 data; private List columnNames; public StudentTableModel() { data = getTableData(); columnNames = getTableColumnNames(); } public List getData() { return data; } public void setData(List 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 getTableData() { List list = new ArrayList(); 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 getTableColumnNames() { List columnNames = new ArrayList(); 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:请告诉我这是否是好方法。