Eclipse JFace Tutorial

1- Instroduction

Ensure that you understand  SWT, and you need to create a SWT Project before starting with JFace. You can see the SWT instruction at:

2- What is JFace

Eclipse JFace is an  API based on  SWTJFace provides classes and a basis for simplifying the use of SWT. JFace doesn't hide API SWT. Thus, the knowledge of SWT is basic and vital.

JFace helps:
  1. Simplifying the data model and visual display. For example, it simplifies data and display in Table, ComboBox, and Tree.
  2. JFace also provides helper layers for managing effectively your systemic resources such as color, image, and font.
  3. JFace supports controlling Preference pages, wizard and Dialog. It also provide features of icon decoration, and user-input supports for SWT controls.
JFace is used in Desktop applications and run well in RAP applications. In this document, Demos are instructed on the Desktop application.

3- The components of JFace

4- Create Project

Create SWT Project:
  • File/New/Project
  • Project name: JFaceTutorial
This Project run on the Desktop, and you select as the following illustration:
Enter:
  • Package name: org.o7planning.tutorial.jface
Project was created.
You need to declare a few required Bundle, namely the SWT and JFace OSGi. They are the SWT and JFace libraries.
Add Bundle:
  • org.eclipse.swt
Continue adding Bundle:
  • org.eclipse.jface
  • org.eclipse.jface.text
Once you add two above-mentioned Bundle JFace to Project,  on the design screen of WindowBuilder, components of JFace appear for drag and drop.
OK, now we start with JFace.

5- Resource Management

Create package:
  • org.o7planning.tutorial.jface.image
And copy a few images into Project:
  • check.png:
We look at how SWT manages data sources (Image, Color, Font) and how JFace manages.
  • File/New/Other...
Enter:
  • Package: org.o7planning.tutorial.jface.rs
  • Name: ResourceDemo

5.1- How SWT manage resource?

First see How SWT manage resource.
A class  SWTResourceManager is automatically created. It is a class with utility methods for managing image, Font, Color.
Tiếp tục đổi mầu chữ của Button:
See the code is generated in ResourceDemo class.
/**
* Create contents of the window.
*/
protected void createContents() {
   shlResourceDemo = new Shell();
   shlResourceDemo.setSize(336, 249);
   shlResourceDemo.setText("Resource Demo");
   shlResourceDemo.setLayout(new RowLayout(SWT.HORIZONTAL));
   
   Button btnButtonU = new Button(shlResourceDemo, SWT.NONE);
   btnButtonU.setFont(SWTResourceManager.getFont("Arial", 12, SWT.NORMAL));
   btnButtonU.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
   btnButtonU.setImage(SWTResourceManager.getImage(ResourceDemo.class, "/org/o7planning/tutorial/jface/image/check.png"));
   btnButtonU.setText("Button using SWT Resource Manager");
}

5.2- How JFace manages Resource

Now see JFace manages Resource.
import org.eclipse.jface.resource.FontDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;


// Create Resource Manager.
LocalResourceManager jfaceRsManager = new LocalResourceManager(
       JFaceResources.getResources(), shlResourceDemo);


Color color = jfaceRsManager.createColor(new RGB(200, 100, 0));
Font font = jfaceRsManager.createFont(FontDescriptor.createFrom(
       "Arial", 10, SWT.BOLD));

// Class in arguments, and image file is located on same Jar file.
ImageDescriptor imageDescriptor = ImageDescriptor.createFromFile(
       ResourceDemo.class,
       "/org/o7planning/tutorial/jface/image/check.png");

Image image = jfaceRsManager.createImage(imageDescriptor);
All of codes of  ResourceDemo.
package org.o7planning.tutorial.jface.rs;

import org.eclipse.jface.resource.FontDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.wb.swt.SWTResourceManager;

public class ResourceDemo {

   protected Shell shlResourceDemo;

