JavaFX TableView 通过单击和自动插入行进行编辑?

2024-01-03

我在程序中使用了 tableview 来显示几行,这很好。 我的程序用于会计,正如你所知,其中插入了大量数据,我使用了表视图,但我遇到了很多问题:。

问题 1:当用户想要修改值时,他将双击以编辑单元格,我希望我的用户选择任何行并开始输入。

问题2:在我的程序中,用户可能会在一天的工作中插入100行,我需要一个自动添加行的策略,例如当他插入行时,它应该在当前行下添加一个空行以轻松完成他的数据输入。

请帮助我解决这些问题,因为我的用户每天都会输入大量数据。 谢谢。


这是一个例子

  • 在焦点单元格上键入内容后立即进入编辑模式
  • 当您在最后一行中按 Enter 时,将创建一个新行(仅作为示例)。或者,您可以单击按钮添加新行。如果您希望在最后一行使用制表符来创建新行,则必须相应地更改代码。

我建议不要使用空行,因为它们会出现在您的模型中。

InlineEditingWithDynamicRowAdding.java

import javafx.application.Application;
import javafx.scene.control.TableView;
import javafx.collections.ObservableList;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableCell;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.DoubleProperty;
import javafx.collections.FXCollections;
import javafx.scene.input.KeyEvent;
import javafx.event.EventHandler;
import javafx.scene.control.SelectionMode;
import javafx.scene.input.KeyCode;
import javafx.scene.control.TablePosition;
import javafx.scene.layout.FlowPane;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.util.StringConverter;
import javafx.scene.Scene;
import javafx.scene.control.cell.TextFieldTableCell;

public class InlineEditingWithDynamicRowAdding extends Application {

    private final ObservableList<Data> data =
        FXCollections.observableArrayList(
                new Data(1.,5.),
                new Data(2.,6.),
                new Data(3.,7.),
                new Data(4.,8.)
        );

    private TableView<Data> table;

