JavaFX 2 Автоматическая ширина столбца
У меня есть таблица JavaFX 2, которая отображает контактные данные людей, давайте представим, что есть три столбца: имя, фамилия и адрес электронной почты. Когда мое приложение запускается, оно заполняет таблицу несколькими строками данных о людях, уже находящихся в системе.
Проблема в том, что ширина столбцов одинакова. В большинстве случаев имя и фамилия отображаются полностью, но адрес электронной почты обрезается. Пользователь может дважды щелкнуть разделитель в заголовке, чтобы изменить размер столбца, но это быстро станет утомительным.
После того, как таблица будет заполнена, я хотел бы программно изменить размер всех столбцов, чтобы отобразить содержащиеся в них данные, но я не могу понять, как этого добиться. Я вижу, что я могу позвонить col.setPrefWidth(x)
но это не очень помогает, так как мне нужно угадать ширину.
8 ответов
Если ваше общее количество столбцов заранее известно. Вы можете распределить ширину столбца по ширине таблицы:
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
В этом коде пропорции ширины столбцов синхронизируются при изменении размера таблицы, поэтому вам не нужно делать это вручную. Так же surnameCol
занимает половину пространства ширины таблицы.
Это работает для меня в 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
В других примерах у вас есть проблема, ширина вертикальной полосы прокрутки игнорируется.
Поскольку я использую SceneBuider, я просто определяю MinWidth и MaxWidth для некоторых столбцов, а для основного столбца я просто определяю PrefWidth как "USE_COMPUTED_SIZE"
Если у вас было 4 столбца, и только последний столбец нужно было развернуть, чтобы заполнить остальную часть ширины таблицы, а остальные столбцы остались размером, который я установил в Scene Builder.
double width = col1.widthProperty().get();
width += col2.widthProperty().get();
width += col3.widthProperty().get();
col4.prefWidthProperty().bind(table.widthProperty().subtract(width));
Или если у вас было 2 столбца, которые нужно было расширить, то.
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));
Через 3 года, наконец, я нашел решение, колонка javafx в табличном представлении размера авто
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();
}
}
}
});
}
}
Кроме того, очень простой трюк, основанный на AnchorPane
будет хорошим решением.
Мы завернем TableView
в AnchorPane
но также мы собираемся закрепить левую и правую сторону TableView
как это:
AnchorPane wrapper = new AnchorPane();
AnchorPane.setRightAnchor(table, 10.0);
AnchorPane.setLeftAnchor(table, 10.0);
wrapper.getChildren().add(table);
Этот простой код растянет TableView
в обоих направлениях (вправо и влево) также он будет корректироваться при каждом добавлении полосы прокрутки.
Вы можете получить представление о том, как это работает, посмотрев этот анимированный GIF.
Теперь вы можете изменить размер столбцов, добавив следующие строки:
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
Чтобы сгенерировать ширину и использовать любое число и убедиться, что ширина составляет 100% ширины таблицы, вы можете использовать:
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-------------^-------------^
}
Моя идея.
table.getColumns().add(new TableColumn<>("Num") {
{
// 15%
prefWidthProperty().bind(table.widthProperty().multiply(0.15));
}
});
table.getColumns().add(new TableColumn<>("Filename") {{
// 20%
prefWidthProperty().bind(table.widthProperty().multiply(.2));
}});
table.getColumns().add(new TableColumn<>("Path") {{
// 50%
prefWidthProperty().bind(table.widthProperty().multiply(.5));
}});
table.getColumns().add(new TableColumn<>("Status") {
{
// 15%
prefWidthProperty().bind(table.widthProperty().multiply(.15));
}
});
Вы также можете сделать это, отредактировав файл fxml, если он у вас есть.
<TableColumn fx:id="blackout_number_column" prefWidth="30.0" text="%number">
Параметр prefWidth
позволяет изменить значение по умолчанию для столбца.