【原创】TreeViewer组件(十一)

上一篇 / 下一篇  2008-06-25 16:19:38 / 个人分类:Eclipse插件开发

 JFace中提供了TreeViewer组件,用TreeViewer来表示树型结构对象的显示。TreeViewer功能比较强,它能定义节点、节点的显示标签、响应事件和显示图标等信息。

ITPUB个人空间l(z1K"P,vT.zF
TreeViewer构建步骤


:C5p,x,fMS,O`Kb!_0TreeViewer中主要通过内容提供器(ITreeContentProvider)和标签提供器(ILabelProvider)组织树节点的内容和显示的信息。TreeViewer的构建步骤如下。
ef8sWU4A2WP$? A01.  创建TreeViewer对象,例如“TreeViewer tv = new TreeViewer(composite);”。
&tL$f?}gTI:nZ02.  设定内容管理器,例如“tv.setContentProvider(new FileTreeContentProvider());”。
`} V|d5J Fx]T:~03.  设定标签提供器,例如“tv.setLabelProvider(new FileTreeLabelProvider());”。
Gw&M u8jlI04.  设定TreeViewer的输入数据,例如“tv.setInput("root");”(用户可以通过输入数据构建树)。


6K(Ze ~'n0TreeViewer内容提供器


xNN_ BZ`7oz0TreeViewer的内容提供器(ITreeContentProvider)构建树中比较复杂的部分,它为树的显示提供了内容,内容提供器要实现的方法如下。
(T/]qSP.O01.  getElementsITPUB个人空间I.o!pO:T dE\
此函数定义为“public Object[] getElements(Object inputElement);”,当程序开始构建树时,首先调用getElements返回一个对象的数组,此数组对象表示当前树的根节点,inputElement参数为TreeViewer的输入(setInput的输入数据)。
G Dr&uM02.  hasChildren
!Szs t3H\0此函数定义为“public boolean hasChildren(Object element);”,当TreeViewer显示一个节点后,会调用hasChildren函数判断当前节点是否有子节点,如果有子节点则显示“+”,element参数为要判断是否有子节点的节点。
/I}1nZ3?"\{03.  getChildrenITPUB个人空间;b3l6M;t x$U9MS
此函数定义为“public Object[] getChildren(Object parentElement);”,当用户选择节点打开子节点时,会调用getChildren函数返回下一层子节点,parentElement参数为选择的节点。
)H,[8i2Xs'P04.  getParent
1E.S3Ic8e(D0此函数定义为“public Object getParent(Object element);”,可以通过此方法返回element的父节点。ITPUB个人空间1y:aH,TD"yz
5.  inputChangedITPUB个人空间yD-g;h1u]Hal
此函数定义为“public void inputChanged(Viewer viewer, Object oldInput, Object newInput);”,当输入改变时调用此方法。ITPUB个人空间}!u^$LNB#W
6.  dispose
s7H H:mJ*N3EZ [TTk0此函数定义为“public void dispose();”,当树销毁时被调用。ITPUB个人空间8C(Y qKR0j
其中,getElements、hasChildren和getChildren是常用的方法,用户通过重写这几个方法构建一棵树,过程如下:通过getElements方法得到根,再通过hasChildren判断根下是否有子节点,如果有子节点,可以通过getChildren得到所有的子节点。如例程1为ITreeContentProvider接口的一个简单实现。ITPUB个人空间 eMfb8~] u9[&j'f
例程1  FileTreeContentProvider.javaITPUB个人空间'hnU/gj!S9DTq4j
class FileTreeContentProvider implements ITreeContentProvider {
(X9l8kWJ ikD0 ITPUB个人空间"g8o5q)u-P6n%J)m_O:q
 public Object[] getChildren(Object arg0) {ITPUB个人空间:f mR5I'B$w}
  //返回树的下一级节点ITPUB个人空间UR2vw,H$qz%D
  return ((File) arg0).listFiles();ITPUB个人空间Vk:R&N,r V6N2B F
 }

 public Object getParent(Object arg0) {ITPUB个人空间g$BoUXa;H
  //返回树的上一级节点 
I]'B.Yr1rs4j0  return ((File) arg0).getParentFile();ITPUB个人空间9Klf#b&b`
 }
