为什么在使用change listener时,JavaFx应用程序中的大写字母会延迟?
我在JavaFx上有一个简单的应用程序,它为javafxbean创建了惰性实例化器,这个应用程序完全是gui,它只有一个fxml和一个main类为什么在使用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
<?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());