如何将TornadoFX中的文本字段限制为仅限数字

时间:2018-02-03 20:43:58

标签: java javafx kotlin tornadofx

这里的问题是我想确保用户没有输入任何字符串或文本,特别是我需要在以后输入他的数据库,所以我不会搞砸任何东西搞砸了数据库的一部分,这里是代码的一部分,这是我希望使用带有限制整数的textview的视图(特别是am字段的数量)。 PS:我对JavaFX和TornadoFX都很陌生,所以希望这听起来不是一个相当愚蠢的问题。

我的代码:

package com.company.view

import javafx.beans.property.SimpleIntegerProperty
import javafx.scene.control.CheckBox
import tornadofx.*
import javafx.scene.control.TextField
import javafx.util.converter.NumberStringConverter
import java.sql.Connection

class Add: View() {
    override val root = Form()
    private val mainMenu: MainMenu by inject()
    private var cname: TextField by singleAssign()
    private var address: TextField by singleAssign()
    private var sname: TextField by singleAssign()
    private var ch: CheckBox by singleAssign()
    private var am: TextField by singleAssign()
    var conn: Connection?= mainMenu.conn

    init {
        with(root) {
            vbox(30.0) {
                fieldset("Enter Your Info below") {
                    field("Enter The Customer's Name") {
                            cname = textfield()
                    }
                    field("Enter the Customer's address") {
                        address = textfield()
                    }
                    field("Enter Bought Stock's Name") {
                        sname = textfield()
                    }
                    field("Do you wish to pay now?") {
                        ch = checkbox()
                    }
                    field("Enter the amount you wish to buy"){
                        am = textfield()
                    }
                    button("Submit")
                    {
                        setOnAction {
                            addPayment(cname.text, address.text, sname.text, ch.isSelected, am.text)
                        }
                    }
                }
            }
        }
    }

   private fun addPayment(cusName: String, caddress: String, stname: String, che: Boolean,am: String){
//required code for inserting into the database here.


    }
}

2 个答案:

答案 0 :(得分:5)

您可以使用我们添加到filterInput的{​​{1}}扩展函数,并检查添加后的文本是否为int。如果不是,则拒绝最后一次输入更改:

TextField

另一方面,你真的需要研究ItemViewModel。将每个输入元素分配给变量并从提交中的输入值中提取值是一种反模式。如果您使用视图模型,您的代码将更清晰,更容易推理和重构。

PS:即将发布的TornadoFX 1.7.15中提供textfield { filterInput { it.controlNewText.isInt() } } 功能,同时您可以将此扩展功能添加到您的项目中:

filterInput

答案 1 :(得分:1)

从您的示例中,您似乎想要使用来自PropertySheetControlsFX。我在生产中使用它,它适用于TornadoFX。

以下是samples项目的一个示例,您可以仔细阅读。这将允许您编辑和绑定多种类型,而不仅仅是数字:

public class PropertySheetExample extends VBox {
    private static Map<String, Object> customDataMap = new LinkedHashMap<>();
    static {
        customDataMap.put("Group 1#My Text", "Same text"); // Creates a TextField in property sheet
        customDataMap.put("Group 1#My Date", LocalDate.of(2000, Month.JANUARY, 1)); // Creates a DatePicker
        customDataMap.put("Group 2#My Enum Choice", SomeEnumType.EnumValue); // Creates a ChoiceBox
        customDataMap.put("Group 2#My Boolean", false); // Creates a CheckBox
        customDataMap.put("Group 2#My Number", 500); // Creates a NumericField
    }

    class CustomPropertyItem implements PropertySheet.Item {
        private String key;
        private String category, name;

        public CustomPropertyItem(String key) {
            this.key = key;
            String[] skey = key.split("#");
            category = skey[0];
            name = skey[1];
        }

        @Override
        public Class<?> getType() {
            return customDataMap.get(key).getClass();
        }

        @Override
        public String getCategory() {
            return category;
        }

        @Override
        public String getName() {
            return name;
        }

        @Override
        public String getDescription() {
            return null;
        }

        @Override
        public Object getValue() {
            return customDataMap.get(key);
        }

        @Override
        public void setValue(Object value) {
            customDataMap.put(key, value);
        }
    }

    public PropertySheetExample {
        ObservableList<PropertySheet.Item> list = FXCollections.observableArrayList();
        for (String key : customDataMap.keySet())
            list.add(new CustomPropertyItem(key));

        PropertySheet propertySheet = new PropertySheet(list);
        VBox.setVgrow(propertySheet, Priority.ALWAYS);
        getChildren().add(propertySheet);
    }
}

您还可以查看this question了解详情。