nNe(z9`cX+] y _0 ITPUB个人空间8_Oo^#l6n"I
 public boolean hasChildren(Object arg0) {ITPUB个人空间^jL K,MHh]
  Object[] bj = getChildren(arg0);

  //判断树是否有下一级节点,true为在节点显示"+"信息
n#~ vW0V0  return bj == null ? false : obj.length > 0;ITPUB个人空间AxV#Y U Jl'W \
 }ITPUB个人空间1f^EE:VIwc*N
 
GXyEvnQ0 public Object[] getElements(Object arg0) {

  //打印出树的输入信息,通常用户可以通过输入信息构建树ITPUB个人空间usqA/m]
  System.out.println(arg0);
R}!t!E&{X{U0  // File.listRoots()作为树的根节点ITPUB个人空间:{G*L'w6w"w:m4@N
  return File.listRoots();ITPUB个人空间 ]D;K0W"Zs
 }
mfD{g| X0上例内容提供器通过文件系统获得树的输入内容,从而使用户构造的树能显示磁盘文件的树结构。


wD!L/KR*r4c e]&dV0TreeViewer标签提供器


z"k1s8i O7b.Q@ F/gM0在TreeViewer中,通过标签提供器(ILabelProvider)来显示节点的相关信息,包括显示内容和图标。
D8Nr*` m#W!^0ILabelProvider主要实现getImage和getText函数。当TreeViewer得到一个节点后会通过getText得到此节点的显示文本,通过getImage方法得到节点的显示图标,代码如例程2所示。
J'i4mBY3~ hn0例程2  ViewLabelProvider.javaITPUB个人空间PxnOKj|Ev
class ViewLabelProvider extends ILabelProvider{
L bq+p'D0
'a(D"~XI:?-}Z7l0  public String getText(Object obj) {
u1cZ'R;\H5a(X'T w0   return obj.toString();
dG,K,kd4h{'Q6aw0  }
Yl5\0L}-R&NEj0  public Image getImage(Object obj) {ITPUB个人空间 E1Q+n%D1H;R%C
   String imageKey = ISharedImages.IMG_OBJ_ELEMENT;
/p'E)n"FF#Pgjc0   if (obj instanceof TreeParent)
0`I0GXxwc[eB4S"n^0      imageKey = ISharedImages.IMG_OBJ_FOLDER;
sw7Z"a1|$A3[%e0   return PlatformUI.getWorkbench().getSharedImages().getImage(imageKey);
K(D5~)Em"o,_"wx0  }ITPUB个人空间,i/nSw7d}i

vy)YtIL~5?}.a0 }


z1t(S4e#]EL9[(i!K0TreeViewer实例


&O8Bf7O:^3`"gC0在TreeViewer实例中,一般还要定义树节点的结构。本例中的File对象就能够表示节点的父子关系,代码如例程3所示。
-].Ha$|_,S"kO0例程3  FileBrowserTreeViewer.java

/**ITPUB个人空间[ W+QG3]%D,cW
 * 为了节省篇幅,把所有的import类注释了ITPUB个人空间a;n{F[w P9eC
 * 读者可以通过ctrl+shift+o快捷键,自动引入所依赖的类ITPUB个人空间wS y;V2@7@$K/H
 * */
}0N)k4I v J2mlU0public class FileBrowserTreeViewer extends ApplicationWindow {
L+p:wsa0 public FileBrowserTreeViewer() {
+^0W/F3K TV0  super(null);
n%G:P.S sK0 }

 public void run() {
L5_0i6d:_"_0  setBlockOnOpen(true);

  open();

  Display.getCurrent().dispose();ITPUB个人空间;~ h4YfUG*CkkR
 }

 protected void configureShell(Shell shell) {
#r/k4j)w#|0  super.configureShell(shell);

  shell.setText("File Tree");ITPUB个人空间)p6U"[i4Y3G
  shell.setSize(400, 400);ITPUB个人空间Q#^}(I2x;T,W:};W
 }

 protected Control createContents(Composite parent) {ITPUB个人空间_-t&S?+X1X'M/n
  Composite composite = new Composite(parent, SWT.NONE);ITPUB个人空间)` LZB{"c2t
  // 父容器分一列显示
Q3w/_ r_ev0  composite.setLayout(new GridLayout(1, false));

  Button preserveCase = new Button(composite, SWT.CHECK);
8SO!k]!K G7n.p_$Yd0  preserveCase.setText("&Preserve case");

  final TreeViewer tv = new TreeViewer(composite);
_z `)APs0  // 让树组件两端对齐ITPUB个人空间i PZ-C%a?!v/D*~%H
  tv.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
