为什么在使用change listener时,JavaFx应用程序中的大写字母会延迟?

为什么在使用change listener时,JavaFx应用程序中的大写字母会延迟?,java,user-interface,javafx,observable,Java,User Interface,Javafx,Observable,我在JavaFx上有一个简单的应用程序,它为javafxbean创建了惰性实例化器,这个应用程序完全是gui,它只有一个fxml和一个main类 <?xml version="1.0" encoding="UTF-8"?> <?import javafx.geometry.Insets?> <?import javafx.scene.control.Button?> <?import javafx.scene.control.Label?> &l

我在JavaFx上有一个简单的应用程序,它为javafxbean创建了惰性实例化器,这个应用程序完全是gui,它只有一个fxml和一个main类

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.Rectangle?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.SuperLazyfxController">
   <children>
      <StackPane layoutX="3.0" prefHeight="400.0" prefWidth="594.0">
         <children>
            <Rectangle arcHeight="5.0" arcWidth="5.0" fill="#0f5694" height="392.0" stroke="BLACK" strokeType="INSIDE" width="594.0" />
            <AnchorPane prefHeight="344.0" prefWidth="594.0">
               <children>
                  <VBox alignment="CENTER" layoutX="38.0" layoutY="59.0" prefHeight="144.0" prefWidth="459.0" spacing="10.0" AnchorPane.bottomAnchor="134.0" AnchorPane.leftAnchor="38.0" AnchorPane.rightAnchor="67.0" AnchorPane.topAnchor="59.0">
                     <children>
                        <HBox prefHeight="29.0" prefWidth="537.0">
                           <children>
                              <Label alignment="CENTER_RIGHT" prefHeight="65.0" prefWidth="262.0" text="Accesibilidad Property :" textFill="#ae9c3e">
                                 <font>
                                    <Font name="Ebrima Bold" size="18.0" />
                                 </font>
                                 <HBox.margin>
                                    <Insets right="10.0" />
                                 </HBox.margin>
                              </Label>
                              <TextField fx:id="accesib" prefHeight="72.0" prefWidth="277.0" />
                           </children>
                        </HBox>
                        <HBox prefHeight="29.0" prefWidth="537.0">
                           <children>
                              <Label alignment="CENTER_RIGHT" prefHeight="65.0" prefWidth="262.0" text="TipoProperty" textFill="#ae9c3e">
                                 <font>
                                    <Font name="Ebrima Bold" size="18.0" />
                                 </font>
                                 <HBox.margin>
                                    <Insets right="10.0" />
                                 </HBox.margin>
                              </Label>
                              <TextField fx:id="Tipo" prefHeight="72.0" prefWidth="277.0" />
                           </children>
                        </HBox>
                        <HBox prefHeight="29.0" prefWidth="537.0">
                           <children>
                              <Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="29.0" prefWidth="261.0" text="Nombre Property :" textFill="#ae9c3e">
                                 <font>
                                    <Font name="Ebrima Bold" size="18.0" />
                                 </font>
                                 <HBox.margin>
                                    <Insets right="10.0" />
                                 </HBox.margin>
                              </Label>
                              <TextField fx:id="nombre" onKeyReleased="#mayusculas" prefHeight="72.0" prefWidth="277.0" />
                           </children>
                        </HBox>
                        <HBox prefHeight="29.0" prefWidth="537.0">
                           <children>
                              <Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="29.0" prefWidth="261.0" text="Shadowfield type" textFill="#ae9c3e">
                                 <font>
                                    <Font name="Ebrima Bold" size="18.0" />
                                 </font>
                                 <HBox.margin>
                                    <Insets right="10.0" />
                                 </HBox.margin>
                              </Label>
                              <TextField fx:id="tiposhadow" prefHeight="72.0" prefWidth="277.0" />
                           </children>
                        </HBox>
                        <Button alignment="CENTER" contentDisplay="CENTER" mnemonicParsing="false" onAction="#Clean" text="Clean" textFill="#907c39">
                           <font>
                              <Font name="System Bold" size="13.0" />
                           </font>
                        </Button>
                     </children>
                  </VBox>
                  <TextArea fx:id="area" layoutX="15.0" layoutY="267.0" prefHeight="118.0" prefWidth="563.0" AnchorPane.bottomAnchor="15.0" AnchorPane.leftAnchor="15.0" AnchorPane.rightAnchor="16.0" AnchorPane.topAnchor="267.0" />
                  <Label alignment="CENTER" layoutX="139.0" prefHeight="62.0" prefWidth="321.0" text="Super-Lazy Insta JavaFX" textFill="RED" AnchorPane.bottomAnchor="338.0" AnchorPane.leftAnchor="139.0" AnchorPane.rightAnchor="134.0" AnchorPane.topAnchor="0.0">
                     <font>
                        <Font name="System Bold" size="25.0" />
                     </font>
                  </Label>
               </children>
            </AnchorPane>
         </children>
      </StackPane>
   </children>
</AnchorPane>
这是控制器类

package app;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.binding.StringBinding;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;

