Лучшие практики — SWT Table, TableViewer, EditingSupport

Я добавляю таблицу в свой основной графический интерфейс. Он появляется и имеет данные, которые он должен показывать. Но я чувствую, что у меня большой беспорядок в коде, и он неправильно структурирован. Я ищу кого-то, кто много использует SWT, чтобы помочь мне разместить нужные фрагменты кода в нужных местах.

Класс A — основной графический интерфейс с TableViewer

Класс B — (ArrayList) Данные для таблицы / Класс B1 — DataModel для ArrayList Структуры

Класс A - есть метод создания TableViewer

  //////////////////////////////////////////////////////////////////////////
  //                         createTableViewer()                          //
  //////////////////////////////////////////////////////////////////////////
private TableViewer createTableViewer(Composite parent) {
    viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
    createColumns(parent, viewer);
    table = viewer.getTable();
    table.setHeaderVisible(true);
    table.setLinesVisible(true);

    // Layout the viewer
    GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
    viewer.setContentProvider(new ArrayContentProvider());
    *** Getting Array from Class B ***       
    viewer.setInput(AplotDataModel.getInstance().getArrayData());
    viewer.getControl().setLayoutData(gridData);
    return viewer;
}

Класс A также имеет метод createColumns() и метод createTableViewerColumn().

 //////////////////////////////////////////////////////////////////////////
 //                         createColumns()                              //
 //////////////////////////////////////////////////////////////////////////
private void createColumns(final Composite parent, final TableViewer viewer) {
    String[] titles = { "ItemId", "RevId", "PRL", "Dataset Name", "EC Markup" };
    int[] bounds = { 150, 150, 100, 150, 100 };

    TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0], 0);
    col.setLabelProvider(new ColumnLabelProvider() {
        @Override
        public String getText(Object element) {
            AplotDatasetData item = (AplotDatasetData) element;
            return item.getDataset().toString();
        }
    });

    col = createTableViewerColumn(titles[1], bounds[1], 1);
    col.setLabelProvider(new ColumnLabelProvider() {
        @Override
        public String getText(Object element) {
            AplotDatasetData item = (AplotDatasetData) element;
            return item.getRev().toString();
        }
    });

    col = createTableViewerColumn(titles[2], bounds[2], 2);
    col.setLabelProvider(new ColumnLabelProvider() {
        @Override
        public String getText(Object element) {
            AplotDatasetData item = (AplotDatasetData) element;
            return item.getPRLValue();
        }
    });

    col = createTableViewerColumn(titles[3], bounds[3], 3);
    col.setLabelProvider(new ColumnLabelProvider() {
        @Override
        public String getText(Object element) {
            AplotDatasetData item = (AplotDatasetData) element;
            return item.getDatasetName();
        }
    });

    col = createTableViewerColumn(titles[4], bounds[4], 4);
    col.setLabelProvider(new ColumnLabelProvider() {
        @Override
        public String getText(Object element) {
            AplotDatasetData item = (AplotDatasetData) element;
            return item.getECMarkupValue();
        }
    });
}

 //////////////////////////////////////////////////////////////////////////
 //                       createTableViewerColumn()                      //
 //////////////////////////////////////////////////////////////////////////
private TableViewerColumn createTableViewerColumn(String title, int bound, final int colNumber) {
    final TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
    final TableColumn column = viewerColumn.getColumn();
    column.setText(title);
    column.setWidth(bound);
    column.setResizable(true);
    column.setMoveable(true);
    return viewerColumn;
}

Вопрос 1. Является ли это наилучшей практикой добавления таблицы в мой класс с графическим интерфейсом? Кажется, что много кода для класса GUI.

Вопрос 2. Следует ли перенести метод createColumns() и метод createTableViewerColumn() в класс B?

Вопрос 3: мой последний столбец в таблице будет раскрывающимся списком/полем со списком. Поэтому мне придется расширить один класс с помощью EditingSupport. Это должен быть класс А или класс В?

Прежде чем я пойду дальше с этим проектом, я хочу убедиться, что он правильно структурирован.


