如何在TableView中复制/粘贴表格单元格

罗兰

问题

处理表时,最基本的需求之一就是复制/粘贴表单元格的数据。JavaFX TableView不开箱即用。

问题

您如何访问表格单元而不是数据对象,以便将剪贴板数据粘贴到所选单元中?

代码

这是到目前为止我得到的:

TableUtils.java

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyEvent;

public class TableUtils {

    /**
     * Install the keyboard handler:
     *   + CTRL + C = copy to clipboard
     *   + CTRL + V = paste to clipboard
     * @param table
     */
    public static void installCopyPasteHandler(TableView<?> table) {

        // install copy/paste keyboard handler
        table.setOnKeyPressed(new TableKeyEventHandler());

    }

    /**
     * Copy/Paste keyboard event handler.
     * The handler uses the keyEvent's source for the clipboard data. The source must be of type TableView.
     */
    public static class TableKeyEventHandler implements EventHandler<KeyEvent> {

        KeyCodeCombination copyKeyCodeCompination = new KeyCodeCombination(KeyCode.C, KeyCombination.CONTROL_ANY);
        KeyCodeCombination pasteKeyCodeCompination = new KeyCodeCombination(KeyCode.V, KeyCombination.CONTROL_ANY);

        public void handle(final KeyEvent keyEvent) {

            if (copyKeyCodeCompination.match(keyEvent)) {

                if( keyEvent.getSource() instanceof TableView) {

                    // copy to clipboard
                    copySelectionToClipboard( (TableView<?>) keyEvent.getSource());

                    // event is handled, consume it
                    keyEvent.consume();

                }

            } 
            else if (pasteKeyCodeCompination.match(keyEvent)) {

                if( keyEvent.getSource() instanceof TableView) {

                    // copy to clipboard
                    pasteClipboard( (TableView<?>) keyEvent.getSource());

                    // event is handled, consume it
                    keyEvent.consume();

                }

            } 

        }

    }

    /**
     * Get table selection and copy it to the clipboard.
     * @param table
     */
    public static void copySelectionToClipboard(TableView<?> table) {

        StringBuilder clipboardString = new StringBuilder();

        ObservableList<TablePosition> positionList = table.getSelectionModel().getSelectedCells();

        int prevRow = -1;

        for (TablePosition position : positionList) {

            int row = position.getRow();
            int col = position.getColumn();

            Object cell = (Object) table.getColumns().get(col).getCellData(row);

            // null-check: provide empty string for nulls
            if (cell == null) {
                cell = "";
            }

            // determine whether we advance in a row (tab) or a column
            // (newline).
            if (prevRow == row) {

                clipboardString.append('\t');

            } else if (prevRow != -1) {

                clipboardString.append('\n');

            }

            // create string from cell
            String text = cell.toString();

            // add new item to clipboard
            clipboardString.append(text);

            // remember previous
            prevRow = row;
        }

        // create clipboard content
        final ClipboardContent clipboardContent = new ClipboardContent();
        clipboardContent.putString(clipboardString.toString());

        // set clipboard content
        Clipboard.getSystemClipboard().setContent(clipboardContent);

        System.out.println( "Clipboard string: " + clipboardContent);

    }

    public static void pasteClipboard(TableView<?> table) {

        TablePosition focusedCellPosition = table.getFocusModel().getFocusedCell();

        System.out.println("Pasting into cells starting at " + focusedCellPosition);

        String pasteString = Clipboard.getSystemClipboard().getString();

        System.out.println(pasteString);

        Pattern pattern = Pattern.compile("([^\t]*)\t([^\t]*)\t([^\n]*)(\n)?");
        Matcher matcher = pattern.matcher(pasteString);
        while (matcher.find()) {

            System.out.println(matcher.group(1) + "," + matcher.group(2) + "," + matcher.group(3));

            // TODO: what now? how to paste the data?  

        }

    }


}

TableCopyCellsDemo.java

