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

标签 java swt tableviewer

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

A 类 - 带有 TableViewer 的主 GUI

B 类 - (ArrayList) 表数据/B1 类 - 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 类添加表格的最佳做法吗? GUI 类的代码似乎很多。

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

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

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

最佳答案

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

问答

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. 代码很大(对我来说超过 100 行)。
  2. 整个系统将超过数千行代码。
  3. 其他人将维护它
  4. 如果我需要即插即用的特性,例如今天 Table 就足够了,但将来我可能会使用 Grid
  5. 如果我正在做一些自定义绘图(在 Windows 绘画事件上做一些自定义绘画)或使用自定义控件,然后

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

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

不,你不应该。与您的情况一样,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?

我建议您去学习一个新类并在扩展的 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)]);
    }
}

关于java - 最佳实践 - SWT 表、TableViewer、EditingSupport,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12269958/

相关文章:

java - 将自定义控件添加到 Eclipse 工具栏的正确方法是什么(使用 WorkbenchWindowControlContribution)?

java - 如何在 SWT TableViewer 中使用 Enter 键向下导航

java - 如何在SWT中构建TableViewer的弹出窗口?

java - ViewerComparator 构造函数上的 AssertionFailedException

java - 请帮助我遵循数据类型

java - swt 库 - 链接到 eclipse javadoc

java - 使用 log4j 每天创建新的日志文件

java - SWT 文件删除 : identify folders

java - 根据 java 目标禁用 gradle 插件

Java ServerSocket 不会从客户端发送或接收消息