person jkteater    schedule 04.09.2012    source источник
comment
+1, хороший вопрос. Я очень хочу увидеть хорошие ответы, так как мой код выглядит очень похоже.   -  person Baz    schedule 04.09.2012


Ответы (2)


Ответить на этот вопрос все равно, что ответить на вопрос, какой вкус мороженого вам нравится :)

Q & A

Вопрос 1. Является ли это наилучшей практикой добавления таблицы в мой класс с графическим интерфейсом? Кажется, что много кода для класса GUI.

Если код меньше, чем это неплохая идея. Но если -

  1. Код большой (для меня больше 100 строк).
  2. Общая система будет состоять из нескольких тысяч строк кода.
  3. Кто-то другой будет поддерживать его
  4. Если мне нужен plug-and-play характер, например, сегодня Table достаточно, но в будущем я могу использовать Grid.
  5. Если я делаю какой-то пользовательский рисунок (выполняю пользовательское рисование в событии Windows Paint) или использую пользовательские элементы управления, THEN

Обычно я предпочитаю подкласс просмотра/управления. Таким образом, я мог сохранить разделение между базовым кодом перекачки сообщений, элементами управления GUI и моей моделью данных.

Вопрос 2. Следует ли перенести методы createColumns() и createTableViewerColumn() в класс B?

Нет, вы не должны. Как и в вашем случае, класс B является вашей моделью/поставщиком данных. Модель программирования JFace поддерживает архитектуру MVC, и по возможности следует ей следовать. Предлагаемое решение — создать новый класс, расширяющий TableViewer.

Вопрос 3. Мой последний столбец в таблице будет раскрывающимся списком/полем со списком. Поэтому мне придется расширить один класс с помощью EditingSupport. Это должен быть класс А или класс В?

Я бы посоветовал вам перейти на новый класс и использовать его в расширенном TableViewer. Одним из преимуществ является то, что в случае, если вы записываете данные обратно в некоторую базу данных, ваш класс просмотра остается независимым от уровня базы данных/постоянства.

Пример кода

Ниже приведен простой пример приложения. Как видите, я могу изменить свой комбо-редактор на текстовый, просто изменив класс OptionEditingSupport. Кроме того, код выглядит чистым и лаконичным.

Основной класс

package sample;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class SampleApp 
{
    public SampleApp(Shell shell)
    {
        AppPersonViewer personViewer = new AppPersonViewer(shell, SWT.BORDER|SWT.V_SCROLL|SWT.FULL_SELECTION);
        DataModel model = new DataModel(20);
        personViewer.setInput(model);
    }

    public static void main(String[] args) {
        Display display = new Display ();
        Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());
        new SampleApp(shell);
        shell.open ();

        while (!shell.isDisposed ()) {
            if (!display.readAndDispatch ()) display.sleep ();
        }

        display.dispose ();
    }
}


Расширенное средство просмотра таблиц

package sample;

import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;

public class AppPersonViewer extends TableViewer
{
    public AppPersonViewer(Composite parent, int style) 
    {
        super(parent, style);
        Table table = getTable();
        GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
        table.setLayoutData(gridData);
        createColumns();
        table.setHeaderVisible(true);
        table.setLinesVisible(true);
        setContentProvider(new AppContentProvider());
    }

    private void createColumns()
    {
        String[] titles = { "First Name", "Second Name", "Age", "Country", "Likes SO" };
        int[] bounds = { 150, 150, 100, 150, 100 };

        TableViewerColumn column = createTableViewerColumn(titles[0], bounds[0], 0);
        column.setLabelProvider(new ColumnLabelProvider(){
            public String getText(Object element) {
                if(element instanceof Person)
                    return ((Person)element).getFirst();
                return super.getText(element);
            }
        });

        column = createTableViewerColumn(titles[1], bounds[1], 1);
        column.setLabelProvider(new ColumnLabelProvider(){
            public String getText(Object element) {
                if(element instanceof Person)
                    return ((Person)element).getSecond();
                return super.getText(element);
            }
        });

        column = createTableViewerColumn(titles[2], bounds[2], 2);
        column.setLabelProvider(new ColumnLabelProvider(){
            public String getText(Object element) {
                if(element instanceof Person)
                    return ""+((Person)element).getAge();
                return super.getText(element);
            }
        });

        column = createTableViewerColumn(titles[3], bounds[3], 3);
        column.setLabelProvider(new ColumnLabelProvider(){
            public String getText(Object element) {
                if(element instanceof Person)
                    return ((Person)element).getCountry();
                return super.getText(element);
            }
        });

        column = createTableViewerColumn(titles[4], bounds[4], 4);
        column.setLabelProvider(new ColumnLabelProvider(){
            public String getText(Object element) {
                if(element instanceof Person)
                    return ((Person)element).getLikes();
                return super.getText(element);
            }
        });

        column.setEditingSupport(new OptionEditingSupport(this));
    }

