项目展开时自动调整列大小

发布于 2024-09-08 16:01:28 字数 1458 浏览 1 评论 0原文

在具有多列的树中,如何在展开/折叠和数据更新时调整列的大小以适应内容?

类似的表问题的解决方案不起作用。

与:

  tree.addListener(SWT.Collapse, new Listener(){
   @Override
   public void handleEvent(Event e) {
    expandAndResize(false, (TreeItem) e.item);
   }
  });

  tree.addListener(SWT.Expand, new Listener() {
   @Override
   public void handleEvent(Event event) {
    expandAndResize(false, (TreeItem) event.item);
   }
  });

 private static void expandAndResize(Boolean expand_, TreeItem item_)
 {
  System.out.println( (expand_?"Expanding":"Collapsing") + "item={" + item_ + "}");
  item_.setExpanded(expand_);
  System.out.println(" Resizing columns");
  resizeTree(item_.getParent());
 }

 private static void resizeTree(Tree tree_)
 {
  for (TreeColumn tc: tree_.getColumns())
   resizeTreeColumn(tc);
 }

 private static void resizeTreeColumn(TreeColumn treeColumn_)
 {
  treeColumn_.pack();  
 }

这适用于数据更新(通过调用resizeTree),但对于展开/折叠它落后了一步!

更具体地说,如果我展开第一列中的项目,并且底层项目比列宽度长,则将在下一次折叠或展开其他项目时调整大小到该宽度(或者如果我直接调用 调整树大小)。

以防万一,这很重要:数据由 TreeContentProviderITableLabelProvider 给出,我的猜测是 ITableLabelProvider 可能会导致问题(宽度在生成标签之前调整列的值?!)

X-发布到 Eclipse 社区论坛

In a tree with multiple columns, how do I resize columns to contents upon expand/collapse and data updates?

The solution to the similar question for tables doesn't work.

Same as:

  tree.addListener(SWT.Collapse, new Listener(){
   @Override
   public void handleEvent(Event e) {
    expandAndResize(false, (TreeItem) e.item);
   }
  });

  tree.addListener(SWT.Expand, new Listener() {
   @Override
   public void handleEvent(Event event) {
    expandAndResize(false, (TreeItem) event.item);
   }
  });

 private static void expandAndResize(Boolean expand_, TreeItem item_)
 {
  System.out.println( (expand_?"Expanding":"Collapsing") + "item={" + item_ + "}");
  item_.setExpanded(expand_);
  System.out.println(" Resizing columns");
  resizeTree(item_.getParent());
 }

 private static void resizeTree(Tree tree_)
 {
  for (TreeColumn tc: tree_.getColumns())
   resizeTreeColumn(tc);
 }

 private static void resizeTreeColumn(TreeColumn treeColumn_)
 {
  treeColumn_.pack();  
 }

This works for data updates (by calling the resizeTree), but for expands/collapses it is one step behind!

More specifically, if I expand an item in the first column, and the underlying item is longer than the column width, the resize to that width will be done upon a next collapse or expand of some other item (or if I directly call resizeTree).

Just in case it is important: the data is given by TreeContentProvider and ITableLabelProvider, and my guess is that ITableLabelProvider might cause the problem (the width of the column is adjusted before the label gets generated?!)

X-posted to Eclipse Community Forum

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

忆梦 2024-09-15 16:01:29

显示您的问题的 snippet 会让这变得更容易。

要解决此问题,您所需要做的就是将侦听器的代码放入 asyncExec 块中,以推迟其执行。 (我有一种似曾相识的感觉,因为我最近用相同的提示回答了另一个问题......)

顺便说一句:您不必调用 TreeItem.setExpanded(.)。另外,当您有原始类型时,不要使用布尔值。它可以工作,但虚拟机始终进行自动装箱,这对性能不利。这在这里并不重要,但这是一个坏习惯。然后:变量的下划线后缀?

现在是工作片段,取自并改编自 此处

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.*;

public class Snippet {

