preface
Recently, I started to write a student management system, involving the use of TableView. I also have some experience and ideas. I want to record and share them (in fact, I'm trying to use html web pages instead of the interface), which is more for learning.
Let's first look at what's in TableView
In the IDEA, press and hold Ctrl, and then click the TableView keyword. The keyword will automatically follow up to its definition. We can see what's in it first.
You will see its two constructors first:
// First constructor public TableView() { this(FXCollections.<S>observableArrayList()); } // Second constructor public TableView(ObservableList<S> items) { getStyleClass().setAll(DEFAULT_STYLE_CLASS); setAccessibleRole(AccessibleRole.TABLE_VIEW); // we quite happily accept items to be null here setItems(items); // install default selection and focus models // it's unlikely this will be changed by many users. setSelectionModel(new TableViewArrayListSelectionModel<S>(this)); setFocusModel(new TableViewFocusModel<S>(this)); // we watch the columns list, such that when it changes we can update // the leaf columns and visible leaf columns lists (which are read-only). getColumns().addListener(weakColumnsObserver); // watch for changes to the sort order list - and when it changes run // the sort method. getSortOrder().addListener((ListChangeListener<TableColumn<S, ?>>) c -> { doSort(TableUtil.SortEventType.SORT_ORDER_CHANGE, c); }); // We're watching for changes to the content width such // that the resize policy can be run if necessary. This comes from // TreeViewSkin. getProperties().addListener(new MapChangeListener<Object, Object>() { @Override public void onChanged(Change<? extends Object, ? extends Object> c) { if (c.wasAdded() && SET_CONTENT_WIDTH.equals(c.getKey())) { if (c.getValueAdded() instanceof Number) { setContentWidth((Double) c.getValueAdded()); } getProperties().remove(SET_CONTENT_WIDTH); } } }); isInited = true; }
You can have a general look, but the most important thing is to be clear: TableView maintains a type fxcollections< S > collection of observablearraylist. Where < s > represents the user-defined type.
You can also see how to add listeners to a Table:
getProperties().addListener(new MapChangeListener<Object, Object>() { @Override public void onChanged(Change<? extends Object, ? extends Object> c) { if (c.wasAdded() && SET_CONTENT_WIDTH.equals(c.getKey())) { if (c.getValueAdded() instanceof Number) { setContentWidth((Double) c.getValueAdded()); } getProperties().remove(SET_CONTENT_WIDTH); } } });
In short, you will see many very interesting things. I won't elaborate here. You can read them yourself if you are interested. It is very helpful to understand the TableView control. You can better understand its operation principle and mechanism.
Practical application
Let's take a look at the actual application. The official has given a very detailed document. Fortunately, we have found a website that translates it into a better version of Chinese. We can link it directly. There are some simple applications:
Simple application: http://www.javafxchina.net/blog/2015/04/doc03_tableview/
Official documents: http://docs.oracle.com/javafx/2/ui_controls/table-view.htm
Two data forms of TableView columns:
One is to maintain the tablecolumn < Person, String > type of the class. Each data of the column is a class (here is a Person class), and the String type corresponds to the column name. The mapping needs to be set as follows:
col.setCellValueFactory( new PropertyValueFactory<Person, String>("firstName")); // Column name corresponding to firstName
The other is to maintain the tablecolumn < Map, string > type of Map. Each data in the column is a Map. This is required when setting up the mapping:
col.setCellValueFactory(new MapValueFactory(colName)); // colName corresponds to the character type column name```
Table editable:
You can add a TextFieldTableCell as in the official document, and then add the response function:
// Set CellFactory and fill in a TextField column col.setCellFactory(TextFieldTableCell.<Map>forTableColumn()); // Set function for editing response col.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Map, String>>() { @Override public void handle(TableColumn.CellEditEvent<Map, String> t) { System.out.println("Change detected"); // Here, modify and maintain the corresponding settings into the ObservableList collection of TableView } });
Adding or deleting rows is the same operation. You can directly modify the collection maintained by TableView.
Add column, delete column
This requires not only deleting the data in the set, but also deleting the corresponding data from the Columns set in the table. Maybe you will add some judgment in the deletion and addition to ensure the correctness of the operation:
table.getColumns().add(tempCol); // The newly added columns are displayed in the list table.getColumns().remove(index); // Delete column at index position
Monitor column changes
You can choose to use getproperties () as in the source file AddListener to complete listening. You can also add a ListChangeListener:
// Set the listener for table to listen for changes in the column table.getColumns().addListener(new ListChangeListener() { @Override public void onChanged(Change c) { c.next(); // Accept the change, otherwise an error will be reported // Handle events after column drag if (c.wasRemoved()) { // Define a collection that holds the current column sorting List<TableColumn<ObservableList<Map>, String>> newList = new ArrayList<>(table.getColumns()); // Define a collection that holds the original column sort List<TableColumn<ObservableList<Map>, String>> oldList = new ArrayList<>(c.getList()); // Related operations } // end if: the drag event has been processed } });
TableView TableColumn column
Building a table mainly includes TableView,TableColumn,ObservableList and Bean
Add column
table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
ObservableList stores data
Add data
table.setItems(ObservableList)
observableList usually contains stored beans
The column is associated with the Bean to obtain the value.
Establish the relationship between the column and the Bean, and establish the relationship with the Bean through the cell value factory.
RoomIdCol.setCellValueFactory(new PropertyValueFactory<Person, String>("RoomIdCol"))
It doesn't need to know what Bean you passed here. It only needs to reflect "RoomIdCol" into a getRoomIdCol() method to get the value in the Bean. Therefore, the name of the Bean attribute definition does not need to be the same as it, but only needs to have a getRoomIdCol() method.
firstNameCol.setCellValueFactory (new Callback<TableColumn.CellDataFeatures<Person, String>, ObservableValue<String>>() { @Override public ObservableValue<String> call(CellDataFeatures<Person, String> arg0) { // return new // SimpleStringProperty(arg0.getValue(),"sd",arg0.getValue().getFirstName()); // //bean, bean name, value return new SimpleStringProperty(arg0.getValue().getFirstName()); // In this way, you can not establish the mapping relationship between value and object. } });
arg0.getValue() is equal to the person here. If you observablelist Add (list), then arg0 GetValue () equals list.
SimpleStringProperty(arg0.getValue(),"sd",arg0.getValue().getFirstName());
This means arg0 GetValue () is your observablelist Add, "sd" gets the name of the bean, arg0 getValue(). Getfirstname () is the value you want to get for this column. If it is a list, arg0 getValue(). Get (J) assigns a value to each row of the column.
The cell can store not only text, but also other nodes:
firstNameCol.setCellFactory(new Callback<TableColumn<Person, String>, TableCell<Person, String>>() { @Override public TableCell<Person, String> call( // Cell content TableColumn<Person, String> arg0) { return new TableCell<Person, String>() { @Override protected void updateItem(final String str,boolean arg1) { super.updateItem(str, arg1); if (arg1) { setText(null); setGraphic(null); else { setText(str); setGraphic(new CheckBox()); } } } });
Like TreeCell, you can reconstruct the cell.
lastNameCol.setCellFactory(TextFieldTableCell.forTableColumn());
There are some default constructs, so you don't need to go to new TableCell yourself
//TableColumn three methods for setting sort firstNameCol.setSortNode(new Text("a")); // The default is the small icon triangle on the header, which can be changed firstNameCol.setSortable(true); // Set sortable firstNameCol.setSortType(SortType.DESCENDING);//Set lifting sequence
To include multiple columns in a column, you can call getcolumns () of tablecolumn setAll(TableColumn…);
firstNameColumn = new TableColumn<Person, String>("First"); firstNameColumn.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); // firstNameColumn.setCellFactory(TextFieldCellFactory.<Person>forTableColumn()); lastNameColumn = new TableColumn<Person, String>("Last"); lastNameColumn.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); // lastNameColumn.setCellFactory(TextFieldCellFactory.<Person>forTableColumn()); nameColumn = new TableColumn<Person, String>("Name"); nameColumn.getColumns().setAll(firstNameColumn, lastNameColumn);
There are obvious horizontal lines between the cells of table, which can be removed through css.
Remove horizontal lines
.table-view .table-row-cell { -fx-background-insets: 0; }
If you want to remove the vertical line without data at the same time
.table-row-cell:empty .table-cell { -fx-border-width: 0px; }
If you want to operate on rows, you can use setRowFactory. Double click the row as follows
tableView.setRowFactory(new Callback<TableView<T>, TableRow<T>>() { @Override public TableRow<T> call(TableView<T> param) { return new TableRowControl(); } }); class TableRowControl extends TableRow<T> { public TableRowControl() { super(); this.setOnMouseClicked(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { if (event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2 && TableRowControl.this.getIndex() < tableView.getItems().size()) { //doSomething } } }); } }
Insert data into the table. The data in the table is displayed according to your itemlist. The order of the data in the list is the same as that of the table. If you add a new piece of data, add it directly to the list. The list provides adding by location, so the table display is adding by location.
tableView.getItems().add(selectedRow, newRecord);
newRecord is a new object with no assignment.
Custom tablecells generally override the updateItem method. If you need to edit, you can override startEdit and cancelEdit
@Override public void startEdit() { if (!this.getTableRow().isVisible()) { return; } super.startEdit(); if (checkBox == null) { createCheckBox(); } setText(null); setGraphic(checkBox); } @Override public void cancelEdit() { super.cancelEdit(); setText(getItem().toString()); setGraphic(null); }
You can see that once you click the edit status, the contents in the cell will be changed. As soon as you leave the editor, change to the content in the original cell. In this way, the string can be displayed, and a control, such as calendar, can be made during editing.
Gets the selected TableColumn
table.getSelectionModel().getSelectedCells().get(0).getTableColumn()
table's own method can filter columns, that is, only which columns are displayed
table.setTableMenuButtonVisible(true);
When set to true, a plus sign column will appear, which can filter the column
By default, only one row can be selected in table. If you want to select multiple rows, set SelectionMode. At this time, you can listen to the selected multiple rows.
ListChangeListener<Person> indicesListener = new ListChangeListener<Person>() { @Override public void onChanged(Change<? extends Person> c) { while (c.next()) { selectionUpdated(c.getAddedSubList(), c.getRemoved()); } } }; tableView.getSelectionModel().getSelectedItems().addListener(indicesListener); tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
tableView.getSelectionModel() gets an abstract class SelectionModel, which has two subclasses: multipleselectionmodel and singleselectionmodel. They mainly handle selection events. You can see their methods:
getSelectedIndex() getSelectedItem() selectedIndexProperty() selectedItemProperty()
Gets the selected item and index. One is to get its value, and the other is to get the encapsulated attribute for bind change.
select(int index) select(T obj) selectFirst() selectLast() ... clearSelection() clearSelection(int index)
These methods are selected by operation.
setSelectionMode(SelectionMode.MULTIPLE); selectIndices(int index, int... indices) selectRange(int start, int end)
MultipleSelectionModel provides multiple selection function and some methods of multiple selection.
select(int row, TableColumn<S,?> column) selectAboveCell() selectBelowCell() selectLeftCell() selectRightCell() setCellSelectionEnabled(boolean value)