    private TableViewerColumn createTableViewerColumn(String header, int width, int idx) 
    {
        TableViewerColumn column = new TableViewerColumn(this, SWT.LEFT, idx);
        column.getColumn().setText(header);
        column.getColumn().setWidth(width);
        column.getColumn().setResizable(true);
        column.getColumn().setMoveable(true);

        return column;
    }
}


Поставщик контента

package sample;

import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.Viewer;

public class AppContentProvider implements IStructuredContentProvider
{
    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
     */
    public Object[] getElements(Object inputElement) {
        if(inputElement instanceof DataModel)
            return ((DataModel)inputElement).getData().toArray();
        return null;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.IContentProvider#dispose()
     */
    public void dispose() {
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
     */
    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
    }
}


Поддержка редактора ячеек

package sample;

import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.TableViewer;

public class OptionEditingSupport extends EditingSupport 
{
    private ComboBoxCellEditor cellEditor;

    public OptionEditingSupport(ColumnViewer viewer) {
        super(viewer);
        cellEditor = new ComboBoxCellEditor(((TableViewer)viewer).getTable(), new String[]{"Y", "N"});
    }
    protected CellEditor getCellEditor(Object element) {
        return cellEditor;
    }
    protected boolean canEdit(Object element) {
        return true;
    }
    protected Object getValue(Object element) {
        return 0;
    }
    protected void setValue(Object element, Object value) 
    {
        if((element instanceof Person) && (value instanceof Integer)) {
            Integer choice = (Integer)value;
            String option = (choice == 0? "Y":"N");
            ((Person)element).setLikes( option );
            getViewer().update(element, null);
        }
    }
}


Модель данных

package sample;

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

public class DataModel 
{
    private int samples;
    public DataModel(int samples) {
        this.samples = samples;
    }

    List<Person> getData()
    {
        List<Person> persons = new ArrayList<Person>();
        for(int i=0; i<samples; i++)
            persons.add(Person.createRandomPerson());
        return persons;
    }
}


Личный объект

package sample;

import java.util.Random;

public class Person 
{
    private static final String[]   FIRST = {"Favonius", "Tim", "Brad", "Scott", "Linda"};
    private static final String[]   SECOND = {"Cruise", "Temp", "Abbey", "Adam", "Albert", "Thomas"};
    private static final String[]   COUNTRY = {"India", "USA", "Russia", "UK", "France", "Germany"};
    private static final int[]      AGE = {22, 23, 24, 25, 26, 27, 28, 29, 30};

    private static Random random = new Random(System.currentTimeMillis());

    private String first;
    private String second;
    private String country;
    private String likes;

    private int age;

