我想在JavaFX8中ComboBox
的{{1}}内向ComboBoxTableCell
添加处理程序。我可以看到TableView
类中存在私有ComboBox
值,但我不知道如何访问它。我告诉专栏通过ComboBoxTableCell
方法使用ComboBoxTableCell
。有没有办法获得setCellFactory
?
编辑:我想在ComboBox
添加一个监听器,通过输入密钥来选择项目。我已经有一个正常的ComboBox
,我想对ComboBox
中的ComboBox
重复使用它。
答案 0 :(得分:1)
据我所知,无法获得ComboBox
ComboBoxTableCell
的引用。如果这是真的,就不可能为它添加一个监听器。
另一种方法是创建包含ComboBox
的自定义单元格。使用这种方法,您可以以任何方式操纵ComboBox
。
import java.util.function.BiConsumer;
import java.util.function.Function;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
public class ComboBoxTable extends Application {
@Override
public void start(Stage stage) {
int numOfCols = 2;
ObservableList<ObservableList<String>> tableData = FXCollections.observableArrayList();
// Generate dummy data.
for (int i = 0; i < 10; i++) {
ObservableList<String> row = FXCollections.observableArrayList();
for (int j = 0; j < numOfCols; j++)
row.add("Row" + i + "Col" + j);
tableData.add(row);
}
TableView<ObservableList<String>> table = new TableView<ObservableList<String>>();
// Add columns to the table.
for (int i = 0; i < numOfCols; i++) {
final int j = i;
// The fourth argument in the method, the BiConsumer, might require
// an explanation. Basically we are saying that when the BiConsumer
// are given an ObservableList<String> and a String, we set the
// value of the String as the value of the element at position "j"
// of the row, where "j" will be the column index.
table.getColumns().add(addComboBoxColumn(i, "Column " + i, row -> new SimpleStringProperty(row.get(j)),
(row, newText) -> row.set(j, newText)));
}
table.getItems().addAll(tableData);
Scene scene = new Scene(table);
stage.setScene(scene);
stage.show();
}
/**
* Returns a TableColumn with ComboBoxCells.
*/
private TableColumn<ObservableList<String>, String> addComboBoxColumn(int index, String name,
Function<ObservableList<String>, ObservableValue<String>> property,
BiConsumer<ObservableList<String>, String> updater) {
TableColumn<ObservableList<String>, String> col = new TableColumn<ObservableList<String>, String>(name);
col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
col.setCellFactory(e -> new ComboBoxCell(updater, index));
return col;
}
/**
* A TableCell with a ComboBox in it.
*/
public class ComboBoxCell extends TableCell<ObservableList<String>, String> {
private ComboBox<String> comboBox = new ComboBox<String>();
/**
* @param updater
* The updater makes sure that the cell value corresponds
* with the value in the ComboBox.
* @param colIndex
* The index of this column.
*/
public ComboBoxCell(BiConsumer<ObservableList<String>, String> updater, int colIndex) {
comboBox.setEditable(true);
comboBox.getEditor().textProperty().addListener((old, oldValue, newValue) -> {
if (getIndex() >= 0) {
// We provide the BiConsumer.accept() with an
// ObservableList<String> and a String. The BiConsumer will
// do the operation specified in the definition we provided
// in addColumn() using these two objects.
updater.accept(getTableView().getItems().get(getIndex()), (String) newValue);
}
});
}
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
// If we don't check if this value is the same as the old one,
// the cursor is moved to the beginning of the editor every time
// anything is typed.
if (!item.equals(comboBox.getEditor().getText())) {
comboBox.getEditor().setText(item);
}
setGraphic(comboBox);
}
}
}
public static void main(String[] args) {
launch();
}
}