为 SWT 树和 table 编写通用代码
Write common code for both SWT tree and table
SWT 控件 classes Tree
和 Table
有几个具有相同签名且工作方式相同的方法。
例如:
getItems
getSelection
但是这些方法是直接在Tree
和Table
上定义的,没有公共的超class或方法声明的接口。因此很难编写同时适用于 Tree
和 Table
的代码。
是否有解决方案可以为这两个 class 编写通用代码?
一个可能的解决方案是使用常用方法创建一个 class,子classes 包装 Tree
或 Table
并委托这些方法到他们包装的控件。
使用这样的 classes 通用代码可以如下所示:
CollectionControl c = CollectionControl.create(treeOrTable);
int nrItems = c.getSelectionCount();
以下是此类 classes 的示例:
/**
* Wrapps a {@link Tree} or {@link Table} to make it possible to work with them
* in a generic way.
*
* This class could be an interface in Java 8, which allows static methods on interfaces.
*/
public abstract class CollectionControl {
public abstract CollectionItem[] getItems();
public abstract CollectionItem[] getSelection();
public abstract int getSelectionCount();
public abstract Control getControl();
public abstract int getColumnCount();
interface CollectionItem {
String getText(int columnIx);
}
/**
* @param control Either a {@link Tree} or {@link Table}..
* @return A collection which wraps the argument an delegate method calls to it.
* @throws IllegalArgumentException if the argument is not a Tree or a Table.
*/
public static CollectionControl create(Control control) {
if (control instanceof Tree) {
return new TreeControl((Tree) control);
} else if (control instanceof Table) {
return new TableControl((Table) control);
}
throw new IllegalArgumentException();
}
private static class TreeControl extends CollectionControl {
private Tree tree;
public TreeControl(Tree tree) {
this.tree = tree;
}
@Override
public CollectionItem[] getSelection() {
CollectionItem[] items = new CollectionItem[tree.getSelectionCount()];
int ix = 0;
for (TreeItem item : tree.getSelection()) {
items[ix++] = new TreeCollectionItem(item);
}
return items;
}
@Override
public int getSelectionCount() {
return tree.getSelectionCount();
}
@Override
public Tree getControl() {
return tree;
}
@Override
public CollectionItem[] getItems() {
CollectionItem[] items = new CollectionItem[tree.getItemCount()];
int ix = 0;
for (TreeItem item : tree.getItems()) {
items[ix++] = new TreeCollectionItem(item);
}
return items;
}
@Override
public int getColumnCount() {
return tree.getColumnCount();
}
private static class TreeCollectionItem implements CollectionItem {
private TreeItem item;
public TreeCollectionItem(TreeItem item) {
this.item = item;
}
@Override
public String getText(int columnIx) {
return item.getText(columnIx);
}
}
}
private static class TableControl extends CollectionControl {
private Table table;
public TableControl(Table table) {
this.table = table;
}
@Override
public CollectionItem[] getSelection() {
CollectionItem[] items = new CollectionItem[table.getSelectionCount()];
int ix = 0;
for (TableItem item : table.getSelection()) {
items[ix++] = new TableCollectionItem(item);
}
return items;
}
@Override
public int getSelectionCount() {
return table.getSelectionCount();
}
@Override
public Table getControl() {
return table;
}
@Override
public CollectionItem[] getItems() {
CollectionItem[] items = new CollectionItem[table.getItemCount()];
int ix = 0;
for (TableItem item : table.getItems()) {
items[ix++] = new TableCollectionItem(item);
}
return items;
}
@Override
public int getColumnCount() {
return table.getColumnCount();
}
private static class TableCollectionItem implements CollectionItem {
private TableItem item;
public TableCollectionItem(TableItem item) {
this.item = item;
}
@Override
public String getText(int columnIx) {
return item.getText(columnIx);
}
}
}
}
SWT 控件 classes Tree
和 Table
有几个具有相同签名且工作方式相同的方法。
例如:
getItems
getSelection
但是这些方法是直接在Tree
和Table
上定义的,没有公共的超class或方法声明的接口。因此很难编写同时适用于 Tree
和 Table
的代码。
是否有解决方案可以为这两个 class 编写通用代码?
一个可能的解决方案是使用常用方法创建一个 class,子classes 包装 Tree
或 Table
并委托这些方法到他们包装的控件。
使用这样的 classes 通用代码可以如下所示:
CollectionControl c = CollectionControl.create(treeOrTable);
int nrItems = c.getSelectionCount();
以下是此类 classes 的示例:
/**
* Wrapps a {@link Tree} or {@link Table} to make it possible to work with them
* in a generic way.
*
* This class could be an interface in Java 8, which allows static methods on interfaces.
*/
public abstract class CollectionControl {
public abstract CollectionItem[] getItems();
public abstract CollectionItem[] getSelection();
public abstract int getSelectionCount();
public abstract Control getControl();
public abstract int getColumnCount();
interface CollectionItem {
String getText(int columnIx);
}
/**
* @param control Either a {@link Tree} or {@link Table}..
* @return A collection which wraps the argument an delegate method calls to it.
* @throws IllegalArgumentException if the argument is not a Tree or a Table.
*/
public static CollectionControl create(Control control) {
if (control instanceof Tree) {
return new TreeControl((Tree) control);
} else if (control instanceof Table) {
return new TableControl((Table) control);
}
throw new IllegalArgumentException();
}
private static class TreeControl extends CollectionControl {
private Tree tree;
public TreeControl(Tree tree) {
this.tree = tree;
}
@Override
public CollectionItem[] getSelection() {
CollectionItem[] items = new CollectionItem[tree.getSelectionCount()];
int ix = 0;
for (TreeItem item : tree.getSelection()) {
items[ix++] = new TreeCollectionItem(item);
}
return items;
}
@Override
public int getSelectionCount() {
return tree.getSelectionCount();
}
@Override
public Tree getControl() {
return tree;
}
@Override
public CollectionItem[] getItems() {
CollectionItem[] items = new CollectionItem[tree.getItemCount()];
int ix = 0;
for (TreeItem item : tree.getItems()) {
items[ix++] = new TreeCollectionItem(item);
}
return items;
}
@Override
public int getColumnCount() {
return tree.getColumnCount();
}
private static class TreeCollectionItem implements CollectionItem {
private TreeItem item;
public TreeCollectionItem(TreeItem item) {
this.item = item;
}
@Override
public String getText(int columnIx) {
return item.getText(columnIx);
}
}
}
private static class TableControl extends CollectionControl {
private Table table;
public TableControl(Table table) {
this.table = table;
}
@Override
public CollectionItem[] getSelection() {
CollectionItem[] items = new CollectionItem[table.getSelectionCount()];
int ix = 0;
for (TableItem item : table.getSelection()) {
items[ix++] = new TableCollectionItem(item);
}
return items;
}
@Override
public int getSelectionCount() {
return table.getSelectionCount();
}
@Override
public Table getControl() {
return table;
}
@Override
public CollectionItem[] getItems() {
CollectionItem[] items = new CollectionItem[table.getItemCount()];
int ix = 0;
for (TableItem item : table.getItems()) {
items[ix++] = new TableCollectionItem(item);
}
return items;
}
@Override
public int getColumnCount() {
return table.getColumnCount();
}
private static class TableCollectionItem implements CollectionItem {
private TableItem item;
public TableCollectionItem(TableItem item) {
this.item = item;
}
@Override
public String getText(int columnIx) {
return item.getText(columnIx);
}
}
}
}