web-dev-qa-db-fra.com

Largeur de colonne automatique JavaFX 2

J'ai une table JavaFX 2 qui affiche les détails de contact pour les personnes, imaginons qu'il y a trois colonnes: prénom, nom et adresse électronique. Lorsque mon application démarre, la table contient plusieurs lignes de données sur les personnes déjà présentes dans le système.

Le problème est que les largeurs de colonne sont toutes les mêmes. La plupart du temps, le prénom et le nom sont affichés en entier, mais l'adresse e-mail est en train d'être coupée. L'utilisateur peut double-cliquer sur le séparateur dans l'en-tête pour redimensionner la colonne, mais cela deviendra rapidement fastidieux. 

Une fois le tableau pré-rempli, je souhaite redimensionner par programme toutes les colonnes pour afficher les données qu'elles contiennent, mais je ne vois pas comment y parvenir. Je peux voir que je peux appeler col.setPrefWidth(x) mais cela n’aide en rien car je devrais deviner la largeur.

41
wobblycogs

Si votre nombre total de colonnes est pré-connu. Vous pouvez répartir les largeurs de colonne entre celles de la tableview:

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

Dans ce code, les proportions de largeur des colonnes sont synchronisées lorsque la vue tabulaire est redimensionnée. Vous n'avez donc pas besoin de le faire manuellement. De plus, la variable surnameCol prend la moitié de la largeur de la vue de table.

66
Uluk Biy

Cela fonctionne pour moi dans 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

Dans les autres exemples du problème, la largeur de la barre de défilement verticale est ignorée.

14
Rene Kiupel

Après 3 ans, j'ai finalement trouvé la solution, javafx column in tableview auto fit size

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
yelliver

Lorsque j'utilise SceneBuider, je ne fais que définir les propriétés MinWidth et MaxWidth sur certaines colonnes et sur la colonne principale.

2
Rubens

Si vous aviez 4 colonnes et que seule la dernière colonne devait être développée pour remplir le reste de la largeur du tableau, les autres colonnes restaient à la taille définie dans Scene Builder.

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

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

Ou si vous aviez 2 colonnes qui devaient être développées alors.

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
Kelly Wiles

De plus, une astuce très simple basée sur une AnchorPane sera une bonne solution.

Nous allons envelopper la TableView dans une AnchorPane mais nous allons aussi ancrer les côtés gauche et droit de la TableView comme ceci:

AnchorPane wrapper = new AnchorPane();

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

Ce code simple étendra la TableView dans les deux sens (droite et gauche) et s’ajustera à chaque ajout de la barre de défilement.

Vous pouvez avoir une idée de la façon dont cela fonctionne en regardant ce gif animé.

 enter image description here

Maintenant, vous pouvez redimensionner les colonnes, en ajoutant ces lignes:

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
Teocci

Vous pouvez également le faire en modifiant le fichier fxml si vous en avez un.

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

Le paramètre prefWidth vous permet de modifier la valeur par défaut d'une colonne.

0
lmiguelvargasf

Pour généraliser la largeur et utiliser n'importe quel nombre et s'assurer que la largeur correspond à 100% de la largeur de la table, vous pouvez utiliser:

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
YCF_L