JavaFX TableView copy to clipboard
Asked Answered
K

3

14

Is it possible to allow a user to select rows and copy from a TableView?

Kist answered 5/7, 2012 at 15:25 Comment(0)
D
16
tableView.getSelectionModel().setCellSelectionEnabled(true);
tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

MenuItem item = new MenuItem("Copy");
item.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {
        ObservableList<TablePosition> posList = tableView.getSelectionModel().getSelectedCells();
        int old_r = -1;
        StringBuilder clipboardString = new StringBuilder();
        for (TablePosition p : posList) {
            int r = p.getRow();
            int c = p.getColumn();
            Object cell = tableView.getColumns().get(c).getCellData(r);
            if (cell == null)
                cell = "";
            if (old_r == r)
                clipboardString.append('\t');
            else if (old_r != -1)
                clipboardString.append('\n');
            clipboardString.append(cell);
            old_r = r;
        }
        final ClipboardContent content = new ClipboardContent();
        content.putString(clipboardString.toString());
        Clipboard.getSystemClipboard().setContent(content);
    }
});
ContextMenu menu = new ContextMenu();
menu.getItems().add(item);
tableView.setContextMenu(menu);
Disfranchise answered 1/2, 2013 at 9:11 Comment(0)
Y
13

yelliver's solution only copies the content of selected cells, but apparently only cells that were explicitly clicked on are considered selected. Roberto's solution only works if the objects held in the table are iterable. Here is a general solution that copies the data from all cells in all selected rows:

@SuppressWarnings("rawtypes")
public void copySelectionToClipboard(final TableView<?> table) {
    final Set<Integer> rows = new TreeSet<>();
    for (final TablePosition tablePosition : table.getSelectionModel().getSelectedCells()) {
        rows.add(tablePosition.getRow());
    }
    final StringBuilder strb = new StringBuilder();
    boolean firstRow = true;
    for (final Integer row : rows) {
        if (!firstRow) {
            strb.append('\n');
        }
        firstRow = false;
        boolean firstCol = true;
        for (final TableColumn<?, ?> column : table.getColumns()) {
            if (!firstCol) {
                strb.append('\t');
            }
            firstCol = false;
            final Object cellData = column.getCellData(row);
            strb.append(cellData == null ? "" : cellData.toString());
        }
    }
    final ClipboardContent clipboardContent = new ClipboardContent();
    clipboardContent.putString(strb.toString());
    Clipboard.getSystemClipboard().setContent(clipboardContent);
}

To enable copying with Ctrl+C, add

    final KeyCodeCombination keyCodeCopy = new KeyCodeCombination(KeyCode.C, KeyCombination.CONTROL_ANY);
    table.setOnKeyPressed(event -> {
        if (keyCodeCopy.match(event)) {
            copySelectionToClipboard(table);
        }
    });
Yep answered 6/1, 2018 at 9:38 Comment(2)
works for me, thx. It worth to add to your answer first two lines of the Yelliver's answer in order to make a TableView selectable: tableView.getSelectionModel().setCellSelectionEnabled(true); tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);Effluvium
even just make a table in a multi-select mode is enough: tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);Effluvium
S
4

I couldn't implement Yelliver's Answer, it doesn't compile for me, but I found another very clear way to extract to clipboard the TableView's multiple selected data, it goes as follows

TableView tableView = new TableView();
tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
MenuItem item = new MenuItem("Copy");
    item.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {

            ObservableList rowList = (ObservableList) tableView.getSelectionModel().getSelectedItems();

            StringBuilder clipboardString = new StringBuilder();

            for (Iterator it = rowList.iterator(); it.hasNext();) {
                ObservableList<Object> row = (ObservableList<Object>) it.next();

                for (Object cell : row) {
                    if (cell == null) {
                        cell = "";
                    }
                    clipboardString.append(cell);
                    clipboardString.append('\t');
                }
                clipboardString.append('\n');

            }
            final ClipboardContent content = new ClipboardContent();

            content.putString(clipboardString.toString());
            Clipboard.getSystemClipboard().setContent(content);
        }
    });
    ContextMenu menu = new ContextMenu();
    menu.getItems().add(item);
    tableView.setContextMenu(menu);
}

Hope it can help you, or anyone trying to copy easily TableView's data

Sheasheaf answered 5/8, 2014 at 18:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.