java - 制作文本的 SWT 树列剪辑开头

标签 java swt eclipse-rcp jface

我有一个 SWT 树(通过 JFace TreeViewer),它在列中显示项目,其中一些具有长字符串。字符串的末尾对用户来说是有意义的位,而不是开始,所以当文本被剪裁时,我希望剪裁发生在字符串的开头而不是结尾。示例:

包含以下内容的单元格的默认行为:“这是一个非常长的字符串,完全超出了树列的边界”是:

|This is a very l...|

我想要的地方:

|... the tree column|

编辑:

我使用自定义 PaintItem 监听器解决了这个问题,如下所述:http://www.eclipse.org/articles/article.php?file=Article-CustomDrawingTableAndTreeItems/index.html

提出了以下代码(不是很完美,其中有一些重复和魔数(Magic Number)):

    tree.addListener(SWT.EraseItem, new Listener()
    {
        public void handleEvent(Event event)
        {
            String text = ((TreeItem)event.item).getText(event.index);
            Point size = event.gc.textExtent(text);
            TreeColumn column = ((Tree)event.widget).getColumn(event.index);                
            int columnWidth = column.getWidth() - 10; /* magic number alert - the cells have some padding - must be a way of determining this... */ 
            if(size.x > columnWidth)
            {
                event.detail &= ~SWT.FOREGROUND;
            }
        }
    });

    tree.addListener(SWT.PaintItem, new Listener()
    {               
        @Override
        public void handleEvent(Event event)
        {   
            String text = ((TreeItem)event.item).getText(event.index);
            Point size = event.gc.textExtent(text);
            TreeColumn column = ((Tree)event.widget).getColumn(event.index);                
            int columnWidth = column.getWidth() - 10; /* magic number alert - the cells have some padding - must be a way of determining this... */ 
            if(size.x > columnWidth)
            {
                drawTextTail(event, text, columnWidth);
            }                               
        }

        private void drawTextTail(Event event, String text, int columnWidth)
        {
            String clippedText = "";
            int offset = text.length() - 1; 
            String nextClippedText = text.charAt(offset) + clippedText;
            while(fits(nextClippedText, columnWidth, event.gc))
            {
                clippedText = nextClippedText;
                offset--;
                nextClippedText = text.charAt(offset) + clippedText;
            }
            event.gc.drawText("..." + clippedText, 
                    event.x + 5, /* magic number alert - the cells have some padding - must be a way of determining this... */ 
                    event.y, false);
        }

        private boolean fits(String clippedText, int columnWidth, GC gc)
        {
            Point size = gc.textExtent("..." + clippedText);                        
            return size.x < columnWidth;
        }
    });

最佳答案

试试这个。第二列自动裁剪 String 以适合该列。

public static void main(String[] args) {
    Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setLayout(new FillLayout());

    final Tree tree = new Tree(shell, SWT.NONE);
    tree.setLayout(new FillLayout());
    tree.setHeaderVisible(true);

    TreeColumn column = new TreeColumn(tree, SWT.NONE);
    column.pack();
    column.setWidth(100);

    TreeColumn column2 = new TreeColumn(tree, SWT.NONE);
    column2.pack();
    column2.setWidth(100);

    TreeItem item = new TreeItem(tree, SWT.NONE);
    item.setText(0, "Baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz");
    item.setText(1, "VERY VERY VERY VERY VERY VERY VERY VERY VERY VERY VERY long text");

    final TextLayout textLayout = new TextLayout(display);

    tree.addListener(SWT.PaintItem, new Listener() {
        public void handleEvent(Event event) {
            TreeItem item = (TreeItem) event.item;

            Point pt = new Point(event.x + 2, event.y + 2);

            for (int i = 0; i < tree.getColumnCount(); i++) {
                Rectangle rect = item.getBounds(i);

                String text = item.getText(i);

                if (rect.contains(pt)) {
                    String clippedText = "";
                    int offset = text.length() - 1; 
                    int columnWidth = tree.getColumn(i).getWidth();
                    String nextClippedText = text.charAt(offset) + clippedText;
                    while(fits(nextClippedText, columnWidth, event.gc) && offset >= 0)
                    {
                        clippedText = nextClippedText;
                        offset--;
                        if(offset >= 0)
                            nextClippedText = text.charAt(offset) + clippedText;
                    }

                    textLayout.setText(clippedText);

                    textLayout.draw(event.gc, event.x + 3, event.y + 3);
                }
            }
        }
    });
    tree.addListener(SWT.EraseItem, new Listener() {
        public void handleEvent(Event event) {
            /*
             * indicate that we'll be drawing the foreground in the
             * PaintItem listener
             */
            event.detail &= ~SWT.FOREGROUND;
        }
    });

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

private static boolean fits(String clippedText, int columnWidth, GC gc)
{
    Point size = gc.textExtent("..." + clippedText);                        
    return size.x < columnWidth;
}

可能需要一些修复才能在裁剪后的 String 之前真正显示 ...,但这只是一个开始。

关于java - 制作文本的 SWT 树列剪辑开头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11797014/

相关文章:

java - 我的 JButton 操作监听器不工作

java - 从 API 获取数据

eclipse - 如何将 enter 作为快捷键分配给 Eclipse RCP 应用程序中的按钮

java - Eclipse RCP 相互比较命令

java - 使用 p2 更新 Eclipse E4 应用程序

java - 为具有不带参数的方法的接口(interface)编写单元测试用例

Java:迭代 BiMap - 给我带来了一些问题

java.lang.NoSuchMethodError : org. eclipse.swt.internal.win32.OS.GetForegroundWindow() 错误

java - SWT - 如何更改 TabFolder 中现有 TabItems 的顺序

eclipse-rcp - 手动控制 EditorPart 生命周期以将其嵌入 ViewPart