Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javafx column in tableview auto fit size

afaik The TableView in javafx have 2 column resize policies: CONSTRAINED_RESIZE_POLICY and UNCONSTRAINED_RESIZE_POLICY, but I want columns is resized to fit the content of theirs cells I think it's a simple problem in other platform (like datagridview in C#) but can not resolve

like image 707
yelliver Avatar asked Feb 01 '13 16:02

yelliver


2 Answers

After 3 years I come back to this problem again, some suggestions are calculating the size of text of data in each cell (it's complicated depending on font size, font family, padding...)

But I realize that when I click on the divider on table header, it's resized fit to content as I want. So I dig into JavaFX source code I finally found resizeColumnToFitContent method in TableViewSkin, but it is protected method, we can resolve by reflection:

import com.sun.javafx.scene.control.skin.TableViewSkin; import javafx.scene.control.Skin; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;  public class GUIUtils {     private static Method columnToFitMethod;      static {         try {             columnToFitMethod = TableViewSkin.class.getDeclaredMethod("resizeColumnToFitContent", TableColumn.class, int.class);             columnToFitMethod.setAccessible(true);         } catch (NoSuchMethodException e) {             e.printStackTrace();         }     }      public static void autoFitTable(TableView tableView) {         tableView.getItems().addListener(new ListChangeListener<Object>() {             @Override             public void onChanged(Change<?> c) {                 for (Object column : tableView.getColumns()) {                     try {                         columnToFitMethod.invoke(tableView.getSkin(), column, -1);                     } catch (IllegalAccessException | InvocationTargetException e) {                         e.printStackTrace();                     }                 }             }         });     } } 

Note that we call "tableView.getItems()" so we have to call this function after setItems()

like image 158
yelliver Avatar answered Sep 21 '22 00:09

yelliver


After testing the previous solutions I finally found one that worked for me. So here is mine (call the method after inserting the data into table):

public static void autoResizeColumns( TableView<?> table ) {     //Set the right policy     table.setColumnResizePolicy( TableView.UNCONSTRAINED_RESIZE_POLICY);     table.getColumns().stream().forEach( (column) ->     {         //Minimal width = columnheader         Text t = new Text( column.getText() );         double max = t.getLayoutBounds().getWidth();         for ( int i = 0; i < table.getItems().size(); i++ )         {             //cell must not be empty             if ( column.getCellData( i ) != null )             {                 t = new Text( column.getCellData( i ).toString() );                 double calcwidth = t.getLayoutBounds().getWidth();                 //remember new max-width                 if ( calcwidth > max )                 {                     max = calcwidth;                 }             }         }         //set the new max-widht with some extra space         column.setPrefWidth( max + 10.0d );     } ); } 
like image 21
HarleyDavidson Avatar answered Sep 22 '22 00:09

HarleyDavidson