2013-04-25 13 views
5

私は、ユーザーがテキストを入力できるセルのセル検証が必要なJTableを持っています。ユーザーが無効なテキストを入力すると、セルの境界線が赤色に変わります。JTableのセル検証

私は、各セルにエラーがあるかどうかを判断するために、2次元配列にフラグを付けることができました。

問題は、ユーザーが(列ごとに)表を並べ替えることができるということです。テーブルモデルにエラーフラグを格納する必要があります。誰でもこれを行う方法がありますか?

+0

ユーザーは、一度に1つのセルを編集することができます。データが有効になるまでモデルを更新させないでください。モデルのすべてのデータが常に有効であるため、2次元配列でエラーを追跡する必要はありません。 – camickr

+0

また、モデルによってインデックス付けされた "エラー"状態に向けることもできます。この方法で、必要に応じてビューインデックスをモデルインデックスに戻すことができます。私が好きなのは、 'TableCellRenderer'を使ってセルを強調表示するための、camickrの提案 – MadProgrammer

答えて

4

私は1つのアプローチを試みました。 TableCellRendererを使用してセル内のデータをチェックし、データにエラーがある場合はREDに表示します。ここで私はテーブルにデータを取得するStudentTableModelがあります。

Error Check

After Reordering

セルが'@', '#', '$'などの特殊文字が含まれている場合、テーブルはセル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 . 
} 

P.S:私はこれは良いアプローチであるかどうか教えてください。

+1

+1です。 – trashgod

+0

@Che。ありがとう。実際、これは私のアプローチです。 2つの問題があります:1)いくつかのセルバリデーションルールは2つのセルに依存しています2)どのようにセルレンダラを通して繰り返しを取得し、背景の色をチェックできますか?だから、私はエラーをチェックするために2次元配列を作成した...しかし、それは行のソートを防ぐ(私の質問) –

+0

@AlexandreGoncalves並べ替えを行う必要がある場合は、行番号を保存する必要があります。 – Amarnath

6

また、カスタム(here以下を参照)を考慮してください。図のようにInputVerifierを追加すると、hereのようになります。ユーザがカラムによってテーブルを並べ替えることができなければならないよう

: - convertColumnIndexToViewconvertRowIndexToView -

JTableモデルへ変換する方法を提供するには、座標を表示する座標とそのビューへ変換座標をモデル化するために座標 - convertColumnIndexToModelおよびconvertRowIndexToModel

image