JavaFX 2 Ancho de Columna Automático


Tengo una tabla JavaFX 2 que muestra los detalles de contacto de las personas, imaginemos que hay tres columnas: nombre, apellido y dirección de correo electrónico. Cuando mi aplicación se inicia, rellena la tabla con varias filas de datos sobre las personas que ya están en el sistema.

El problema es que los anchos de columna son todos iguales. La mayoría de las veces, el nombre y el apellido se muestran en su totalidad, pero la dirección de correo electrónico se está recortando. El usuario puede hacer doble clic en el divisor en el encabezado para cambiar el tamaño de la columna, pero que se convertirá en tedioso rápidamente.

Una vez que la tabla se ha rellenado previamente, me gustaría cambiar el tamaño de todas las columnas para mostrar los datos que contienen, pero no puedo averiguar cómo lograr esto. Puedo ver que puedo llamar col.setPrefWidth(x) pero eso realmente no ayuda ya que tendría que adivinar el ancho.

 40
Author: wobblycogs, 2012-04-14

8 answers

Si su número total de columnas es pre-conocido. Puede distribuir los anchos de columna entre el ancho de la vista de tabla:

nameCol.prefWidthProperty().bind(personTable.widthProperty().divide(4)); // w * 1/4
surnameCol.prefWidthProperty().bind(personTable.widthProperty().divide(2)); // w * 1/2
emailCol.prefWidthProperty().bind(personTable.widthProperty().divide(4)); // w * 1/4

En este código, las proporciones de ancho de las columnas se mantienen sincronizadas cuando se cambia el tamaño de la vista de tabla, por lo que no es necesario hacerlo manualmente. También el surnameCol toma el medio espacio del ancho de la vista de tabla.

 64
Author: Uluk Biy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-17 14:19:08

Esto funciona para mí en JavaFX 8

table.setColumnResizePolicy( TableView.CONSTRAINED_RESIZE_POLICY );
col1.setMaxWidth( 1f * Integer.MAX_VALUE * 50 ); // 50% width
col2.setMaxWidth( 1f * Integer.MAX_VALUE * 30 ); // 30% width
col3.setMaxWidth( 1f * Integer.MAX_VALUE * 20 ); // 20% width

En los otros ejemplos que tiene el problema, el ancho de la barra de desplazamiento vertical se ignora.

 11
Author: Rene Kiupel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-08 08:47:35

Después de 3 años, finalmente encontré la solución, columna javafx en tableview tamaño de ajuste automático

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();
                    }
                }
            }
        });
    }
}
 3
Author: yelliver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:18

Como uso SceneBuider, solo defino el MinWidth, y maxWidth a algunas columnas y a la columna principal solo defino el PrefWidth a "USE_COMPUTED_SIZE"

 2
Author: Rubens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-18 11:38:29

Si tenía 4 columnas y solo la última columna necesitaba expandirse para llenar el resto del ancho de la tabla y las otras columnas seguían siendo el tamaño que establecí en Scene Builder.

double width = col1.widthProperty().get();
width += col2.widthProperty().get();
width += col3.widthProperty().get();

col4.prefWidthProperty().bind(table.widthProperty().subtract(width));

O si tuviera 2 columnas que necesitaran expandirse entonces.

double width = col1.widthProperty().get();
width += col3.widthProperty().get();

col2.prefWidthProperty().bind(table.widthProperty().subtract(width).divide(2));
col4.prefWidthProperty().bind(table.widthProperty().subtract(width).divide(2));
 1
Author: Kelly Wiles,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-12 12:37:47

También puede hacerlo editando el archivo fxml si tiene uno.

<TableColumn fx:id="blackout_number_column" prefWidth="30.0" text="%number">

El parámetro prefWidth le permite modificar el valor predeterminado con de una columna.

 0
Author: lmiguelvargasf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-07 01:20:05

Para generalizar el ancho y usar cualquier número y asegurarse de que el ancho sea el 100% del ancho de la tabla, puede usar:

double[] widths = {20, 30, 50, 20, 30, 70, 50};//define the width of the columns

//calculate the sum of the width
double sum = 0;
for (double i : widths) {
    sum += i;
}

//set the width to the columns
for (int i = 0; i < widths.length; i++) {
    table.getColumns().get(i).prefWidthProperty().bind(
            table.widthProperty().multiply(sizes[i] / sum));
    //---------The exact width-------------^-------------^
}
 0
Author: YCF_L,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-24 11:56:22

Además, un truco muy simple basado en un AnchorPane será una buena solución.

Vamos a envolver el TableView en un AnchorPane pero también vamos a anclar el lado izquierdo y derecho del TableView así:

AnchorPane wrapper = new AnchorPane();

AnchorPane.setRightAnchor(table, 10.0);
AnchorPane.setLeftAnchor(table, 10.0);
wrapper.getChildren().add(table);

Este simple código estirará el TableView en ambas direcciones (derecha e izquierda) también, se ajustará cada vez que se agregue la barra de desplazamiento.

Puedes hacerte una idea de cómo funciona esto viendo este gif animado.

introduzca la descripción de la imagen aquí

Ahora puede cambiar el tamaño de las columnas, añadiendo estas líneas:

fnColumn.setMaxWidth( 1f * Integer.MAX_VALUE * 30 ); // 30% width
lnColumn.setMaxWidth( 1f * Integer.MAX_VALUE * 40 ); // 40% width
emColumn.setMaxWidth( 1f * Integer.MAX_VALUE * 30 ); // 30% width
 0
Author: Teocci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-13 09:34:28