Search code examples
javajfacetableviewer

Unable to wrap text within JFace TableViewerColumn


I am unable to wrap the text within a table cell when the width exceeds a specified limit.

Code:

public static void main(String[] args) {

    List<TableData> list = Collections.synchronizedList(new ArrayList<TableData>());
    list.add(new TableData("Jack Hodgins", 24) );
    list.add(new TableData("This is just aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
            + "\n" + "hugeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
            + "\n" + "messsageeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
            + "\n" + "to checkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk"
            + "\n" + "wrap functionalityyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy", 50));

    Display display = new Display();
    Shell shell = new Shell(display);

    shell.setText("Table Viewer Column");
    shell.setSize(800, 1500);

    TableViewer viewer = new TableViewer(shell, SWT.FILL | SWT.MULTI |  SWT.H_SCROLL |  SWT.V_SCROLL |  SWT.FULL_SELECTION | SWT.BORDER);

    Table table = viewer.getTable();
    table.setHeaderVisible(true);
    table.setLinesVisible(true);
    table.setSize(1000, 1500);
    table.setLayout(new TableLayout());

    /** Column for Name */
    TableViewerColumn columnName = new TableViewerColumn(viewer, SWT.MULTI | SWT.WRAP);
    columnName.getColumn().setWidth(250);       
    columnName.getColumn().setText("Name");
    columnName.setLabelProvider(new ColumnLabelProvider() {
        @Override
        public void update(ViewerCell cell)
        {
            Object element = cell.getElement();
            if (element instanceof TableData)
            {
                TableData obj = (TableData) element;
                cell.setText(obj.getName());

            }
        }
    });

    /** Column for Age */
    TableViewerColumn columnAge = new TableViewerColumn(viewer, SWT.NONE);
    columnAge.getColumn().setWidth(100);    
    columnAge.getColumn().setText("Age");
    columnAge.setLabelProvider(new ColumnLabelProvider() {
        @Override
        public void update(ViewerCell cell)
        {
            Object element = cell.getElement();
            if (element instanceof TableData)
            {
                TableData obj = (TableData) element;
                cell.setText(String.valueOf(obj.getAge()) );

            }
        }
    });

    viewer.setContentProvider(ArrayContentProvider.getInstance());
    viewer.setInput(list);
    viewer.refresh();

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

}

public static class TableData
{
    String name;
    int age;

    public TableData(String name, int age)
    {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


}



}

I will know the width of my table cell, and if the text exceeds that limit I want the remaining text to be in a new line.

I have looked at other links from stackoverflow -

multiline feature or wrap text feature in jface tableviewer http://git.eclipse.org/c/platform/eclipse.platform.swt.git/tree/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet231.java http://git.eclipse.org/c/platform/eclipse.platform.ui.git/tree/examples/org.eclipse.jface.snippets/Eclipse%20JFace%20Snippets/org/eclipse/jface/snippets/viewers/Snippet006TableMultiLineCells.java

Still unable to find a solution to this. Kindly help.


Solution

  • This owner draw label provider set as the label provider for columnName shows multiple lines split at the newlines. But all rows have the size of the deepest row.

      private static class NameLabelProvider extends OwnerDrawLabelProvider
      {
        private static final int TEXT_MARGIN = 3;
    
        @Override
        protected void erase(final Event event, final Object element)
        {
          event.detail &= ~SWT.FOREGROUND;
        }
    
        @Override
        protected void measure(final Event event, final Object element)
        {
          final TableData data = (TableData)element;
          final String text = data.getName();
          final Point size = event.gc.textExtent(text);
          event.width = size.x + 2 * TEXT_MARGIN;
          event.height = Math.max(event.height, size.y + TEXT_MARGIN);
        }
    
        @Override
        protected void paint(final Event event, final Object element)
        {
          final TableData data = (TableData)element;
          final String text = data.getName();
          event.gc.drawText(text, event.x + TEXT_MARGIN, event.y, true);
        }
      }