在swt中,tableeditor提供了添加tableItem添加附加控件的功能。但是在删除的时候,
有可能会遇到删除了item,btn,editor之后,item和btn没有对齐的情况,就好像下面这种。
那问题怎么解决呢,其实很简单,你可以重新去调用一次tableEditor的layout()事件,就可以帮你刷新了。
又或者重新再setEditor,当然有最方便的,调用table.notifyListeners(SWT.KeyDown, null);
下面是一个小栗子
import java.util.HashMap;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
public class TView extends Composite {
private Table table;
public static final String[] COLUMU_NAME = { "ID", "状态" };
public static final int[] COLUMU_WIDTH = { 50, 70 };
private TView me;
private HashMap<Integer, TableEditor> editorHm = new HashMap<Integer, TableEditor>();// 存放tableEditor
private HashMap<Integer, Button> btnHm = new HashMap<Integer, Button>();// 存放按钮
private HashMap<Integer, TableItem> itemHm = new HashMap<Integer, TableItem>();// 存放tableitem
public TView(Composite parent, int style) {
super(parent, style);
me = this;
initTable();
}
private void initTable() {
me.setLayout(new FillLayout());
table = new Table(this, SWT.FULL_SELECTION | SWT.MULTI);
for (int i = 0; i < COLUMU_NAME.length; i++) {
TableColumn t = new TableColumn(table, SWT.LEFT);
t.setText(COLUMU_NAME[i]);
t.setWidth(COLUMU_WIDTH[i]);
}
table.setHeaderVisible(true);
table.setLinesVisible(true);
initTableContent();
}
private void initTableContent() {
for (int i = 0; i < 10; i++) {
TableItem item = new TableItem(table, 0);
item.setText(0, i + "");
item.setData(i);// 做匹配的标志,可以用其它方法,只要达到删除时删除btn的功能就可以了
Button btn = new Button(table, 0);
btn.setText("来点我啊" + i);
btn.setData(i);
TableEditor editor = new TableEditor(table);
editor.grabHorizontal = true;
editor.minimumWidth = 10;
editor.minimumHeight = 20;
editor.setEditor(btn, item, COLUMU_NAME.length - 1);
editorHm.put(i, editor);
itemHm.put(i, item);
btnHm.put(i, btn);
btn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent arg0) {
int bIndex = Integer.valueOf(arg0.widget.getData() + "");
TableItem[] items = table.getItems();
for (int i = 0; i < items.length; i++) {
TableItem item = items[i];
int index = Integer.valueOf(item.getData() + "");
if (index == bIndex) {
System.err.println("找到了");
// 释放掉
editorHm.get(index).dispose();// 当editor.dispose的时候,并不会讲里面的控件也一并dispose,而是将引用设置为null
table.remove(i);
btnHm.get(index).dispose();
// 删除掉
editorHm.remove(index);
btnHm.remove(index);
itemHm.remove(index);
break;
}
}
// 一下三种都可以达到刷新的效果
table.notifyListeners(SWT.KeyDown, null);
// flushEditor();
// setEditor
}
});
}
}
/**
*
* 重新设定TableEditor令其强制更新,此段代码可以注释掉,可以看到效果
*
* */
private void flushEditor() {
for (int key : editorHm.keySet()) {
TableEditor editor = editorHm.get(key);
editor.layout();// .setEditor(b, item, COLUMU_NAME.length-1);
}
}
/**
*
* 重新设定TableEditor令其强制更新,此段代码可以注释掉,可以看到效果
*
* */
private void setEditor() {
for (int key : editorHm.keySet()) {
TableEditor editor = editorHm.get(key);
Button btn = btnHm.get(key);
TableItem item = itemHm.get(key);
editor.setEditor(btn, item, COLUMU_NAME.length - 1);
}
}
}
editor的layout可以刷新,我想大家都知道这字面的意思,就是刷新布局,其实就是去获取table的滚动条来计算比例,然后刷新位置,具体实现有兴趣的可以去看看源码;
至于为什么table.notifyListeners(SWT.KeyDown, null);可以达到刷新的效果,那是因为
在tableeditor的父类中,contorlEditor注册了一个事件就是
public class ControlEditor
{
private static final int[] EVENTS = { 1, 2, 3, 4, 11 };
..................
.................
public ControlEditor{
for (int i = 0; i < EVENTS.length; i++) {
parent.addListener(EVENTS[i], this.controlListener);//注册事件
}
..................
.................
}
this.controlListener = new Listener() {
public void handleEvent(Event e) {
ControlEditor.this.layout();//这是刷新布局
}
};
}
所以,当你触发了keydown之后就会自动刷新
同理
table.notifyListeners(1, null);
table.notifyListeners(2, null);
table.notifyListeners(3, null);
table.notifyListeners(4, null);
table.notifyListeners(11, null);
都可以让它们自动对齐。
下附源码:
使用的时候,new一个就可以了
TView table = new TView(shell, 0);