Wednesday, February 11, 2009

Lazy tree content provider in SWT/JFace

I'm currently learning JAVA SWT/JFace for my pet project JSQLMaster (I will post more details about that project maybe other time :). So I was doing this project and I thought it would be grate to have lazy tree in my application. I believe this example could be useful for others so I post it here. Add TreeViewer to Application So in your ApplicationWindow you should add your tree viewer:
TreeViewer treeViewer = new TreeViewer(treePanel, SWT.BORDER | SWT.VIRTUAL);
treeViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 3));
treeViewer.setContentProvider(new DatabaseTreeContentProvider(getDatabase(), this));
treeViewer.setLabelProvider(new DatabaseTreeLabelProvider());
Construct TreeContentProvider Next you should construct your TreeContentProvider:
//Author: Darius Kucinskas (c) 2008-2009
//Email: d[dot]kucinskas[eta]gmail[dot]com
//Blog: http://blog-of-darius.blogspot.com/
//License: GPL

public class DatabaseTreeContentProvider implements ITreeContentProvider {
  
  public DatabaseTreeContentProvider(DatabaseWrapper db, SWTApp w){
    database = db;
    window = w;
  }

  @Override
  public Object[] getChildren(Object parentElement) {
    final DatabaseModelObject obj = (DatabaseModelObject)parentElement;
    
    if (obj.getType() == DATABASE_OBJECT_TYPE.DATABASE){
      if (obj.getChildren().size() == 0){
        List<string> types = database.getTableTypes();
        for(String typeName: types){
          DatabaseModelObject type = new DatabaseModelObject(typeName);
          type.setType(DATABASE_OBJECT_TYPE.TYPE);
          obj.addChild(type);
        }
      }
    } else if (obj.getType() == DATABASE_OBJECT_TYPE.TYPE){
      if (obj.getChildren().size() == 0){
        List<string> tables = database.getTables(obj.getName());
        for(String tableName: tables){
          DatabaseModelObject type = new DatabaseModelObject(tableName);
          type.setType(DATABASE_OBJECT_TYPE.TABLE);
          obj.addChild(type);
        }
      }
    } else if (obj.getType() == DATABASE_OBJECT_TYPE.TABLE){
      if (obj.getChildren().size() == 0){
        List<Map<string, string>> columns = database.getColumns(obj.getName());
        for(Map<string, string> column: columns){
          DatabaseModelObject columnName = new DatabaseModelObject(column.get("COLUMN_NAME"));
          columnName.setType(DATABASE_OBJECT_TYPE.COLUMN);
          obj.addChild(columnName);

          DatabaseModelObject columnType = new DatabaseModelObject(column.get("TYPE_NAME"));
          columnType.setType(DATABASE_OBJECT_TYPE.PROPERTY);
          columnName.addChild(columnType);
        }
      }
      return obj.getChildren().toArray();
    }

    @Override
    public Object getParent(Object element) {
      return ((DatabaseModelObject)element).getParent();
    }

    @Override
    public boolean hasChildren(Object element) {
      return true;
    }

    @Override
    public Object[] getElements(Object inputElement) {
      DatabaseModelObject obj = (DatabaseModelObject)inputElement;
      if (obj.getType() == DATABASE_OBJECT_TYPE.ROOT){
        if (obj.getChildren().size() == 0){
          DatabaseConfiguration dbCfg = database.getDatabaseConfiguration();
          String databaseName = dbCfg.getName();
          databaseName += "[" + dbCfg.getDriver() + "]";
          
          DatabaseModelObject db = new DatabaseModelObject(databaseName);
          db.setType(DATABASE_OBJECT_TYPE.DATABASE);
          obj.addChild(db);
        }
      }
      return obj.getChildren().toArray();
    }

    @Override
    public void dispose() {
    }

    @Override
    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
    }
    
    final private DatabaseWrapper database;
    final private SWTApp window;
}
Write Domain Model Next you should write your domain model:
//Author: Darius Kucinskas (c) 2008-2009
//Email: d[dot]kucinskas[eta]gmail[dot]com
//Blog: http://blog-of-darius.blogspot.com/
//License: GPL

public class DatabaseModelObject {
 public enum DATABASE_OBJECT_TYPE {NULL, ROOT, DATABASE, TYPE, TABLE, COLUMN, PROPERTY, PRIMARY_KEY, PROCEDURE};
 
 public DatabaseModelObject(String n) {
  name = n;
  children = new ArrayList<DatabaseModelObject>();
  parent = null;
  type = DATABASE_OBJECT_TYPE.NULL;
 }
 
 public String getName() {
  return name;
 }
 
 public String toString() {
  return getName();
 }
 
 public DatabaseModelObject getParent() {
  return parent;
 }
 
 public List getChildren(){
  return children;
 }
 
 public void addChild(DatabaseModelObject child) {
  children.add(child);
  child.setParent(this);
 }
 
 public void setParent(DatabaseModelObject p) {
  parent = p;
 }
 
 public DATABASE_OBJECT_TYPE getType() {
  return type;
 }
 
 public void setType(DATABASE_OBJECT_TYPE t) {
  type = t;
 }
 
 public void removeAllChilds(){
  children.clear();
 }

 private DATABASE_OBJECT_TYPE type;
 private String name = "";
 private List<DatabaseModelObject> children = null;
 private DatabaseModelObject parent = null;
}