мы хотим создать комбинированный список в таблице.Каждый комбинированный список должен иметь разные параметры в зависимости от ряда.В нашем примере у нас есть таблица с разными IP-адресами сервера и выпадающий список со всеми пользователями на этом сервере.
Мы не знаем, как заполнить различные параметры для комбинированного списка внутри CellFactory, а также мы не уверены, как связать запись comboxbox с соответствующей моделью.
Мы создали пример, возможно у кого-то есть идеи:
CredentialModel
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class CredentialModel {
private StringProperty username = new SimpleStringProperty();
private StringProperty password = new SimpleStringProperty();
public CredentialModel(String username, String password) {
setUsername(username);
setPassword(password);
}
public String getUsername() {
return username.get();
}
public StringProperty usernameProperty() {
return username;
}
public void setUsername(String username) {
this.username.set(username);
}
public String getPassword() {
return password.get();
}
public StringProperty passwordProperty() {
return password;
}
public void setPassword(String password) {
this.password.set(password);
}
}
ServerModel
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
public class ServerModel {
private IntegerProperty id = new SimpleIntegerProperty();
private StringProperty ip = new SimpleStringProperty();
private ObjectProperty<CredentialModel> credential = new SimpleObjectProperty<>();
private ObservableList<CredentialModel> allCredentials = FXCollections.observableArrayList();
public ObservableList<CredentialModel> getAllCredentials() {
return allCredentials;
}
public void setAllCredentials(ObservableList<CredentialModel> allCredentials) {
this.allCredentials = allCredentials;
}
public ServerModel(Integer id, String ip) {
setId(id);
setIp(ip);
}
public String getIp() {
return ip.get();
}
public StringProperty ipProperty() {
return ip;
}
public void setIp(String ip) {
this.ip.set(ip);
}
public CredentialModel getCredential() {
return credential.get();
}
public ObjectProperty<CredentialModel> credentialProperty() {
return credential;
}
public void setCredential(CredentialModel credential) {
this.credential.set(credential);
}
public int getId() {
return id.get();
}
public IntegerProperty idProperty() {
return id;
}
public void setId(int id) {
this.id.set(id);
}
}
И основное приложение TableApplication
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;
public class TableApplication extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
VBox box = new VBox();
TableView<ServerModel> tableView = new TableView<>();
TableColumn<ServerModel, String> ipColumn = new TableColumn<>("IP-Address");
TableColumn<ServerModel, CredentialModel> userColumn = new TableColumn<>("Username");
tableView.getColumns().addAll(ipColumn, userColumn);
ipColumn.setCellValueFactory(param -> param.getValue().ipProperty());
tableView.getItems().addAll(populateTable());
userColumn.setCellFactory(new Callback<TableColumn<ServerModel,CredentialModel>, TableCell<ServerModel,CredentialModel>>() {
@Override
public TableCell<ServerModel, CredentialModel> call(TableColumn<ServerModel, CredentialModel> param) {
return new UserComboBoxTableCell();
}
});
Button button = new Button("Start");
button.setOnAction(event -> System.out.println(tableView.getSelectionModel().getSelectedItem().getCredential().getUsername()));
box.getChildren().addAll(tableView, button);
Scene scene = new Scene(box,800, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
private ObservableList<ServerModel> populateTable() {
ServerModel serverModel1 = new ServerModel(1, "192.168.0.1");
serverModel1.setAllCredentials(FXCollections.observableArrayList(new CredentialModel("user1", "pw1"), new CredentialModel("user2", "pw2")));
ServerModel serverModel2 = new ServerModel(2, "192.168.0.2");
serverModel2.setAllCredentials(FXCollections.observableArrayList(new CredentialModel("user3", "pw3")));
return FXCollections.observableArrayList(serverModel1, serverModel2);
}
И TableCellClass UserComboBoxTableCell
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableCell;
public class UserComboBoxTableCell extends TableCell<ServerModel, CredentialModel> {
public UserComboBoxTableCell() {
}
@Override
protected void updateItem(CredentialModel item, boolean empty) {
super.updateItem(item, empty);
if(empty == false) {
if(getTableRow() != null && getTableView() != null) {
int index = getTableRow().getIndex();
ServerModel serverModel = getTableView().getItems().get(index);
ComboBox<CredentialModel> box = new ComboBox<>(serverModel.getAllCredentials());
box.valueProperty().bindBidirectional(serverModel.credentialProperty());
setGraphic(box);
}
}
}
}
Идея метода loadCredentials заключается в том, что для каждой строки этот метод должен вызываться для "фиктивной" загрузки учетных данных для строки сервера.
Идея метода onAction для кнопки заключается в следующем.для отображения выбранного имени пользователя с выбранного сервера.В данный момент мы просто печатаем IP-адрес, потому что учетные данные всегда нулевые (потому что они не связаны в данный момент).
Спасибо за вашу помощь.Хауке
РЕДАКТИРОВАТЬ Я просто добавил наблюдаемый список моделей учетных данных на сервер и заполнил представление списка по-другому.Но все же я не уверен, как установить параметры для комбинированного списка в CellFactory, потому что мне нужен доступ к строке, и я не уверен насчет привязки.
EDIT2 Теперь он работает,Я обновил примеры выше.