2016-12-01 6 views
1

Итак, у меня есть база данных, содержащая таблицу с несколькими параметрами, одна из которых - «тип» (ТЕКСТ). Im наполнение ComboBox с этим «типа» с этим методом:JavaFX ComboBox работает с задержкой

public void loadTypefromDB() 
{ 
    types = FXCollections.observableArrayList(); 
    try{ 
     ResultSet rs = conn.createStatement().executeQuery("SELECT type FROM Products"); 
     while(rs.next()){ 
      String product = rs.getString("type"); 
      types.add(product); 
     } 
    } 
    catch (SQLException e) { 
     e.printStackTrace(); 
    } 
    choiceBox.setItems(types); 
} 

тогда я использую этот ComboBox, чтобы показать все элементы выбранного типа в TableView.

public void choiceType(ActionEvent event) 
{ 
    choiceBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() { 
     @Override 
     public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) { 
      loadTypeDataFromDB(newValue.toString()); 
     } 
    }); 
} 

и здесь метод loadTypeDataFromDB, который выполняет запрос с выбранным параметром

public void loadTypeDataFromDB(String type){ 
    products = FXCollections.observableArrayList(); 

    try { 
     PreparedStatement pst = conn.prepareStatement("SELECT name, kcal, protein, carb, fat FROM Products WHERE type=?"); 
     pst.setString(1, type); 
     ResultSet rs = pst.executeQuery(); 

     while(rs.next()){ 
      products.add(new productData(rs.getString("name"), rs.getString("kcal"), rs.getString("protein"), rs.getString("carb"), rs.getString("fat"))); 
     } 
    } 
    catch (SQLException e) { 
     e.printStackTrace(); 
    } 

    colProduct.setCellValueFactory(new PropertyValueFactory<productData, String>("name")); 
    colKcal.setCellValueFactory(new PropertyValueFactory<productData, String>("kcal")); 
    colProtein.setCellValueFactory(new PropertyValueFactory<productData, String>("protein")); 
    colCarbs.setCellValueFactory(new PropertyValueFactory<productData, String>("carb")); 
    colFat.setCellValueFactory(new PropertyValueFactory<productData, String>("fat")); 

    tableProduct.setItems(null); 
    tableProduct.setItems(products); 
} 

Это ПОЧТИ работает правильно. Я запускаю свое приложение, выбираю один из типов из ComboBox, и ничего не происходит (TableView остается чистым). Затем я выбираю другой тип из этого ComboBox, и вдруг он показывает элементы этого типа в TableView, и с этого момента я могу отображать все типы, которые я хочу, все работает. Таким образом, похоже, что первый выбор из ComboBox - null (я не получаю никаких исключений tho). После первого выбора все начинает работать правильно ...

+0

Если вы отладки, является 'changed' метод, названный по первым обновлением ? IE: Вы действительно получаете событие изменения, и метод загрузки не работает, или проблема в том, что поле со списком ничего не сообщает? – Ironcache

ответ

1

Ваша установка ChangeListener кажется сомнительной для меня, и, вероятно, источник ваших проблем (хотя, я не могу знать наверняка, не видя больше коды):

public void choiceType(ActionEvent event) 
{ 
    choiceBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() { 
     @Override 
     public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) { 
      loadTypeDataFromDB(newValue.toString()); 
     } 
    }); 
} 

Где вы называете этот метод? В качестве входа требуется ActionEvent; вы не настраиваете своего слушателя до после Вы получаете событие? Потому что это наверняка объясняет, почему вы не видите первый.

Рассмотрим настройки слушателя после добавления продуктов (еще лучше, где вы создаете ComboBox), и посмотреть, если это помогает:

public void loadTypefromDB() 
{ 
    types = FXCollections.observableArrayList(); 
    try{ 
     ResultSet rs = conn.createStatement().executeQuery("SELECT type FROM Products"); 
     while(rs.next()){ 
      String product = rs.getString("type"); 
      types.add(product); 
     } 
    } 
    catch (SQLException e) { 
     e.printStackTrace(); 
    } 
    choiceBox.setItems(types); 
    choiceBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() { 
     @Override 
     public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) { 
      loadTypeDataFromDB(newValue.toString()); 
     } 
    }); 
} 
+0

Ну, я вызывал метод choiceType с помощью ComboBox onAction (в Scene Builder). Iv сделал, как и предложил, переместил его в loadTypefromDB() , и теперь он отлично работает. Благодаря! – AGasior

+1

Вы все равно можете использовать вызов 'onAction' из SB, чтобы вызывать метод' choiceType', но если вы это сделаете **, не ** создавайте прослушиватель изменений в методе 'choiceType'. Связывание 'onAction' от SB ** является ** вашим слушателем изменений. Вместо этого, в методе 'choiceType', проверьте текущее значение combobox и передайте это значение в свой метод' load ... (String). – Ironcache