t1cwd'k,Z_b0  // 添加内容管理器ITPUB个人空间D ~Gqm"s[ W
  tv.setContentProvider(new FileTreeContentProvider());ITPUB个人空间nssUKF ^*]:_
  // 添加标签管理器
i;W1RbcE#N2Ys4k0  tv.setLabelProvider(new FileTreeLabelProvider());
+c9p^'p-f&}.\5Hp6?0  // 设置treeviewer的输入
1`[~,J7P|H-g2t0  tv.setInput("root"); // pass a non-null that will be ignored

  preserveCase.addSelectionListener(new SelectionAdapter() {
%oO\u,lzn0   public void widgetSelected(SelectionEvent event) {ITPUB个人空间;q'c3{X{^
    boolean preserveCase = ((Button) event.widget).getSelection();
@ @R*w?/J0    FileTreeLabelProvider ftlp = (FileTreeLabelProvider) tvITPUB个人空间w,w5EJa
      .getLabelProvider();
?&u9[/D-m0    ftlp.setPreserveCase(preserveCase);ITPUB个人空间@~!Z0vhk CV$`$t
   }
n/S1GwH y&@%O0  });ITPUB个人空间2c8]1b)c&tq*^
  return composite;
7`Pd6^ QT f!M'k0 }ITPUB个人空间b"KG9](Wk~dZa
 ITPUB个人空间6N?.FE*_+O'|)}}
 public static void main(String[] args) {ITPUB个人空间&] J0k4a#A%I
  new FileBrowserTreeViewer().run();
u&D,OZY3O%F6s:fC0 }
5[vI-S$QE0}

//定义内容提供器
b Xz2pU S,v$k0class FileTreeContentProvider implements ITreeContentProvider {
HWV}I`0 
Fw0Y K OA-d0 public Object[] getChildren(Object arg0) {
D\\4^ M/_7x5p0  //返回树的下一级节点ITPUB个人空间Q:E'U"H1N]+D
  return ((File) arg0).listFiles();ITPUB个人空间s\_5B5V.n2X&M
 }

 public Object getParent(Object arg0) {ITPUB个人空间QB;W4o Af$Ng
  ITPUB个人空间;i}I8o0@4o+kNi
  //返回树的上一级节点 ITPUB个人空间|0]k(l1U%|t
  return ((File) arg0).getParentFile();
