jface的CheckboxTreeViewer实现单选

时间:2023-03-08 19:14:36

需求:使用FilteredTree实现一个下面这样的Dialog,要求Check框单选,即只能选择一个:当选择新的时候,旧的不选。说明:FilteredTree自带一个文本输入框。

jface的CheckboxTreeViewer实现单选

1、自己的类继承org.eclipse.jface.dialogs.Dialog

2、在createDialogArea方法中实现自己的窗体:

 protected Control createDialogArea(Composite parent) {
Composite composite = new Composite(parent,SWT.NULL);
composite.getShell().setText("****选择"); composite.setLayout(new GridLayout(1,false));
GridData compositeGridData = new GridData(GridData.FILL_BOTH);
composite.setLayoutData(compositeGridData); Label title = new Label(composite,SWT.NONE);
title.setAlignment(SWT.LEFT);
title.setText("可选**信息");
title.setLayoutData(new GridData(SWT.LEFT,SWT.TOP,false,false,1,1)); ChooseProjectEntryFilteredTree filteredTree = new ChooseProjectEntryFilteredTree(
composite,
SWT.BORDER,
new ChooseProjectEntryPatternFilter(),
true);
this.treeViewer = filteredTree.getViewer();
//this.treeViewer.setUseHashlookup(true); this.tree = this.treeViewer.getTree();
this.tree.setToolTipText("请输入***的关键词"); this.checkboxTreeViewer = new CheckboxTreeViewer(this.tree); GridData gd = new GridData(SWT.FILL,SWT.FILL,true,false,1,1);
gd.heightHint = 250;
this.tree.setLayoutData(gd);
this.tree.setLinesVisible(true);
this.tree.setHeaderVisible(true); TreeColumn funcDecl = new TreeColumn(this.tree,SWT.CENTER);
funcDecl.setText("****");
funcDecl.setWidth(240);
funcDecl.addSelectionListener(new SelectionAdapter() {
boolean sortType = true; @Override
public void widgetSelected(SelectionEvent e) {
sortType = !sortType;
treeViewer.setSorter(sortType ? ChooseProjectEntrySorter.sorter
: ChooseProjectEntrySorter.reverseSorter);
} }); TreeColumn file = new TreeColumn(this.tree,SWT.CENTER);
file.setText("****");
file.setWidth(270); TreeColumn line = new TreeColumn(this.tree,SWT.CENTER);
line.setText("***");
line.setWidth(100); treeViewer.setContentProvider(new ChooseProjectEntryContentProvider());
treeViewer.setLabelProvider(new ChooseProjectEntryLabelProvider());
treeViewer.setSorter(ChooseProjectEntrySorter.sorter);
treeViewer.setInput(manager); this.selectedLabel = new Label(composite,SWT.NONE);
this.selectedLabel.setAlignment(SWT.LEFT);
GridData labelGd = new GridData(SWT.LEFT,SWT.TOP,true,false,1,1);
labelGd.widthHint = 380;
this.selectedLabel.setLayoutData(labelGd); this.checkboxTreeViewer.addCheckStateListener(checkStateListener); //this.treeViewer.addSelectionChangedListener(listener);
return null;
}

代码如下:

说明:

treeViewer.setContentProvider(new ChooseProjectEntryContentProvider());
treeViewer.setLabelProvider(new ChooseProjectEntryLabelProvider());
treeViewer.setSorter(ChooseProjectEntrySorter.sorter);
treeViewer.setInput(manager);

这里设置的是TreeViewer的content provider和label provider、sorter,所以并不能正常使用checkboxTreeViewer.setChecked()和setSubtreeChecked(),并不能像这个链接中那样设置指定行的checked状态为false,所以需要使用下面的方法:

1)、checkboxTreeViewer监听事件:

     /**
* 单选表格
*/
private ICheckStateListener checkStateListener = new ICheckStateListener(){
@Override
public void checkStateChanged(CheckStateChangedEvent event) {
if (event.getChecked()) {
setAllCheckedFalse();
//checkboxTreeViewer.setChecked(getTreeItem(event.getElement()), true);
checkFunc = (FuncItem)(event.getElement());
TreeItem item = getTreeItem(checkFunc);
if(item != null){
item.setChecked(true);
}
selectedLabel.setText("已选**:" + checkFunc.***);
}else{
checkFunc = null;
} treeViewer.refresh();
} };

代码如下:

2)、设置所有checked的行为unchecked状态:

 /**
* 设置所有被checked的选项unchecked
*/
private void setAllCheckedFalse(){
TreeItem[] items = this.tree.getItems(); if(items.length > 0){
for(int i = 0; i < items.length; i ++){
TreeItem item = items[i];
item.setChecked(false);
}
}
}

代码如下:

3)、getTreeItem函数:

 private TreeItem getTreeItem(FuncItem element){
TreeItem[] items = this.tree.getItems(); if(items.length > 0){
for(int i = 0; i < items.length; i ++){
TreeItem item = items[i];
if(element.equals((FuncItem)item.getData())){
return item;
}
}
} return null;
}

代码如下:

3、贴一下ChooseProjectEntryFilteredTree的代码

 /**
* 自行导入需要的包
*/
public class ChooseProjectEntryFilteredTree extends FilteredTree { public ChooseProjectEntryFilteredTree(Composite parent, int treeStyle,
PatternFilter filter, boolean useNewLook) {
super(parent, treeStyle, filter, useNewLook);
} @Override
protected TreeViewer doCreateTreeViewer(Composite parent, int style) {
return super.doCreateTreeViewer(parent, SWT.CHECK | SWT.SINGLE | SWT.BORDER
| SWT.V_SCROLL | SWT.H_SCROLL);
} }

代码如下:

4、贴一下ChooseProjectEntryPatternFilter的代码

 public class ChooseProjectEntryPatternFilter extends PatternFilter {

     @Override
protected boolean isLeafMatch(Viewer viewer, Object element) {
TreeViewer treeViewer = (TreeViewer) viewer; int numberOfColumns = treeViewer.getTree().getColumnCount(); ITableLabelProvider labelProvider = (ITableLabelProvider) treeViewer
.getLabelProvider(); boolean isMatch = false; for (int columnIndex = 0; columnIndex < numberOfColumns; columnIndex++) {
String labelText = labelProvider
.getColumnText(element, columnIndex);
isMatch |= wordMatches(labelText);
} return isMatch;
} }

代码如下:

ChooseProjectEntryContentProvider、ChooseProjectEntryLabelProvider、ChooseProjectEntrySorter跟一般的TreeViewer差不多,

这里再贴ChooseProjectEntryLabelProvider的部分代码:

 public class ChooseProjectEntryLabelProvider extends LabelProvider implements ITableLabelProvider{

     @Override
public Image getColumnImage(Object element, int columnIndex) {
return null;
} @Override
public String getColumnText(Object element, int columnIndex) { if(element instanceof FuncItem){
FuncItem func = (FuncItem)element;
switch(columnIndex){
case 0:
return func.***;
case 1:
return func.***;
case 2:
return String.valueOf(func.***);
default:
return "";
}
} return getText(element);
} }

代码如下

注意这里实现的是ITableLabelProvider接口。

我自己用checkboxTreeViewer.setChecked(element, state)无法设置event.getElement()【checkStateChanged方法中】元素的状态,

但是使用checkboxTreeViewer.setAllChecked(state)可以设置所有元素的状态为checked或者unchecked,

没办法,我又需要使用FilteredTree,又无法使用setChecked办法设置指定元素状态(我单步调试进入setChecked方法里面看了看,应该是event.getElement()元素的问题),只好想出上面的馊办法,希望对读者有用。