简体   繁体   English

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

[英]How to restrict textfields in TornadoFX to numbers only

The problem here is that I wanna make sure that the user doesn't enter any strings or text especially that I need to enter his choice into a database later so I don't things to get messed up in the database's part, here is part of code which is the view I wish to use the textview with restricted Integers (specifically the amount am field). 这里的问题是我想确保用户没有输入任何字符串或文本,特别是我需要在以后输入他的数据库,所以我不会在数据库的部分搞砸了,这里是部分代码是我希望使用带有限制整数的textview(特别是am字段的数量)的视图。 PS: I'm still new to both JavaFX and TornadoFX so hope this doesn't sound like a rather silly question. PS:我还是JavaFX和TornadoFX的新手,所以希望这听起来不是一个相当愚蠢的问题。

My Code: 我的代码:

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.


    }
}

You can use the filterInput extension function we've added to TextField and check that the text after the addition is in int. 您可以使用我们添加到TextFieldfilterInput扩展函数,并检查添加后的文本是否为int。 If it's not, deny the last input change: 如果不是,则拒绝最后一次输入更改:

textfield {
    filterInput { it.controlNewText.isInt() } 
}

On another note, you really need to look into ItemViewModel. 另外,您需要查看ItemViewModel。 It's an anti-pattern to assign each input element to a variable and extract the values from the input values on submit. 将每个输入元素分配给变量并从提交中的输入值中提取值是一种反模式。 Your code will be a lot cleaner and easier to reason about and refactor later if you use view models. 如果您使用视图模型,您的代码将更清晰,更容易推理和重构。

PS: The filterInput function is available in the soon to be released TornadoFX 1.7.15, in the mean time you can add this extension function to your project: PS: filterInput函数在即将发布的TornadoFX 1.7.15中可用,同时你可以将这个扩展函数添加到你的项目中:

fun TextInputControl.filterInput(discriminator: (TextFormatter.Change) -> Boolean) {
    textFormatter = TextFormatter<Any>(CustomTextFilter(discriminator))
}

From your example it seems like that you'd want to use a PropertySheet which comes from ControlsFX . 从您的示例看来,您似乎想要使用来自ControlsFXPropertySheet I use it in production and it works well with TornadoFX. 我在生产中使用它,它适用于TornadoFX。

Here is an example from the samples project which you can peruse. 以下是您可以仔细阅读的示例项目中的示例。 This will let you edit and bind multiple types not just numbers: 这将允许您编辑和绑定多个类型,而不仅仅是数字:

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);
    }
}

You can also take a look at this question for more info. 您还可以查看此问题以获取更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM