Search code examples
javaswtnattable

Data in the NatTable is not displayed


Objects are added, but they aren't displayed in the table. And the place for these two added objects in the table is allocated, but all cells are empty.

And could someone suggest good documentation on NatTable, or well-written source about NatTable?

    ArrayList<Student> students = new ArrayList<>();

    final ColumnGroupModel columnGroupModel = new ColumnGroupModel();
    ColumnHeaderLayer columnHeaderLayer;

    students.add(new Student("Andrey","1", new Exam("Math", 4)));
    students.add(new Student("John","2", new Exam("Physics", 5)));
    String[] propertyNames = { "Full Name", "Group", "Name", "Mark" };
    DefaultBodyDataProvider<Student> bodyDataProvider = new DefaultBodyDataProvider<Student>(students, propertyNames);
    ColumnGroupBodyLayerStack bodyLayer = new ColumnGroupBodyLayerStack(new DataLayer(bodyDataProvider), columnGroupModel);

    DefaultColumnHeaderDataProvider defaultColumnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames);
    DefaultColumnHeaderDataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(defaultColumnHeaderDataProvider);
    columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, bodyLayer, bodyLayer.getSelectionLayer());
    ColumnGroupHeaderLayer columnGroupHeaderLayer = new ColumnGroupHeaderLayer(columnHeaderLayer, bodyLayer.getSelectionLayer(), columnGroupModel);

    columnGroupHeaderLayer.addColumnsIndexesToGroup("Exams", 2, 3);
    columnGroupHeaderLayer.setGroupUnbreakable(2);

    final DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataProvider);
    DefaultRowHeaderDataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
    ILayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, bodyLayer, bodyLayer.getSelectionLayer());

    final DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider(defaultColumnHeaderDataProvider, rowHeaderDataProvider);
    DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
    ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, columnGroupHeaderLayer);

    GridLayer gridLayer = new GridLayer(
            bodyLayer,
            columnGroupHeaderLayer,
            rowHeaderLayer,
            cornerLayer);

    NatTable table = new NatTable(shell, gridLayer, false);
    table.configure();

Class Student and Exam

class Student {
   String name;
   String groupNumber;
   Exam exam = new Exam();

   public Student() { }

   public Student(String name, String groupNumber, Exam exam) {
    super();
    this.name = name;
    this.groupNumber = groupNumber;
    this.exam = exam;
   }
}

class Exam {
  String name;
  int mark;

  public Exam() { }

  public Exam(String name, int mark) {
    super();
    this.name = name;
    this.mark = mark;
  }
}

Solution

    1. Substitute

      NatTable table = new NatTable(shell, gridLayer, false);
      table.configure();
      

      with

      NatTable table = new NatTable(shell, gridLayer, true);
      

      so the table autoconfigure itself, otherwise you would have to specify the configurations yourself.

    2. DefaultBodyDataProvider uses reflection to get the data from the specified class, so Student must be a proper bean class, so it has to be public and must have the getters for its properties. If you also want to retrieve the Exam properties you could create the getters for them in 'Student':

      public class Student {
          String name;
          String groupNumber;
          Exam exam = new Exam();
      
          public Student() {
          }
      
          public Student(String name, String groupNumber, Exam exam) {
              super();
              this.name = name;
              this.groupNumber = groupNumber;
              this.exam = exam;
          }
      
          public String getName() {
              return name;
          }
      
          public String getGroupNumber() {
              return groupNumber;
          }
      
          public Exam getExam() {
              return exam;
          }
      
          public String getExamName() {
              return exam.getName();
          }
      
          public int getExamMark() {
              return exam.getMark();
          }
      
      }
      
      public class Exam {
          String name;
          int mark;
      
          public Exam() {
          }
      
          public Exam(String name, int mark) {
              super();
              this.name = name;
              this.mark = mark;
          }
      
          public String getName() {
              return name;
          }
      
          public int getMark() {
              return mark;
          }
      }
      
    3. propertyNames should contains the actual names of the variables in Student because they are used to retrieve the getters via reflection, for example:

      String[] propertyNames = { "name", "groupNumber", "examName", "examMark" };
      

      If you want to change the labels in the columns you could create a map to link the properties names with the desired labels and pass it to the column header:

      Map<String, String> propertyToLabelMap = new HashMap<String, String>();
      propertyToLabelMap.put("name", "Full Name");
      propertyToLabelMap.put("groupNumber", "Group");
      propertyToLabelMap.put("examName", "Name");
      propertyToLabelMap.put("examMark", "Mark");
      
      ...
      
      DefaultColumnHeaderDataProvider defaultColumnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);