Hi Scott,

The pre-built cell factories that ship with JavaFX are intended to provide convenience for the common use cases, and in some cases it just makes more sense to roll your own. Which use case you fall into I'm not quite sure, so the first thing to do is file bugs on the issues you're uncovering and we can try to make things more convenient for you. If that just isn't possible, then we can try to work out the best way forward from there. It certainly sounds like there is a combination of bugs and feature work to be done, so we can review again once the bugs are squashed.

Thanks,
-- Jonathan

On 19/07/2013 7:01 a.m., Scott Palmer wrote:
ComboBoxTableCell is very awkward to use if you want to have graphics in
the choices.

There is poor support in general for setting the graphic for items in a
combobox,  we have a StringConverter for the text part, but no
"NodeConverter" for the graphic part.

With ComboBoxTableCell it gets worse because the TableCell graphic is used
to render the actual combobox during editing.  If you subclassed to
override updateItem such as

                     @Override
                     public void updateItem(MyData data, boolean bln) {
                         super.updateItem(data, bln);
                         setGraphic(createGraphicFor(data));
                     }

(createGraphicFor is part of your implementation that returns a Node)
You get graphics in the table cells, but cancelEdit will clear the graphic
on you when it removes the ComboBox.
You need to override cancelEdit as well with something like:
                     @Override
                     public void cancelEdit() {
                         super.cancelEdit();
                         setGraphic(createGraphicFor(getItem()));
                     }


That's just to keep the TableCell rendering the graphic outside of edit
mode.  To get the graphics into the ComboBox used for editing you need to
do something even uglier like:

                     @Override
                     public void startEdit() {
                         super.startEdit();
                         ComboBox<MyData > cb = (ComboBox) getGraphic();
                         cb.setCellFactory(new Callback<ListView<MyData >,
ListCell<MyData >>() {

                             @Override
                             public ListCell<MyData > call(ListView<MyData >
p) {
                                 return createMyListCell();
                             }
                         });
                         cb.setButtonCell(createMyListCell());
                     }

Which uses undocumented knowledge of how these things work to know that it
can get a ComboBox from the graphic in the first place.

Just needed to subclass ListCell to get graphics into the Node seems like
an over-complicated way to implement this concept.

            new ListCell<MyData >() {
             @Override
             protected void updateItem(MyData data, boolean bln) {
                 super.updateItem(data, bln);
                 setGraphic(createGraphicFor(data));
                 setText(data != null ? data.toString() : null);
             }

Would it be reasonable to extend the things like ComboBoxXXXCell to better
handle graphics?

The idea is to avoid having to override things in so many places:
ComboBoxTableCell.updateItem, startEdit, cancelEdit, replace the
cellFactory for the Combo which is itself buried inside the TableCell
graphic, all in addition to setting the TableColumn cellFactory.
Instead of just the one CellFactory that can be set on a ComboBox or
ComboBoxXXXCell, such that the right thing just happens.

The Cell editing process needs better documentation, but I already filed an
issue for that.


Regards,

Scott

Reply via email to