问题
lets say that I have two models. Teacher and Students and each Student can have one Teacher (not several). So I want to have an combo box on my student pane where I can select one teacher.
Both models are also stored in the database and I want only the database ID of the teacher to be in the model of the student but inside the combo box the name of the teacher should appear.
Also the model should be binded to the combo box, so if somebody changed the teacher in the combobox, the model (of the student) should be refreshed as well. With textfields I can bind them to StringProperty objects, but in this case I need to bind the comboxbox item (Teacher.java) to an interger-property inside my Student.java.
I also thought about having the teacher-model as a property inside my student class, but I think that will not help, because then I need to bind the combobox item (teacher.java) with a teacher object inside my student model but only property objects can be binded.
Teacher.java
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class Teacher {
private Integer databaseID;
private StringProperty name = new SimpleStringProperty();
private IntegerProperty age = new SimpleIntegerProperty();
public Teacher (Integer databaseID) {
// load data from database and fill into model
}
public void store() {
// write model to database
}
// getters and setters ...
@Override
public String toString() {
return name.get();
}
@Override
public boolean equals(Object obj) {
// compare databaseIDs ...
return true;
}
}
Student.java
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class Student {
private Integer databaseID;
private StringProperty name = new SimpleStringProperty();
private Integer teacherID;
public Student (Integer databaseID) {
// load data from database and fill into model
}
public void store() {
// write model to database
}
// getters and setters ...
@Override
public String toString() {
return name.get();
}
@Override
public boolean equals(Object obj) {
// compare databaseIDs ...
return true;
}
}
Application.java
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class TestApplication extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
Student student = new Student(4711);
ComboBox<Teacher> teachers = new ComboBox<Teacher>();
fillTeacherComboBox(teachers);
// TODO: select the teacher from the student by default
// FIXME: Binding student.databaseID <--> ComboBox-Item.databaseID
StackPane root = new StackPane();
root.getChildren().add(teachers);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
private void fillTeacherComboBox(ComboBox<Teacher> teachers) {
// TODO: Load data from database and fill teacher combo box
}
}
回答1:
I would make (at least) one change to the design here: store a reference to the Teacher
object in the Student
object (and use a JavaFX property to do it):
public class Student {
private Integer databaseID;
private StringProperty name = new SimpleStringProperty();
private ObjectProperty<Teacher> teacher = new SimpleObjectProperty<>();
public Student (Integer databaseID) {
// load data from database and fill into model
/* Just as an aside, it is really bad practice to include
database code in your domain objects as you suggest here.
You should create a separate class that manages the database
code (a DataAccessObject) and the domain objects Student and
Teacher should be completely agnostic as to the mechanism by
which they are persisted (or even whether they are persisted).*/
}
public void store() {
// write model to database
// see above comment.
}
// getters and setters ...
public ObjectProperty<Teacher> teacherProperty() {
return teacher ;
}
public final Teacher getTeacher() {
return teacherProperty().get();
}
public final void setTeacher(Teacher teacher) {
teacherProperty().set(teacher);
}
@Override
public String toString() {
return name.get();
}
@Override
public boolean equals(Object obj) {
// compare databaseIDs ...
return true;
}
}
And now you just do
Student student = ... ;
ComboBox<Teacher> teachers = new ComboBox<>();
// populate combo box...
teachers.valueProperty().bindBidirectional(student.teacherProperty());
回答2:
You Can try one of these:(worked for me)
semesterBoxDay.selectionModelProperty().bind(semesterBox.selectionModelProperty());
When change 1st one 2d one change and verse happen,I know this is odd i don't know if there's explain for that (it work like bindBidirectional() here)
semesterBoxDay.valueProperty().bindBidirectional(semesterBox.valueProperty());
when i use bind() here i can't change the 2d one value until i change the 1st one
(i think because the 2d one value will never change untill u set it but i don't know why not change if click the new item in list). if anyone have answer for these problems i hope he could write them .
来源:https://stackoverflow.com/questions/34506662/javafx-combobox-binding