*~2H:Bf9W$x*}.st0 }ITPUB个人空间n ^\B%e[
 ITPUB个人空间V,].f$s$E
 public boolean hasChildren(Object arg0) {ITPUB个人空间#n#C0l:W4O/^WO
  Object[] bj = getChildren(arg0);

  //判断树是否有下一级节点,true为在节点显示"+"信息ITPUB个人空间 IyR3EPY$r
  return bj == null ? false : obj.length > 0;ITPUB个人空间#]OY!?*B
 }ITPUB个人空间;H}T z$~%ce*c
 ITPUB个人空间6@7CB nJe{R|
 public Object[] getElements(Object arg0) {
{.k*{!~6P-]x&q*dE0  
}0| Tjj0  //打印出树的输入信息,通常用户可以通过输入信息构建树
&n l U3Ou} W:BV I0  System.out.println(arg0);ITPUB个人空间BuApE NT
  // File.listRoots()作为树的根节点
{ {"kCzt(M0  return File.listRoots();ITPUB个人空间e1?_q;A%_*M"@0e`'u
 }ITPUB个人空间P t C'~'I4D"u
 
"mz-m%OkM+t)Q%R0 public void dispose() {ITPUB个人空间Ob,k9m:k h%gBL
  
a3\xp O l7Yl[0 }

 public void inputChanged(Viewer arg0, Object arg1, Object arg2) {ITPUB个人空间U&]-tG*xuY['B
  ITPUB个人空间wj.]%EB]/Eu
 }
4b M `8Kie;u0}

//定义标签提供器
:R`/M'\"`*E0class FileTreeLabelProvider implements ILabelProvider {ITPUB个人空间+J,@{hw/w:t
 private List listeners;

 private Image file;

 private Image dir;

 boolean preserveCase;

 public FileTreeLabelProvider() {
(db ]Jnb:C0  listeners = new ArrayList();

  try {
|i%_:E IX0   //添加文件和目录的图标
1vH#skO1L0   file = new Image(null, new FileInputStream("icons/file.gif"));
Q;Zr x6\w7u0   dir = new Image(null, new FileInputStream("icons/directory.gif"));
6N{B+K;W_0  } catch (FileNotFoundException e) {
;?w d.p&r0   
9X5_'P3TbW0  }ITPUB个人空间1R6NYnrWb
 }
5K6V b&?*H(L\u&v0 
Q*^lOMK0 public void setPreserveCase(boolean preserveCase) {ITPUB个人空间 p0IQ#t\-O3@D4X&?5Z
  this.preserveCase = preserveCase;

  //触发事件,重新得到显示标签ITPUB个人空间3q)YO8C(^
  LabelProviderChangedEvent event = new LabelProviderChangedEvent(this);
m Z pi-B(O#I"p"m0  for (int i = 0, n = listeners.size(); i < n; i++) {ITPUB个人空间(_ YY2t$g(g}'\&t"Q7m
   ILabelProviderListener ilpl = (ILabelProviderListener) listenersITPUB个人空间"FI.h] @
     .get(i);
Oc)N_6\ ^/C0   ilpl.labelProviderChanged(event);
0kHZ|7V{DUo+Z0  }
;Gy/I(Z*f8i*s1\WE0 }ITPUB个人空间Yru#leXQ]a fu+Z
 
I"]4RlF.S0 public Image getImage(Object arg0) {ITPUB个人空间 C e!J2u!nW+_sz s
  //返回目录或文件的图标
M0T? m-`#D2[ E0  return ((File) arg0).isDirectory() ? dir : file;ITPUB个人空间[ {3s0a]/HI [ r
 }

 public String getText(Object arg0) {ITPUB个人空间QSWZDq4?/~h
  String text = ((File) arg0).getName();

  if (text.length() == 0) {
0e7qny5k T0D0   text = ((File) arg0).getPath();ITPUB个人空间w7G(cI5X@l/d}l3I-a;n
  }

  //返回目录或文件的文件名
]L]%y:S |UA(v2t0  return preserveCase ? text : text.toUpperCase();
V:]:IP @-fn.GI0 }

 public void addListener(ILabelProviderListener arg0) {
}I.D}Gb0  //添加监听器ITPUB个人空间K\#?LTY1[
  listeners.add(arg0);ITPUB个人空间"B!dE2T|R#k0Rg`(I
 }

 public void dispose() {
Mi7ZF&Xb0  if (dir != null)
7YQ^JB'KFwL0   dir.dispose();ITPUB个人空间/F`5z(hvLjh(]
  if (file != null)
Pu/^D]f5[ n.p4v0   file.dispose();ITPUB个人空间Y4{ x#LvV
 }

 public boolean isLabelProperty(Object arg0, String arg1) {
,e'x'AO`{,a0  return false;
'h:nPz.G5Ka0 }
\5W(mp!r _x;ak0 
7b'e0HJswwI1j&w0 public void removeListener(ILabelProviderListener arg0) {
5['{6E aX{3]0  //删除监听器ITPUB个人空间%_ G7_;v!W'k_"g
  listeners.remove(arg0);
(`)|2d/z%Sl!v+\6e9A0S*I0 }
(B'w0o/i&x)d ]z$p@6l0}
3F3tE3B}7g8[;`*I-k!C _0以上代码中,在主窗口上添加了TreeViewer组件,在树中显示当前磁盘和文件结构。另外可以通过“Preserve case”复选按钮选择是为原有显示文本还是全部大写显示文本,程序运行效果如图1所示。ITPUB个人空间1a%b+m&O-OT9l
 

图1 TreeViewer组件

ITPUB个人空间DM6ia-j;{W Q
TreeViewer的功能比较强大,在复杂的应用可以用它代替SWT的Tree组件,实现树的完美展现。
Y-~V-fD0上例中文件“icons/file.gif”和目录“icons/directory.gif”的图片没有加入,读者可以加入相应的显示图片,图片的位置为相对于当前工程根目录的相对路径。

 


TAG:

引用 删除 Guest   /   2008-08-14 14:57:35
5
引用 删除 elvaelva1232003   /   2008-07-25 15:51:42
5
引用 删除 Guest   /   2008-07-24 11:14:11
5
 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2008-10-16  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

  • 访问量: 11383
  • 日志数: 43
  • 文件数: 11
  • 建立时间: 2008-02-14
  • 更新时间: 2008-09-05

RSS订阅

Open Toolbar