【原创】TableViewer组件(十二)

TableViewer组件


   JFace中提供了TableViewer组件,用TableViewer来表示表格。TableViewer 和TreeViewer类似,它也提供了内容提供器(IStructuredContentProvider)和标签提供器(ITableLabelProvider),用来组织表格的信息。


TableViewer构建步骤


TableViewer中主要通过内容提供器(IStructuredContentProvider)和标签提供器(ITable- LabelProvider)组织表中单元格的显示信息。TableViewer构建步骤如下。
1.  创建TableViewer对象,例如“tableViewer = new TableViewer(table);”,其中table是SWT中Table对象。
2.  设定内容管理器,例如“tableViewer.setContentProvider(contentProvider);”。
3.  设定标签提供器,例如“tableViewer.setLabelProvider(labelProvider);”。
4.  设定TableViewer的输入数据,例如“tableViewer.setInput("root");”(用户可以通过输入数据构建表)。
另外,用户可以添加排序器和过滤器对表格数据进行排序和过滤,后面将通过实例介绍排序器和过滤器。


TableViewer内容提供器(IStructuredContentProvider)


TableViewer中的内容管理器比较简单,用户可以通过实现getElements返回表格的所有数据。
getElements定义为“public Object[] getElements(Object inputElement)”,返回Object[]对象数组,其中数组中每一个对象代表表格的一列。当TableViewer输入数据后,内容管理器将根据输入数据构造表格对象数据,如下代码所示。
public Object[] getElements(Object inputElement) {

 //通过输入的数据建表
 Vector v = (Vector) inputElement;
 return v.toArray();
}
其中,输入数据inputElement为Vector类型的变量,通过“v.toArray();”返回对象数组。
TableViewer标签提供器(ITableLabelProvider)
TableViewer中的标签提供器主要负责每个单元格中文本和图标的显示。ITableLabelProvider接口要求实现getColumnText和getColumnImage两个主要的方法,getColumnText返回指定单元格的显示文本,getColumnImage返回指定单元格的显示图标,解释如下。
1.  getColumnText:此函数定义为“public String getColumnText(Object element, int columnIndex)”,其中element表示单元格所在行的对象,columnIndex表示单元格所在的列,返回显示的文本。如下代码返回Bug对象的某特定列的显示文本。
   public String getColumnText(Object element, int columnIndex) {
    Bug bug = (Bug) element;
    switch (columnIndex) {
    case 0:
     return bug.id;
    case 1:
     return bug.summary;
    case 2:
     return bug.assignedTo;
    case 3:
     return bug.isSolved ? "YES" : "NO";
    }
    return null;
   }
2.  getColumnImage:此函数定义为“public Image getColumnImage(Object element, int columnIndex)”,其中element表示单元格所在行的对象,columnIndex表示单元格所在的列,返回此单元格的显示图标。如下代码返回Bug对象的某特定列的显示图标。
   public Image getColumnImage(Object element, int columnIndex) {
    if (columnIndex == 0)
     return bugIcon;
    return null;
   }
从上面代码可以看出,只有第一列显示图标,其他列不显示图标。


TableViewer实例


本节的实例为一个Bug列表实例(BugTrackerTableViewer),程序的功能如下。
1.  在窗口中通过ToolBar建立工具栏,并通过ToolBarManager添加相应的Action到工具栏中。
2.  在表格中设置内容管理器和标签管理器。
3.  在表格的每一列添加排序器。当用户单击列头时,排序器将按列排序。排序器中主要通过compare方法比较两行(即两个对象)中的特定列单元格数据大小,返回比较后表格排列的顺序。
4.  通过工具栏的Action(actionShowUnsolvedOnly)添加或删除过滤器,过滤器将根据过滤条件选择出符合要求的行(即对象)。
另外,程序中将在运行时加载上次存储的Bug列表,用户也可以保存当前的Bug列表,程序如例程1所示。
例程1  BugTrackerTableViewer.java
      
