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.
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.
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.
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();
}
}
}
});
}
}
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.
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));
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é.
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
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.
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-------------^-------------^
}