java 最佳实践 - SWT Table、TableViewer、EditingSupport

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12269958/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 08:16:13  来源:igfitidea点击:

Best Practices - SWT Table, TableViewer, EditingSupport

javaswttableviewer

提问by jkteater

I am adding a table to my main GUI. It does show up and has the data it is suppose to show. But I feel like I have a big mess of code and it is not structured correctly. I am looking for someone that uses SWT a lot to help me put the right pieces of code in the right places.

我正在向我的主 GUI 添加一个表格。它确实出现并具有它应该显示的数据。但我觉得我有一大堆代码,而且结构不正确。我正在寻找经常使用 SWT 的人来帮助我将正确的代码片段放在正确的位置。

Class A - Main GUI with TableViewer

A 类 - 主 GUI TableViewer

Class B - (ArrayList) Data for table / Class B1 - DataModel for ArrayListStructure

B 类 - ( ArrayList) 表数据 / B1 类 -ArrayList结构数据模型

Class A - has method for creating TableViewer

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;
}

Class A also has createColumns()method and a createTableViewerColumn()method.

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;
}

Question 1: Is this the best practice to adding a table to my GUI class? Seems like a lot of code for the GUI class.

问题 1:这是将表添加到我的 GUI 类的最佳实践吗?似乎有很多 GUI 类的代码。

Question 2: Should the createColumns()method and the createTableViewerColumn()method be moved to Class B?

问题2createColumns()方法和createTableViewerColumn()方法是否应该移动到B类?

Question 3: My last column in the table is going to be a dropdown/combo box. So I am going to have to extend one class with EditingSupport. Should it be Class A or Class B?

问题 3:我在表格中的最后一列将是下拉/组合框。所以我将不得不用EditingSupport. 应该是A类还是B类?

Before I go any farther with this project I want to make sure I have it correctly structured.

在我继续这个项目之前,我想确保我的结构正确。

回答by Favonius

Answering this question is like answering which ice-cream flavor do you like :)

回答这个问题就像回答你喜欢哪种冰淇淋口味:)

Q & A

问答

Question 1:Is this the best practice to adding a table to my GUI class? Seems like a lot of code for the GUI class.

问题 1:这是将表添加到我的 GUI 类的最佳实践吗?似乎有很多 GUI 类的代码。

If the code is less than its not a bad idea. But if -

如果代码小于它不是一个坏主意。但如果——

  1. The code is large (for me if its more than 100 lines).
  2. Overall System is going to be more than some thousand of lines of code.
  3. Someone else is going to maintain it
  4. If I need plug-and-play nature, for example today Tableis sufficient but in future I may use Grid.
  5. If I am doing some custom drawing (doing some custom painting on windows paint event) or using custom controls, THEN
  1. 代码很大(对我来说,如果超过 100 行)。
  2. 整个系统将超过数千行代码。
  3. 其他人会维护它
  4. 如果我需要即插即用的特性,例如今天Table就足够了,但将来我可能会使用Grid.
  5. 如果我正在做一些自定义绘图(在 windows 绘制事件上做一些自定义绘画)或使用自定义控件,那么

I normally prefer to sub-class the viewer/control. In this way I could maintain the separation between the bare-bone message pumping code, GUI controls and my data model.

我通常更喜欢对查看器/控件进行子类化。通过这种方式,我可以保持基本的消息泵代码、GUI 控件和我的数据模型之间的分离。

Question 2:Should the createColumns() method and the createTableViewerColumn() method be moved to Class B?

问题 2:createColumns() 方法和 createTableViewerColumn() 方法是否应该移至 B 类?

No, You should not. As in your case the class B is your data model/supplier. The JFace programming model supports MVC architecture and if possible one should follow it. Suggested solution is to have a new class extending the TableViewer.

不,你不应该。与您的情况一样,B 类是您的数据模型/供应商。JFace 编程模型支持 MVC 架构,如果可能的话,应该遵循它。建议的解决方案是使用一个新类来扩展 TableViewer。

Question 3:My last column in the table is going to be a dropdown/combo box. So I am going to have to extend one class with EditingSupport. Should it be Class A or Class B?

问题 3:我在表格中的最后一列将是下拉/组合框。所以我将不得不使用 EditingSupport 扩展一个类。应该是A类还是B类?

I would suggest you to go for a new class and use that in the extended TableViewer. One benefit is that in case you are writing data back to some db then your viewer class remain db/persistence layer agnostic.

我建议你去一个新的类并在扩展的 TableViewer 中使用它。一个好处是,如果您将数据写回某个数据库,那么您的查看器类将保持与数据库/持久层无关。

Code Sample

代码示例

Below is a simple sample application. As you can see I can change my combo editor to text editor just by changing the OptionEditingSupportclass. And also, the code looks clean and concise.

下面是一个简单的示例应用程序。如您所见,我可以通过更改OptionEditingSupport类将我的组合编辑器更改为文本编辑器。而且,代码看起来干净简洁。

Main Class

主班

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 ();
    }
}



Extended Table Viewer扩展表查看器

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;
    }
}



Content Provider内容提供商

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) {
    }
}



Cell Editor Support单元格编辑器支持

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);
        }
    }
}



Data Model数据模型

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;
    }
}



The Person Entity人实体

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)]);
    }
}

回答by Chetan Bhagat

simple way to insert the column name and Table item using TableViewer

使用 TableViewer 插入列名和表项的简单方法

Student 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();

    }
}


Class : Student

班级:学生

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;
    }

}


I got best practices for SWT Table, TableViewer

我得到了 SWT Table、TableViewer 的最佳实践

thanks..

谢谢..