/**
 * 为了节省篇幅,把所有的import类注释了
 * 读者可以通过ctrl+shift+o快捷键,自动引入所依赖的类
 * */
public class BugTrackerTableViewer {
 // 内部类Bug,代表一个BUG显示
 public static class Bug {

  public String id;
  public String summary;
  public String assignedTo;
  public boolean isSolved;

  public Bug(String id, String summary, String assignedTo,
    boolean isSolved) {
   this.id = id;
   this.summary = summary;
   this.assignedTo = assignedTo;
   this.isSolved = isSolved;
  }

  public static Vector loadBugs(File file) {
   Vector v = new Vector();

   DataInputStream in = null;

   try {
    if (!file.exists())
     return v;
    in = new DataInputStream(new FileInputStream(file));

    while (true) {
     String id = in.readUTF();
     String summary = in.readUTF();
     String assignedTo = in.readUTF();
     boolean solved = in.readBoolean();
     v.add(new Bug(id, summary, assignedTo, solved));
    }
   } catch (IOException ioe) {

   } finally {
    try {
     if (in != null)
      in.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
   return v;
  }
 }

 Display display = new Display();
 Shell shell = new Shell(display);
 Table table;
 TableViewer tableViewer;
 Vector bugs;

 /**
  * 读者可以通过图片创建自己的Image 例如:Image bugIcon = new Image(shell.getDisplay(),
  * "icons/mybug.gif");
  */
 Image bugIcon = WorkbenchImages
   .getImage(IWorkbenchGraphicConstants.IMG_OBJ_SIGNED_YES);

 String[] colNames = new String[] { "ID", "Summary", "Assigned to", "Solved" };

 // 实现表格的排序器
 class BugSorter extends ViewerSorter {
  private String property;
  private int propertyIndex;

  public BugSorter(String sortByProperty) {
   for (int i = 0; i < colNames.length; i++) {
    if (colNames[i].equals(sortByProperty)) {
     this.property = sortByProperty;
     this.propertyIndex = i;
     return;
    }
   }
   throw new IllegalArgumentException("Unrecognized property: "
     + sortByProperty);
  }

  // 比较e1和e2的大小
  public int compare(Viewer viewer, Object e1, Object e2) {
   Bug bug1 = (Bug) e1;
   Bug bug2 = (Bug) e2;
   switch (propertyIndex) {
   case 0:
    return bug1.id.compareTo(bug2.id);
   case 1:
    return bug1.summary.compareTo(bug2.summary);
   case 2:
    return bug1.assignedTo.compareTo(bug2.assignedTo);
   case 3:
    if (bug1.isSolved == bug2.isSolved)
     return 0;
    if (bug1.isSolved)
     return 1;
    else
     return -1;
   default:
    return 0;
   }
  }

 }

 public BugTrackerTableViewer() {
  // 添加工具栏的相应Action
  // 添加新建按钮的Action
  Action actionAddNew = new Action("New bug") {
   public void run() {
    // Append.
    Bug bug = new Bug("", "", "", false);
    bugs.add(bug);
    tableViewer.refresh(false);
   }
  };

  Action actionDelete = new Action("Delete selected") {
   public void run() {
    IStructuredSelection selection = (IStructuredSelection) tableViewer
      .getSelection();
    Bug bug = (Bug) selection.getFirstElement();
    if (bug == null) {
     System.out.println("Please select an item first. ");
     return;
    }
    MessageBox messageBox = new MessageBox(shell, SWT.YES | SWT.NO);
    messageBox.setText("Confirmation");
    messageBox
      .setMessage("Are you sure to remove the bug with id #"
        + bug.id);
    if (messageBox.open() == SWT.YES) {
     bugs.remove(bug);
     tableViewer.refresh(false);
    }
   }
  };

  Action actionSave = new Action("Save") {
   public void run() {
    saveBugs(bugs);
   }
  };
  // 添加表的过滤器
  final ViewerFilter filter = new ViewerFilter() {
   public boolean select(Viewer viewer, Object parentElement,
     Object element) {
    if (!((Bug) element).isSolved)
     return true;
    return false;
   }
  };
  Action actionShowUnsolvedOnly = new Action("Show unsolved only") {
   public void run() {
    if (!isChecked())
     tableViewer.removeFilter(filter);
    else
     tableViewer.addFilter(filter);
   }
  };
  actionShowUnsolvedOnly.setChecked(false);

  ToolBar toolBar = new ToolBar(shell, SWT.RIGHT | SWT.FLAT);

  ToolBarManager manager = new ToolBarManager(toolBar);
  // 添加工具项,并把工具项关联到相应的Action
  manager.add(actionAddNew);
  manager.add(actionDelete);
  manager.add(new Separator());
  manager.add(actionSave);
  manager.add(new Separator());
  manager.add(actionShowUnsolvedOnly);
  manager.update(true);
  shell.setLayout(new GridLayout());
  table = new Table(shell, SWT.BORDER | SWT.FULL_SELECTION);

  TableColumn tcID = new TableColumn(table, SWT.LEFT);
  tcID.setText(colNames[0]);

  TableColumn tcSummary = new TableColumn(table, SWT.NULL);
  tcSummary.setText(colNames[1]);

  TableColumn tcAssignedTo = new TableColumn(table, SWT.NULL);
  tcAssignedTo.setText(colNames[2]);

  TableColumn tcSolved = new TableColumn(table, SWT.NULL);
  tcSolved.setText(colNames[3]);

  tcID.setWidth(60);
  tcSummary.setWidth(200);
  tcAssignedTo.setWidth(80);
  tcSolved.setWidth(50);
  tableViewer = new TableViewer(table);
  tableViewer.getTable().setLinesVisible(true);
  tableViewer.getTable().setHeaderVisible(true);
  tableViewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH));
  // 设定表的内容管理器
  tableViewer.setContentProvider(new IStructuredContentProvider() {
   // 获得所有对象
   public Object[] getElements(Object inputElement) {

    // 通过输入的数据建表
    Vector v = (Vector) inputElement;
    return v.toArray();
   }

   public void dispose() {
    System.out.println("Disposing ...");
   }

   public void inputChanged(Viewer viewer, Object oldInput,
     Object newInput) {
    System.out.println("Input changed: ld=" + oldInput + ", new="
      + newInput);
   }
  });
  // 设定表的标签管理器
  tableViewer.setLabelProvider(new ITableLabelProvider() {
   public Image getColumnImage(Object element, int columnIndex) {
    if (columnIndex == 0)
     return bugIcon;
    return null;
   }

   // 获得列的显示文本
   public String getColumnText(Object element, int columnIndex) {
    Bug bug = (Bug) element;
    switch (columnIndex) {
    case 0:
     return bug.id;
    case 1:
     return bug.summary;
    case 2:
     return bug.assignedTo;
    case 3:
     return bug.isSolved ? "YES" : "NO";
    }
    return null;
   }

   public void addListener(ILabelProviderListener listener) {
   }

   public void dispose() {
   }

   public boolean isLabelProperty(Object element, String property) {
    return false;
   }

   public void removeListener(ILabelProviderListener listener) {
   }
  });
  // 设定单元格编辑器
  tableViewer.setColumnProperties(colNames);
  CellEditor[] cellEditors = new CellEditor[4];
  cellEditors[0] = new TextCellEditor(table);
  cellEditors[1] = cellEditors[0];
  cellEditors[2] = cellEditors[0];
  cellEditors[3] = new CheckboxCellEditor(table);
  tableViewer.setCellEditors(cellEditors);
  // 设定单元格修改器
  tableViewer.setCellModifier(new ICellModifier() {
   public boolean canModify(Object element, String property) {
    return true;
   }

   public Object getValue(Object element, String property) {
    int index = -1;
    for (int i = 0; i < colNames.length; i++) {
     if (colNames[i].equals(property)) {
      index = i;
      break;
     }
    }
    Bug bug = (Bug) element;
    switch (index) {
    case 0:
     return bug.id;
    case 1:
     return bug.summary;
    case 2:
     return bug.assignedTo;
    case 3:
     return new Boolean(bug.isSolved);
    }
    return null;
   }

   public void modify(Object element, String property, Object value) {
    System.out.println("Modify: " + element + ", " + property
      + ", " + value);

    int index = -1;
    for (int i = 0; i < colNames.length; i++) {
     if (colNames[i].equals(property)) {
      index = i;
      break;
     }
    }
    Bug bug = null;
    if (element instanceof Item) {
     TableItem item = (TableItem) element;
     bug = (Bug) item.getData();
    } else {
     bug = (Bug) element;
    }
    switch (index) {
    case 0:
     bug.id = (String) value;
     break;
    case 1:
     bug.summary = (String) value;
     break;
    case 2:
     bug.assignedTo = (String) value;
     break;
    case 3:
     bug.isSolved = ((Boolean) value).booleanValue();
     break;
    }
    tableViewer.update(bug, null);
   }
  });
  // 设定表格的排序方式
  // 单击第一列列头按第一列排序
  tcID.addListener(SWT.Selection, new Listener() {
   public void handleEvent(Event event) {
    tableViewer.setSorter(new BugSorter(colNames[0]));
   }
  });
  // 单击第二列列头按第二列排序
  tcSummary.addListener(SWT.Selection, new Listener() {
   public void handleEvent(Event event) {
    tableViewer.setSorter(new BugSorter(colNames[1]));
   }
  });
  // 单击第三列列头按第三列排序
  tcAssignedTo.addListener(SWT.Selection, new Listener() {
   public void handleEvent(Event event) {
    tableViewer.setSorter(new BugSorter(colNames[2]));
   }
  });
  // 单击第四列列头按第四列排序
  tcSolved.addListener(SWT.Selection, new Listener() {
   public void handleEvent(Event event) {
    tableViewer.setSorter(new BugSorter(colNames[3]));
   }
  });
  // 从文件中读取Bug记录
  bugs = Bug.loadBugs(new File("bugs.dat"));
  // 把bugs作为表格的输入
  tableViewer.setInput(bugs);

