0

I am trying to get the Key value of my HashMap from a ComboBox, but every time I use the variable of my ComboBox it just returns the name of the ComboBox: cmbCourse. I want the code to get the key value and save it into my database.

Here is my insertion code

String query2 = ("INSERT INTO tblcourseinfo (user_id, course_id, school_id) VALUES (?,?,?)");
            QueryCourses qc = new QueryCourses();
            HashMap<String, Integer> map = qc.hashMap();
            stmt = conn.prepareStatement(query2);
            System.out.println(cmbCourse);
            System.out.println(cmbSchool);
            stmt.setInt(1, key);
            stmt.setObject(2, cmbCourse.getValue());
            stmt.setObject(3, cmbSchool.getValue());
            stmt.executeUpdate();

this is how I call the HashMap to populate the ComboBoxes

public void populateCourse() throws SQLException, ClassNotFoundException {
    QueryCourses qc = new QueryCourses();
    HashMap<String, Integer> map = qc.hashMap();

    cmbCourse.getItems().setAll(map.keySet());
}

public void populateSchool() throws SQLException {
    QuerySchools qs = new QuerySchools();
    HashMap<String, Integer> map = qs.hashMap();

    cmbSchool.getItems().setAll(map.keySet());
}

and here is the query to populate it

public class QueryCourses {    
public static ArrayList<Courses> getCourses() throws ClassNotFoundException, SQLException {
    String queryCourses = "SELECT course_id, course_title FROM tblcourses";
    Connection conn = DbConnection.ConnectDB();
    Statement stmt = conn.createStatement();
    ResultSet rs;
    rs = stmt.executeQuery(queryCourses);
    ArrayList<Courses> courseList = new ArrayList<>();
    while (rs.next()) {
        Courses crse = new Courses(rs.getInt("course_id"), rs.getString("course_title"));
        courseList.add(crse);
    }
    return courseList;
}

public HashMap<String, Integer> hashMap() throws SQLException, ClassNotFoundException{
    HashMap<String, Integer> map = new HashMap<>();
    try {            
        for (Courses crse : getCourses()) {
            map.put(crse.getCourseTitle(), crse.getCourseId());
        }
    } catch (SQLException ex) {
        Logger.getLogger(NewStudentController.class.getName()).log(Level.SEVERE, null, ex);
    }
    return map;
}
}
  • I'm wondering if `cmbCourse.getItems()` should be `cmbCourse.getValue()` – MadProgrammer Dec 06 '17 at 05:05
  • I tried to use getValue() also but it returns an error of com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect integer value: 'BSIT' for column 'course_id' at row 1 – jansen jordan Dec 06 '17 at 05:08
  • Then I guess it's expecting a `int` value and you're inserting a `String` – MadProgrammer Dec 06 '17 at 05:09
  • Yes it is, how do I get the key value exactly? – jansen jordan Dec 06 '17 at 05:11
  • From what I can understand, `getValue` will return the `courseTitle`, you need to go back to your original `HashMap` and use that value to get the `courseID` from it. I'm not familiar with JavaFX, but, it should support the concept of "renderers", where you can customise how the combobox renders elements, so instead of seeding it with the "key" value, you seed it with the object, this will give you both pieces of information you need to solve your problem – MadProgrammer Dec 06 '17 at 05:13
  • Maybe something like [this](https://stackoverflow.com/questions/13368572/rendering-a-pojo-with-javafx-2s-combo-box-without-overriding-the-tostring-met) or [this](https://stackoverflow.com/questions/19242747/javafx-editable-combobox-showing-tostring-on-item-selection) or [this](https://docs.oracle.com/javafx/2/ui_controls/combo-box.htm) (scroll down to the section on "cell factories") – MadProgrammer Dec 06 '17 at 05:15
  • I don't get how to use this in a HashMap, all the examples are for Lists not ObservableLists. – jansen jordan Dec 06 '17 at 06:01
  • `hashMap().get(cmbCourse.getValue())` - although this is in efficient as it will query the database again – MadProgrammer Dec 06 '17 at 06:02
  • I tried to do another approach which is setting the Integer as key value, in which I realized that key value is not the actual Primary Key itself...which is stupid of me. Now I have the problem of displaying both the key and the value onto my ComboBox or just the value itself. I tried to do it instead of using keySet() I just used values() but it now returns com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'course_id' cannot be null which means that the key is not read. – jansen jordan Dec 06 '17 at 07:35
  • I would debug you code, make sure that the information is been loaded from the database and that your look up is working correctly, OR, just forgo the lookup mechanism altogether and make use a `ListCell` and `cellFactory` to encapsulate the `Course` object directly – MadProgrammer Dec 06 '17 at 09:33

1 Answers1

1

Focusing on the primary issue

How to get the ID of the selected item

This is most easily solved by not using a HashMap and instead, adding the Course object directly to the ComboBox ObservableList and changing the way that the items are rendered.

In this way, you don't need to worry about providing lookups or other fancy pancy solutions, as all the information you need is stored in the Course object itself.

So, I don't have access to your code, so I had to make a few things up, starting with the Course object...

public class Course {

    private long id;
    private String title;

    public Course(long id, String title) {
        this.id = id;
        this.title = title;
    }

    public long getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    @Override
    public String toString() {
        return "Course{" + "id=" + id + ", title=" + title + '}';
    }

}

When that in hand we can create a custom ListCell...

public class CourseCell extends ListCell<Course> {

    @Override
    protected void updateItem(Course item, boolean empty) {
        super.updateItem(item, empty);
        if (item != null) {
            setText(item.getTitle());
        } else {
            setText(null);
        }
    }
}

Then we need to apply the data and renderers together...

// I can imagine this been loaded from a ResultSet
ObservableList<Course> options = FXCollections.observableArrayList(
                new Course(0, "JavaFX"),
                new Course(1, "Swing"),
                new Course(2, "Objective C"),
                new Course(3, "Swift")
);
ComboBox<Course> comboBox = new ComboBox<Course>(options);
comboBox.setCellFactory(new Callback<ListView<Course>, ListCell<Course>>() {
    @Override
    public ListCell<Course> call(ListView<Course> courses) {
        return new CourseCell();
    }
});
comboBox.setButtonCell(new CourseCell());

Then at some point, we need to get the selected value...

Course course = comboBox.getValue();
if (course != null) {
    System.out.println(course);
    System.out.println(course.getId());
}

getValue will now return a Course object, including the title and id, convenient.

Remember, you're dealing with a OO language, where ever possible, maintain the encapsulation of the data, it just makes life so much simpler.

Runnable Example...

This is like only the third JavaFX app I've written, and most of it was gleamed from tutorials, other answers and some blogs, so forgive me any glaring mistakes, I tried to focus on the ListCell implementation

ListCell implementation

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import javafx.util.Callback;

public class Test extends Application {

    @Override
    public void start(Stage primaryStage) {

        GridPane gridPane = new GridPane();

        ObservableList<Course> options = FXCollections.observableArrayList(
                        new Course(0, "JavaFX"),
                        new Course(1, "Swing"),
                        new Course(2, "Objective C"),
                        new Course(3, "Swift")
        );
        ComboBox<Course> comboBox = new ComboBox<Course>(options);
        comboBox.setCellFactory(new Callback<ListView<Course>, ListCell<Course>>() {
            @Override
            public ListCell<Course> call(ListView<Course> courses) {
                return new CourseCell();
            }
        });
        comboBox.setButtonCell(new CourseCell());

        Button btn = new Button();
        btn.setText("Use");
        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                Course course = comboBox.getValue();
                if (course != null) {
                    System.out.println(course);
                    System.out.println(course.getId());
                }
            }
        });

        GridPane.setHalignment(comboBox, HPos.CENTER);
        GridPane.setHalignment(btn, HPos.CENTER);

        gridPane.setAlignment(Pos.CENTER);

        gridPane.add(comboBox, 0, 0);
        gridPane.add(btn, 0, 1);

        Scene scene = new Scene(gridPane, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

    public class CourseCell extends ListCell<Course> {

        @Override
        protected void updateItem(Course item, boolean empty) {
            super.updateItem(item, empty);
            if (item != null) {
                setText(item.getTitle());
            } else {
                setText(null);
            }
        }
    }

    public class Course {

        private long id;
        private String title;

        public Course(long id, String title) {
            this.id = id;
            this.title = title;
        }

        public long getId() {
            return id;
        }

        public String getTitle() {
            return title;
        }

        @Override
        public String toString() {
            return "Course{" + "id=" + id + ", title=" + title + '}';
        }

    }

}
Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366