Reputation: 1391
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.
Class A - Main GUI with TableViewer
Class B - (ArrayList
) Data for table / Class B1 - DataModel for ArrayList
Structure
Class A - has method for creating 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.
//////////////////////////////////////////////////////////////////////////
// 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.
Question 2: Should the createColumns()
method and the createTableViewerColumn()
method be moved to Class 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?
Before I go any farther with this project I want to make sure I have it correctly structured.
Upvotes: 15
Views: 18588
Reputation: 572
simple way to insert the column name and Table item using 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
thanks..
Upvotes: 0
Reputation: 13974
Answering this question is like answering which ice-cream flavor do you like :)
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.
If the code is less than its not a bad idea. But if -
Table
is sufficient but in future I may use Grid
.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.
Question 2: Should the createColumns() method and the createTableViewerColumn() method be moved to Class 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.
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?
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.
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.
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 ();
}
}
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)]);
}
}
Upvotes: 27