Ответ 1
Ответ на этот вопрос подобен тому, как нравится вкус мороженого:)
Q & A
Вопрос 1: Является ли это лучшей практикой добавления таблицы в мой графический интерфейс класс? Кажется, что много кода для GUI-класса.
Если код меньше его не плохой идеи. Но если -
- Код большой (для меня, если его более 100 строк).
- Общая система будет содержать более тысячи строк кода.
- Кто-то еще собирается его поддерживать
- Если мне нужен plug-and-play характер, например, сегодня
Table
достаточно, но в будущем я могу использоватьGrid
. - Если я делаю какой-то пользовательский чертеж (выполняя какую-то пользовательскую покраску на событии красок Windows) или используя пользовательские элементы управления, THEN
Обычно я предпочитаю подкласс класса viewer/control. Таким образом, я мог бы поддерживать разделение между кодом перекоса сообщений голосовой кости, элементами управления графическим интерфейсом и моей моделью данных.
Вопрос 2: Если метод createColumns() и createTableViewerColumn() можно перенести в класс B?
Нет, не надо. Как и в вашем случае, класс B является вашей моделью данных/поставщиком. Модель программирования JFace поддерживает архитектуру MVC, и, если возможно, следует следовать ей. Предлагаемое решение состоит в том, чтобы новый класс расширял TableViewer.
Вопрос 3: Мой последний столбец в таблице будет выпадающий список/поле со списком. Поэтому мне придется расширить один класс с помощью EditingSupport. Должен ли он быть классом A или классом B?
Я бы предложил вам перейти на новый класс и использовать его в расширенном TableViewer. Одно из преимуществ заключается в том, что в случае, если вы записываете данные обратно в какой-то db, ваш класс зрителя остается агностиком db/persistence.
Пример кода
Ниже приведено простое примерное приложение. Как вы можете видеть, я могу изменить свой редактор комбо в текстовый редактор, просто изменив класс 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;
}
}
Объект Person
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)]);
}
}