0

I'm implementing a desktop chat application using JavaFX. I'm using a listview to show contacts.

I customized the list cell by following this link JavaFX custom cell factory with custom Objects.

When a contact becomes online/offline, the server notifies me appropriately, so I need to change the color of online icon accordingly.

Below is my code...

File: MainController.java

public class MainController implements Initializable {

    @FXML
    private ListView<ContactInfo> contactListView;

    private ObservableList<ContactInfo> contactList = FXCollections.observableArrayList();

    this.contactListView.setCellFactory( listView -> {
        return new ContactCell();
    }
}

File: ContactCell.java

public class ContactCell extends ListCell<ContactInfo> {

    private final ContactItemController controller = new ContactItemController();

    public ContactCell() {
    }

    @Override
    protected void updateItem(ContactInfo item, boolean empty) {

        super.updateItem(item, empty);

        if (empty) {
            setText(null);
            setGraphic(null);
        } else {            
            controller.setItem(item);
            setGraphic(controller.getView());
        }

    }

}

File: ContactItemController.java

public class ContactItemController {

    @FXML
    private Pane pane;

    @FXML
    private ImageView contactImage;

    @FXML
    private Label contactName;

    @FXML
    private FontAwesomeIconView onlineIcon;

    public ContactItemController() {

        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/snippets/ContactItem.fxml"));
        fxmlLoader.setController(this);

        try {
            pane = fxmlLoader.load();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void setItem(ContactInfo item) {

        this.contactName.setText(item.getName());

        if(item.getOnline().getOnline())
            this.onlineIcon.setFill(Color.LIGHTGREEN);
        else
            this.onlineIcon.setFill(Color.web("#838383"));


    }

    public Pane getView() {
        return this.pane;       
    }

}

File: ContactInfo.java

public class ContactInfo {
    private String name;
    private BooleanProperty online;

    // Getters and setters
    ..............
    ..............
}

I tried to add change listener to each item's boolean property inside setItem() method of the ContactItemController class.

But the listener is getting added more than once.... Is this the right way to do this?

Akila
  • 1,258
  • 2
  • 16
  • 25
Nishanth
  • 54
  • 4
  • What's exactly the problem? – arxakoulini Feb 06 '18 at 13:45
  • 1
    *"But the listener is getting added more than once...."* UNregister it. `updateItem` will inevitably be called with the same item as parameter for multiple cells (at least if there are enough items and you scroll). Therefore you must implement a way of setting the state of the cell back to the original state/"disconnect" the cell's state from the item state, which includes unregistering listeners... – fabian Feb 06 '18 at 15:25
  • 1
    Or use a binding... (I'm assuming `FontAwesomeIconView` follows the JavaFX property pattern here): `this.onlineIcon.fillProperty().bind(Bindings.createObjectBinding(...))`. `bind(...)` will remove the existing binding, if there is one. – James_D Feb 06 '18 at 17:01
  • Thanks for the reply Mr.Fabian and Mr.James. But which method is efficient? Adding and removing listeners or using a binding? – Nishanth Feb 07 '18 at 07:16
  • I'm using Filteredlist to implement searching of contacts. Does using listeners would cause any issue here..? – Nishanth Feb 07 '18 at 07:38

0 Answers0