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
Best Practices - SWT Table, TableViewer, EditingSupport
提问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 ArrayList
Structure
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?
问题2:createColumns()
方法和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 -
如果代码小于它不是一个坏主意。但如果——
- The code is large (for me if its more than 100 lines).
- Overall System is going to be more than some thousand of lines of code.
- Someone else is going to maintain it
- If I need plug-and-play nature, for example today
Table
is sufficient but in future I may useGrid
. - If I am doing some custom drawing (doing some custom painting on windows paint event) or using custom controls, THEN
- 代码很大(对我来说,如果超过 100 行)。
- 整个系统将超过数千行代码。
- 其他人会维护它
- 如果我需要即插即用的特性,例如今天
Table
就足够了,但将来我可能会使用Grid
. - 如果我正在做一些自定义绘图(在 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 OptionEditingSupport
class. 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..
谢谢..