-2

When I try to use this piece of code:

students.add(new Student("John","1", 3));
students.add(new Student("Chris","2", 2));
NatTable table = createTable(shell, students);
table.refresh();

NullPointerException appears, maybe it is because something is wrong with getters in Student class or maybe in generating the table. Also one of the messages when this problem appears is ReflectiveColumnPropertyAccessor.getDataValue. Also I need to fix ColumnGroup in NatTable to display many exams properly.

It gives me (the line 48 in my code is the Student Constructor):

WARNING: java.lang.NullPointerException
java.lang.RuntimeException: java.lang.NullPointerException
    at net.sourceforge.nattable.data.ReflectiveColumnPropertyAccessor.getDataValue(ReflectiveColumnPropertyAccessor.java:48)
at net.sourceforge.nattable.data.ListDataProvider.getDataValue(ListDataProvider.java:36)
at net.sourceforge.nattable.layer.DataLayer.getDataValueByPosition(DataLayer.java:289)
at net.sourceforge.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:319)
at net.sourceforge.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:319)
at net.sourceforge.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:319)
at net.sourceforge.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:319)
at net.sourceforge.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:319)
at net.sourceforge.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:319)
at net.sourceforge.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:319)
at net.sourceforge.nattable.layer.CompositeLayer.getDataValueByPosition(CompositeLayer.java:547)
at net.sourceforge.nattable.layer.cell.LayerCell.getDataValue(LayerCell.java:166)
at net.sourceforge.nattable.layer.cell.CellDisplayConversionUtils.convertDataType(CellDisplayConversionUtils.java:10)
at net.sourceforge.nattable.painter.cell.AbstractTextPainter.convertDataType(AbstractTextPainter.java:104)
at net.sourceforge.nattable.painter.cell.TextPainter.paintCell(TextPainter.java:96)
at net.sourceforge.nattable.painter.cell.CellPainterWrapper.paintCell(CellPainterWrapper.java:51)
at net.sourceforge.nattable.painter.cell.decorator.LineBorderDecorator.paintCell(LineBorderDecorator.java:64)
at net.sourceforge.nattable.painter.layer.CellLayerPainter.paintCell(CellLayerPainter.java:60)
at net.sourceforge.nattable.selection.SelectionLayerPainter.paintCell(SelectionLayerPainter.java:143)
at net.sourceforge.nattable.painter.layer.CellLayerPainter.paintLayer(CellLayerPainter.java:32)
at net.sourceforge.nattable.painter.layer.GridLineCellLayerPainter.paintLayer(GridLineCellLayerPainter.java:31)
at net.sourceforge.nattable.selection.SelectionLayerPainter.paintLayer(SelectionLayerPainter.java:34)
at net.sourceforge.nattable.layer.CompositeLayer$CompositeLayerPainter.paintLayer(CompositeLayer.java:898)
at net.sourceforge.nattable.painter.layer.NatLayerPainter.paintLayer(NatLayerPainter.java:26)
at net.sourceforge.nattable.NatTable.paintNatTable(NatTable.java:313)
at net.sourceforge.nattable.NatTable.paintControl(NatTable.java:309)
at org.eclipse.swt.widgets.TypedListener.handleEvent(Unknown Source)
at org.eclipse.swt.widgets.EventTable.sendEvent(Unknown Source)
at org.eclipse.swt.widgets.Display.sendEvent(Unknown Source)
at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
at org.eclipse.swt.widgets.Control.gtk_draw(Unknown Source)
at org.eclipse.swt.widgets.Composite.gtk_draw(Unknown Source)
at org.eclipse.swt.widgets.Canvas.gtk_draw(Unknown Source)
at org.eclipse.swt.widgets.Widget.windowProc(Unknown Source)
at org.eclipse.swt.widgets.Control.windowProc(Unknown Source)
at org.eclipse.swt.widgets.Display.windowProc(Unknown Source)
at org.eclipse.swt.internal.gtk.OS._gtk_main_do_event(Native Method)
at org.eclipse.swt.internal.gtk.OS.gtk_main_do_event(Unknown Source)
at org.eclipse.swt.widgets.Display.eventProc(Unknown Source)
at org.eclipse.swt.internal.gtk.OS._g_main_context_iteration(Native Method)
at org.eclipse.swt.internal.gtk.OS.g_main_context_iteration(Unknown Source)
at org.eclipse.swt.widgets.Display.readAndDispatch(Unknown Source)
at student.StudentMain.main(StudentMain.java:585)