   public static void main( String[] args ) {
      final Display display = new Display();
      Shell shell = new Shell(display);
      shell.setLayout(new FillLayout());
      final Tree tree = new Tree(shell, SWT.BORDER);
      tree.setHeaderVisible(true);
      TreeColumn col1 = new TreeColumn(tree, 0);
      col1.setText("col1");
      TreeColumn col2 = new TreeColumn(tree, 0);
      col2.setText("col2");

      for ( int i = 0; i < 4; i++ ) {
         TreeItem iItem = new TreeItem(tree, 0);
         iItem.setText(new String[] { "TreeItem (0) -" + i, "x" });
         for ( int j = 0; j < 4; j++ ) {
            TreeItem jItem = new TreeItem(iItem, 0);
            jItem.setText(new String[] { "TreeItem (1) -" + i, "x" });
            for ( int k = 0; k < 4; k++ ) {
               TreeItem kItem = new TreeItem(jItem, 0);
               kItem.setText(new String[] { "TreeItem (2) -" + i, "x" });
               for ( int l = 0; l < 4; l++ ) {
                  TreeItem lItem = new TreeItem(kItem, 0);
                  lItem.setText(new String[] { "TreeItem (3) -" + i, "x" });
               }
            }
         }
      }

      col1.pack();
      col2.pack();

      Listener listener = new Listener() {

         @Override
         public void handleEvent( Event e ) {
            final TreeItem treeItem = (TreeItem)e.item;
            display.asyncExec(new Runnable() {

               @Override
               public void run() {
                  for ( TreeColumn tc : treeItem.getParent().getColumns() )
                     tc.pack();
               }
            });
         }
      };

      tree.addListener(SWT.Collapse, listener);
      tree.addListener(SWT.Expand, listener);

      shell.setSize(200, 200);
      shell.open();
      while ( !shell.isDisposed() ) {
         if ( !display.readAndDispatch() ) display.sleep();
      }
      display.dispose();
   }
}

A snippet showing your issue would have made this easier.

All you have to do to fix this, is put your listener's code into an asyncExec block, to postpone its execution. (I have a deja-vu, since I answered another question with the same tip very recently...)

BTW: You don't have to call TreeItem.setExpanded(.). Also, don't use Boolean when you have a primitive type. It works, but the VM does auto boxing all the time, which isn't good for performance. That doesn't matter here, but it's a bad habbit. And then: Underscore suffixes for variables?

Now the working snippet, taken and adapted from here:

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.*;

public class Snippet {

   public static void main( String[] args ) {
      final Display display = new Display();
      Shell shell = new Shell(display);
      shell.setLayout(new FillLayout());
      final Tree tree = new Tree(shell, SWT.BORDER);
      tree.setHeaderVisible(true);
      TreeColumn col1 = new TreeColumn(tree, 0);
      col1.setText("col1");
      TreeColumn col2 = new TreeColumn(tree, 0);
      col2.setText("col2");

      for ( int i = 0; i < 4; i++ ) {
         TreeItem iItem = new TreeItem(tree, 0);
         iItem.setText(new String[] { "TreeItem (0) -" + i, "x" });
         for ( int j = 0; j < 4; j++ ) {
            TreeItem jItem = new TreeItem(iItem, 0);
            jItem.setText(new String[] { "TreeItem (1) -" + i, "x" });
            for ( int k = 0; k < 4; k++ ) {
               TreeItem kItem = new TreeItem(jItem, 0);
               kItem.setText(new String[] { "TreeItem (2) -" + i, "x" });
               for ( int l = 0; l < 4; l++ ) {
                  TreeItem lItem = new TreeItem(kItem, 0);
                  lItem.setText(new String[] { "TreeItem (3) -" + i, "x" });
               }
            }
         }
      }

      col1.pack();
      col2.pack();

      Listener listener = new Listener() {

         @Override
         public void handleEvent( Event e ) {
            final TreeItem treeItem = (TreeItem)e.item;
            display.asyncExec(new Runnable() {

               @Override
               public void run() {
                  for ( TreeColumn tc : treeItem.getParent().getColumns() )
                     tc.pack();
               }
            });
         }
      };

      tree.addListener(SWT.Collapse, listener);
      tree.addListener(SWT.Expand, listener);

      shell.setSize(200, 200);
      shell.open();
      while ( !shell.isDisposed() ) {
         if ( !display.readAndDispatch() ) display.sleep();
      }
      display.dispose();
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文