javafx創建多樣化表格
一、概述:
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); } } }