import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class TableCopyCellsDemo extends Application {

    private final ObservableList<Person> data = FXCollections.observableArrayList(new Person("Jacob", "Smith", 18), new Person("Isabella", "Johnson", 19), new Person("Ethan", "Williams", 20), new Person("Michael", "Brown", 21));

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

    @Override
    public void start(Stage stage) {

        stage.setWidth(500);
        stage.setHeight(550);

        // create table columns
        TableColumn<Person, String> firstNameCol = new TableColumn<Person, String>("First Name");
        firstNameCol.setMinWidth(100);
        firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));

        TableColumn<Person, String> lastNameCol = new TableColumn<Person, String>("Last Name");
        lastNameCol.setMinWidth(100);
        lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));

        TableColumn<Person, Integer> ageCol = new TableColumn<Person, Integer>("Age");
        ageCol.setMinWidth(60);
        ageCol.setCellValueFactory(new PropertyValueFactory<Person, Integer>("age"));


        TableView<Person> table = new TableView<>();
        table.setPlaceholder(new Text("No content in table"));
        table.setItems(data);
        table.getColumns().addAll(firstNameCol, lastNameCol, ageCol);

        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 10, 10, 10));

        BorderPane borderPane = new BorderPane();
        borderPane.setCenter(table);

        vbox.getChildren().addAll(borderPane);

        vbox.getChildren().add( new Label( "Select cells and press CTRL+C. Paste the data into Excel or Notepad"));

        Scene scene = new Scene(vbox);

        stage.setScene(scene);
        stage.show();

        // enable multi-selection
        table.getSelectionModel().setCellSelectionEnabled(true);
        table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

        // enable copy/paste
        TableUtils.installCopyPasteHandler(table);
    }


    public static class Person {

        private final StringProperty firstName;
        private final StringProperty lastName;
        private final IntegerProperty age;

        private Person(String fName, String lName, Integer age) {
            this.firstName = new SimpleStringProperty(fName);
            this.lastName = new SimpleStringProperty(lName);
            this.age = new SimpleIntegerProperty(age);
        }

        public final StringProperty firstNameProperty() {
            return this.firstName;
        }

        public final java.lang.String getFirstName() {
            return this.firstNameProperty().get();
        }

        public final void setFirstName(final java.lang.String firstName) {
            this.firstNameProperty().set(firstName);
        }

        public final StringProperty lastNameProperty() {
            return this.lastName;
        }

        public final java.lang.String getLastName() {
            return this.lastNameProperty().get();
        }

        public final void setLastName(final java.lang.String lastName) {
            this.lastNameProperty().set(lastName);
        }

        public final IntegerProperty ageProperty() {
            return this.age;
        }

        public final int getAge() {
            return this.ageProperty().get();
        }

        public final void setAge(final int age) {
            this.ageProperty().set(age);
        }
    }
}

问题是pasteClipboard方法中TODO您可以通过CTRL + C将所选单元格的数据复制到剪贴板使用CTRL + V,您可以从剪贴板中获取数据并进行分析。但是我还没有找到一种将数据直接写入表的方法。

非常感谢你!

罗兰

经过一番挖掘和阅读有关反射的解决方案后,我发现自己比我想象的要容易。最重要的是:没有反思。

我以为我会分享代码,希望对其他人有帮助。

这是修改单元格的基本方法。这就是我发现的。如果有人知道更好的方法,请分享。

        // get cell
        TableColumn tableColumn = table.getColumns().get(colIndex);
        ObservableValue observableValue = tableColumn.getCellObservableValue(rowIndex);

        if( observableValue instanceof StringProperty) { 

            ((StringProperty) observableValue).set(clipboardCellContent);

        }

因此,粘贴方法基本上如下所示:

public static void pasteClipboard( TableView<?> table) {

    // abort if there's not cell selected to start with
    if( table.getSelectionModel().getSelectedCells().size() == 0) {
        return;
    }

    // get the cell position to start with
    TablePosition pasteCellPosition = table.getSelectionModel().getSelectedCells().get(0);

    System.out.println("Pasting into cell " + pasteCellPosition);

    String pasteString = Clipboard.getSystemClipboard().getString();

    System.out.println(pasteString);

    int rowClipboard = -1;

    StringTokenizer rowTokenizer = new StringTokenizer( pasteString, "\n");
    while( rowTokenizer.hasMoreTokens()) {

        rowClipboard++;

        String rowString = rowTokenizer.nextToken();

        StringTokenizer columnTokenizer = new StringTokenizer( rowString, "\t");

        int colClipboard = -1;

        while( columnTokenizer.hasMoreTokens()) {

            colClipboard++;

            // calculate the position in the table cell
            int rowTable = pasteCellPosition.getRow() + rowClipboard;
            int colTable = pasteCellPosition.getColumn() + colClipboard;

            // skip if we reached the end of the table
            if( rowTable >= table.getItems().size()) {
                continue;
            }
            if( colTable >= table.getColumns().size()) {
                continue;
            }

            String clipboardCellContent = columnTokenizer.nextToken();

            // System.out.println( rowClipboard + "/" + colClipboard + ": " + cell);

            // get cell
            TableColumn tableColumn = table.getColumns().get(colTable);
            ObservableValue observableValue = tableColumn.getCellObservableValue(rowTable);

            System.out.println( rowTable + "/" + colTable + ": " +observableValue);

            // TODO: handle double, etc
            if( observableValue instanceof StringProperty) { 

                ((StringProperty) observableValue).set(clipboardCellContent);

            }
            else if( observableValue instanceof IntegerProperty) { 

                int value;
                try {
                    value = NumberFormat.getInstance().parse(clipboardCellContent).intValue();
                    ((IntegerProperty) observableValue).set(value);
                } catch (ParseException e) {
                    e.printStackTrace();
                }

            }
        }

    }

}

