2013-04-25 15 views
5

Ho una tabella J che richiede la convalida della cella per le celle in cui l'utente può inserire il testo. Quando un utente immette un testo non valido, il bordo della cella diventa rosso.Convalida cella in JTable

Sono riuscito a ottenere questo lavoro associando una matrice di due dimensioni da contrassegnare se ogni cella ha errori o meno.

Il problema è che l'utente deve essere in grado di riordinare la tabella (per colonna). Devo memorizzare il flag di errore nel modello di tabella, non separatamente. Qualcuno ha idee su come farlo?

+0

Un utente può modificare solo una cella alla volta. Non lasciare che aggiornino il modello finché i dati non sono validi. Non vedo alcuna necessità che una matrice bidimensionale tenga traccia dell'errore poiché tutti i dati nel modello dovrebbero sempre essere validi. – camickr

+0

Si può anche orientare lo stato di "errore" indicizzato dal modello. In questo modo è possibile convertire l'indice di vista nuovamente all'indice del modello, come richiesto. A me piace suggerire Camickr – MadProgrammer

risposta

4

Ho provato un approccio. Possiamo usare uno TableCellRenderer e controllare i dati nella cella e se i dati stanno avendo errori, basta mostrarli in RED. Qui ho un StudentTableModel che otterrà i dati alla tabella.

Error Check

After Reordering

La tabella riporta i globuli rossi se la cella contiene caratteri speciali come '@', '#', '$'. Puoi ancora reorder il tavolo ma il rendering si prenderà cura di esso. Le bandiere AFAIK non sono necessarie per raggiungere questo obiettivo.

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 . 
} 

P.S: Per favore fatemi sapere se questo è il buon approccio oppure no.

+1

+1 per usare 'TableCellRenderer' per evidenziare le celle. – trashgod

+0

@Che. Grazie. In effetti, questo è il mio approccio. ma ci sono 2 problemi: 1) alcune regole di validazione delle celle dipendono da 2 celle 2) come si può iterare attraverso i renderer di celle e controllare il colore dello sfondo? Ecco perché ho creato un array bidimensionale per controllare gli errori ... ma questo impedisce l'ordinamento delle righe (la mia domanda) –

+0

@AlexandreGoncalves Se hai bisogno di fare l'ordinamento, devi salvare i numeri delle righe. – Amarnath

6

Considerare anche un numero personalizzato TableCellEditor, visto here e sotto. Aggiungere uno hereInputVerifier è una buona alternativa.

Come l'utente deve essere in grado di riordinare la tabella per colonna:

JTable prevede metodi che convertono dal modello coordinate per visualizzare le coordinate - convertColumnIndexToView e convertRowIndexToView - e che converte da vista coordinate al modello coordinate - convertColumnIndexToModel e convertRowIndexToModel.

image

Problemi correlati