JavaFX ComboBox绑定 [英] JavaFX ComboBox binding

查看:974
本文介绍了JavaFX ComboBox绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想说我有两个型号。老师和学生以及每个学生可以有一位教师(不是几位)。所以我希望在我的学生窗格中有一个组合框,我可以选择一位老师。



两个模型也存储在数据库中,我只想要数据库ID老师要在学生的模型中但在组合框内应该出现老师的名字。



此外,模型应绑定到组合框,所以如果有人改变了组合框中的老师,那么(学生的)模型也应该更新。使用textfields我可以将它们绑定到StringProperty对象,但在这种情况下,我需要将comboxbox项(Teacher.java)绑定到Student.java中的interger-property。



<我还考虑过将老师模型作为学生班级内的一个属性,但我认为这无济于事,因为我需要将组合框项目(teacher.java)与学生模型中的教师对象绑定,但是只有属性对象可以绑定。



Teacher.java

  import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

公共类教师{

private Integer databaseID;

private StringProperty name = new SimpleStringProperty();

private IntegerProperty age = new SimpleIntegerProperty();


公共教师(整数databaseID){
//从数据库加载数据并填入模型
}

public void store( ){
//将模型写入数据库
}

// getter和setter ...

@Override
public String toString (){
return name.get();
}

@Override
public boolean equals(Object obj){
//比较databaseIDs ...
返回true;
}
}

Student.java

  import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty;

公共班学生{

private Integer databaseID;

private StringProperty name = new SimpleStringProperty();

private Integer teacherID;


public Student(整数databaseID){
//从数据库加载数据并填入模型
}

public void store( ){
//将模型写入数据库
}

// getter和setter ...

@Override
public String toString (){
return name.get();
}

@Override
public boolean equals(Object obj){
//比较databaseIDs ...
返回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;

公共类TestApplication扩展Application {

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

@Override
public void start(Stage primaryStage){

学生=新学生(4711);

ComboBox< Teacher> teachers = new ComboBox< Teacher>();
fillTeacherComboBox(老师);

// TODO:默认情况下从学生中选择教师

// FIXME:绑定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>老师){
// TODO:从数据库加载数据并填充教师组合框
}


}


解决方案

我会在此处对(至少)设计进行一次更改:在 Student 对象中存储对 Teacher 对象的引用(并使用JavaFX属性来执行此操作):

  public class Student {

private Integer databaseID;

private StringProperty name = new SimpleStringProperty();

私人ObjectProperty<老师> teacher = new SimpleObjectProperty<>();


公共学生(整数数据库ID){
//从数据库加载数据并填入模型

/ *顺便说一下,它是非常糟糕的做法是在你的域对象中包含
数据库代码,如你所建议的那样。
您应该创建一个单独的类来管理数据库
代码(一个DataAccessObject)和域对象Student和
教师应该完全不知道机制是否为
它们是什么持久化(甚至是否持久化)。* /
}

public void store(){
//将模型写入数据库

/ /见上面的评论。
}

// getter and setters ...

public ObjectProperty< Teacher> teacherProperty(){
返回老师;
}

公共最终教师getTeacher(){
return teacherProperty()。get();
}

public final void setTeacher(教师老师){
teacherProperty()。set(teacher);
}

@Override
public String toString(){
return name.get();
}

@Override
public boolean equals(Object obj){
//比较databaseIDs ...
返回true;
}
}

现在你只需

 学生= ...; 
ComboBox< Teacher> teachers = new ComboBox<>();
//填充组合框...
teachers.valueProperty()。bindBidirectional(student.teacherProperty());


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
    }


}

解决方案

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());

这篇关于JavaFX ComboBox绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