仅在用户开始键入时清除JavaFX TextField中的提示文本

默认行为是,当字段正在聚焦时,字段中的提示文本将被删除。 那是标记在场中的时候。

是否可以配置文本字段,以便仅在用户开始键入时删除提示文本?

否则,我需要在每个文本字段旁边/上方添加一个标签,以便对其中的值进行描述。

此示例将允许JavaFX中的TextFields,其提示行为是在字段为空时显示提示,即使该字段具有焦点。 该解决方案是自定义CSS和自定义TextField类的组合,后者操纵TextField的CSS样式。

promptpersist

持久prompt.css

.persistent-prompt:focused { -fx-prompt-text-fill: derive(-fx-control-inner-background,-30%); } .no-prompt { -fx-prompt-text-fill: transparent !important; } 

PersistentPromptTextField.java

 import javafx.scene.control.TextField; public class PersistentPromptTextField extends TextField { PersistentPromptTextField(String text, String prompt) { super(text); setPromptText(prompt); getStyleClass().add("persistent-prompt"); refreshPromptVisibility(); textProperty().addListener(observable -> refreshPromptVisibility()); } private void refreshPromptVisibility() { final String text = getText(); if (isEmptyString(text)) { getStyleClass().remove("no-prompt"); } else { if (!getStyleClass().contains("no-prompt")) { getStyleClass().add("no-prompt"); } } } private boolean isEmptyString(String text) { return text == null || text.isEmpty(); } } 

PromptChanger.java

 import javafx.application.Application; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.TextField; import javafx.scene.layout.VBox; import javafx.stage.Stage; public class PromptChanger extends Application { @Override public void start(Stage stage) throws Exception { TextField textField1 = new PersistentPromptTextField("", "First name"); TextField textField2 = new PersistentPromptTextField("", "Last name"); VBox layout = new VBox( 10, textField1, textField2 ); layout.setPadding(new Insets(10)); Scene scene = new Scene(layout); scene.getStylesheets().add( getClass().getResource( "persistent-prompt.css" ).toExternalForm() ); stage.setScene(scene); stage.show(); } public static void main(String[] args) { Application.launch(args); } } 

如何在JavaFX 8中实现快速处理

用于控制提示文本的JavaFX 8(modena.css)的默认CSS如下:

 .text-input { -fx-prompt-text-fill: derive(-fx-control-inner-background,-30%); } .text-input:focused { -fx-prompt-text-fill: transparent; } 

只要字段被聚焦,这将使提示文本透明,即使字段中没有数据。

在与HTML的比较中

HTML输入有一个占位符 ,其指定如下:

用户代理应该向用户提供此提示。 。 。 当元素的值为空字符串或控件未聚焦(或两者都有)时。

您可以在此测试链接的浏览器中尝试此function。

我认为反对JavaFX的这种行为的论据“当获取焦点以便接收用户输入的信号时,应该清除提示文本”是没有意义的,因为聚焦文本字段获得清晰可见的聚焦环,因此用户知道控件已准备好即使显示提示文本,也会收到输入。

我认为JavaFX默认情况下应该像大多数HTML用户代理一样在这方面运行。 随意在JavaFX问题跟踪器中创建一个Tweak请求,以请求JavaFX中的输入提示与HTML实现类似(如果没有为此创建问题)。

替代

第三方Gluon Glisten有一个自定义TextField控件可以具有以下属性:

  • 浮动文本 – TextField中的占位符文本,当收到焦点时,该文本将转换到TextField的顶部。

基于Glisten的TextField的优点在于提示文本始终可见,无论用户是否在控件中输入了任何内容。

胶子休息

胶子活性

您可以在’.text-field:focused’区域配置’-fx-prompt-text-fill’键,如’.text-field’区域(css):

 `.text-field { -fx-prompt-text-fill: derive(-fx-control-inner-background,-30%); } .text-field:focused { -fx-prompt-text-fill: derive(-fx-control-inner-background,-30%); }` 

并在fxml文件中添加’promptText’条目:

  

这就是全部,对我有用。

我知道它有点旧,但我自己需要它,这仍然非常重要。
我将完成jewelsea的回答,并给出一个更简单的解决方案。

背景

显然这是Java(FX)的默认行为(仅当用户开始键入时,TextField中的提示文本才被清除)。
但是,根据JIRA系统中的请求(或错误报告),
Java改变了这种行为(并且默认情况下在TextField获得焦点时清除文本)。

您可以在此处查看此错误报告。


要回到旧的默认(以及更好的行为IMO),您需要做的就是添加以下代码行。

如果您的应用程序接口是使用适当的Java代码编写的。

Java代码:

 textField.setStyle("-fx-prompt-text-fill: derive(-fx-control-inner-background, -30%);"); 

textField是TextField组件的位置。


如果您的应用程序界面是使用FXML和CSS编写的,请将以下内容添加到CSS文件中。

JavaFX FXML(CSS):

 .text-input, .text-input:focused { -fx-prompt-text-fill: derive(-fx-control-inner-background, -30%); } 

————————————————– ——————————

清除焦点行为

目前它是默认行为(当文本字段获得焦点时,文本字段的提示文本被清除),
所以你不需要做任何事情来获得这种行为
但是如果Java决定回到清除键入的行为,
并且您希望获得清除焦点行为,这是如何:

在适当的Java代码的情况下 – 它有点棘手,因为您无法直接定义伪类的行为。

Java代码(使用绑定):

 textField.styleProperty().bind( Bindings .when(textField.focusedProperty()) .then("-fx-prompt-text-fill: transparent;") .otherwise("-fx-prompt-text-fill: derive(-fx-control-inner-background, -30%);")); 

要么 –

Java代码(使用事件):

 textField.focusedProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) { if (newValue) { textField.setStyle("-fx-prompt-text-fill: transparent;"); } else { textField.setStyle("-fx-prompt-text-fill: derive(-fx-control-inner-background, -30%);"); } } }); 

JavaFX FXML CSS:

将以下内容添加到CSS文件中。

 .text-input { -fx-prompt-text-fill: derive(-fx-control-inner-background, -30%); } .text-input:focused { -fx-prompt-text-fill: transparent; } 

希望这有助于……

假设您通过以下方式设置提示文字:

  @FXML TextField tf; public void someMethod() { tf.setPromptText("This is the prompt text"); } 

您可以改为使用tf.setText(String str)来设置初始文本。

然后,在控制器的initialize方法中,添加:

  tf.setOnKeyTyped(new EventHandler() { @Override public void handle(KeyEvent event) { tf.setText(null); } }); 

您可以参考的链接以获得更多帮助: 点击我!

我确信可能有几种方法和技巧可以实现您的要求,但是,当您这样做时,您将覆盖默认的,预期的和标准的UI行为。 当抓取焦点以表示准备接收用户输入时,应该清除提示文本,而不是在用户开始键入之后。