Pull to refresh

Пишем Eclipse клиент к БД с использованием hibernate И fishbolt технологий

Reading time37 min
Views1.7K
Этот и другие примеры доступны для скачивания здесь

Плагин – модель данных


В этом разделе мы создаём отдельный eclise-плагин, который будет содержать модель данных (отделять данные от пользовательского интерфейса – хороший тон, как нам известно)

Создаём плагин


После создания плагина пропишем необходимые зависимости:
И добавим строку в файл MANIFEST.MF (для ислользования единого загрузчика классов, что требуется при работе с библиотеками hibernate):
Eclipse-RegisterBuddy: org.fishbolt.model.hibernate.annotations


Создаём классы объектов данных и менеджеров объектов данных


Объект данных «Отдел»:
/**<br>* Data object presenting department<br>*/<br>@DisplayLabel("Department")<br>@ImageResource("department.gif")<br>@Entity<br>@Tuplizer(impl = CompanyModelTuplizer.class)<br>@AccessType("org.fishbolt.model.hibernate.FieldAccessor")<br>public class Department <br>  extends HDataObject<DepartmentManager> {<br><br><br>  @Id<br>  @GeneratedValue<br>  @DisplayLabel("Identity")<br>  public final static FieldDeclaration<Integer> id = <br>    new FieldDeclaration<Integer>(Department.class);<br><br>  @ObjectPresentationField<br>  @Column(unique=true, nullable=false)<br>  @DisplayLabel("Name")<br>  @Width(250)<br>  public final static FieldDeclaration<String> name = <br>    new FieldDeclaration<String>(Department.class);<br><br><br>  @DisplayLabel("Employees")<br>  @Relation(inverse="department")<br>    @OneToMany(targetEntity=Employee.class)<br>    @JoinColumn(name="department")<br>  public final static FieldDeclaration<Set<Employee>> employees = <br>    new FieldDeclaration<Set<Employee>>(Department.class);<br>  <br>  public Department(DepartmentManager manager) {<br>    super(manager);<br>  }<br>  <br>  public Department() {<br>    super();<br>  }<br>}<br>
Менеджер объекта данных «Отдел»:
/**<br> * Manager class for {@link Department} data object.<br> */<br>public class DepartmentManager <br>  extends HDataObjectManager<Department,Integer>{<br>  <br>  /**<br>   * Constructor inherited from the super class<br>   */<br>  public DepartmentManager(IDataModel dataModel,<br>      ObjectDescriptor<?,?> objectDescriptor) {<br>    super(dataModel, objectDescriptor);<br>  }<br><br>  /**<br>   * Searches for a department by its name<br>   * @param name - the name of the department to search for<br>   * @return department or <code>null</code><br>   */<br>  public Department findDepartment(String name){<br>    String hql = "from Department where name=?";<br>    QueryUniqueResultCommand<Department> cmd = <br>      new QueryUniqueResultCommand<Department>(hql);<br>    cmd.setParameters(new Parameter(name));<br>    return this.getModel().processCommand(cmd);<br>  }<br>}<br>
Объект данных «Сотрудник»:
/**<br> * Data object presenting employee<br> */ <br>@DisplayLabel("Employee")<br>@ImageResource("employee.gif")<br>@Entity<br>@Tuplizer(impl = CompanyModelTuplizer.class)<br>@AccessType("org.fishbolt.model.hibernate.FieldAccessor")<br>public class Employee extends HDataObject<EmployeeManager> {<br>  <br>  @Id<br>  @GeneratedValue<br>  @DisplayLabel("Identity")<br>  public final static FieldDeclaration<Integer> id = <br>    new FieldDeclaration<Integer>(Employee.class);<br><br>  @Transient<br>  @ObjectPresentationField<br>  @DisplayLabel("Name")<br>  @Width(250)<br>  public final static FieldDeclaration<String> name = <br>    new FieldDeclaration<String>(Employee.class);<br><br>  @Column(nullable=false)<br>  @DisplayLabel("First Name")<br>  public final static FieldDeclaration<String> firstName = <br>    new FieldDeclaration<String>(Employee.class);<br>  <br>  @Column(nullable=false)<br>  @DisplayLabel("Last Name")<br>  public final static FieldDeclaration<String> lastName = <br>    new FieldDeclaration<String>(Employee.class);<br>  <br>  @DisplayLabel("Phone Number")<br>  public final static FieldDeclaration<String> phoneNumber = <br>    new FieldDeclaration<String>(Employee.class);<br>  <br>  @SimpleDateFormatPresentation("dd/MM/yyyy")<br>  @DisplayLabel("Birthday")<br>  public final static FieldDeclaration<Date> birthday = <br>    new FieldDeclaration<Date>(Employee.class);<br><br>  @DisplayLabel("Salary")<br>  @Column(nullable=false)<br>  @DecimalFormatPresentation("#,##0.00")<br>  @PresentationDecorator(prefix="$ ")<br>  public final static FieldDeclaration<BigDecimal> salary = <br>    new FieldDeclaration<BigDecimal>(Employee.class);<br>  <br>  @DisplayLabel("Health")<br>  @NumberFormatPresentation(NumberFormatInstance.percent)<br>  public final static FieldDeclaration<Double> health = <br>    new FieldDeclaration<Double>(Employee.class);<br>  <br>  @DisplayLabel("Department")<br>  @Relation(inverse="employees")<br>  @ManyToOne(optional=false)<br>  @JoinColumn(name="department")<br>  public final static FieldDeclaration<Department> department = <br>    new FieldDeclaration<Department>(Employee.class);<br>  <br>  public Employee(EmployeeManager manager) {<br>    super(manager);<br>  }<br>  <br>  public Employee() {<br>    super();<br>  }<br>}<br>
Менеджер объекта данных «Сотрудник»:
/**<br> * Manager class for {@link Employee} data object.<br> */<br>public class EmployeeManager <br>  extends HDataObjectManager<Employee,Integer>{<br>  <br>  /**<br>   * Constructor inherited from the super class<br>   */<br>  public EmployeeManager(IDataModel dataModel,<br>      ObjectDescriptor<?,?> objectDescriptor) {<br>    super(dataModel, objectDescriptor);<br>  }<br><br>  /**<br>   * Searches for an employee among all employees of a company<br>   * @param firstName - employee's first name<br>   * @param lastName - employee's last name<br>   * @return <code>List</code> of employees<br>   */<br>  public List<Employee> findEmployee(String firstName,String lastName){<br>    String hql = "from Employee where firstName=? and lastName = ?";<br>    QueryListCommand<Employee> cmd = new QueryListCommand<Employee>(hql);<br>    cmd.setParameters(<br>        new Parameter(firstName),<br>        new Parameter(lastName));<br>    return this.getModel().processCommand(cmd);<br>  }<br>  <br>  /**<br>   * Searches for an employee in a department <br>     * @param firstName - employee's first name<br>     * @param lastName - employee's last name<br>   * @param department<br>   * @return <code>List</code> of employees<br>   */<br>  public List<Employee> findEmployee(String firstName,String lastName, Department department){<br>    String hql = "from Employee where firstName=? and lastName=? and department=?";<br>    QueryListCommand<Employee> cmd = new QueryListCommand<Employee>(hql);<br>    cmd.setParameters(<br>      new Parameter(firstName),<br>      new Parameter(lastName),<br>      new Parameter(department));<br>    return this.getModel().processCommand(cmd);<br>  }<br>}<br>