    @Override
    public void start(Stage stage) {

        // create edtiable table
        table = new TableView<Data>();
        table.setEditable(true);

        // column 1 contains numbers
        TableColumn<Data, Number> number1Col = new TableColumn<>("Number 1");
        number1Col.setMinWidth(100);
        number1Col.setCellValueFactory( cellData -> cellData.getValue().number1Property());
        number1Col.setCellFactory( createNumberCellFactory());

        // column 2 contains numbers
        TableColumn<Data, Number> number2Col = new TableColumn<>("Number 2");
        number2Col.setMinWidth(100);
        number2Col.setCellValueFactory( cellData -> cellData.getValue().number2Property());
        number2Col.setCellFactory( createNumberCellFactory());

        // add columns & data to table
        table.setItems(data);
        table.getColumns().addAll( number1Col, number2Col);




        // switch to edit mode on keypress
        // this must be KeyEvent.KEY_PRESSED so that the key gets forwarded to the editing cell; it wouldn't be forwarded on KEY_RELEASED
        table.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {

                if( event.getCode() == KeyCode.ENTER) {
//                  event.consume(); // don't consume the event or else the values won't be updated;
                    return;
                }

                // switch to edit mode on keypress, but only if we aren't already in edit mode
                if( table.getEditingCell() == null) {
                    if( event.getCode().isLetterKey() || event.getCode().isDigitKey()) {  

                        TablePosition focusedCellPosition = table.getFocusModel().getFocusedCell();
                        table.edit(focusedCellPosition.getRow(), focusedCellPosition.getTableColumn());

                    }
                }

            }
        });

        table.addEventFilter(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {

                if( event.getCode() == KeyCode.ENTER) {


                    // move focus & selection
                    // we need to clear the current selection first or else the selection would be added to the current selection since we are in multi selection mode 
                    TablePosition pos = table.getFocusModel().getFocusedCell();

                    if (pos.getRow() == -1) {
                        table.getSelectionModel().select(0);
                    } 
                    // add new row when we are at the last row
                    else if (pos.getRow() == table.getItems().size() -1) {
                        addRow();
                    } 
                    // select next row, but same column as the current selection
                    else if (pos.getRow() < table.getItems().size() -1) {
                        table.getSelectionModel().clearAndSelect( pos.getRow() + 1, pos.getTableColumn());
                    }


                }

            }
        });     

        // single cell selection mode
        table.getSelectionModel().setCellSelectionEnabled(true);

        // add row index column as 1st column
        // -------------------------------------
        TableColumn<Data, Data> indexCol = new TableColumn<Data, Data>("#");

        indexCol.setCellFactory(new Callback<TableColumn<Data, Data>, TableCell<Data, Data>>() {
            @Override public TableCell<Data, Data> call(TableColumn<Data, Data> param) {
                return new TableCell<Data, Data>() {
                    @Override protected void updateItem(Data item, boolean empty) {
                        super.updateItem(item, empty);

                        if (this.getTableRow() != null) {

                            int index = this.getTableRow().getIndex();

                            if( index < table.getItems().size()) {
                                int rowNum = index + 1;
                                setText( String.valueOf(rowNum));
                            } else {
                                setText("");
                            }

                        } else {
                            setText("");
                        }

                    }
                };
            }
        });

        table.getColumns().add( 0, indexCol); // number column is at index 0

        // allow multi selection
        table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

        // buttons
        // --------------------------------------------
        FlowPane buttonBar = new FlowPane();

        // add new row button
        Button addButton = new Button( "Add");
        addButton.setOnAction(e -> {
            addRow();
        });
        addButton.setFocusTraversable(false);// don't let it get the focus or else the table would lose it when we click the button and we's have to request the focus on the table in the event handler

        // remove selected rows button
        Button removeButton = new Button( "Remove");
        removeButton.setOnAction(e -> {
            removeSelectedRows();
        });
        removeButton.setFocusTraversable(false);// don't let it get the focus or else the table would lose it when we click the button and we's have to request the focus on the table in the event handler

        buttonBar.getChildren().addAll( addButton, removeButton);

        // add nodes to stage
        BorderPane root = new BorderPane();
        root.setCenter(table);
        root.setBottom(buttonBar);

        Scene scene = new Scene( root, 800,600);
        scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());

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


        // select first cell
        // TODO: why isn't this selecting the 1st cell in the index column?
        table.getSelectionModel().selectFirst();

    }

    /**
     * Insert a new default row to the table, select a cell of it and scroll to it. 
     */
    public void addRow() {

        // get current position
        TablePosition pos = table.getFocusModel().getFocusedCell();

        // clear current selection
        table.getSelectionModel().clearSelection();

        // create new record and add it to the model
        Data data = new Data(0d,0d);
        table.getItems().add( data);

        // get last row
        int row = table.getItems().size() - 1;
        table.getSelectionModel().select( row, pos.getTableColumn());

        // scroll to new row
        table.scrollTo( data);

    }

    /**
     * Remove all selected rows.
     */
    public void removeSelectedRows() {

        table.getItems().removeAll(table.getSelectionModel().getSelectedItems());

        // table selects by index, so we have to clear the selection or else items with that index would be selected 
        table.getSelectionModel().clearSelection();


    }

    /**
     * Number cell factory which converts strings to numbers and vice versa.
     * @return
     */
    private Callback<TableColumn<Data, Number>, TableCell<Data, Number>>  createNumberCellFactory() {

        Callback<TableColumn<Data, Number>, TableCell<Data, Number>> factory = TextFieldTableCell.forTableColumn( new StringConverter<Number>() {

            @Override
            public Number fromString(String string) {
                return Double.parseDouble(string);
            }

            @Override
            public String toString(Number object) {
                return object.toString();
            }
        });

        return factory;
    }

    /**
     * Table data container
     */
    public static class Data {

        private final SimpleDoubleProperty number1;
        private final SimpleDoubleProperty number2;

        private Data( Double number1, Double number2) {
            this.number1 = new SimpleDoubleProperty(number1);
            this.number2 = new SimpleDoubleProperty(number2);
        }

        public final DoubleProperty number1Property() {
            return this.number1;
        }

        public final double getNumber1() {
            return this.number1Property().get();
        }

        public final void setNumber1(final double number1) {
            this.number1Property().set(number1);
        }

        public final DoubleProperty number2Property() {
            return this.number2;
        }

        public final double getNumber2() {
            return this.number2Property().get();
        }

        public final void setNumber2(final double number2) {
            this.number2Property().set(number2);
        }


    }

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


} 

