ChrisWhoCodes
ChrisWhoCodes

Reputation: 640

ComboBox.setValue(T) not calling updateItem(T,boolean) when using cell factory

I've overridden ListCell.updateItem(T, boolean) to provide a custom renderer for my ComboBox items (as per Oracle ComboBox tutorial) and this is working fine except when I programmatically set an item using ComboBox.setValue(T).

Instead the toString() method of T is being called. The item being set is already in the ObservableList which backs the ComboBox.

comboBox.setCellFactory(new Callback<ListView<MyType>, ListCell<MyType>>()
{
  @Override
  public ListCell<MyType> call(ListView<MyType> arg0)
  {
    return new ListCell<MyType>()
    {
      @Override
      protected void updateItem(MyType item, boolean empty)
      {
        super.updateItem(item, empty);

        if (item == null || empty)
        {
          setText("");
        }
        else
        {
          setText(item.myCustomRenderMethod());
        }
      }
    };
  }
});

Is there another method I need to override?

JavaFX2 on JDK1.7.0_45.

Thanks.

Upvotes: 2

Views: 332

Answers (2)

JOpolka
JOpolka

Reputation: 121

In my case using Platform.runLater() solved the issue:

Platform.runLater(() -> comboBox.setValue(value));

My best guess is that setting a value before the ComboBox is part of a Scene causes the problem. Also, be sure to use the setButtonCell(...) method of ComboBox.

Upvotes: 0

ChrisWhoCodes
ChrisWhoCodes

Reputation: 640

OK, found the answer here: JavaFx Editable ComboBox : Showing toString on item selection

You also need to override ComboBox.setConverter() to ensure that the selected object shows the correct text. This is not in the Oracle tutorial and violates the principle of least surprise for me as it duplicates some of the code from ListCell.updateItem()

 comboBox.setConverter(new StringConverter<MyType>() {
  @Override
  public String toString(MyType obj) {
    if (obj == null)
    {
      return "";
    }
    else 
    {
      return obj.myCustomRenderMethod();
    }
  }

  @Override
  public MyType fromString(String s)
  {

      return null;  
  }
});

Upvotes: 2

Related Questions