2016-09-26 71 views
1

我正在运行Java 8u102。我有一个模式窗口,其中包含Combobox,其中的项目是从字符串列表创建的FilteredListComboBox是可编辑的,以便用户可以输入文本(自动转换为大写)。弹出的ComboBox中的项目将被过滤,只有那些以输入文本开头的项目才会保留。这很好。JavaFX 8已过滤组合框在弹出窗口单击时抛出IndexOutOfBoundsException

问题是,当您单击筛选弹出窗口中的项目时,所选项目将在组合框编辑器中正确显示,并且弹出窗口将关闭,但会引发IndexOutOfBoundsException,可能从创建窗口的代码开始在线 - stage.showAndWait()。以下是运行ComboBox的代码。

任何解决方法的建议?我打算为组合框添加更多功能,但我想首先处理这个问题。谢谢。

FilteredList<String> filteredList = 
    new FilteredList(FXCollections.observableArrayList(myStringList), p -> true); 
    cb.setItems(filteredList); 
    cb.setEditable(true); 

    // convert text entry to uppercase 
    UnaryOperator<TextFormatter.Change> filter = change -> { 
    change.setText(change.getText().toUpperCase()); 
    return change; 
    }; 
    TextFormatter<String> textFormatter = new TextFormatter(filter); 
    cb.getEditor().setTextFormatter(textFormatter); 

    cb.getEditor().textProperty().addListener((ov, oldValue, newValue) -> { 
    filteredList.setPredicate(item -> { 
     if (item.startsWith(newValue)) { 
      return true; // item starts with newValue 
     } else { 
      return newValue.isEmpty(); // show full list if true; otherwise no match 
     } 
    }); 
    }); 

回答

2

的问题是一样this question:你可以用听众对textProperty内容为Platform.runLater块。

cb.getEditor().textProperty().addListener((ov, oldValue, newValue) -> { 
    Platform.runLater(() -> { 
     filteredList.setPredicate(item -> { 
      if (item.startsWith(newValue)) 
       return true; // item starts with newValue 
      else 
       return newValue.isEmpty(); // show full list if true; otherwise no match 
     }); 
    }); 
}); 

或者使用ternary operator总之形式是相同的:

cb.getEditor().textProperty().addListener((ov, oldValue, newValue) -> Platform.runLater(
     () -> filteredList.setPredicate(item -> (item.startsWith(newValue)) ? true : newValue.isEmpty()))); 
+0

伟大的答案。它支持我的初学者倾向,即当JavaFx中的某些事情有点“愚蠢”时,我是那些不认识并发问题并且应该考虑Platform.runLater(() - > {})的愚蠢者;有趣的是,同一天有人提出类似的问题(并由您回答)。非常感谢。 –

相关问题