public class SuperLazyfxController implements Initializable {

    @FXML
    private TextField Tipo;
    @FXML
    private TextField nombre;
    @FXML
    private TextField tiposhadow;
    @FXML
    private TextField accesib;
    @FXML
    private TextArea area;

    private StringBinding sbind;
    private StringProperty nombreMayus = new SimpleStringProperty("Nombrevar");
    private StringProperty nombreMin = new SimpleStringProperty("");

    @Override
    public void initialize(URL url, ResourceBundle rb) {

        sbind = new StringBinding() {

            {
                super.bind(Tipo.textProperty(), nombre.textProperty(), tiposhadow.textProperty(), accesib.textProperty());
            }

            @Override
            protected String computeValue() {

                return accesib.textProperty().get() + " " + Tipo.textProperty().get() + " " + nombre.textProperty().get() + ";\n"
                        + accesib.textProperty().get() + " " + tiposhadow.textProperty().get() + " _" + nombre.textProperty().get() + ";\n\n"

                        + "public " + tiposhadow.textProperty().get() + " get" + nombreMayus.get() + nombreMin.get()+"(){"
                        + "\n\t return ("+nombre.textProperty().get()+" ==null)? _"+nombre.textProperty().get()+": "+nombre.textProperty().get()+".get();\n"
                        +"}\n\n"

                        + "public void set"+ nombreMayus.get() + nombreMin.get()+"("+tiposhadow.textProperty().get()+" "+nombre.textProperty().get()+"){"
                        + "\t\nif(this."+nombre.textProperty().get()+"==null){\n"
                        + "\t_"+nombre.textProperty().get()+"="+nombre.textProperty().get()+";\n"
                        + "\t} else{\n"
                        + "\tthis."+nombre.textProperty().get()+".set("+nombre.textProperty().get()+");\n"
                        + "\t}\n"
                        + "}\n\n"

                        + "public "+ Tipo.textProperty().get()+" "+nombre.textProperty().get()+"Property(){\n"
                        + "\treturn ("+nombre.textProperty().get()+"== null)? "+nombre.textProperty().get()+"= new Simple"+Tipo.textProperty().get()+"(this,\""+nombre.textProperty().get()+"\", _"+nombre.textProperty().get()+"): "+nombre.textProperty().get()+";\n"
                        + "}"
                        ;
            }
        };

        area.textProperty().bind(sbind);

    }

    @FXML
    private void mayusculas(KeyEvent event) {
        nombre.textProperty().addListener((ov, oldV, newV) -> {
            if (!(nombre.textProperty().get().isEmpty())) {
                nombreMayus.set(newV.substring(0, 1).toUpperCase());
            } else {
                nombreMayus.set("Nombrevar");
            }
        });
        nombre.textProperty().addListener((ov, oldV, newV) -> {
            if (!(nombre.textProperty().get().isEmpty())) {
                nombreMin.set(newV.substring(1));
            } else {
                nombreMin.set("");
            }
        });
    }

    @FXML
    private void Clean(ActionEvent event) {
        Tipo.textProperty().set("");
        nombre.textProperty().set("");
        tiposhadow.textProperty().set("");
        accesib.textProperty().set("");
    }


}
问题在于:

@FXML
    private void mayusculas(KeyEvent event) {
        nombre.textProperty().addListener((ov, oldV, newV) -> {
            if (!(nombre.textProperty().get().isEmpty())) {
                nombreMayus.set(newV.substring(0, 1).toUpperCase());
            } else {
                nombreMayus.set("Nombrevar");
            }
        });
        nombre.textProperty().addListener((ov, oldV, newV) -> {
            if (!(nombre.textProperty().get().isEmpty())) {
                nombreMin.set(newV.substring(1));
            } else {
                nombreMin.set("");
            }
        });
    }
在这里:

+ "public void set"+ nombreMayus.get() + nombreMin.get()+"("+tiposhadow.textProperty().get()+" "+nombre.textProperty().get()+"){"

当在文本区域中键入第一个字母“Nombrevar”时,nombreMayus.get()会显示,而当键入第二个字母时,它会显示您看到的第一个字母!!!延迟了

onKeyReleased()
事件中添加更改侦听器是不正确的。这样,每当用户在键盘上键入某些内容时,您都会添加一个全新的侦听器

您可能可以这样做:

nombreMayus.bind(() -> nombre.getText().substring(0, 1).toUpperCase(), nombre.textProperty());
nombreMin.bind(() -> nombre.getText().substring(1), nombre.textProperty());

我认为这与以下事实有关:
如果(!(nombre.textProperty().get().isEmpty()){
当你按下第一个字母时,textProperty是空的,一旦你按下第二个字母,它就不再是空的。也许你需要将它延迟到按键释放之后,因为按键事件会记录所有按键结果(上下)第一个结果将是keyDown,所以它会在键按下时看到它是空的。
nombreMayus.bind(() -> nombre.getText().substring(0, 1).toUpperCase(), nombre.textProperty());
nombreMin.bind(() -> nombre.getText().substring(1), nombre.textProperty());