在我的应用中,TextField双向绑定到窗格的layoutXProperty。文本字段中的任何更改都将立即更新窗格的layoutX。
例如,如果layoutX为500并且删除了最后一个零,则窗格的位置将immediatley跳转到x = 50.同样,如果窗格被拖动,则texfield中的值会反映窗格的layoutX值。
拖动'绑定很好,但现在我想在更新窗格的layoutX之前等待文本字段中的RETURN键(我想先检查有效的边界值)。我已经尝试过ChangeListeners和低级绑定,但无法令它满意地工作。
是否有人对如何实现这一点有任何想法。在我看来,这将是一个共同的行动,但在书籍或网络上有关于此的非常少的信息。 changelistener可以使用绑定事件'?
答案 0 :(得分:1)
只需向更新文本字段的layoutX
属性添加侦听器,并将操作事件的处理程序添加到执行验证的TextField
并更新layoutX
属性。如果用户按Enter键,处理程序将被触发,但之前不会。由于您不希望layoutX
在文本更新时随时更新,因此此处的绑定并不合适。
SSCCE:
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class PaneCoordinatesInTextField extends Application {
@Override
public void start(Stage primaryStage) {
Label draggingLabel = createDraggingLabel();
TextField textField = new TextField();
draggingLabel.layoutXProperty().addListener((obs, oldLayoutX, newLayoutX) ->
textField.setText(newLayoutX.toString()));
textField.setOnAction(e -> {
try {
double x = Double.parseDouble(textField.getText());
if (x < 0) {
x = 0 ;
}
if (x > 400) {
x = 400 ;
}
draggingLabel.setLayoutX(x);
} catch (NumberFormatException exc) {
textField.setText(Double.toString(draggingLabel.getLayoutX()));
}
});
Pane pane = new Pane(draggingLabel);
pane.setMinSize(600, 600);
BorderPane root = new BorderPane(pane, textField, null, null, null);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
private Label createDraggingLabel() {
Label label = new Label("Drag me", new Rectangle(200, 200, Color.CORNFLOWERBLUE));
label.setContentDisplay(ContentDisplay.CENTER);
label.setTextFill(Color.WHITE);
label.setAlignment(Pos.CENTER);
ObjectProperty<Point2D> mouseLocation = new SimpleObjectProperty<>();
label.setOnDragDetected(e -> mouseLocation.set(new Point2D(e.getSceneX(), e.getSceneY())));
label.setOnMouseReleased(e -> mouseLocation.set(null));
label.setOnMouseDragged(e -> {
if (mouseLocation.get() == null) {
return ;
}
double deltaX = e.getSceneX() - mouseLocation.get().getX();
double deltaY = e.getSceneY() - mouseLocation.get().getY();
label.setLayoutX(label.getLayoutX() + deltaX);
label.setLayoutY(label.getLayoutY() + deltaY);
mouseLocation.set(new Point2D(e.getSceneX(), e.getSceneY()));
});
return label;
}
public static void main(String[] args) {
launch(args);
}
}
答案 1 :(得分:0)
我找到了'a'解决方案,但它似乎更像是一个kludge。
我将onMouseClicked和onActon处理程序附加到文本字段。
在onMouseClicked的文本字段中,我取消绑定文本字段并等待按下RETURN键。在onAction中,我使用新的文本字段值更新先前绑定的值,然后再次双向绑定它。瞧......它有效。
我可以在onAction处理程序中检查有效值。
但就像我说的那样,它似乎有点像一个极限的解决方案。有人关心评论吗?