2016-06-20 5 views
0

Ich habe eine ComboBox, die die eingestellten Werte auflistet. Ich habe es bearbeitbar gemacht mit setEditable (true) Methode, aber wie bekomme ich den Wert vom Benutzer eingegeben? Ich habe versucht, getSelectionModel(). GetSelectedItem() und getValue() -Methode aber nicht erfolgreich.Wie wird der Wert in editierbare ComboBox in JavaFx eingegeben?

Hier ist der Code.

public class Comparator extends Application { 

    @Override 
     public void start(Stage stage) { 
     stage.setTitle("ComboBoxSample"); 
     Scene scene = new Scene(new Group(), 450, 250); 

     ComboBox<String> emailComboBox = new ComboBox<>(); 
     emailComboBox.getItems().addAll("A","B","C","D","E"); 

     emailComboBox.setEditable(true);   

     Button b = new Button("get text"); 

     GridPane grid = new GridPane(); 
     grid.setVgap(4); 
     grid.setHgap(10); 
     grid.setPadding(new Insets(5, 5, 5, 5)); 
     Label to = new Label("To: "); 
     Label selected = new Label(); 
     grid.add(to, 0, 0); 
     grid.add(emailComboBox, 1, 0); 
     grid.add(b, 2, 0); 
     grid.add(selected, 3, 0); 

     b.setOnAction(e -> { 
      selected.setText(emailComboBox.????); 
     }); 

     Group root = (Group) scene.getRoot(); 
     root.getChildren().add(grid); 
     stage.setScene(scene); 
     stage.show(); 
     } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

Ich möchte eigentlich den neu eingegebenen Wert erhalten. PS: Nur um die Verwirrung zu vermeiden, wenn für den Fall. Ich kann einen beliebigen String eingeben, der in der Liste nicht existiert. Dies wird ein neuer Wert sein.

+0

Was bedeutet "nicht gelungen" bedeuten? 'emailComboBox.getValue()' sollte gut funktionieren. Was geschieht? –

+0

Wenn ich Text eingeben und auf die Schaltfläche klicke, wird nichts angezeigt. – Ajeetkumar

+0

Geben Sie den Wert durch Drücken der Eingabetaste ein, nachdem Sie ihn eingegeben haben? –

Antwort

3

Standardmäßig "committen" die meisten JavaFX-Steuerelemente keinen Wert beim Verlieren des Fokus - also TextField s, wenn sie als Bearbeitungssteuerelemente in einem größeren Steuerelement wie ComboBox verwendet werden, übergeben Sie den Wert nicht an das übergeordnete Steuerelement es sei denn, der Benutzer drückt Geben Sie ein. Es gibt eine Menge Kontroversen über diese Design-Entscheidung: Wie auch immer die Entscheidung getroffen wurde, und wenn wir JavaFX verwenden wollen, müssen wir dies entweder akzeptieren oder Wege finden, um es zu umgehen, um das gewünschte Verhalten zu erzielen.

One „quick and dirty“ -Ansatz in das Textfeld zu graben wäre und den Text von ihm, wie in @ Ajeetkumar Antwort erhalten:

selected.setText(emailComboBox.getEditor().getText()); 

Das Problem bei diesem Ansatz ist, dass es verläßt die Anwendung in einem inkonsistenten Zustand: Der Wert, der dem Benutzer im Label angezeigt wird, ist nicht der Wert, der im Modell des Kombinationsfelds enthalten ist. Mit anderen Worten: emailComboBox.getValue() gibt einen anderen Wert als den im Label angezeigten zurück (seit dem Wert aus dem Textfeld wurde nie in die Combobox übernommen). Zu einem bestimmten Zeitpunkt muss Ihre Anwendung die angezeigten Daten verarbeiten, und der natürliche Ort, an dem der Programmierer (oder ein anderes Mitglied des Teams) nach den Daten sucht, befindet sich im Modell der Combobox: d. H., Sie erwarten, dass sich die Daten in emailComboBox.getValue() befinden. Ein besserer Ansatz besteht darin, sicherzustellen, dass der Wert des Kombinationsfelds aktualisiert wird, wenn Sie es möchten, und dann einfach das erwartete emailComboBox.getValue() verwenden, um die Daten abzurufen.

emailComboBox.getEditor().focusedProperty().addListener((obs, wasFocused, isNowFocused) -> { 
     if (! isNowFocused) { 
      emailComboBox.setValue(emailComboBox.getEditor().getText()); 
     } 
    }); 

und dann die natürliche:

Zum Beispiel könnten Sie den Wert aktualisieren, wenn das Textfeld den Fokus verliert

b.setOnAction(e -> { 
     selected.setText(emailComboBox.getValue()); 
    }); 

Mit diesem Ansatz ist die Anwendung immer in einem konsistenten Zustand : dh das Etikett zeigt den Wert des Kombinationsfelds an, was weit weniger wahrscheinlich ist, später Fehler zu verursachen, als das Etikett direkt aus dem Textfeld zu setzen.

Eine weitere Variante ist die Combo-Box-Wert, sobald der Text in den Editor Änderungen zu aktualisieren:

emailComboBox.getEditor().textProperty().addListener((obs, oldText, newText) -> { 
     emailComboBox.setValue(newText); 
    }); 

Beachten Sie, dass, wenn Sie mit dieser Version wollten Sie eigentlich mit der Taste ganz verzichtet werden könnte und nur direkt an den Wert binden den Text der Bezeichnung des Kombinationsfelds:

import javafx.application.Application; 
import javafx.geometry.Insets; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.control.ComboBox; 
import javafx.scene.control.Label; 
import javafx.scene.layout.GridPane; 
import javafx.stage.Stage; 

public class Comparator extends Application { 