应用程序.css

/* edit cell appearance */

/* If the padding is 0, then there's a grey area. If you set it to 2, then there won't be a great area.
 * However if you use a border color, then the border requires its size, so the padding is set to 2 - 1 = 1.
 * You have to toy around with the border. If necessary give it a width of 2 and make it the same color as the background color.
 */
.text-field-table-cell .text-field {
   -fx-padding: 1; 
   -fx-border-color:red; 
   -fx-border-width:1; 
   -fx-background-color:yellow;
 }
.table-cell:focused {
   -fx-padding: 0;
}

/* right-align the cell content in view mode */
.table-cell {
    -fx-alignment: CENTER-RIGHT;
}
/* right-align the cell content in edit mode */
.text-field {
    -fx-alignment: CENTER-RIGHT;
}

/* colorize background only of rows which have data */
.table-row-cell:empty {
    -fx-background-color: white;
}

.table-row-cell:empty .table-cell {
    -fx-border-width: 0px;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaFX TableView 通过单击和自动插入行进行编辑? 的相关文章

  • JavaFx ComboBox 绑定混乱

    我有一个 I18N 实现 它通过属性绑定 JavaFX UI 元素 例如 def translateLabel l Label key String args Any Unit l textProperty bind createStrin
  • JavaFX中如何获取鼠标位置?

    我是java fx 的初学者 如何在 JavaFX 中获取鼠标在 x 和 y 中的位置 我尝试使用 AWTMouseInfo 也导入了它 但它不起作用 我还在 Ensembles 中看到了它的代码 在 高级阶段 拖动球窗口 这就是我需要做的
  • 如何在javafx中获取当前屏幕详细信息?

    我的电脑连接了多个显示器 从 javaFX 我可以获得主屏幕 但我需要了解当前舞台所在屏幕的屏幕详细信息 我怎样才能得到它 尝试使用获取矩形屏幕 http docs oracle com javafx 2 api javafx stage
  • JavaFX MediaPlayer - 音乐在 10 秒后停止

    这是代码 就像标题所说的 音乐在10秒后停止 我在vlc或其他程序中正常播放该文件 持续了5分钟多 public void music String bip src data fjordmusic mp3 Media hit new Med
  • 如何在 JavaFX 中连接可观察列表?

    我所说的串联是指获得一个新列表 该列表侦听所有串联部分的更改 方法的目的是什么FXCollections concat ObservableList
  • 如何在 JavaFX 中将 FontAwesome 升级到版本 5

    我有一个使用 FontAwesome 图标的 JavaFX 我想使用新版本 5 但似乎已经不起作用了 这是一个用 Groovy 编写的简单演示应用程序 可与旧版 FontAwesome 一起使用 import javafx applicat
  • 将 JavaFX FXML 对象分组在一起

    非常具有描述性和信息性的答案将从我这里获得价值 50 声望的赏金 我正在 JavaFX 中开发一个应用程序 对于视图 我使用 FXML
  • Javafx 从 TextField 获取输入

    这是我当前的代码 它所做的只是为我制作的计算器设置一个 GUI 界面 我希望用户输入两个值 然后当按下 Sum 按钮时 它将两个值加在一起并将其显示在 Sum 文本字段中 我正在尝试使用 JavaFX 如果您能提供一些帮助 我将不胜感激 i
  • JavaFX ReadOnlyListProperty 不是只读的?

    这段代码抛出 UnsupportedOperationException 正如我所期望的那样 因为它是只读的 ListProperty
  • 为什么 JavaFX API 不包含在 Java 8 J2SE 中? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 有谁知道为什么 JavaFX 8 仍然不是即将推出的 Java 8 中的日常 J2SE API 显示所有 Java 组件的技术图清楚地将 Jav
  • JavaFX ScrollPane 样式

    我正在尝试在 JavaFX 中创建一个黑白 ScrollPane 我已经创建了一个 CSS 文件 它工作得很好 除了这个小方块 无论我尝试什么 我都无法将其变黑 这是我的 CSS 文件 scroll pane fx background c
  • JavaFX HTMLEditor - 插入图像功能

    我正在使用 JavaFX 集成的 HTMLEditor 它具有的所有功能都很好 但我还需要具有在 HTML 文本中插入图像的功能 你知道我可以使用的一些来源吗 或者其他一些可以在 JavaFX 中使用的 HTML WYSIWYG 编辑器并且
  • JAVAFX 缩放、ScrollPane 滚动

    I have JAVAFX application with zoom and scale as described here Scale at pivot point in an already scaled node https sta
  • 包含 ListView 更新、CellValueFactory 的 JavaFX TableView

    我确实有一个引擎 其中包含以下列表中的部件 UPDATE 我更新了文本以提供示例 我想要一个包含 2 列 名称 零件 的引擎 TableView 我希望将 Column 部分呈现为 TableCell 中的 ListView 因此我重写了该
  • JavaFX 动画使用循环?

    我正在尝试制作一款类似太空侵略者的游戏 我画了一个正方形 我想通过使用循环逐步向下移动它thread sleep 然而 正方形立即被绘制出来 我知道有可以使用的动画路径 但我想保持低水平并仅使用坐标系 有没有办法使用这样的循环来制作时间轴动
  • mobileapplication.mobileevent BACK_BUTTON_PRESSED

    我的两个视图中有 2 个 Android 本机音频实例 当用户按下后退按钮并离开视图时 我试图让音频停止 因为它不会自动发生 我查看了文档并看到了 MobileEvent 类 我尝试实现它的构造函数 但没有成功 这是我的第一个应用程序 为此
  • 使用 Maven 构建 JavaFX 8

    我测试了使用 Netbeans 7 4 创建 JavaFX 8 项目 但不幸的是没有运气 这是 POM 文件
  • 访问 FXML 控制器类

    我想随时与 FXML 控制器类进行通信 以更新主应用程序或其他阶段屏幕上的信息 这可能吗 我还没有找到任何方法来做到这一点 静态函数可能是一种方法 但它们无法访问表单的控件 有任何想法吗 您可以从以下位置获取控制器FXMLLoader FX
  • 如何在谓词中对 FilteredList 结果进行优先级排序/排名?

    我的应用程序包含一个TextField and a ListView The TextField允许用户输入搜索词来过滤内容ListView当他们打字时 过滤过程将匹配每个字段中的多个字段DataItem in the ListView如果
  • JavaFX 打印自定义纸张尺寸

    在 JavaFX 中 我想将照片打印到 10x15 的纸张上 有一些纸张常数 但没有 100x150 mm 常数 是否可以创建自己的纸张以在页面布局中使用它 Thanks PageLayout pageLayout printer crea

随机推荐

  • Spark 作业失败,因为 HDFS 正在缓存 jar

    我将 Scala Spark jar 上传到 HDFS 以在我们的集群上测试它们 跑步后 我经常意识到需要做出改变 因此 我在本地进行更改 然后将新 jar 推送回 HDFS 然而 经常 并非总是 当我这样做时 hadoop 会抛出一个错误
  • 将 HH:MM:SS 格式的时间仅转换为秒?

    如何转换时间格式HH MM SS变成单位秒数 P S 时间有时可能有格式MM SS only 无需explode任何事物 str time 23 12 95 str time preg replace d 1 2 d 2 00 1 2 st
  • 解释 lambda argparse.HelpFormatter(prog, width)

    此代码可以正常工作以增加帮助文本的宽度 但尚不清楚 lambda 函数是做什么的 编辑 为了澄清 问题不是为什么 lambda 函数通常很有用 但反而 参数解析器初始化代码如何使用 lambda 函数 import argparse imp
  • Windows中的JRE安装目录[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 有没有命令可以检查Windows下活动的 因为机器可以安装1个以上的JRE JRE安装目录 对于linux来说 对应的命令是 which java W
  • Firebase idToken 过期后我该怎么办

    我在用着onAuthStateChanged this unregisterAuthObserver firebase auth onAuthStateChanged user gt if user user getIdToken true
  • grep 在目录中查找包含字符串的文件

    我正在尝试熟悉终端的基础知识 我想在我的 CMS 网站中找到包含我的 Google Analytics 跟踪代码 gaq 作为搜索字符串的文件应该可以解决问题 我的桌面上有一个文件夹 其中包含所有站点文件 用户 我的名字 桌面 网站 我打开
  • Android:如何查找设备的帧速率?

    帧速率 我指的是显示变化的速率 即调用 Ondraw 并重新绘制画布 所有 Android 设备都有默认费率吗 由于该速率取决于设备的处理能力 因此在开始为该移动设备编程之前如何找出该设备的帧速率 这可能是后续这个问题 https stac
  • CSS如何在伪元素内垂直对齐文本

    我创建了一个伪元素来放置无序列表 CSS如下 ul pricing column width 200px height 400px background red position relative margin 50px pricing c
  • dataTables .row( ) 不是服务器端处理行详细信息的函数

    function format d return Full name br Salary br The child row can contain any data you wish including links images inner
  • Android 中使用 iText 生成的 PDF 中不显示西里尔字母

    我正在尝试在我的 Android 应用程序中生成 PDF 我使用 iText 它生成 PDF 但只显示英文字母 我找到了使用 unicode 的 iText 示例代码 我在一个简单的 comsole java 应用程序中尝试了这个示例代码
  • 8086边画边听键盘

    我熟悉等待键盘输入的 INT 16h 但我正在开发一个游戏 我希望有一个游戏循环 它可以在屏幕上显示动画 并且只要有键盘敲击 8086 就应该运行到我的中断处理程序并告诉我按下了哪个键来相应地更新我的数据 我怎么能这样做呢 当调用 INT
  • 使用 OpenCV 删除孤立像素

    我正在寻找一种使用 OpenCV 从二进制图像中删除孤立的白色像素的方法 类似的问题 OpenCV 摆脱孤立像素 https stackoverflow com questions 13755840 opencv get rid of is
  • 参数化数组#uniq(即uniq_by)[重复]

    这个问题在这里已经有答案了 如果我不想从数组中删除重复元素 而是想删除具有特定共同属性的元素 该怎么办 具体来说 我想从数组中删除具有重复 essences 的所有字符串 其中essence 的定义如下 class String def e
  • StreamBuilder Firestore 分页

    我是 flutter 的新手 当滚动到达顶部时 我正在尝试使用 Streambuilder 对聊天进行分页 问题是 当我在滚动监听器流构建器中进行查询时 将其查询优先于滚动监听器并返回旧响应 有什么办法可以做到这一点吗 我在这里有什么选择
  • 从 C# Web 浏览器控件调用控件上的 Javascript 事件

    I am working on a web scraper in C where I have a web browser control that loads a web page I then collect data and depe
  • 使用 python panda 按月、年计算出现频率

    假设我有以下数据系列 Date Category 2014 8 Facebook 2014 8 Vimeo 2014 8 Facebook 2014 8 Facebook 2014 9 Facebook 2014 9 Orkut 2014
  • 在 PyQt5 中,我们如何获取焦点小部件的名称/对象名称?

    在我们的 PyQt5 程序中 我们多次使用 Qline Edits QcheckBox QListwidget 如何知道 我们的程序中使用的小部件有哪些小部件名称 如何获取 返回当前具有焦点的小部件的名称 用户指定的名称 正如 Heike所
  • 在 C++ 中将函数模板作为参数传递

    例如 我想从两个序列中获取最大值列表 left and right 并将结果保存在max seq 它们都是先前定义和分配的 std transform left begin left end right begin max seq begi
  • “py.test”与“pytest”命令

    The py test在我的例子中 命令失败了 而pytest运行完全正常 我使用 pytest flask 插件 platform linux Python 3 5 2 pytest 3 0 2 py 1 4 31 pluggy 0 3
  • JavaFX TableView 通过单击和自动插入行进行编辑?

    我在程序中使用了 tableview 来显示几行 这很好 我的程序用于会计 正如你所知 其中插入了大量数据 我使用了表视图 但我遇到了很多问题 问题 1 当用户想要修改值时 他将双击以编辑单元格 我希望我的用户选择任何行并开始输入 问题2