   /**
    * Launch the application.
    *
    * @param args
    */
   public static void main(String[] args) {
       try {
           ResourceDemo window = new ResourceDemo();
           window.open();
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

   /**
    * Open the window.
    */
   public void open() {
       Display display = Display.getDefault();
       createContents();
       shlResourceDemo.open();
       shlResourceDemo.layout();
       while (!shlResourceDemo.isDisposed()) {
           if (!display.readAndDispatch()) {
               display.sleep();
           }
       }
   }

   /**
    * Create contents of the window.
    */
   protected void createContents() {
       shlResourceDemo = new Shell();
       shlResourceDemo.setSize(336, 249);
       shlResourceDemo.setText("Resource Demo");
       shlResourceDemo.setLayout(new RowLayout(SWT.HORIZONTAL));

       Button btnButtonU = new Button(shlResourceDemo, SWT.NONE);
       btnButtonU.setFont(SWTResourceManager.getFont("Arial", 12, SWT.NORMAL));
       btnButtonU.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
       btnButtonU.setImage(SWTResourceManager.getImage(ResourceDemo.class,
               "/org/o7planning/tutorial/jface/image/check.png"));
       btnButtonU.setText("Button using SWT Resource Manager");

       //

       Button button2 = new Button(shlResourceDemo, SWT.NONE);
       button2.setText("Button using JFace Resource Manager");

       LocalResourceManager jfaceRsManager = new LocalResourceManager(
               JFaceResources.getResources(), shlResourceDemo);

       
       Color color = jfaceRsManager.createColor(new RGB(200, 100, 0));
       Font font = jfaceRsManager.createFont(FontDescriptor.createFrom(
               "Arial", 10, SWT.BOLD));
       
       ImageDescriptor imageDescriptor = ImageDescriptor.createFromFile(
               ResourceDemo.class,
               "/org/o7planning/tutorial/jface/image/check.png");
       Image image = jfaceRsManager.createImage(imageDescriptor);

       button2.setFont(font);
       button2.setForeground(color);
       button2.setImage(image);
   }
}

6- Using Control Decoration

Decoration is a Widget used to decorate other Widgets in some situations. For example, to highlight a Text field requires input...
  • Package: org.o7planning.tutorial.jface.decoration
  • Name: DecorationDemo
DecorationDemo.java
package org.o7planning.tutorial.jface.decoration;

import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import swing2swt.layout.FlowLayout;

public class DecorationDemo {

  protected Shell shlDecorationDemo;
  private Text text;

  /**
   * Launch the application.
   * @param args
   */
  public static void main(String[] args) {
      try {
          DecorationDemo window = new DecorationDemo();
          window.open();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

  /**
   * Open the window.
   */
  public void open() {
      Display display = Display.getDefault();
      createContents();
      shlDecorationDemo.open();
      shlDecorationDemo.layout();
      while (!shlDecorationDemo.isDisposed()) {
          if (!display.readAndDispatch()) {
              display.sleep();
          }
      }
  }

  /**
   * Create contents of the window.
   */
  protected void createContents() {
      shlDecorationDemo = new Shell();
      shlDecorationDemo.setSize(327, 245);
      shlDecorationDemo.setText("Decoration Demo");
      shlDecorationDemo.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
     
      text = new Text(shlDecorationDemo, SWT.BORDER);
     
      ControlDecoration controlDecoration = new ControlDecoration(text, SWT.LEFT | SWT.TOP);
     
      controlDecoration.setDescriptionText("Some description");
     
      Image image = FieldDecorationRegistry.
                getDefault().
                getFieldDecoration(FieldDecorationRegistry.DEC_ERROR_QUICKFIX).
                getImage();
     
      controlDecoration.setImage(image);
  }

}
Results running class DecorationDemo:

7- JFace Viewer

SWT provides some controls:
  • List
  • Combo
  • Table
  • Tree
It is difficult to use it, and coding is lengthy. For example, when working with Table, to display data, you need to add each TableItem to Table. Each TableItem is a row of Table. Adding or removing a row is also lengthy .
The principle of JFace is to create a Viewer. Viewer wrap the control, so instead of working with control, we work with Viewer. Viewer helps you hiding the handling of data display. You just need to provide Content Provider and Label Provider for viewer through method:
  • Viewer.setContentProvider(IContentProvider)
  • Viewer.setLabelProvider(IBaseLabelProvider)
Set up input data for control through method:
  • Viewer.setInput(Object)
Therein:

Content Provider:
  • A class implements interface IContentProvider. It tells Viewer how to use input data, split those data into a set of Objects, each of which is one-line data (of Table, Tree, Combo, or List).
Label Provider:
  • A class manipulates interface  IBaseLabelProvider. It tells Viewer how to create a one-line Object, and in a specific columnIndex what image and Text display.

7.1- Some classes participated in the demo

There are some classes put in examples of this document, and they are used repeatedly many times.

Model:

AppMenu.java
package org.o7planning.tutorial.jface.model;

import java.util.List;

public class AppMenu {

  private String menuName;
  private String menuTitle;
  private List<AppMenu> children;

  public AppMenu(String menuName, String menuTitle, List<AppMenu> children) {
      this.menuName = menuName;
      this.menuTitle = menuTitle;
      this.children = children;
  }

  public String getMenuName() {
      return menuName;
  }

  public void setMenuName(String menuName) {
      this.menuName = menuName;
  }

  public String getMenuTitle() {
      return menuTitle;
  }

  public void setMenuTitle(String menuTitle) {
      this.menuTitle = menuTitle;
  }

  public List<AppMenu> getChildren() {
      return children;
  }

}
Article.java
package org.o7planning.tutorial.jface.model;

public class Article {

  private String title;
  private String author;
  private boolean published;

  public Article(String title, String author, boolean published) {
      this.title = title;
      this.author = author;
      this.published = published;
  }

  public String getTitle() {
      return title;
  }

  public void setTitle(String title) {
      this.title = title;
  }

  public String getAuthor() {
      return author;
  }

  public void setAuthor(String author) {
      this.author = author;
  }

  public boolean isPublished() {
      return published;
  }

  public void setPublished(boolean published) {
      this.published = published;
  }

}
Employee.java
package org.o7planning.tutorial.jface.model;

public class Employee {

  private String empNo;
  private String firstName;
  private String lastName;

  public Employee(String empNo, String firstName, String lastName) {
      this.empNo = empNo;
      this.firstName = firstName;
      this.lastName = lastName;
  }

  public String getEmpNo() {
      return empNo;
  }

  public void setEmpNo(String empNo) {
      this.empNo = empNo;
  }

  public String getFirstName() {
      return firstName;
  }

  public void setFirstName(String firstName) {
      this.firstName = firstName;
  }

  public String getLastName() {
      return lastName;
  }

  public void setLastName(String lastName) {
      this.lastName = lastName;
  }
}
Department.java
package org.o7planning.tutorial.jface.model;

import java.util.List;

public class Department {

  private String deptNo;
  private String deptName;
  private List<Employee> employees;

  public Department(String deptNo, String deptName, List<Employee> employees) {
      this.deptNo = deptNo;
      this.deptName = deptName;
      this.employees = employees;
  }

  public String getDeptNo() {
      return deptNo;
  }

  public void setDeptNo(String deptNo) {
      this.deptNo = deptNo;
  }

  public String getDeptName() {
      return deptName;
  }

  public void setDeptName(String deptName) {
      this.deptName = deptName;
  }

  public List<Employee> getEmployees() {
      return employees;
  }

}
DataModel.java
package org.o7planning.tutorial.jface.model;

import java.util.ArrayList;
import java.util.List;

public class DataModel {

  private static List<Article> articleList;
  private static List<Department> departmentList;
  private static List<AppMenu> appMenuList;

  public static List<Article> getArticles() {
      if (articleList == null) {
          articleList = new ArrayList<Article>();
          articleList.add(new Article("Java basic", "Tom", true));
          articleList
                  .add(new Article("Hibernate for beginners", "Tran", true));
          articleList.add(new Article("Maven for beginners", "Smith", false));
      }
      return articleList;
  }

  public static List<Department> getDepartments() {
      if (departmentList == null) {

          Employee emp11 = new Employee("E11", "Michael", "Smith");
          Employee emp12 = new Employee("E12", "Susan", "Barker");
          List<Employee> empList1 = new ArrayList<Employee>();
          empList1.add(emp11);
          empList1.add(emp12);

          Department dept1 = new Department("D01", "Operation", empList1);
          //
          Employee emp21 = new Employee("E21", "Robert", "Tyler");
          List<Employee> empList2 = new ArrayList<Employee>();
          empList2.add(emp21);

          Department dept2 = new Department("D02", "Adminstration", empList2);
          //
          departmentList = new ArrayList<Department>();

          departmentList.add(dept1);
          departmentList.add(dept2);
      }
      return departmentList;
  }

  public static List<AppMenu> getAppMenus() {
      if (appMenuList == null) {
          appMenuList = new ArrayList<AppMenu>();

          AppMenu appMenu31 = new AppMenu("ErrorLog", "Error Log", null);
          AppMenu appMenu32 = new AppMenu("ProjectExplorer",
                  "Project Explorer", null);

          List<AppMenu> list3 = new ArrayList<AppMenu>();
          list3.add(appMenu31);
          list3.add(appMenu32);

          AppMenu appMenu21 = new AppMenu("ShowView", "Show View", list3);
          AppMenu appMenu22 = new AppMenu("ClosePerspective",
                  "Close perspective...", null);
          List<AppMenu> list2 = new ArrayList<AppMenu>();
          list2.add(appMenu21);
          list2.add(appMenu22);

          AppMenu appMenu1 = new AppMenu("Window", "Window", list2);

          appMenuList.add(appMenu1);
      }
      return appMenuList;
  }

}

Content/Label Provider:

AbstractComboContentLabelProvider.java
package org.o7planning.tutorial.jface.provider;

import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.graphics.Image;

public abstract class AbstractComboContentLabelProvider implements
      IStructuredContentProvider, ILabelProvider {

  @Override
  public void dispose() {

  }

  @Override
  public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {

  }

  @Override
  public void addListener(ILabelProviderListener listener) {
  }

  @Override
  public boolean isLabelProperty(Object element, String property) {
      return false;
  }

  @Override
  public void removeListener(ILabelProviderListener listener) {

  }

  @Override
  public Image getImage(Object element) {
      return null;
  }
}
AbstractTableContentLabelProvider.java
package org.o7planning.tutorial.jface.provider;

import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.graphics.Image;

public abstract class AbstractTableContentLabelProvider implements
      ITableLabelProvider, IStructuredContentProvider {

  @Override
  public void dispose() {

  }

  @Override
  public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {

  }

  @Override
  public void addListener(ILabelProviderListener listener) {

  }

  @Override
  public boolean isLabelProperty(Object element, String property) {
      return false;
  }

  @Override
  public void removeListener(ILabelProviderListener listener) {

  }

  @Override
  public Image getColumnImage(Object element, int columnIndex) {
      return null;
  }

}
AbstractTreeContentLabelProvider.java
package org.o7planning.tutorial.jface.provider;

import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.graphics.Image;

public abstract class AbstractTreeContentLabelProvider implements
      ITreeContentProvider, ILabelProvider {

  @Override
  public void dispose() {

  }

  @Override
  public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {

  }

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

  @Override
  public void addListener(ILabelProviderListener listener) {

  }

  @Override
  public boolean isLabelProperty(Object element, String property) {
      return false;
  }

  @Override
  public void removeListener(ILabelProviderListener listener) {
  }

  @Override
  public Image getImage(Object element) {
      return null;
  }

}
AbstractTreeTableContentLabelProvider.java
package org.o7planning.tutorial.jface.provider;

import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.graphics.Image;

public abstract class AbstractTreeTableContentLabelProvider implements
      ITreeContentProvider, ITableLabelProvider {

  @Override
  public void dispose() {
  }

  @Override
  public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
  }

  @Override
  public void addListener(ILabelProviderListener listener) {
  }

  @Override
  public boolean isLabelProperty(Object element, String property) {
      return false;
  }

  @Override
  public void removeListener(ILabelProviderListener listener) {
  }

  @Override
  public Image getColumnImage(Object element, int columnIndex) {
      return null;
  }

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

}

7.2- JFace TableViewer

With TableViewer. Content/Label Provider should use is:
  • Content Provider: implements IStructuredContentProvider
  • Label Provider: implements ITableLabelProvider
  • File/New/Other...
Enter:
  • Package: org.o7planning.tutorial.jface.tableviewer1
  • Name: TableViewerDemo
  • Select: protected createContents() method
    • (The code will be generated in this method).
Set up FillLayout for shell by selecting the FillLayout icon and clicking on the Shell screen.
Create two columns for the table by selecting the  TableColumn icon and putting it on the screen. Simultaneously, change the titles of columns as illustrated below.
Class ArticleTableCLProvider extends AbstractTableContentLabelProvider, It is a Content Provider and Label Provider
ArticleTableCLProvider.java
package org.o7planning.tutorial.jface.tableviewer1;

import java.util.List;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.o7planning.tutorial.jface.model.Article;
import org.o7planning.tutorial.jface.provider.AbstractTableContentLabelProvider;

public class ArticleTableCLProvider extends AbstractTableContentLabelProvider {

    private Image image;

    public ArticleTableCLProvider() {
        LocalResourceManager jfaceRsManager = new LocalResourceManager(
                JFaceResources.getResources(),
                Display.getCurrent().getShells()[0]);

        ImageDescriptor imageDescriptor = ImageDescriptor.createFromFile(
                ArticleTableCLProvider.class,
                "/org/o7planning/tutorial/jface/image/check.png");
        image = jfaceRsManager.createImage(imageDescriptor);
    }

    @Override
    public String getColumnText(Object element, int columnIndex) {
        Article article = (Article) element;
        switch (columnIndex) {

         // 0 - For first column
        case 0:
            return article.getTitle();
 
        // 1 - For Second column
        case 1:
            return article.getAuthor();
        default:
            return null;
        }
    }

    @Override
    public Image getColumnImage(Object element, int columnIndex) {
        Article article = (Article) element;
        switch (columnIndex) {
 
        // 0 - For first column
        case 0:
            if (article.isPublished()) {
                return image;
            }
        default:
            return null;
        }
    }

 
    // see: viewer.setInput(..)
    @Override
    public Object[] getElements(Object input) {
        List<Article> list = (List<Article>) input;
        return list.toArray();
    }

}
Thêm một số đoạn code vào TableViewerDemo
//
ArticleTableCLProvider provider = new ArticleTableCLProvider();        
tableViewer.setContentProvider(provider);        
tableViewer.setLabelProvider(provider);  

// Set InputData for TableViewer.
List<Article> articleList= DataModel.getArticles();
tableViewer.setInput(articleList);
Like the illustration below.
And here is the result of running class TableViewerDemo:
Entire code of TableViewerDemo
TableViewerDemo.java
package org.o7planning.tutorial.jface.tableviewer1;

import java.util.List;

public class TableViewerDemo {

    protected Shell shlTableviewerdemo;
    private Table table;

    /**
     * Launch the application.
     * @param args
     */
    public static void main(String[] args) {
        try {
            TableViewerDemo window = new TableViewerDemo();
            window.open();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Open the window.
     */
    public void open() {
        Display display = Display.getDefault();
        createContents();
        shlTableviewerdemo.open();
        shlTableviewerdemo.layout();
        while (!shlTableviewerdemo.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }

    /**
     * Create contents of the window.
     */
    protected void createContents() {
        shlTableviewerdemo = new Shell();
        shlTableviewerdemo.setSize(366, 277);
        shlTableviewerdemo.setText("TableViewerDemo");
        shlTableviewerdemo.setLayout(new FillLayout(SWT.HORIZONTAL));
        
        TableViewer tableViewer = new TableViewer(shlTableviewerdemo, SWT.BORDER | SWT.FULL_SELECTION);        
        
        // Content Provider & Label Provider.
        ArticleTableCLProvider provider = new ArticleTableCLProvider();        
        tableViewer.setContentProvider(provider);        
        tableViewer.setLabelProvider(provider);        
        
        table = tableViewer.getTable();
        table.setLinesVisible(true);
        table.setHeaderVisible(true);
        
        TableColumn tblclmnNewColumn = new TableColumn(table, SWT.NONE);
        tblclmnNewColumn.setWidth(148);
        tblclmnNewColumn.setText("Article");
        
        TableColumn tblclmnNewColumn_1 = new TableColumn(table, SWT.NONE);
        tblclmnNewColumn_1.setWidth(119);
        tblclmnNewColumn_1.setText("Author");
        
        // Set input data to TableViewer
        List<Article> articleList= DataModel.getArticles();
        tableViewer.setInput(articleList);

    }

}
Add, remove row of the table.
// Get TableViewer data.
List<Article> input = (List<Article>)tableViewer.getInput();

// Add row
Article newArticle = .... ;
input.add(newArticle);

// Refresh row
tableViewer.refresh(newArticle);
// Or
tableViewer.refresh();

// remove row
input.remove(<article>);

tableViewer.refresh();

7.3- JFace Tree Table Viewer

With TreeViewer show as Tree and Table. Content/Label Provider should use is:
  • Content Provider: implements ITreeContentProvider
  • Label Provider: implements ITableLabelProvider
Example:
DeptEmpTreeTableCLProvider.java
package org.o7planning.tutorial.jface.treetable1;

import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.o7planning.tutorial.jface.model.Department;
import org.o7planning.tutorial.jface.model.Employee;
import org.o7planning.tutorial.jface.provider.AbstractTreeTableContentLabelProvider;

public class DeptEmpTreeTableCLProvider extends
     AbstractTreeTableContentLabelProvider {

 private Image EMP_IMAGE;
 private Image DEPT_IMAGE;

 public DeptEmpTreeTableCLProvider() {
    // Dùng tạm ảnh của có sẵn trong hệ thống để minh họa
   
     DEPT_IMAGE = Display.getCurrent().getSystemImage(SWT.ICON_INFORMATION);
   
     EMP_IMAGE = Display.getCurrent().getSystemImage(SWT.ICON_ERROR  );
 }

 @Override
 public Object[] getElements(Object inputElement) {
     List<Department> departments = (List<Department>) inputElement;
     return departments.toArray();
 }

 @Override
 public Object[] getChildren(Object parentElement) {
     if (parentElement instanceof Department) {
         Department dept = (Department) parentElement;
         List<Employee> emps = dept.getEmployees();
         return emps == null ? null : emps.toArray();
     } else {
         // Employee has no children
         return null;
     }
 }

 @Override
 public boolean hasChildren(Object element) {
     if (element instanceof Department) {
         Department dept = (Department) element;
         List<Employee> emps = dept.getEmployees();
         return emps != null && !emps.isEmpty();
     } else {
         // Employee has no children
         return false;
     }
 }

 @Override
 public String getColumnText(Object element, int columnIndex) {
     if (element instanceof Department) {
         Department dept = (Department) element;
         switch (columnIndex) {
         case 0:
             return dept.getDeptNo();
         case 1:
             return dept.getDeptName();
         default:
             return null;
         }
     } else {
         Employee emp = (Employee) element;
         switch (columnIndex) {
         case 2:
             return emp.getEmpNo();
         case 3:
             return emp.getFirstName();
         case 4:
             return emp.getLastName();
         default:
             return null;
         }
     }
 }

 @Override
 public Image getColumnImage(Object element, int columnIndex) {
     if (element instanceof Department) {
         switch (columnIndex) {
         case 0:
             return DEPT_IMAGE;
         default:
             return null;
         }
     } else {
         switch (columnIndex) {
         case 2:
             return EMP_IMAGE;
         default:
             return null;
         }
     }
 }

}
Edit code of TreeTableViewerDemo:
View the entire code of the class TreeTableViewerDemo:
TreeTableViewerDemo.java
package org.o7planning.tutorial.jface.treetable1;

import org.eclipse.swt.widgets.Display;

public class TreeTableViewerDemo {

  protected Shell shlTreeTableViewer;

  /**
   * Launch the application.
   * @param args
   */
  public static void main(String[] args) {
      try {
          TreeTableViewerDemo window = new TreeTableViewerDemo();
          window.open();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

  /**
   * Open the window.
   */
  public void open() {
      Display display = Display.getDefault();
      createContents();
      shlTreeTableViewer.open();
      shlTreeTableViewer.layout();
      while (!shlTreeTableViewer.isDisposed()) {
          if (!display.readAndDispatch()) {
              display.sleep();
          }
      }
  }

  /**
   * Create contents of the window.
   */
  protected void createContents() {
      shlTreeTableViewer = new Shell();
      shlTreeTableViewer.setSize(438, 226);
      shlTreeTableViewer.setText("Tree Table Viewer");
      shlTreeTableViewer.setLayout(new FillLayout(SWT.HORIZONTAL));
     
      TreeViewer treeViewer = new TreeViewer(shlTreeTableViewer, SWT.BORDER);
     
      DeptEmpTreeTableCLProvider provider= new DeptEmpTreeTableCLProvider();
      treeViewer.setContentProvider(provider);
      treeViewer.setLabelProvider(provider);
             
      Tree tree = treeViewer.getTree();
      tree.setLinesVisible(true);
      tree.setHeaderVisible(true);
     
      TreeColumn trclmnDeptNo = new TreeColumn(tree, SWT.NONE);
      trclmnDeptNo.setWidth(71);
      trclmnDeptNo.setText("Dept No");
     
      TreeColumn trclmnDeptName = new TreeColumn(tree, SWT.NONE);
      trclmnDeptName.setWidth(79);
      trclmnDeptName.setText("Dept Name");
     
      TreeColumn trclmnEmpNo = new TreeColumn(tree, SWT.NONE);
      trclmnEmpNo.setWidth(69);
      trclmnEmpNo.setText("Emp No");
     
      TreeColumn trclmnFirstName = new TreeColumn(tree, SWT.NONE);
      trclmnFirstName.setWidth(77);
      trclmnFirstName.setText("First Name");
     
      TreeColumn trclmnLastName = new TreeColumn(tree, SWT.NONE);
      trclmnLastName.setWidth(100);
      trclmnLastName.setText("Last Name");
     
      treeViewer.setInput(DataModel.getDepartments());
  }

}
Results of running the example:
Add to remove row of TreeViewer
// Get data of TreeViewer.
List<Department> input = (List<Department>)treeViewer.getInput();

Department dept =  input.get(0);
List<Employee> empList  = dept.getEmployees();

// Add employee for Department.
empList.add(newEmployee);

// Refresh
treeViewer.refresh(dept);
// or
treeViewer.refresh();

// Remove row similar.

7.4- JFace TreeViewer

With TreeViewer show as Tree and Table. Content/Label Provider should use is:
  • Content Provider: implements ITreeContentProvider
  • Label Provider: implements ITableLabelProvider
With Tree (one column, not Table):
  • Content Provider: implements ITreeContentProvider
  • Label Provider: implements ILabelProvider

Note: Interface ITableLabelProvider extends from interface ILabelProvider

Example:
You can add a TreeColumn to Tree, or we don't need any TreeColumn. In the following illustration, I use a Tree without a TreeColumn.

In the case of a Tree with  Column, you can set up the title of columns, but sometimes it is unnecessary.

AppMenuTreeCLProvider.java
package org.o7planning.tutorial.jface.treeviewer1;

import java.util.List;

import org.o7planning.tutorial.jface.model.AppMenu;
import org.o7planning.tutorial.jface.provider.AbstractTreeContentLabelProvider;

public class AppMenuTreeCLProvider extends AbstractTreeContentLabelProvider {

  @Override
  public String getText(Object element) {
      AppMenu appMenu= (AppMenu) element;
      return appMenu.getMenuTitle();
  }

  @Override
  public Object[] getElements(Object inputElement) {
      List<AppMenu> menus = (List<AppMenu>) inputElement;
      return menus.toArray();
  }

  @Override
  public Object[] getChildren(Object parentElement) {
       AppMenu menu= (AppMenu) parentElement;
       List<AppMenu> children= menu.getChildren();
       return children== null? null: children.toArray();
  }

  @Override
  public boolean hasChildren(Object element) {
       AppMenu menu= (AppMenu) element;
       List<AppMenu> children= menu.getChildren();
       return children!= null&&!children.isEmpty();
  }

}
TreeViewerDemo.java
package org.o7planning.tutorial.jface.treeviewer1;

import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.o7planning.tutorial.jface.model.DataModel;

public class TreeViewerDemo {

  protected Shell shlTreeviewerDemo;

  /**
   * Launch the application.
   * @param args
   */
  public static void main(String[] args) {
      try {
          TreeViewerDemo window = new TreeViewerDemo();
          window.open();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

  /**
   * Open the window.
   */
  public void open() {
      Display display = Display.getDefault();
      createContents();
      shlTreeviewerDemo.open();
      shlTreeviewerDemo.layout();
      while (!shlTreeviewerDemo.isDisposed()) {
          if (!display.readAndDispatch()) {
              display.sleep();
          }
      }
  }

  /**
   * Create contents of the window.
   */
  protected void createContents() {
      shlTreeviewerDemo = new Shell();
      shlTreeviewerDemo.setSize(246, 202);
      shlTreeviewerDemo.setText("TreeViewer Demo");
      shlTreeviewerDemo.setLayout(new FillLayout(SWT.HORIZONTAL));
     
      TreeViewer treeViewer = new TreeViewer(shlTreeviewerDemo, SWT.BORDER);
     
      AppMenuTreeCLProvider provider= new AppMenuTreeCLProvider();
      treeViewer.setContentProvider(provider);
      treeViewer.setLabelProvider(provider);
     
      Tree tree = treeViewer.getTree();
      tree.setLinesVisible(true);
      tree.setHeaderVisible(true);
     
      treeViewer.setInput(DataModel.getAppMenus());
  }
}
Results of running the example:

Add, remove the row on TreeViewer

// Get data of TreeViewer.
List<AppMenu> input = (List<AppMenu>)treeViewer.getInput();

AppMenu menu =  input.get(0);
List<AppMenu> childMenus = menu.getChildren();

// add AppMenu
childMenus .add(newAppMenu);

// Refresh
treeViewer.refresh(menu );
// or
treeViewer.refresh();

// Remove row similar.

7.5- JFace CheckboxTableViewer

  • Package: org.o7planning.tutorial.jface.cbtableviewer
  • Name: CheckboxTableViewerDemo
  • TODO...