How to convert an observableset to an observablelist

Will editing this in the table update the underlying set as expected ?

No because, you are doing a copy of the set:

new ArrayList<E>(pojo.getObservableSet())

Is it the 'right' way of doing this ?

I think the right way is not doing that. Set are not List and vice versa. Both have specific contraints. For example, the lists are ordered and sets contains no duplicate elements.

Moreover, nor FXCollections neither Bindings provides this kind of stuff.

I would like the collection to remain as a set to enforce uniqueness

I guess you could write a custom ObservableList, for example the Parent::children have a similar behavior. It throws an IllegalArgumentException if a duplicate children is added. If you look at the source code, you will see that it is a VetoableListDecorator extension. You could write your own:

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import com.sun.javafx.collections.VetoableListDecorator;

public class CustomObservableList<E> extends VetoableListDecorator<E> {

    public CustomObservableList(ObservableList<E> decorated) {
        super(decorated);
    }

    @Override
    protected void onProposedChange(List<E> toBeAdded, int... indexes) {
        for (E e : toBeAdded) {
            if (contains(e)) {
                throw new IllegalArgumentException("Duplicament element added");
            }
        }
    }
}

class Test {
    public static void main(String[] args) {
        Object o1 = new Object();
        Object o2 = new Object();

        Set<Object> set = new HashSet<Object>();
        set.add(o1);
        CustomObservableList<Object> list = new CustomObservableList<Object>(FXCollections.observableArrayList(set));
        list.add(o2);
        list.add(o1); // throw Exception
    }
}

Just in Case someone stumbles over this question looking for a one-way to convert an ObservableSet into an ObservableList... I post my solution. It doesn't support feeding back data to the set (which in my opinion wouldn't be nice since TableView doesn't have a concept of not being able to change a value) but supports updates of the set and preserves the (in this case) sorted order.

package de.fluxparticle.lab;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.ObservableSet;
import javafx.collections.SetChangeListener;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.Collections;
import java.util.Random;
import java.util.TreeSet;

import static javafx.collections.FXCollections.observableSet;

/**
 * Created by sreinck on 23.01.17.
 */
public class Set2List extends Application {

    private final ObservableSet<Integer> setModel = observableSet(new TreeSet<Integer>());

    @Override
    public void start(Stage primaryStage) throws Exception {
        TableView<Integer> tableView = new TableView<>();
        addColumn(tableView, "Number");

        ObservableList<Integer> list = convertSetToList(setModel);
        tableView.setItems(list);

        Random rnd = new Random();
        scheduleTask(Duration.millis(1000), () -> setModel.add(rnd.nextInt(10)));

        primaryStage.setScene(new Scene(tableView, 800, 600));
        primaryStage.setTitle("Set2List");
        primaryStage.show();
    }

    private static void scheduleTask(Duration interval, Runnable task) {
        Timeline timeline = new Timeline(new KeyFrame(interval, event -> task.run()));
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.play();
    }

    private static ObservableList<Integer> convertSetToList(ObservableSet<Integer> set) {
        ObservableList<Integer> list = FXCollections.observableArrayList(set);

        set.addListener((SetChangeListener<Integer>) change -> {
            if (change.wasAdded()) {
                Integer added = change.getElementAdded();
                int idx = -Collections.binarySearch(list, added)-1;
                list.add(idx, added);
            } else {
                Integer removed = change.getElementRemoved();
                int idx = Collections.binarySearch(list, removed);
                list.remove(idx);
            }
        });

        return list;
    }

    private static void addColumn(TableView<Integer> tableView, String text) {
        TableColumn<Integer, String> column = new TableColumn<>(text);
        column.setCellValueFactory(param -> new SimpleStringProperty(param.getValue().toString()));
        tableView.getColumns().add(column);
    }

    public static void main(String[] args) {
        launch(args);
    }

}