我正在使用JavaFX 2.2项目,使用TextField控件时出现问题。我想限制用户输入到每个TextField的字符,但是我找不到一个属性或类似maxlength的东西。同样的问题存在摇摆,并用this方式解决。如何解决它的JavaFX 2.2?JavaFX 2.2 TextField maxlength
回答
这是一个更好的方式做一个普通的文本字段的工作:
public static void addTextLimiter(final TextField tf, final int maxLength) {
tf.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(final ObservableValue<? extends String> ov, final String oldValue, final String newValue) {
if (tf.getText().length() > maxLength) {
String s = tf.getText().substring(0, maxLength);
tf.setText(s);
}
}
});
}
完美的工作,除了那个撤消错误。
当心:通知期间修改发送方的状态通常是一个坏主意 - 你可能会难以跟踪的副作用(撤消错误可能是这样一个不必要的副作用,虽然我没有挖进去) – kleopatra 2015-10-19 15:23:04
@ceklock请不要介意,如果我要求解释,会发生什么情况:::: String s = tf.getText()。substring(0,maxLength);被替换为s = oldValue;因为我很难理解它! – 2017-02-06 16:36:44
你可以做同样的事情到这里的方法描述:http://fxexperience.com/2012/02/restricting-input-on-a-textfield/
class LimitedTextField extends TextField {
private final int limit;
public LimitedTextField(int limit) {
this.limit = limit;
}
@Override
public void replaceText(int start, int end, String text) {
super.replaceText(start, end, text);
verify();
}
@Override
public void replaceSelection(String text) {
super.replaceSelection(text);
verify();
}
private void verify() {
if (getText().length() > limit) {
setText(getText().substring(0, limit));
}
}
};
首先检查并替换文本不是很好吗? – keuleJ 2013-03-01 15:41:38
这是可能的,但对于短期样本,逻辑将变得太复杂。 – 2013-03-01 16:34:39
为了使它工作,我添加了一个0参数构造函数和一个限制属性的setter方法。谢谢你。 – 2013-03-01 18:01:22
完整的代码我用来解决我的问题是下面的代码。我扩展了像Sergey Grinev那样的TextField类,并且我添加了一个空构造函数。要设置最大长度,我添加了一个setter方法。我首先检查并替换TextField中的文本,因为我想禁止插入多于maxlength字符,否则将在TextField的末尾插入maxlength + 1字符,并删除TextField的第一个字符。
package fx.mycontrols;
public class TextFieldLimited extends TextField {
private int maxlength;
public TextFieldLimited() {
this.maxlength = 10;
}
public void setMaxlength(int maxlength) {
this.maxlength = maxlength;
}
@Override
public void replaceText(int start, int end, String text) {
// Delete or backspace user input.
if (text.equals("")) {
super.replaceText(start, end, text);
} else if (getText().length() < maxlength) {
super.replaceText(start, end, text);
}
}
@Override
public void replaceSelection(String text) {
// Delete or backspace user input.
if (text.equals("")) {
super.replaceSelection(text);
} else if (getText().length() < maxlength) {
// Add characters, but don't exceed maxlength.
if (text.length() > maxlength - getText().length()) {
text = text.substring(0, maxlength- getText().length());
}
super.replaceSelection(text);
}
}
}
里面的FXML文件我增加了进口(的该TextFieldLimited类是现有的包装)上的文件的顶部,代之以自定义TextFieldLimited的文本字段标签。
<?import fx.mycontrols.*?>
.
.
.
<TextFieldLimited fx:id="usernameTxtField" promptText="username" />
控制器类内部,
在顶部(属性声明),
@FXML
private TextFieldLimited usernameTxtField;
initialize方法内,
usernameTxtField.setLimit(40);
就是这样。
你能解释一下,为什么你在设置或替换一些文本之前使用'getText' **?听起来对我错了。你是否用C&P测试了这个? – Hardcoded 2013-05-27 09:27:39
我想将新的字符输入附加到TextField中,**仅**如果文本的长度不会超过maxlength。这就是为什么我第一次检查长度是否达到maxlength,然后追加新字符。当用户点击删除或退格时,存在错误的部分。我更新了代码。此外,我更新replaceSelection()方法,以防止用户粘贴文本的长度,除了现有的文本,超过maxlength字符超过maxlength。我测试过,它工作正常。 – 2013-05-27 20:01:13
我用一个简单的方法来限制双方的字符数,并迫使数字输入:
public TextField data;
public static final int maxLength = 5;
data.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable,
String oldValue, String newValue) {
try {
// force numeric value by resetting to old value if exception is thrown
Integer.parseInt(newValue);
// force correct length by resetting to old value if longer than maxLength
if(newValue.length() > maxLength)
data.setText(oldValue);
} catch (Exception e) {
data.setText(oldValue);
}
}
});
不会downvote,但如果你输入上面的'maxLength'并尝试使用系统默认撤消这种方法会导致'java.lang.IndexOutOfBoundsException'。 – Neeko 2013-10-04 14:17:40
好一点 - 我还使用这样的技术现在:http://stackoverflow.com/questions/13562712/how-to-disable-the-default-context-menu-on-a-text-field – hemisphire 2013-10-08 21:22:49
我关于这个Undo错误的问题开了我自己的问题。请参阅http://stackoverflow.com/questions/19184305/limiting-character-count-of-javafx-textfield-causes-indexoutofbounds-on-undo获取相当好的解决方案。 – Neeko 2013-10-09 13:22:13
下面的代码将重新定位光标,以便用户不会意外地覆盖其输入。
public static void setTextLimit(TextField textField, int length) {
textField.setOnKeyTyped(event -> {
String string = textField.getText();
if (string.length() > length) {
textField.setText(string.substring(0, length));
textField.positionCaret(string.length());
}
});
}
此方法让TextField完成所有处理(复制/粘贴/撤消安全)。 不要求扩展课程。 并允许您设定在每次更改 (将其推到逻辑,或回到之前的值,甚至修改它)后如何处理新文本。
// fired by every text property change
textField.textProperty().addListener(
(observable, oldValue, newValue) -> {
// Your validation rules, anything you like
// (! note 1 !) make sure that empty string (newValue.equals(""))
// or initial text is always valid
// to prevent inifinity cycle
// do whatever you want with newValue
// If newValue is not valid for your rules
((StringProperty)observable).setValue(oldValue);
// (! note 2 !) do not bind textProperty (textProperty().bind(someProperty))
// to anything in your code. TextProperty implementation
// of StringProperty in TextFieldControl
// will throw RuntimeException in this case on setValue(string) call.
// Or catch and handle this exception.
// If you want to change something in text
// When it is valid for you with some changes that can be automated.
// For example change it to upper case
((StringProperty)observable).setValue(newValue.toUpperCase());
}
);
为了您的情况,只需在里面添加这个逻辑。完美的作品。
// For example 10 characters
if (newValue.length() >= 10) ((StringProperty)observable).setValue(oldValue);
随着java8u40我们得到了一类新的TextFormatter:它的主要职责之一是之前提供一个勾成文本输入的任何变化它就会comitted的内容。在那个钩子我们可以accept/rejec t甚至改变建议的变化。
在OP's self-answer解决的要求是
- 规则:限制文本的长度短于n个字符
- 修改:如果违反规则,保持最后n个字符的输入
:文本,并删除在其开始// here we adjust the new text TextField adjust = new TextField("scrolling: " + len); UnaryOperator<Change> modifyChange = c -> { if (c.isContentChange()) { int newLength = c.getControlNewText().length(); if (newLength > len) { // replace the input text with the last len chars String tail = c.getControlNewText().substring(newLength - len, newLength); c.setText(tail); // replace the range to complete text // valid coordinates for range is in terms of old text int oldLength = c.getControlText().length(); c.setRange(0, oldLength); } } return c; }; adjust.setTextFormatter(new TextFormatter(modifyChange));
多余的字符使用的TextFormatter,这可能等来实现
旁白:
- 修改属性,一边听它的变化可能会导致意想不到的副作用
- 所有建议的解决方案的关键级事件被破坏(他们不能处理粘贴/程序化的变化
我有这样的代码,它只允许数字并限制Javafx中文本字段的输入长度。
// Event handler for inputPrice
inputPrice.setOnAction(event2 -> {
// Obtain input as a String from text field
String inputPriceStr = inputPrice.getText();
// Get length of the String to compare with max length
int length = inputPrice.getText().length();
final int MAX = 10; // limit number of characters
// Validate user input allowing only numbers and limit input size
if (inputPriceStr.matches("[0-9]*") && length < MAX) {
// your code here
}});
- 1. 如何使用javafx textfield maxlength
- 2. JavaFX TextField验证
- 3. JavaFX TextField EventHandler
- 4. JavaFX TextField监听器
- 5. JavaFX - 自定义TextField
- 6. 自定义TextField - JavaFX
- 7. 从JavaFX的2.2 JavaFX8
- 8. JavaFX 2.2:如何将String绑定到Integer?
- 9. Javafx Robot无法从Javafx 2.2工作
- 10. onAction为javafx中的textfield
- 11. JavaFX TextField focusProperty touch on touchScrollEvent
- 12. Textfield CSS样式使用JavaFx
- 13. JavaFX TextField自动建议
- 14. TextField右对齐问题javafx
- 15. JavaFX自定义TextField限制
- 16. Django:model maxlength和form maxlength
- 17. JavaFX初始化TextField的数组
- 18. JavaFX Sqlite检查TextField是否为空
- 19. java.lang.reflect.InvocationTargetException当从TextField获取值时 - Javafx
- 20. JavaFX TextField获取点击项目
- 21. TextField和为Hangman游戏提交JavaFx
- 22. 无法将JavaFX TextField绑定到ListView值
- 23. JavaFX - Textfield/Textarea中的内嵌图像
- 24. 如何格式化TextField的文本? JavaFX
- 25. 验证javaFX中的TextField数组
- 26. FloatField(TextField for javafx中的浮点数)?
- 27. JavaFX textfield不更新与MYSQL查询
- 28. JavaFX将行打印到TextField中
- 29. JavaFx TextField焦点丢失格式化
- 30. 从TextField消耗JavaFX KeyTyped事件
对JavaFX而言,不具备开箱即用的基本功能不太好。 – 2016-06-30 13:00:30