2016-08-07 20 views
1

我有一个可过滤的ComboBox填充自定义Subjekt对象。自定义对象的可编辑组合框重写下拉列表中的项目

过滤列表从数据库使用SubjektDAO.searchSubjectsByName()方法填充。

增加了对ComboBox的编辑器的监听器,并使用cbNazivKupca.show()方法在我开始键入时自动打开下拉列表(填充并显示)。当我从列表中选择项目(让我们说“亚伯拉罕”),改变它的值在ComboBox textfield(可以说是“abrah”),然后单击其他地方(所以ComboBox失去焦点)“下拉列表”值出现在下拉列表中,我松开了原始值。

我需要禁用在列表中输入新的值(我可以通过设置combobox不可编辑来实现这一点),但我有大量的滚动。

此外,如果我点击按钮来显示列表中的项目,并点击第一个在线它填充文本框中,但如果我点击第二或一些接下来我需要点击他两次(这只发生一次) 。

我不知道如何解决这个问题,即时通讯新的JavaFX和学习。

请帮忙。

try { 

    final FilteredList<Subjekt> filteredItems = new FilteredList<>(SubjektDAO.searchSubjectsByName(), p -> true); 

    cbNazivKupca.getEditor().textProperty().addListener((obs, oldValue, newValue) -> { 


     cbNazivKupca.show(); 

     final TextField editor = cbNazivKupca.getEditor(); 
     final Subjekt selected = cbNazivKupca.getSelectionModel().getSelectedItem(); 


    /* 
    This needs run on the GUI thread to avoid the error described 
    here: https://bugs.openjdk.java.net/browse/JDK-8081700. 
    */ 

     Platform.runLater(() -> { 

     /* 
     If the no item in the list is selected or the selected item 
     isn't equal to the current input, we refilter the list. 
     */ 
      if (selected == null || !selected.toString().equals(editor.getText())) { 
       filteredItems.setPredicate(item -> { 
        cbNazivKupca.setVisibleRowCount(10); 
        // We return true for any items that contains the 
        // same letters as the input. We use toUpperCase to 
        // avoid case sensitivity. 
        if (item.getSubjekt_naziv().toUpperCase().contains(newValue.toUpperCase())) { 
         return true; 
        } else { 
         return false; 
        } 
       }); 
      } 
     }); 
    }); 

    cbNazivKupca.setItems(filteredItems); 
} catch (SQLException | ClassNotFoundException e) { 
    e.printStackTrace(); 
} 


// rendering of the list of values in ComboBox drop down. 
cbNazivKupca.setCellFactory((comboBox) -> { 
    return new ListCell<Subjekt>() { 
     @Override 
     protected void updateItem(Subjekt subjekt, boolean empty) { 
      super.updateItem(subjekt, empty); 

      if (subjekt == null || empty) { 
       setText(null); 
      } else { 
       setText(subjekt.getSubjekt_naziv()); 
      } 
     } 
    }; 
}); 

cbNazivKupca.setConverter(new StringConverter<Subjekt>() { 
    @Override 
    public String toString(Subjekt subjekt) { 
     if (subjekt == null) { 
      return null; 
     } else { 
      return subjekt.getSubjekt_naziv(); 
     } 
    } 

    @Override 
    public Subjekt fromString(String productString) 
    { 
     if(cbNazivKupca.getValue() != null) 
     { 
      ((Subjekt)cbNazivKupca.getValue()).setSubjekt_naziv(productString); 

      return (Subjekt)cbNazivKupca.getValue(); 
     } 
     return null; 

    } 

}); 

EDITED:我已经缩小的问题的cbNazivKupca.setConverter fromString法源,但即时通讯坚持我需要检查,如果cbNazivKupca.getValue()出现在下拉列表中。

EDITED:我来到了类似的解决方案也是如此,但令我感到困惑的事情是: 当我在下拉按钮点击和项目被列出,如果我点击第一个在列表它被复制到可编辑的一部分,但如果我点击其他任何编辑器获取光标,是空的,如果我再次单击它,一切都很好,这只发生一次。

回答

0

您的转换器的fromString方法无效。的this method的目的是为了与通用参数类型的StringConverter,没有别的类型返回一个对象:

提供进入由特定 转换器定义的对象转换为字符串。字符串的格式和结果对象的类型是由特定转换器定义的 。

所以在这种方法中,你不应该得到选择的项目,更糟的是你不应该修改选定的项目,实际上这是你的下拉列表中的项目被修改的原因。

当您键入ComboBox的编辑器时,使用fromString方法,然后根据您输入到编辑器中的字符串(输入参数)按Enter键找出应选择哪个项目(该项目的方法返回)的方法)。

你应该做的是从ComboBox的项目得到corresposing Subject实例,如:

@Override 
public Subjekt fromString(String productString) { 
    return cbNazivKupca.getItems().stream().filter(item -> productString.equals(item.getSubjekt_naziv())).findFirst().orElse(null); 
} 

这将从项目中ComboBox其中subjekt_naziv成员返回的第一个元素是一样的指定的String;如果匹配不可能,则返回null。

相关问题