Объявляем класс модели данных



/**<br> * Company model class<br> */<br>public class CompanyModel extends DataModel {<br>  <br>  public final static <br>    ObjectDescriptor<EmployeeManager,Employee> employee = <br>      new EObjectDescriptor<EmployeeManager,Employee>(CompanyModel.class);<br>  <br>  public final static <br>    ObjectDescriptor<DepartmentManager,Department> department = <br>      new EObjectDescriptor<DepartmentManager,Department>(CompanyModel.class);<br>  <br>  public static ModelDescriptor getDescriptor(){<br>    return CompanyModel.department.getModelDescriptor();<br>  }<br>  <br>  private static CompanyModel instance;<br>  <br>  public static CompanyModel getInstance(){<br>    return (instance == null) ? <br>        instance = new CompanyModel(getDescriptor()) : <br>          instance;<br>  }<br><br>  private CompanyModel(ModelDescriptor modelDescriptor) {<br>    super(modelDescriptor);<br>  }  <br>}<br>


Настраиваем Hibernate


Создадим некий Tuplizer-класс (упоминается в одноимённой аннотации классов объектов данных):
public class CompanyModelTuplizer extends DataObjectTuplizer {<br><br>  /**<br>   * Constructor inherited from the super class<br>   */<br>  public CompanyModelTuplizer(EntityMetamodel entityMetamodel, <br>      PersistentClass mappedEntity) {<br>    super(entityMetamodel, mappedEntity);<br>  }<br><br>  @Override<br>  protected ModelDescriptor getModelDescriptor() {<br>    return CompanyModel.getDescriptor();<br>  }<br>}<br>
создадим hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?><br><!DOCTYPE hibernate-configuration PUBLIC<br>  "-//Hibernate/Hibernate Configuration DTD//EN"<br>  "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><br>  <br><hibernate-configuration><br>    <session-factory><br>      <property name="hibernate.dialect"><br>        org.hibernate.dialect.PostgreSQLDialect<br>      </property><br>      <property name="hibernate.connection.driver_class"><br>        org.postgresql.Driver<br>      </property><br>      <property name="hibernate.connection.url"><br>        jdbc:postgresql://localhost/company<br>      </property><br>      <property name="hibernate.connection.username"><br>        postgres<br>      </property><br>      <property name="hibernate.connection.password"><br>        ********<br>      </property><br>      <br>    <mapping class="example.model.objects.Department"/><br>    <mapping class="example.model.objects.Employee"/><br>    </session-factory><br></hibernate-configuration><br><br>


