2009-06-23 24 views
9

Tôi đang áp dụng một ViewerFilter cho một cây của một vài nhánh, nhưng chủ yếu là lá. Bộ lọc thực sự áp dụng cho lá, sử dụng các thuộc tính trong lá. Tất cả các cành cây đều bị bỏ hoang để lá của chúng có thể xuất hiện.Cách tốt nhất để sử dụng ViewerFilter trên TreeViewer?

Tuy nhiên tôi muốn lọc ra các nhánh không chứa lá đã chọn và tôi không thể thấy cơ chế nào trong phạm vi ViewerFilter cho phép điều này.

Điều này có thể thực hiện được không?

Ví dụ, với cây danh nghĩa bên dưới (nơi b là một chi nhánh, một L là một lá)

b0 
    b1 
    L2 
    L4 
    L8 
    b2 
    L1 
    L3 
    L5 

Tôi muốn áp dụng một ViewerFilter mà chỉ chọn thậm chí lá và cành có chứa thậm chí lá . Cây kết quả sẽ được ..

b0 
    b1 
    L2 
    L4 
    L8 

.. nơi chi nhánh b2 không hiển thị vì nó có chứa không có con được lựa chọn, nhưng chi nhánh b0b1 làm.

Trả lời

13
class MyFilter extends ViewerFilter{ 

    private boolean isLeaf(Object element){ 
    // implement this 
    } 

    private boolean isEvenLeaf(Object leaf){ 
    // implement this 
    } 

    @Override 
    public boolean select(Viewer viewer, Object parentElement, Object element){ 
    if (isLeaf(element)) 
     return isEventLeaf(element); 
    else { 
     StructuredViewer sviewer = (StructuredViewer) viewer; 
     ITreeContentProvider provider = (ITreeContentProvider) sviewer.getContentProvider(); 
     for (Object child: provider.getChildren(element)){ 
     if (select(viewer, element, child)) 
      return true; 
     } 
     return false; 
    } 
    } 
} 
+0

Tôi nghi ngờ rằng thời gian chạy của điều này khá xấu cho các bộ sưu tập lớn của các yếu tố. Ví dụ, tất cả các tài nguyên là một không gian làm việc. Tôi nghĩ rằng điều này sẽ, đối với mỗi tài nguyên, hãy truy cập tất cả các tài nguyên có chứa của nó. Đó là do đó * O (n^2) *. Nên có một giải pháp * O (n) *. – Lii

+0

Giải pháp này hoạt động thực sự tồi tệ khi người xem có các bộ lọc khác. Ví dụ trong trường hợp tài nguyên không gian làm việc, khi một bộ lọc khác lọc tất cả tài nguyên khỏi một thư mục, bộ lọc này sẽ vẫn báo cáo thư mục là không trống, vì bộ lọc này không nhận biết được bộ lọc khác. – Lii

0

Tôi không chắc chắn ý của bạn về lá được chọn. Nếu bạn có nghĩa là được chọn trong dạng xem, bạn có thể tìm thấy điều này bằng cách gọi Viewer.getSelection(). Phương pháp chọn mà bạn triển khai trong bộ lọc của bạn sẽ chuyển vào trình xem, phụ huynh và lá. Bạn sẽ có thể sử dụng thông tin này để quyết định xem lá có được chọn hay không và lọc chúng ra. Nếu bạn có thể cung cấp thêm một số thông tin, tôi có thể trả lời chi tiết hơn.

+0

Thay vì lá và cành, hãy nói về các thư mục và tệp. Cho một cây thư mục tùy ý, tôi chỉ muốn hiển thị các tệp phù hợp với * .foo. Hơn nữa, tôi muốn chỉ hiển thị các thư mục chứa các tệp * .foo, hoặc đệ quy chứa các thư mục làm. Các thư mục không chứa tệp như vậy sẽ không được hiển thị. Không giúp đỡ à? M. –

+0

Trong trường hợp đó, trong phương thức chọn, bạn sẽ cần xem xét đệ quy bắt đầu phần tử, nhận con của nó cho đến khi bạn đạt đến một lá thậm chí (trả về true) hoặc kết thúc (trả về false). – AdamC

1

Có, nếu bạn không lọc ra các nút nhánh, chúng sẽ được hiển thị ngay cả khi không có lá trong đó. Nếu bạn muốn bộ lọc được vĩnh viễn, một cái gì đó bạn có thể xem xét là sử dụng ITreeContentProvider làm bộ lọc.

Vì nhà cung cấp nội dung có cả hai phương thức getChildren() và hasChildren(), bạn có nhiều quyền kiểm soát hơn một chút.

2

Ngoài ra, hãy xem org.eclipse.ui.dialogs.FilteredTree điều phù hợp với lá con.

Các vấn đề liên quan