user1009569
user1009569

Reputation: 477

Defining a ComboBoxTableCell and ComboBox nodes FXML

import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.ComboBoxTableCell;
import javafx.util.Callback;

public class ComboBoxTableCellFactory<S, T> implements Callback<TableColumn<S, T>, TableCell<S, T>> {

    private T[] nodes;

    public void setNodes(T[] nodes) {
        this.nodes = nodes;
    }

    public T[] getNodes() {
        return nodes;
    }

    @Override
    public TableCell<S, T> call(TableColumn<S, T> column) {
        if (nodes == null) {
            return new ComboBoxTableCell<S, T>();
        }
        return new ComboBoxTableCell<S, T>(nodes);
    }

}

I've written this class for declaring ComboBoxTableCells in fxml. This is how I would declare a cell factory for a table cell:

<TableColumn prefWidth="50" text="Grade">
    <cellFactory>
        <ComboBoxTableCellFactory />
        <nodes>
            //How would i declare nodes?
        </nodes>
    </cellFactory>
</TableColumn>

My question is, how would I declare an array of nodes for the combo box. It will run with an empty array obviously but i want to be able to declare nodes in FXML. So what would I put in between the two nodes tags? An example would be a Grade column where a ComboBox would be populated with a number of single character strings from which you'd have to choose a grade.

EDIT: Changed the class to this:

import javafx.collections.ObservableList;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.ComboBoxTableCell;
import javafx.util.Callback;

public class ComboBoxTableCellFactory<S, T> implements Callback<TableColumn<S, T>, TableCell<S, T>> {

    private ObservableList<T> nodes;

    public void setNodes(ObservableList<T> nodes) {
        this.nodes = nodes;
    }

    public ObservableList<T> getNodes() {
        return nodes;
    }

    @Override
    public TableCell<S, T> call(TableColumn<S, T> column) {
        if (nodes != null) {
            return new ComboBoxTableCell<S, T>(nodes);
        }
        return new ComboBoxTableCell<S, T>();
    }

}

And:

<TableColumn prefWidth="50" text="Grade">
    <cellFactory>
        <ui.view.ComboBoxTableCellFactory />
        <nodes>
            <FXCollections fx:factory="observableArrayList">
                //don't know how to declare the nodes here!
            </FXCollections>
        </nodes>
    </cellFactory>
</TableColumn>

I just don't know how to declare the nodes!

Essentially, I'm trying to do this:

ObservableList<String> values = FXCollections.observableArrayList("A", "B", "C");

TableColumn<String, String> gradeColumn = new TableColumn<>(tableView);
gradeColumn.setCellFactory(ComboBoxTableCell.forTableColumn(new DefaultStringConverter(), values));

In FXML.

Upvotes: 0

Views: 1230

Answers (2)

user1009569
user1009569

Reputation: 477

Alright, I figured out why it wasn't working. By default the combo box doesn't show, you have to click for it to show. I didn't realize but the Table view wasn't editable and so when i clicked to edit, the combo box didn't show. Everything's working fine now! Thanks for the help.

Upvotes: 0

James_D
James_D

Reputation: 209245

If you are creating Strings, you can do

<TableColumn prefWidth="50" text="Grade">
    <cellFactory>
        <ui.view.ComboBoxTableCellFactory />
        <nodes>
            <FXCollections fx:factory="observableArrayList">
                <String fx:value="A"/>
                <String fx:value="B"/>
                <String fx:value="C"/>
            </FXCollections>
        </nodes>
    </cellFactory>
</TableColumn>

See the "Instance declarations" section of the Introduction to FXML for details. (And note, a little counter-intuitively, that you have to explicitly import String with <?import java.lang.String?>.)

Upvotes: 2

Related Questions