1

I have a class that extends DataRow:

import org.jdesktop.dataset.DataRow;

public class MainDataRow extends DataRow {
  private MainDataTable baseDataTable;

  protected MainDataRow(MainDataTable dt) {
    super(dt);
    this.baseDataTable = dt;
  }

  public int    getId()                           { return (int)    super.getValue(baseDataTable.getColId()); };
  public void   setId(int id)                     {                 super.setValue(baseDataTable.getColId(), id); };
  public int    getDelta()                        { return (int)    super.getValue(baseDataTable.getColDelta()); };
  public void   setDelta(int delta)               {                 super.setValue(baseDataTable.getColDelta(), delta); };
  public String getNombre()                       { return (String) super.getValue(baseDataTable.getColNombre()); };
  public void   setNombre(String nombre)          {                 super.setValue(baseDataTable.getColNombre(), nombre); };

Also MainDataTable extends DataTable, and returns valid columns for getColId(), getColDelta(), getColNombre().

I would like to do:

MainDataTable dt = new MainDataTable(ds);
MainDataRow dr = (MainDataRow) dt.appendRow();

But this is not possible due to a CastClassException (dt.appendRow return DataRow and MainDataRow is extending DataRow, not vice versa, so the only possibility could be something similar to DataRow dr = (DataRow) new MainDataRow(dt);).

In c++ it can be easyly achieved through DataRowBuilder, overriding NewRowFromBuilder() in MainDataTable and overriding the protected creator from DataRowBuilder in MainDataRow (Casting DataRow to Strongly-Typed DataRow: How do they do it?).

How could I do it in Java?

Edit

MainDataTable class:

public class MainDataTable extends TypedDataTable<MainDataRow> {
...
}

And TypedDataTable class:

public abstract class TypedDataTable<TypeOfRow> extends DataTable {
  protected boolean locked;

  public TypedDataTable(DataSet ds, boolean appendRowSupported) {
    super(ds);
    InitClass();
    super.setAppendRowSupported(appendRowSupported);
    locked = false;
  }

  public Object clone() {
    try {
      return super.clone();
    } catch (CloneNotSupportedException e) {
      e.printStackTrace();
      return null;
    }
  }

  @Override
  public abstract DataRow appendRow();
  @Override
  public abstract DataRow appendRowNoEvent();
  public abstract void InitVars();
  public abstract void InitClass();

  public boolean isLocked() {
    return locked;
  }

  public void setLocked(boolean locked) {
    this.locked = locked;
  }
}
Community
  • 1
  • 1
Miquel
  • 8,339
  • 11
  • 59
  • 82
  • Your code is suspicious. Usually method 'appendRow' appends row to a table, so it should have one input argument - `row` and `void` return result. – Vadim Ponomarev May 07 '12 at 11:58
  • Not in swinglabs see[link]( http://download.java.net/javadesktop/swinglabs/releases/0.8/docs/api/org/jdesktop/dataset/DataTable.html#appendRow()) – Miquel May 07 '12 at 12:14

1 Answers1

1

Override appendRow() and appendRowNoEvent() in MainDataTable to return a MainDataRow

public abstract class TypedDataTable<TypeOfRow extends DataRow> extends DataTable {
  protected boolean locked;

  public TypedDataTable(DataSet ds, boolean appendRowSupported) {
    super(ds);
    InitClass();
    super.setAppendRowSupported(appendRowSupported);
    locked = false;
  }

  public Object clone() {
    try {
      return super.clone();
    } catch (CloneNotSupportedException e) {
      e.printStackTrace();
      return null;
    }
  }

 @Override
 public TypeOfRow appendRowNoEvent() {
     if (appendRowSupported) {
         TypeOfRow row = createDataRow(); //<-- HERE we create a MainDataRow!!!
         rows.add(row);
         return row;
     } else {
         return null;
     }
 }

 @Override
 public TypeOfRow appendRow() {
      return (TypeOfRow)super.appendRow();
 }

  public abstract TypeOfRow createDataRow();
  public abstract void InitVars();
  public abstract void InitClass();

  public boolean isLocked() {
    return locked;
  }

  public void setLocked(boolean locked) {
    this.locked = locked;
  }
}
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • It sounds good. Is this method appending the returned row in the table? So when iterating through baseDataTable rows I can find the new appened rows. In fact, if you are sure of this, if you agree, 4th line should be: _MainDataRow row = new MainDataRow(this)_ – Miquel May 07 '12 at 12:26
  • @Miguel I found the original code of DataTable and I updated my post to show you exactly how you can make this work. – Guillaume Polet May 07 '12 at 12:36
  • the first you provided worked, what is in solution now doesn't work because appendRow can not be casted to MainDataRow (it throws CastClassException). Thanks to you I reached the solution I'm going to post in a few. +1 for this if you could undo the edit and post previous response. – Miquel May 07 '12 at 12:59
  • 1
    @Miguel Have you overriden both methods? You should not get a ClassCastException in that case. In DataTable, the method that creates the DataRow is appendRowNoEvent. Since we override it to create a MainDataRow, we can safely cast it. See the original code here: http://kickjava.com/src/org/jdesktop/dataset/DataTable.java.htm My edit is actually a better way to do things since you don't have to worry about firing events. All you have to do is create a row and add it to the rows List – Guillaume Polet May 07 '12 at 13:13
  • I can't make your code working when MainDataTable extends TypedDataTable (edited the post to attach TypedDataTable. Anyway it works with your previous solution. – Miquel May 07 '12 at 13:28
  • I edited the question and put TyedDataTable. When adding appendRow to the MainDataTable, it says *"Cannot directly invoke the abstract method appendRow() for the type TypedDataTable"* I don't see how could I reach DataTable.appendRow with a TypedDataTable in the middle. (Well, only not declaring them in TypedDataTable, but I doesn't like too much because allows to make mistakes...) I agree with you that this is cleaner not having to worry about firing events. – Miquel May 07 '12 at 13:37
  • @Miguel I updated my post again to show how to make this work – Guillaume Polet May 07 '12 at 13:46