Вычисляемые поля


Оъект данных «Сотрудник» содержит поле name. Это поле является вычисляемым и соответcвенно не имеет отражения в базе данных. Ниже, мы реализуем алгоритм вычисления этого поля:
public class EmployeeFullNameCalculation <br>  implements IFieldCalculation<String> {<br>  <br>  public FieldPath[] getInfluencingPaths(FieldDescriptor<String> dependent) {<br>    return new FieldPath[]{<br>        new FieldPath(true, CompanyModel.employee,Employee.firstName),<br>        new FieldPath(true, CompanyModel.employee,Employee.lastName)<br>      };<br>  }<br><br>  public String evaluateValue(IDataField<String> toEvaluate) {<br>    Employee employee = (Employee)toEvaluate.getDataObject();<br>    return ModelUtil.getValue(employee,Employee.firstName)+<br>    " " +  ModelUtil.getValue(employee,Employee.lastName);<br>  }<br>}<br>
Cвяжeм реализованный алгоритм вычисления с полем данных в коде
public class CompanyCalculationProviderFactory <br>  extends FieldCalculationProviderFactorySafe{<br><br>  /**<br>   * Binds calculated fields with calculation classes<br>   */<br>  @Override<br>  protected void bindCalculations() {<br>    // binding <code>Employee.name</code> with <code>EmployeeFullNameCalculation</code><br>    bindCalculation(CompanyModel.employee,Employee.name, <br>        new EmployeeFullNameCalculation());<br>    <br>  }<br>}<br>


Изменения в манифесте плагина


Регистрируем провайдеров фабрики — объявляем расширение точки ModelAdapterFactory:Файл plugin.xml вылядит следующим образом:
<?xml version="1.0" encoding="UTF-8"?><br><?eclipse version="3.2"?><br><plugin><br>  <extension<br>     point="org.fishbolt.model.ModelAdapterFactory"><br>     <model class="example.model.CompanyModel"><br>      <factory class="example.model.calculations.CompanyCalculationProviderFactory"/><br>      <factory class="org.fishbolt.model.memory.ext.compare.ComparatorProviderFactory"/><br>      <factory class="org.fishbolt.model.memory.ext.listener.ListenerRegistryAdapterFactory"/><br>      <factory class="org.fishbolt.model.ext.width.WidthProviderFactory"/><br>      <factory class="org.fishbolt.model.ext.image.ObjectImageProviderFactory"/><br>      <factory class="org.fishbolt.model.hibernate.ext.presenter.HPresenterProviderFactory"/><br>      <factory class="org.fishbolt.model.hibernate.ext.calculate.HInfluencingFieldProviderFactory"/><br>      <factory class="org.fishbolt.model.memory.ext.state.FieldStateFactory"/><br>      <factory class="org.fishbolt.model.hibernate.ext.state.HObjectStateFactory"/><br>      <factory class="org.fishbolt.model.hibernate.ext.state.HFieldDescriptorStateFactory"/><br>      <factory class="org.fishbolt.model.hibernate.ext.state.HObjectDescriptorStateFactory"/><br>      <factory class="org.fishbolt.model.hibernate.provider.field.HFieldManagerProviderFactory"/><br>      <factory class="org.fishbolt.model.hibernate.provider.object.HObjectManagerProviderFactory"/><br>      <factory class="org.fishbolt.model.memory.ext.label.LabelProviderFactory"/><br>      <factory class="org.fishbolt.model.hibernate.provider.HModelProviderFactory"/><br>      <factory class="org.fishbolt.model.hibernate.annotations.provider.AnnotationConfigurationProviderFactory"/><br>      <factory class="org.fishbolt.model.hibernate.ext.lo.HLargeObjectProviderFactory"/><br>     </model><br>  </extension><br></plugin>
Экспортируем пакеты:
И добавим библиотеку драйвера к базе данных:



Плагин в итоге




Создаём таблицы базы данных


Создадим базу данных «company» (Postgres — сервер). И создадим таблицы:
CREATE TABLE department<br>(<br> id integer NOT NULL,<br> name character varying(255) NOT NULL,<br> CONSTRAINT department_pkey PRIMARY KEY (id),<br> CONSTRAINT department_name_key UNIQUE (name)<br>)<br><br>CREATE TABLE employee<br>(<br> id integer NOT NULL,<br> firstname character varying(255) NOT NULL,<br> lastname character varying(255) NOT NULL,<br> phonenumber character varying(255),<br> birthday date,<br> health double precision,<br> parttime boolean,<br> salary numeric(19,2),<br> department integer NOT NULL,<br> CONSTRAINT employee_pkey PRIMARY KEY (id),<br> CONSTRAINT fk4afd4acec0414ee2 FOREIGN KEY (department)<br>  REFERENCES department (id) <br>)<br>


Плагин — пользовательский интерфейс


Создаём плагин пользовательского интерфейса и добавляем зависимостиКак мы видим, среди зависимостей расположен, созданный нами ранее плагин — модель данных (example.org.fishbolt.model.hibernate.annotations)

Мастер (wizard) по созданию объектов данных


Создадим классы мастеров по созданию объекта данных. Ниже приведён код мастра для объекта данных «Сотрудник»:
/**<br> * Wizard for adding new employees<br> */<br>public class NewEmployeeWizard extends ObjectNewWizard {<br><br>  public NewEmployeeWizard() {<br>    // indicating the descriptor of a data object<br>    // whose instances will be created by the wizard<br>    super(CompanyModel.employee);<br>  }<br>  <br>  @Override<br>  protected IDataModel getDataModel(IWorkbench workbench, <br>      IStructuredSelection selection) {<br>    // providing a reference to the data model<br>    // to which new Employee instances will be added<br>    return CompanyModel.getInstance();<br>  }<br><br>  @SuppressWarnings("unchecked")<br>  @Override<br>  public void init(IWorkbench workbench, <br>      IStructuredSelection selection){<br>    super.init(workbench, selection);<br>    // setting a default value to Employee.department<br>    Object selectionObject = selection.getFirstElement();<br>    if (selectionObject instanceof Department){<br>      ModelUtil.setValue(this.wizardObject,<br>          Employee.department,(Department)selectionObject);<br>    }<br><br>    String name = <br>      LabelProvider.getDisplayLabel(CompanyModel.employee);<br>    <br>    // adding pages for step-by-step creation of Employee instances<br>    this.addPage(<br>        new ObjectSimpleWizardPage(name,name,null,<br>        Employee.firstName,<br>        Employee.lastName,<br>        Employee.department,<br>        Employee.phoneNumber));<br>    this.addPage(<br>        new ObjectSimpleWizardPage(name,name,null,<br>        Employee.birthday,<br>        Employee.salary,<br>        Employee.health));<br>  }<br>}<br>
Регистрируем соответсвующее расширениеПервая страница мастера (wizard) по созданию объекта типа «Сотрудник» выглядит следующим образом:Добавляем код команды пользовательского интерфейса (UI action), которая открывает диалог визарда по созданию объекта «Сотрудник»
public class OpenNewEmployeeWizardAction extends OpenNewWizardAction {<br><br>  @SuppressWarnings("unchecked")<br>  public OpenNewEmployeeWizardAction(ViewerController controller) {<br>    super(controller, "New Employee...","Creates a new employee");<br>  }<br><br>  @Override<br>  public INewWizard getNewWizard() {<br>    return new NewEmployeeWizard();<br>  }<br>  <br>  @Override<br>  public void updateEnable() {<br>    this.setEnabled(getActionObject() instanceof Department);<br>  }<br>}


Редактор для объектов данных


Создадим классы фабрик редакторов для объектов данных
/**<br> * EditorFactory for <code>Employee</code>s<br> */<br>public class EmployeeEditorFactory extends EditorFactory {<br><br>  EmployeeEditorFactory() {<br>    // Indicating an Employee object via its descriptor<br>    // and creating editor pages    <br>    super(CompanyModel.employee,<br>      new SimpleEditorPageFactory(<br>          "Personal information", <br>          Employee.firstName,<br>          Employee.lastName,<br>          Employee.phoneNumber,<br>          Employee.birthday,<br>          Employee.health),<br>      new SimpleEditorPageFactory(<br>          "Department information",<br>          Employee.department,<br>          Employee.salary)<br>    );<br>  }<br>}



/**<br> * EditorFactory for <code>Department</code>s<br> */<br>public class DepartmentEditorFactory extends EditorFactory {<br><br>  DepartmentEditorFactory() {<br>    // Indicating a Department object via its descriptor<br>    // and creating editor pages    <br>    super(CompanyModel.department,<br>      new SimpleEditorPageFactory(<br>          LabelProvider.getDisplayLabel(CompanyModel.department), <br>          Department.name)<br>    );<br>  }<br>}<br>
Нам также необходимо создать класс – провайдер редактора и зарегистрировать его:
public class CompanyEditorProvider extends EditorProvider {<br>  <br>  public CompanyEditorProvider(){<br>    register(new DepartmentEditorFactory());<br>    register(new EmployeeEditorFactory());<br>  }<br>}
И объявить редактор:
Созданный редактор для объекта типа «Сотрудник» выглядит следующим образом:Добавляем код команды пользовательского интерфейса (UI action), которая открывает редактор для объектов данных
public class OpenInEditorAction extends OpenEditorAction {<br><br>  @SuppressWarnings("unchecked")<br>  public OpenInEditorAction(ViewerController controller) {<br>    super("example.model.eclipse.DataObjectEditor", controller);<br>  }<br>}
Для примера, также добавляем код команды пользовательского интерфейса (UI action), которая открывает редактор для объектов данных в специальной перспективе

public class OpenInEditorPerspectiveAction extends OpenEditorPerspectiveAction {<br><br>  @SuppressWarnings("unchecked")<br>  public OpenInEditorPerspectiveAction(ViewerController controller) {<br>    super("example.model.eclipse.perspectives.ObjectEditorPerspective",<br>        "example.model.eclipse.DataObjectEditor",<br>        controller);<br>  }<br>}


Диалог для изменения значения поля данных


Ниже показан класс диалогового окна, который переводит сотрудника из одного отдела в другой:
/**<br> * Dialog that moves an employee from one department to another<br> */<br>public class ChangeDepartmentDialog <br>  extends Dialog implements IWidgetsContext{<br>  <br>  private Employee employee;<br>  private ContextControllerBinder contextBinder;<br><br>  public ChangeDepartmentDialog(Shell parentShell,Employee employee) {<br>    super(parentShell);<br>    this.employee = employee;<br>  }<br><br>  /**<br>   * Returns ContextControllerBinder that binds<br>   * user interface components with data model components<br>   * through controllers<br>   */<br>  public ContextControllerBinder getContextBinder() {<br>    return contextBinder == null ? <br>        contextBinder = new ContextControllerBinder(this) : contextBinder;<br>  }<br><br>  /**<br>   * Creates dialog's contents <br>   * and binds user interface components with data model components<br>   */<br>  @Override  <br>  protected Control createDialogArea(Composite parent) <br>  {<br>    // dialog title<br>    parent.getShell().setText(PresenterProvider.getPresentation(employee));<br>    <br>    Composite result = new Composite(parent, SWT.NONE);<br>    result.setLayout(new GridLayout(2, true));<br><br>    Label decription = new Label(result, SWT.NULL);<br>    decription.setLayoutData(<br>        new GridData(GridData.FILL,GridData.FILL,true,true,2,1));<br>    decription.setText("To move the employee to another department, " +<br>        "select the department and press OK.");<br>    <br>    // Label presenting the data object field<br>    Label label = new Label(result, SWT.NULL);<br>    label.setLayoutData(new GridData());<br>    <br>    // Combo presenting data field values<br>    Combo combo = new Combo(result, SWT.BORDER | SWT.DROP_DOWN);<br>    combo.setLayoutData(<br>        new GridData(GridData.FILL,GridData.CENTER,true,false));<br>  <br>    ContextControllerBinder binder = getContextBinder();<br>    // binding Label to FieldDescriptor <br>    // (the controller that is responsible for interaction<br>    // between Label and FieldDescriptor is created automatically)<br>    binder.bind(label, <br>        CompanyModel.employee.getFieldDescriptor(Employee.department));<br>    // binding data field to Combo <br>    // (the controller that is responsible for interaction<br>    // between data field and Combo is created automatically)<br>    binder.bind(combo, <br>        employee.getDataField(Employee.department));    <br>    <br>    return result;<br>  }<br><br><br>  /**<br>   * Reacts to changes resulted from user's actions on the UI<br>   * components (controls) that were bound to data model<br>   * components using ContextControllerBinder<br>   */<br>  @SuppressWarnings("unchecked")<br>  public void contextWidgetChanged(<br>      EditableWidgetController<Widget, Object, Object> controller,<br>      PresentationException exception) {<br>    if (exception!= null){<br>      MessageDialog.openError(this.getShell(), <br>          "The value is incorrect.",<br>          "Please specify a correct value.");<br>      return;<br>    }<br>    Collection<ValidationMessage<IDataObject, Severity>> problems <br>      = employee.validate(null);<br>    <br>    if (problems.isEmpty()) return;<br>    <br>    showProblems(problems);<br>    <br>    employee.refresh();<br>  }<br>  <br>  /**<br>   * Shows information about the data object problems<br>   * @param problems<br>   */<br>  protected void showProblems(<br>      Collection<ValidationMessage<IDataObject, Severity>> problems){<br>    StringBuffer msg = new StringBuffer();<br>    for (ValidationMessage<IDataObject, Severity> problem : problems){<br>      msg.append(problem.getDescription());<br>      msg.append("\\;n");<br>    }<br>    <br>    MessageDialog.openError(this.getShell(), <br>        "The value is incorrect.",msg.toString());<br>    <br>  }<br>  <br>  <br>  /**<br>   * Cancel button handler<br>   */<br>  @Override<br>  protected void cancelPressed() {<br>    employee.refresh();<br>    super.cancelPressed();<br>  }<br>  <br>  /**<br>   * OK button handler  <br>   */<br>  @Override<br>  protected void okPressed() {<br>    employee.store();<br>    super.okPressed();<br>  }<br>}
Так выглядит диалоговое окно для перевода сотрудника из одного отдела в другой:

Дерево «Отдел» — «Сотрудник»


Создадим дерево, которое показывает все отделы и их сотрудников:
/**<br> * Creates a view that contains<br> * the tree of departments and employees<br> */<br>public class DepartmentEmployeesView extends ViewPart {<br>  <br>  private TreeViewerController treeController = null;<br>  <br>  @Override<br>  public void createPartControl(Composite parent) {<br>    // creating a controller for TreeViewer<br>    treeController = new TreeViewerController(parent);<br>    // setting layout<br>    GridData data = new GridData(GridData.FILL,GridData.FILL,true,true);<br>    treeController.getViewer().getControl().setLayoutData(data);<br>    <br>    // Using ColumnData to wrap up data objects to be represented in tree nodes.<br>    // Data objects are specified through their descriptors<br>    treeController.setColumnProvider(<br>        new ColumnProvider(<br>            new ColumnData(CompanyModel.department).add(CompanyModel.employee)));<br>    <br>    // Wrapping data in TreeDataObjects and passing it to the controller.<br>    // To put it in more details:<br>    // - indicating data objects to be represented in parent nodes.<br>    //   In this case, these are objects of the Deparment type.<br>    //   The Department objects are indicated through their manager (DepartmentManager).<br>    // - indicating data objects to be represented in child nodes.<br>    //   They are indicated through a bidirectional association.<br>    //   In this case, the bidirectional association is expressed by Department.employees<br>    CompanyModel model = CompanyModel.getInstance();<br>    DepartmentManager manager = model.getDataObjectManager(CompanyModel.department);<br>    treeController.setDataObjects(<br>        new TreeDataObjects(<br>            new ManagerDataObjects(manager),<br>            new ChildRelation(CompanyModel.department,Department.employees)));<br><br>    // building a context menu for the tree<br>    ContextMenu menu = new ContextMenu();<br>    menu.add(new OpenInEditorAction(treeController));<br>    menu.add(new OpenInEditorPerspectiveAction(treeController));<br>    menu.add(new OpenNewDepartmentWizardAction(treeController));<br>    menu.add(new OpenNewEmployeeWizardAction(treeController));<br>    menu.add(new ChangeEmployeeDepartmentAction(treeController));<br>    menu.add(new ShowDepartmentEmployeesAction(treeController));<br>    menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));<br>    menu.add(new RemoveDataObjectAction(treeController));<br>    treeController.setContextMenu(this.getSite(),menu);<br>  }<br><br>  @Override<br>  public void setFocus() {<br>    this.treeController.getViewer().getControl().setFocus();<br>  }<br>}
Зарегистрируем соответствующее расширение (org.eclipse.ui.views)результат наших усилий:

Таблица «Сотрудники»



/**<br> * Creates a view that contains<br> * a table displaying information about employees<br> */<br>public class EmployeesView extends ViewPart{<br>  <br>  private TableViewerController tableController = null;<br><br>  /**<br>   * Opens the view and passes to the controller<br>   * a collection of <code>Employee</code>s to be represented<br>   * in a table within the view.<br>   */<br>  public static void setEmployees(List<? extends Employee> employess){<br>    EmployeesView view = getView();<br>    view.tableController.setDataObjects(<br>        new CollectionDataObjects(employess));<br>  }<br><br>  /**<br>   * Opens the view and passes to the controller<br>   * a collection of <code>Employee</code>s to be represented<br>   * in a table within the view.<br>   * The collection of <code>Employee</code>s is specified via<br>   * the association with the <code>Department</code> object (Department.employees)<br>   */  <br>  public static void setDepartment(Department department){<br>    EmployeesView view = getView();<br>    IDataField<Set<Employee>> field = <br>      department.getDataField(Department.employees);<br>    view.tableController.setDataObjects(new RelationDataObjects(field));<br>  }<br>  <br>  @Override<br>  public void createPartControl(Composite parent) {<br>    // Creating a controller<br>    tableController = new TableViewerController(parent);<br>    // Setting layout<br>    GridData data = new GridData(GridData.FILL,GridData.FILL,true,true);<br>    tableController.getViewer().getControl().setLayoutData(data);<br>    // Specifying data presentation.<br>    // Passing to the controller an OddBackgroundColorPresentation instance<br>    // that pastes the background of even table cells<br>    // with the color specified. Default is RGB(230,230,255)<br>    tableController.setDataPresenation(<br>        new EvenBackgroundColorPresentation(tableController));<br>    <br>    // Configuring table columns.<br>    // Using ColumnData to wrap up data object fields to be represented in tree nodes.<br>    // (Data object fields are indicated through <code>FieldDeclaration</code>s)<br>    tableController.setColumnProvider(<br>        new ColumnProvider(<br>            new ColumnData(CompanyModel.employee,Employee.firstName),<br>            new ColumnData(CompanyModel.employee,Employee.lastName),<br>            new ColumnData(CompanyModel.employee,Employee.phoneNumber),<br>            new ColumnData(CompanyModel.employee,Employee.salary)));<br>    <br>    // Adding actions that open a dialog for column selection<br>    ChangeColumnsAction.registerInMenu(this, tableController);<br>    ChangeColumnsAction.registerInToolBar(this, tableController);<br>    <br>    // adding a context menu<br>    ContextMenu menu = new ContextMenu();<br>    menu.add(new OpenInEditorAction(tableController));<br>    menu.add(new OpenInEditorPerspectiveAction(tableController));<br>    menu.add(new ChangeEmployeeDepartmentAction(tableController));<br>    menu.add(new RemoveDataObjectAction(tableController));<br>    tableController.setContextMenu(this.getSite(),menu);<br><br>  }<br><br>  @Override<br>  public void setFocus() {<br>    this.tableController.getViewer().getControl().setFocus();<br>  }<br><br>  /**<br>   * Opens EmployeesView<br>   */  <br>  private static EmployeesView getView(){<br>    IWorkbenchPage page = PlatformUI.getWorkbench().<br>      getActiveWorkbenchWindow().getActivePage();<br>    EmployeesView result = null;<br>    try {<br>      for (IViewReference ref : page.getViewReferences()) {<br>        if ("example.model.eclipse.views.EmployeesView"<br>            .equals(ref.getId())) {<br>          result = (EmployeesView) ref.getView(true);<br>          break;<br>        }<br>      }<br>      if (result == null) <br>        result = (EmployeesView) page.showView(<br>            "example.model.eclipse.views.EmployeesView");<br>    } catch (PartInitException e) {<br>      throw new RuntimeException(e);<br>    }<br>    return result;<br>  }<br>}
Добавим расширениерезультат:

Панель поиска сотрудников


Создадим панель, которая будет искать сотрудников по введённым параметрам и отображать результат поиска в таблице.
public class SearchEmployeeView extends ViewPart
    implements IWidgetsContext{

  private Label firstNameLabel;
  private Text firstName;
  private Label secondNameLabel;
  private Text secondName;
  private Label departmentLabel;
  private DialogChooser<Department> department;
  private Button searchButton;
  private ContextControllerBinder contextBinder;
  private SelectionAdapter doSearch = new SelectionAdapter() {
    @Override
    public void widgetSelected(SelectionEvent e) {
      CompanyModel model = CompanyModel.getInstance();
      EmployeeManager manager = model.getDataObjectManager(CompanyModel.employee);
      String first = firstName.getText();
      String second = secondName.getText();
      Department d = department.getObject();
      List
Tags:
Hubs:
Total votes 20: ↑10 and ↓100
Comments14

Articles