您可以在此要点上获取完整的代码

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Google表格中将带有超链接文本的单元格复制粘贴?

来自分类Dev

复制粘贴的单元格每粘贴4个单元格就会更改列

来自分类Dev

在QTableWidget单元格PyQt5中的标签中复制粘贴文本

来自分类Dev

如何复制粘贴单元格值,如果单元格包含大于 0,则通过循环粘贴到另一个单元格

来自分类Dev

如果单元格在 excel 中具有红色/绿色/黄色,则复制粘贴整行

来自分类Dev

如何在Tableview中为表格列的单元格设置click事件?

来自分类Dev

尝试在单独的工作表中复制粘贴单元格时的VBA运行时错误1004

来自分类Dev

Google表格复制一个单元格并粘贴到另一个单元格中

来自分类Dev

Excel宏搜索列D单元格1复制粘贴列B单元格7

来自分类Dev

Libreoffice calc复制粘贴时的相对和绝对单元格引用

来自分类Dev

Microsoft Excel-在保留对单个单元格的引用的同时复制粘贴

来自分类Dev

复制粘贴取决于两个区域中的单元格值

来自分类Dev

在两个不同的工作簿之间的错误单元格区域中复制粘贴

来自分类Dev

excel vba复制粘贴单元格而不引起用户注意

来自分类Dev

如何在iOS中设置tableView单元格标题?

来自分类Dev

如何在TableView单元格中检测多个按钮

来自分类Dev

如何在xterm中启用剪切或复制粘贴

来自分类Dev

如何在Edittext中禁用复制粘贴按钮

来自分类Dev

如何在xterm中启用剪切或复制粘贴

来自分类Dev

如何在EditText中启用“复制粘贴”菜单?

来自分类Dev

如何在Ubuntu Touch中复制粘贴?

来自分类Dev

如何在NSViewController中访问复制粘贴功能

来自分类Dev

如何在tableview中的单元格之间放置临时单元格?

来自分类Dev

如何在表格单元格中创建新行

来自分类Dev

如何在React中取消点击表格单元格

来自分类Dev

如何在MediaWiki中合并表格单元格

来自分类Dev

如何在表格单元格中获取元素?

来自分类Dev

如何在表格视图单元格中显示多行

来自分类Dev

如何在表格单元格中插入弹出窗口?

Related 相关文章

  1. 1

    如何在Google表格中将带有超链接文本的单元格复制粘贴?

  2. 2

    复制粘贴的单元格每粘贴4个单元格就会更改列

  3. 3

    在QTableWidget单元格PyQt5中的标签中复制粘贴文本

  4. 4

    如何复制粘贴单元格值,如果单元格包含大于 0,则通过循环粘贴到另一个单元格

  5. 5

    如果单元格在 excel 中具有红色/绿色/黄色,则复制粘贴整行

  6. 6

    如何在Tableview中为表格列的单元格设置click事件?

  7. 7

    尝试在单独的工作表中复制粘贴单元格时的VBA运行时错误1004

  8. 8

    Google表格复制一个单元格并粘贴到另一个单元格中

  9. 9

    Excel宏搜索列D单元格1复制粘贴列B单元格7

  10. 10

    Libreoffice calc复制粘贴时的相对和绝对单元格引用

  11. 11

    Microsoft Excel-在保留对单个单元格的引用的同时复制粘贴

  12. 12

    复制粘贴取决于两个区域中的单元格值

  13. 13

    在两个不同的工作簿之间的错误单元格区域中复制粘贴

  14. 14

    excel vba复制粘贴单元格而不引起用户注意

  15. 15

    如何在iOS中设置tableView单元格标题?

  16. 16

    如何在TableView单元格中检测多个按钮

  17. 17

    如何在xterm中启用剪切或复制粘贴

  18. 18

    如何在Edittext中禁用复制粘贴按钮

  19. 19

    如何在xterm中启用剪切或复制粘贴

  20. 20

    如何在EditText中启用“复制粘贴”菜单?

  21. 21

    如何在Ubuntu Touch中复制粘贴?

  22. 22

    如何在NSViewController中访问复制粘贴功能

  23. 23

    如何在tableview中的单元格之间放置临时单元格?

  24. 24

    如何在表格单元格中创建新行

  25. 25

    如何在React中取消点击表格单元格

  26. 26

    如何在MediaWiki中合并表格单元格

  27. 27

    如何在表格单元格中获取元素?

  28. 28

    如何在表格视图单元格中显示多行

  29. 29

    如何在表格单元格中插入弹出窗口?

热门标签

归档