    public Person(String first, String second, String country, String likes, int age) 
    {
        super();
        this.first = first;
        this.second = second;
        this.country = country;
        this.likes = likes;
        this.age = age;
    }
    public String getFirst() {
        return first;
    }
    public String getSecond() {
        return second;
    }
    public String getCountry() {
        return country;
    }
    public String getLikes() {
        return likes;
    }
    public int getAge() {
        return age;
    }
    public void setLikes(String likes) {
        this.likes = likes;
    }
    public static Person createRandomPerson(){
        return new  Person(FIRST[random.nextInt(FIRST.length)], 
                SECOND[random.nextInt(SECOND.length)], COUNTRY[random.nextInt(COUNTRY.length)], 
                "Y", AGE[random.nextInt(AGE.length)]);
    }
}
person Favonius    schedule 05.09.2012
comment
Большое спасибо за ответ с примененным кодом. Я ценю время, которое вы потратили на этот ответ. Я переделал свой проект, и он, кажется, работает хорошо. Единственное, с чем я вижу некоторую проблему, это то, что поле со списком не отображается, если вы не щелкнете в ячейке. Есть ли способ заставить его показывать все время? - person jkteater; 05.09.2012
comment
@jkteater — версия, показанная в приведенном выше коде, демонстрирует редактирование на месте. Для ваших нужд вы должны посмотреть на TableEditor. См. эту ссылку git.eclipse.org/c/platform/eclipse.platform.swt.git/tree/. Концепция та же, что и для Combo. - person Favonius; 06.09.2012

простой способ вставить имя столбца и элемент таблицы с помощью TableViewer

Просмотр таблиц для учащихся

package rcp_demo.Views;

import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.swt.SWT;
import org.eclipse.wb.swt.SWTResourceManager;
import org.eclipse.swt.widgets.Table;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.widgets.Text;
import rcp_demo.TableView.Student;
import org.eclipse.swt.widgets.TableItem;
import java.util.ArrayList;
import java.util.List;

public class TaskView extends ViewPart {
    private Table table;
    private Text txt_search;
    private TableViewer tableViewer;
    public TaskView() {
        setTitleImage(SWTResourceManager.getImage("D:\\Icon\\Tasksview.png"));
    }

    @Override
    public void createPartControl(Composite parent) {
        parent.setLayout(null);
        //Search Text
        txt_search = new Text(parent, SWT.BORDER);
        txt_search.setBounds(21, 10, 238, 19);
        //TableViewer
        tableViewer = new TableViewer(parent, SWT.BORDER | SWT.FULL_SELECTION);
        table = tableViewer.getTable();
        table.setBounds(21, 47, 290, 213);
        table.setHeaderVisible(true);
        table.setLinesVisible(true);

                //Table(Student): TableViewerColumn Names

                String[] Col_names={"Stud_id","Stud_Name","Stud_Gender"};
                for(int i=0;i<Col_names.length;i++)
                {
                    TableViewerColumn tableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
                    TableColumn tblclmnNewColumn = tableViewerColumn.getColumn();
                    tblclmnNewColumn.setWidth(100);
                    tblclmnNewColumn.setText(Col_names[i]);

                }
                //Table(Student) Item List
                List<Student> std=new ArrayList<Student>();
                std.add(new Student("110","AAA","Male"));
                std.add(new Student("111","FFF","Female"));
                std.add(new Student("112","MMM","Male"));

                for(Student s:std)
                {
                    TableItem std_item=new TableItem(table, SWT.NONE);
                    std_item.setText(0,s.getStd_id());
                    std_item.setText(1,s.getStd_nm());
                    std_item.setText(2,s.getStd_gender());
//                  System.out.println(s);  
                }

    }
      public TableViewer getViewer() {
          return tableViewer;
  }
    @Override
    public void setFocus() {
        tableViewer.getControl().setFocus();

    }
}

Класс : Студент

package rcp_demo.TableView;

public class Student {

    private String std_id;
    private String std_nm;
    private String std_gender;

    public Student() {
        // TODO Auto-generated constructor stub
    }
    public Student(String sid,String snm,String sgender) {
        std_id=sid;
        std_nm=snm;
        std_gender=sgender;
    }

    public String getStd_id() {
        return std_id;
    }
    public void setStd_id(String std_id) {
        this.std_id = std_id;
    }
    public String getStd_nm() {
        return std_nm;
    }
    public void setStd_nm(String std_nm) {
        this.std_nm = std_nm;
    }
    public String getStd_gender() {
        return std_gender;
    }
    public void setStd_gender(String std_gender) {
        this.std_gender = std_gender;
    }

}

У меня есть лучшие практики для SWT Table, TableViewer

Благодарность..

person Chetan Bhagat    schedule 16.01.2017