My initial classes of Exam and Student.

public static class Student {
    private String name;
    private String groupNumber;
    private Exam[] exams;
    public Student() { }
    public Student(String name, String groupNumber, int numbOfExams) {
        this.name = name;
        this.groupNumber = groupNumber;
        this.exams = new Exam[numbOfExams];
        for(int i=0;i<numbOfExams;i++) {
            exams[i]= new Exam();
            this.exams[i].setName("");
            this.exams[i].setMark(0);
        }           
    }
    public String getName() {
        return name;
    }
    public String getGroupNumber() {
        return groupNumber;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setGroupNumber(String groupNumber) {
        this.groupNumber = groupNumber;
    }
    public void setExam(Exam[] exams) {
        this.exams = exams;
    }
    public Exam[] getExam() {
        return exams;
    }       
}
public static class Exam {
    private String name;
    private int mark;
    public Exam() { }
    public Exam(String name, int mark) {
        this.name = name;
        this.mark = mark;
    }
    public String getName() {
        return name;
    }
    public int getMark() {
        return mark;
    }    
    public void setName(String name) {
        this.name = name;
    }
    public void setMark(int mark) {
        this.mark = mark;
    }
}

My realization of NatTable

public static NatTable createTable(final Shell shell, ArrayList<Student> students) {
    final ColumnGroupModel columnGroupModel = new ColumnGroupModel();
    ColumnHeaderLayer columnHeaderLayer;

    String[] propertyNames = { "name", "groupNumber", "examName", "examMark" };
    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");
    DefaultBodyDataProvider<Student> bodyDataProvider = new DefaultBodyDataProvider<Student>(students, propertyNames);
    ColumnGroupBodyLayerStack bodyLayer = new ColumnGroupBodyLayerStack(new DataLayer(bodyDataProvider), columnGroupModel);

    DefaultColumnHeaderDataProvider defaultColumnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
    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, true);
    return table;
}
  • At which line are you getting NPE? – ikos23 May 05 '18 at 12:44
  • No stacktrace, no line number, ... how can anybody help? – UninformedUser May 05 '18 at 12:46
  • 1
    The first code snippet doesn’t say anything about `shell` instance. Where do you get it or how do you create it? – ikos23 May 05 '18 at 12:47
  • And how does your code compile given that you call `this.exams[i].setMark();` and the method signature `setMark(int mark)` requires an int value? – UninformedUser May 05 '18 at 12:47
  • I apologize for the inconsistencies. – Andrey Anischik May 05 '18 at 12:58
  • 4
    First of all, you are using an ancient version of NatTable. The SourceForge version is deprecated for several years as we moved to Eclipse about six years ago. You won't get much support for that version and probably stumble across many issues. I don't understand why people still use that one. Second, you have nested objects (Exam is below Student) and you expect that this can be magically inspected via reflection? Either implement a custom data provider or use the ExtendedReflectiveDataProvider with a correct property definition. A look in our getting started tutorial could help. – Dirk Fauth May 05 '18 at 13:57

1 Answers1

0

Your problem is that you have nested objects and you want to access them via reflection. That is not working!

If your Student would only have one exam, you would need to change the propertyNames to this:

String[] propertyNames = { "name", "groupNumber", "exam.name", "exam.mark" };

and the definition of the data provider to this:

IDataProvider bodyDataProvider =
            new ListDataProvider<>(
                    students,
                    new ExtendedReflectiveColumnPropertyAccessor<Student>(propertyNames));

But your Student class has an array of Exam objects. How do you want to visualize such a tree structure in a table? NatTable is able to do this, but then you need some more things like the TreeLayer etc. And that in turn does not work with your data structure.

I would suggest to first think about what you want to visualize, then check which control fits your needs (is it a table or a tree?), and then check for some tutorials that definitely exist, like the NatTable Getting Started Tutorial or the JFace Table tutorial or the JFace Tree tutorial

Dirk Fauth
  • 4,128
  • 2
  • 13
  • 23