- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想知道是否有办法在 JavaFX 中屏蔽 TextArea
的文本。例如,使用像 PasswordField
这样的“bullet”密码字符来屏蔽文本。对于 TextField
,maskText()
方法效果很好。此方法对 TextArea
没有用。我能做些什么?
注意:我希望 getText()
和 setText()
方法必须使用明文,而不是屏蔽文本。就像 PasswordField
一样有效。
编辑
这是我用来实现结果的方法,但不幸的是没有成功。
我的自定义 TextArea
类:
public class PasswordArea extends TextArea {
@Override
protected Skin<?> createDefaultSkin() {
return new PasswordAreaSkin(this); //my custom skin
}
}
用于自定义 TextArea
的自定义皮肤:
public class PasswordAreaSkin extends TextAreaSkin {
public PasswordAreaSkin(PasswordArea control) {
super(control);
}
//here I override the maskText method to mask the text
@Override
protected String maskText(String text) {
int n = text.length();
StringBuilder passwordBuilder=new StringBuilder(n);
for(int i = 0; i < n; i++) {
passwordBuilder.append('\u2022'); //append 'bullet' char
}
return passwordBuilder.toString();
}
}
最佳答案
你想要的问题是 TextArea
不是为此功能构建的,至少在 JDK 8 中是这样(JDK 9 添加了公共(public)皮肤 API,例如 TextAreaSkin
)。具体来说,它的皮肤 TextAreaSkin
不支持屏蔽机制。
TextFieldSkin
通过将可视文本节点的 textProperty
绑定(bind)到组件的 textProperty
来进行屏蔽。因此,对组件“真实”文本的任何更改都体现在可视组件的文本中,加上适当的屏蔽修改(maskText
方法):
textNode.textProperty().bind(new StringBinding() {
{ bind(textField.textProperty()); }
@Override protected String computeValue() {
return maskText(textField.textProperty().getValueSafe());
}
});
TextAreaSkin
使用一组 Text
节点来实现其视觉效果,尽管在 JDK 8 中只使用了一个节点。通过监听组件的文本:
textArea.textProperty().addListener(observable -> {
invalidateMetrics();
((Text)paragraphNodes.getChildren().get(0)).setText(textArea.textProperty().getValueSafe());
contentView.requestLayout();
});
我们可以使用它来监听视觉文本的变化并自行更新。下面是一个实现的工作示例。 maskText
方法主要是从 TextFieldSkin
复制而来。我们使用反射来访问可视文本表示节点,然后用当前文本更新它(例如,从文本区域构造函数)并注册更新监听器。
public class Test extends Application {
@Override
public void start(Stage stage) throws Exception {
String s = "some times there are\nmore strings\n\nin here";
TextArea ta = new TextArea(s);
ta.setSkin(new TextAreaMaskSkin(ta));
TextArea view = new TextArea();
view.textProperty().bind(ta.textProperty());
Scene scene = new Scene(new HBox(view, ta));
stage.setScene(scene);
stage.show();
}
private static class TextAreaMaskSkin extends TextAreaSkin {
public TextAreaMaskSkin(TextArea textArea) throws Exception {
super(textArea);
Field field = TextAreaSkin.class.getDeclaredField("paragraphNodes");
field.setAccessible(true);
Group group = (Group) field.get(this);
Text text = (Text) group.getChildren().get(0);
text.setText(maskText(textArea.textProperty().getValueSafe()));
text.textProperty().addListener(o -> text.setText(maskText(textArea.textProperty().getValueSafe())));
}
@Override
protected String maskText(String txt) {
int n = txt.length();
StringBuilder passwordBuilder = new StringBuilder(n);
for (int i = 0; i < n; i++) {
if (txt.charAt(i) == '\n') {
passwordBuilder.append('\n');
} else {
passwordBuilder.append(TextFieldSkin.BULLET);
}
}
return passwordBuilder.toString();
}
}
public static void main(String[] args) {
launch(args);
}
}
关于JavaFX - TextArea 的掩码文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46621253/
我是一名优秀的程序员,十分优秀!