Как скачать fxml с пользовательской ячейкой в ​​ListView?

Я хочу сделать собственную ячейку в ListView, Извините за мой плохой английский! Я хочу отобразить изображение, имя и статус в ListView, Для этого я использую другой Fxml который содержит Hbox,

  public class Controller {    
   CollectionContactForListCollection contactForList = new   CollectionContactForListCollection();
@FXML
private ListView<Contact> listContact ;
@FXML
HBox hbox;
@FXML
ImageView avatar;
@FXML
Label labelName;
@FXML
Label lblStatus;
@FXML
Label lblSense;

@FXML
private void initialize(){ 
    contactForList.fieldData();
    // listContact.setItems((ObservableList)       contactForList.getContactList()); 
    listContact.setCellFactory(new Callback<ListView<Contact>, ListCell<Contact>>() {
        @Override
        public ListCell<Contact> call(ListView<Contact> param) {              
            ListCell<Contact> listCell = new ListCell<Contact>() {                    
                @Override
                protected void updateItem(Contact item, boolean empty) {
                    super.updateItem(item, empty);
                    if (empty || item == null) {
                        setText(null);
                        setGraphic(null);
                    } else {
                        //This method does not work download                          
                       FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/view/boxInContact.fxml"));
                       fxmlLoader.setController(this);                      
                        labelName.setText(item.getName());
                        lblSense.setText(item.getSense());
                        lblStatus.setText(item.getStatus());
                        avatar.setImage(item.getImage());                            
                    }
                }
            };
            return listCell;
        }
    });
    listContact.setItems((ObservableList) contactForList.getContactList());
}

1 ответ

Решение

Как правило, вы должны использовать разные классы контроллеров для каждого файла FXML. С имеющимся у вас кодом все ячейки используют один и тот же экземпляр контроллера, поэтому существует только одна ссылка на каждый элемент управления, хотя их много. labelNames и т. д. (по одному для каждой ячейки).

Поэтому определите контроллер для FXML, определенного для ячейки списка, и определите методы, которые необходимы для обновления элементов управления:

public class ContactCellController {

    @FXML
    private Label labelName ;
    @FXML
    private Label labelStatus ;
    @FXML
    private Label labelSense ;
    @FXML
    private ImageView avatar ;

    public void setName(String name) {
        labelName.setText(name);
    }

    public void setStatus(String status) {
        labelStatus.setText(status);
    }

    public void setSense(String sense) {
        labelSense.setText(sense);
    }

    public void setAvatarImage(Image image) {
        avatar.setImage(image);
    }
}

Обновите файл FXML, чтобы использовать атрибут контроллера с fx:controller="my.package.ContactCellController"и тогда реализация вашей ячейки может выглядеть

listContact.setCellFactory(lv -> new ListCell<Contact>() {
    private Node graphic ;
    private ContactCellController controller ;

    {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/boxInContact.fxml"));
            graphic = loader.load();
            controller = loader.getController();
        } catch (IOException exc) {
            throw new RuntimeException(exc);
        }
    }

    @Override
    protected void updateItem(Contact contact, boolean empty) {
        super.updateItem(contact, empty);
        if (empty) {
            setGraphic(null);
        } else {
            controller.setName(contact.getName());
            controller.setStatus(contact.getStatus());
            controller.setSense(contact.getSense());
            controller.setAvatarImage(contact.getImage());
            setGraphic(graphic);
        }
    }
});
Другие вопросы по тегам