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