2017-12-28 43 views
0

Hier ist der Code, was ich unterstützt zu erreichen bin versucht:So binden Sie einen Ereignis-Listener an JavaFX TextFields in einem Dialogfeld. Wenn die Felder leer sind, wird die OK-Taste deaktiviert und umgekehrt

Dialog Controller-Code:

public class DialogController { 
@FXML private TextField firstName; 
@FXML private TextField lastName; 
@FXML private TextField phoneNumber; 
@FXML private TextField notes; 
@FXML private DialogPane dialogPane; 

//All getters defined here 

public void keyReleasedHandler(){ 
    Boolean firstNameEmpty = (firstName.getText().isEmpty() || firstName.getText().trim().isEmpty()); 
    Boolean lastNameEmpty = (lastName.getText().isEmpty() || lastName.getText().trim().isEmpty()); 
    Boolean phoneNumberEmpty = (phoneNumber.getText().isEmpty() || phoneNumber.getText().trim().isEmpty()); 
    if (firstNameEmpty || lastNameEmpty || phoneNumberEmpty){ 
     //When the dialog box opens and I type or a delete a letter from any of the event binded fields, a null pointer exception is thrown 
     dialogPane.lookupButton(ButtonType.OK).setDisable(true); 
    } 
    dialogPane.lookupButton(ButtonType.OK).setDisable(false); 
} 

public Contact processResults(){ 
    String firstName = getFirstName().getText().trim(); 
    String lastName = getLastName().getText().trim(); 
    String phoneNumber = getPhoneNumber().getText().trim(); 
    String notes = getNotes().getText().trim(); 

    return new Contact(phoneNumber, firstName, lastName, notes); 
}} 

Relevante Methode und UI-Definitionen von meinem Haupt-Controller:

public class Controller { 
@FXML private TableView<Contact> tableView; 
@FXML private BorderPane mainBorderPane; 

public void handleNewContact(){ 
    Dialog<ButtonType> dialog = new Dialog<>(); 
    dialog.initOwner(mainBorderPane.getScene().getWindow()); 
    dialog.setTitle("Add a new contact to your list"); 
    dialog.setHeaderText("Use this dialog to create a new contact"); 
    FXMLLoader loader = new FXMLLoader(); 
    loader.setLocation(getClass().getResource("dialogWindow.fxml")); 
    try { 
     dialog.getDialogPane().setContent(loader.load()); 
    } catch (IOException e) { 
     System.out.println("Couldn't load the dialog"); 
     e.printStackTrace(); 
     return; 
    } 

    dialog.getDialogPane().getButtonTypes().add(ButtonType.OK); 
    dialog.getDialogPane().getButtonTypes().add(ButtonType.CANCEL); 

    Optional<ButtonType> result = dialog.showAndWait(); 

    if (result.isPresent() && result.get() == ButtonType.OK){ 
     DialogController controller = loader.getController(); 
     Contact contact = controller.processResults(); 
     contactData.addContact(contact); 
     tableView.getSelectionModel().select(contact); 
    } 
} 

Mein Denkprozess hinter dem keyReleasedHandler() ist, dass die Validierung für meine Textfelder in meinem ‚neuen Kontakt Dialog‘ funktionieren wird. In meinem Hauptcontroller habe ich die Erstellung der Benutzeroberfläche des Dialogs über seine FXML bearbeitet und die ButtonTypes OK und Cancel im Code manuell hinzugefügt. Ich habe alle Dialog TextFields onKeyReleased an meine keyReleasedHandler() gebunden. Immer, wenn ich etwas in meine 'validierten' Felder eintippe, wird eine Nullzeiger-Ausnahme ausgelöst (ich gehe davon aus, dass die Lookup-Methode von dialogPane irgendwie null zurückgibt).

Alternative Implementierungen für diese Validierungsfunktion würden ebenfalls sehr geschätzt werden.

Antwort

2

Was Sie tun, sieht wie eine Swing-Implementierung aus. Mit der Bindung kann viel getan werden.

Was auch immer Sie in keyReleasedHandler() tun, können Sie mit diesem ersetzen:

dialogPane.lookupButton(ButtonType.OK).disableProperty() 
    .bind(Bindings.createBooleanBinding(
     () -> firstName.getText().trim().isEmpty() || 
       lastName.getText().trim().isEmpty() || 
       phoneNumber.getText().trim().isEmpty(), 
     firstName.textProperty(), 
     lastName.textProperty(), 
     phoneNumber.textProperty() 
    )); 

Dadurch wird die Taste deaktiviert werden, wenn eine der drei TextField leeren Text hat.

Einige Randnotizen (nicht wirklich auf die Antwort im Zusammenhang):

  • getText().isEmpty() nicht wirklich, da Sie getText().trim().isEmpty() haben benötigt wird, obwohl es schneller sein kann wohl, dass aufzunehmen.
  • In Ihrer Frage haben Sie verwendet, um einen booleschen Wert zu speichern. Es ist definitiv besser, den primitiven Typ boolean zu verwenden.
+0

Hallo, vielen Dank für die Beantwortung meiner Frage. Ich habe den Code implementiert, den Sie in meinem SchlüsselReleasedHandler() angegeben haben, und er wirft immer noch eine Nullzeigerausnahme. Irgendeine Idee was könnte das verursachen? –

+0

@JustinHernandez Sie müssen uns sagen, wo (im Code) das passiert. Beachten Sie außerdem, dass Sie Ihre Schlüsselereignisse jetzt wirklich entfernen sollten, wenn Sie Bindung verwenden. – Jai

+0

@JustinHernandez Der Code in dieser Antwort soll * den 'keyReleasedHandler' ersetzen. Sie brauchen nur diese Bindung, Sie brauchen den Handler überhaupt nicht. (Abgesehen davon, dass dies sauberer ist, versucht Ihr Ansatz nicht einmal, den Fall des Einfügens von Text mit der Maus durch den Benutzer zu behandeln.) –

Verwandte Themen