    @Override 
     public void start(Stage stage) { 
     stage.setTitle("ComboBoxSample"); 
     Scene scene = new Scene(new Group(), 450, 250); 

     ComboBox<String> emailComboBox = new ComboBox<>(); 
     emailComboBox.getItems().addAll("A","B","C","D","E"); 

     emailComboBox.setEditable(true);   

     emailComboBox.getEditor().textProperty().addListener((obs, oldText, newText) -> { 
      emailComboBox.setValue(newText); 
     }); 


     GridPane grid = new GridPane(); 
     grid.setVgap(4); 
     grid.setHgap(10); 
     grid.setPadding(new Insets(5, 5, 5, 5)); 
     Label to = new Label("To: "); 
     Label selected = new Label(); 
     grid.add(to, 0, 0); 
     grid.add(emailComboBox, 1, 0); 
     grid.add(selected, 2, 0); 

     selected.textProperty().bind(emailComboBox.valueProperty()); 

     Group root = (Group) scene.getRoot(); 
     root.getChildren().add(grid); 
     stage.setScene(scene); 
     stage.show(); 
     } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

die Integrität der Daten zu halten, ist für die Führung der Anwendung sehr zu empfehlen konsistent und macht es weniger wahrscheinlich, dass Fehler einführen später, so ist es sehr empfohlen zu aktualisieren Kamm o Die value Eigenschaft der Box enthält den Wert, den Sie darstellen möchten, und verweist dann auf diesen Wert. Das Textfeld, das als Editor verwendet wird, ist eigentlich ein Implementierungsdetail des Kombinationsfelds, das nur dazu verwendet werden sollte, das Verhalten des Kombinationsfeld-Bearbeitungsprozesses zu ändern: In diesem Beispiel wird das Aktualisierungsverhalten geändert - Sie können auch ein Formatierungsprogramm aktivieren es usw. Es sollte nicht als Stellvertreter für das Modell verwendet werden, da dies das Leben später schwierig machen wird.

+0

Vielen Dank James_D – Ajeetkumar

+0

@Ajeetkumar seit fx9, commit-on-focuslost ist Standardverhalten für alle bearbeitbaren Eingabe-Komponenten (Combo, Spinner, datePicker) - siehe https://bugs.openjdk.java.net/browse/JDK-8150946 Für commit-on-typing, Sie benötigen immer noch einen changeListener für die textProperty des Editors, der Änderungen festschreibt, wie James es vorgeschlagen hat – kleopatra

-1

Sie können die folgende Codezeile verwenden, um den ausgewählten Wert in der ComboBox zu bekommen, und setzen Sie in auf dem Label:

selected.setText(emailComboBox.getValue()); 

Da Sie Strings verwenden, sollten Sie setzen auch die parametrisierte Typ die ComboBox wie folgt:

ComboBox<String> emailComboBox = new ComboBox<>(); 
+0

Ich habe das versucht. es funktioniert nicht. – Ajeetkumar

+0

Haben Sie den Typ der 'ComboBox' wie vorgeschlagen korrigiert? Es wird nicht funktionieren, wenn Sie das nicht tun. –

+0

Ich habe das versucht. es funktioniert immer noch nicht – Ajeetkumar

1

bekam ich die Antwort.

emailComboBox.getEditor(). GetText()

das Textfeld ein, wo wir in einem bearbeitbaren ComboBox geben als Editor bekannt der ComboBox. Und es ist ein normales TextField-Objekt. Um auf dieses Objekt zuzugreifen, müssen Sie die Methode ComboBox.getEditor() verwenden. Auf diese Weise können Sie die Methoden der TextField-Klasse verwenden.

+0

weiß nicht, warum dies abgelehnt wurde. Das funktioniert für mich. keine anderen Antworten funktionierten für mich. – Ajeetkumar

+0

Grund für den Downvote bitte! Für mich geht das. – Ajeetkumar

+0

Das ist wahrscheinlich eine schlechte Idee. Wenn der Editor den Wert nicht festgeschrieben hat, befinden Sie sich in einer Situation, in der sich der Text in der Beschriftung von dem Wert unterscheidet, der in dem Kombinationsfeld enthalten wird. Da Sie anstreben, dass der Text des Labels dem Wert des Kombinationsfelds entspricht, bedeutet dies im Wesentlichen, dass sich Ihre Anwendung in einem inkonsistenten Zustand befindet. Ob dies zu tatsächlichen Problemen führt oder nicht, hängt davon ab, was Ihre Anwendung ausführt und von Ihren tatsächlichen Anforderungen. Selbst wenn die aktuellen Anforderungen dies nicht zu einem Problem machen, können Sie später Funktionen hinzufügen und feststellen, dass dies Probleme verursacht. –

0

Dies wird die Liste ändern, wie Sie den Wert Editor ändern

pluginConfig.getEditor().textProperty().addListener((obs, oldText, newText) -> { 
     if (pluginConfig.getSelectionModel().getSelectedIndex() >= 0) 
      pluginConfig.getItems().set(pluginConfig.getSelectionModel().getSelectedIndex(),newText); 
    }); 
-1

Versuchen Sie folgendes:

String surName=cmbSurName.getSelectionModel().getSelectedItem().toString(); 
System.out.println(surName);