一、概述:
javafx中是按列来创建表格的。首先生成一个TableColumn对象,其次设置TableColumn对象的属性,然后将TableColumn对象加入TableView对象,最后设置表格数据即可。
1、生成TableColumn:
可以通过构造函数直接生成TableColumn对象:
TableColumn<Document, Integer> idColumn = new TableColumn<>("文档ID");
2、设置TableColumn对象属性:
1)必须设置setCellValueFactory方法,如果不设置的话,^_^该列的值将为空。
2)此外,可以通过setMinWidth设置最小宽度,setCellFactory设置多样化表格,setSortable设置可否排序,setEditable是否可编辑等。
3、将TableColumn加入TableView对象:
调用以下语句即可:
tableView.getColumns().add(idColumn);
4、设置表格数据:
可通过以下方法实现:documentData为ObservableList对象。
tableView.setItems(documentData)
二、Demo展示
先看效果图:
(图一) | (图二) |
(图三) | (图四) |
(图五) | |
说明:
(图一)是根据对象属性创建table:setCellValueFactory设置的是PropertyValueFactory对象
// 根据对象属性创建table
public TableView<Document> createTableByObject() {
TableView<Document> tableView = new TableView<Document>();
addDocumentColumns(tableView);
averageColumnsWidth(tableView);
tableView.setItems(documentData);
return tableView;
}
private void addDocumentColumns(TableView<Document> tableView) {
TableColumn<Document, Integer> idColumn = new TableColumn<>("文档ID");
idColumn.setCellValueFactory(new PropertyValueFactory<Document, Integer>(
"id"));
idColumn.setMinWidth(50);
tableView.getColumns().add(idColumn);
TableColumn<Document, String> nameColumn = new TableColumn<>("文档名");
nameColumn
.setCellValueFactory(new PropertyValueFactory<Document, String>(
"name"));
nameColumn.setMinWidth(50);
tableView.getColumns().add(nameColumn);
TableColumn<Document, String> remarkColumn = new TableColumn<>("备注");
remarkColumn
.setCellValueFactory(new PropertyValueFactory<Document, String>(
"remark"));
remarkColumn.setMinWidth(50);
tableView.getColumns().add(remarkColumn);
}
(图二)是根据数组创建table:setCellValueFactory返回的是ReadOnlyStringWrapper对象;
// 根据数组创建table
public TableView<String[]> createTableByStringArray() {
TableView<String[]> tableView = new TableView<>();
for (final String name : columnNames) {
TableColumn<String[], String> column = new TableColumn<>(name);
column.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<String[], String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(
CellDataFeatures<String[], String> param) {
int index = columnNames.indexOf(name);
String value = param.getValue()[index];
return new ReadOnlyStringWrapper(value);
}
});
tableView.getColumns().add(column);
}
tableView.setItems(stringArrayData);
return tableView;
}
(图三)是创建带checkbox的table:使用了setCellFactory方法 ,返回CheckBoxTableCell对象(javafx库中自带)。
// 创建带checkbox的table
public TableView<Document> createTableWithCheckBox() {
initDocumentData();
TableView<Document> tableView = new TableView<Document>();
tableView.setEditable(true);
TableColumn<Document, Boolean> selectColumn = new TableColumn<>("选择");
selectColumn
.setCellValueFactory(new PropertyValueFactory<Document, Boolean>(
"select"));
selectColumn
.setCellFactory(new Callback<TableColumn<Document, Boolean>, TableCell<Document, Boolean>>() {
@Override
public TableCell<Document, Boolean> call(
TableColumn<Document, Boolean> param) {
CheckBoxTableCell<Document, Boolean> cell = new CheckBoxTableCell<>();
cell.setAlignment(Pos.CENTER);
return cell;
}
});
tableView.getColumns().add(selectColumn);
addDocumentColumns(tableView);
averageColumnsWidth(tableView);
tableView.setItems(documentData);
return tableView;
}
(图四)是创建带单选按钮的table:使用了setCellFactory方法 ,返回RadioButtonTableCell对象。
// 创建带单选按钮的table
public TableView<Document> createTableWithRadioButton() {
initDocumentData();
final TableView<Document> tableView = new TableView<Document>();
tableView.setEditable(true);
TableColumn<Document, Boolean> selectColumn = new TableColumn<>("选择");
selectColumn
.setCellValueFactory(new PropertyValueFactory<Document, Boolean>(
"select"));
selectColumn
.setCellFactory(new Callback<TableColumn<Document, Boolean>, TableCell<Document, Boolean>>() {
@Override
public TableCell<Document, Boolean> call(
TableColumn<Document, Boolean> param) {
final RadioButtonTableCell<Document, Boolean> cell = new RadioButtonTableCell<>();
final RadioButton radio = (RadioButton) cell
.getGraphic();
radio.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
for (Document doc : tableView.getItems()) {
doc.setSelect(false);
}
Document doc = documentData.get(cell.getIndex());
doc.setSelect(true);
}
});
return cell;
}
});
tableView.getColumns().add(selectColumn);
addDocumentColumns(tableView);
averageColumnsWidth(tableView);
tableView.setItems(documentData);
return tableView;
}
RadioButtonTableCell类实现代码:RadioButtonTableCell继承TableCell类,覆盖updateItem方法
public class RadioButtonTableCell<S, T> extends TableCell<S, T> {
private final RadioButton radio;
private ObservableValue<T> ov;
public RadioButtonTableCell() {
this.radio = new RadioButton();
setAlignment(Pos.CENTER);
setGraphic(radio);
}
@Override
protected void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
setGraphic(radio);
if (ov instanceof BooleanProperty) {
radio.selectedProperty().unbindBidirectional(
(BooleanProperty) ov);
}
ov = getTableColumn().getCellObservableValue(getIndex());
if (ov instanceof BooleanProperty) {
radio.selectedProperty()
.bindBidirectional((BooleanProperty) ov);
}
}
}
}
(图五)是创建带图表的table:使用了setCellFactory方法 ,返回ChartTableCell对象。
// 创建带图表的table
public TableView<Document> createTableWithGraphic() {
final TableView<Document> tableView = new TableView<Document>();
addDocumentColumns(tableView);
TableColumn<Document, List<Double>> chartColumn = new TableColumn<>(
"图形");
chartColumn
.setCellValueFactory(new PropertyValueFactory<Document, List<Double>>(
"charts"));
chartColumn
.setCellFactory(new Callback<TableColumn<Document, List<Double>>, TableCell<Document, List<Double>>>() {
@Override
public TableCell<Document, List<Double>> call(
TableColumn<Document, List<Double>> param) {
return new ChartTableCell();
}
});
tableView.getColumns().add(chartColumn);
chartColumn.setMinWidth(150);
chartColumn.setPrefWidth(200);
chartColumn.setMaxWidth(300);
tableView.setItems(documentData);
return tableView;
}
ChartTableCell类类实现代码:ChartTableCell继承TableCell类,覆盖updateItem方法
package table;
import java.util.List;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.util.StringConverter;
/**
* @author hanxi
*
*/
public class ChartTableCell extends TableCell<Document, List<Double>> {
NumberAxis xAxis;
NumberAxis yAxis;
AreaChart<Number, Number> chart;
public ChartTableCell() {
super();
getStyleClass().add("table-chart-cell");
xAxis = new NumberAxis();
yAxis = new NumberAxis();
chart = new AreaChart<Number, Number>(xAxis, yAxis);
chart.getStyleClass().add("table-chart");
chart.setLegendVisible(false);
chart.setTitle(null);
chart.setAnimated(false);
xAxis.setLabel(null);
xAxis.setTickMarkVisible(false);
xAxis.setMinorTickVisible(false);
xAxis.setTickLabelFormatter(new StringConverter<Number>() {
@Override
public String toString(Number t) {
return "";
}
@Override
public Number fromString(String string) {
return 0;
}
});
yAxis.setLabel(null);
yAxis.setTickMarkVisible(false);
yAxis.setMinorTickVisible(false);
yAxis.setTickLabelFormatter(new StringConverter<Number>() {
@Override
public String toString(Number t) {
return "";
}
@Override
public Number fromString(String string) {
return 0;
}
});
chart.setMinSize(20, 35);
chart.setPrefSize(150, 35);
chart.setMaxSize(Double.MAX_VALUE, 35);
setGraphic(chart);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
@Override
public void updateItem(List<Double> item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
XYChart.Series<Number, Number> salesSeries = new XYChart.Series<Number, Number>();
for (int i = 0; i < item.size(); i++) {
salesSeries.getData().add(
new XYChart.Data<Number, Number>(i, item.get(i)));
}
chart.getData().clear();
chart.getData().add(salesSeries);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
}
}