  shell.pack();
  shell.open();

  while (!shell.isDisposed()) {
   if (!display.readAndDispatch()) {
    display.sleep();
   }
  }

  display.dispose();
 }

 // 保存当前的Bug记录
 private void saveBugs(Vector v) {

  DataOutputStream ut = null;
  try {
   File file = new File("bugs.dat");

   out = new DataOutputStream(new FileOutputStream(file));

   for (int i = 0; i < v.size(); i++) {
    Bug bug = (Bug) v.elementAt(i);
    out.writeUTF(bug.id);
    out.writeUTF(bug.summary);
    out.writeUTF(bug.assignedTo);
    out.writeBoolean(bug.isSolved);
   }
  } catch (IOException ioe) {

  } finally {
   try {
    if (out != null)
     out.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

 public static void main(String[] args) {
  new BugTrackerTableViewer();
 }
}
上例为表格添加了过滤器(ViewerFilter)和排序器(BugSorter),用户可以单击表格的列头按此列进行排序。另外,还能够通过工具栏按钮过滤掉已解决的Bug信息。程序运行效果如图1所示。

13081368_200806260947521.jpg


 
图1  TableViewer组件


TableViewer的功能比较强大,在复杂的应用中可以用它代替SWT中的Table组件,实现表格的完美展现。
除了TreeViewer和TableViewer组件外,JFace中还封装了ListViewer等组件,用户可以直接使用这些组件实现自己的功能。
提示:所有的Viewer组件都封装了SWT中组件的实现,例如TreeViewer封装了Tree组件,可以通过Viewer组件得到对应的SWT组件(“getTree”),这可能在窗口布局或直接处理Viewer中的SWT窗口时会使用到。


 

fj.pngimage002.jpg

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/13081368/viewspace-365969/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/13081368/viewspace-365969/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值