我创建了一个(JavaFX)组合框,我在其中填充了一个由 HBoxes 制作的可观察列表,这样我就可以在每个列表中显示一些带有文本的图像列表单元格。
这显示得很好,除了每当您选择列表中的一个项目时,它将消失。一旦选择了每个项目,它就不会呈现任何项目。 (您仍然可以通过点击之前的空格来选择它们。
你知道我怎么纠正这个吗?
我的部分代码显示如下:
public class IconListComboBox {
Group listRoot = new Group();
VBox mainVBox = new VBox();
ComboBox selectionBox = new ComboBox();
List<HBox> list = new ArrayList<HBox>();
ListView<HBox> listView = new ListView<HBox>();
ObservableList<HBox> observableList;
public IconListComboBox(int dimensionX, int dimensionY, ArrayList<String> names, ArrayList<ImageView> icons)
{
//VBox.setVgrow(list, Priority.ALWAYS);
selectionBox.setPrefWidth(dimensionY);
selectionBox.setPrefHeight(40);
for(int i = 0; i < names.size(); i++)
{
HBox cell = new HBox();
Label name = new Label(names.get(i));
Label icon = new Label();
icon.setGraphic(icons.get(i));
name.setAlignment(Pos.CENTER_RIGHT);
icon.setAlignment(Pos.CENTER_LEFT);
icon.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(icon, Priority.ALWAYS);
cell.getChildren().add(icon);
cell.getChildren().add(name);
list.add(cell);
}
observableList = FXCollections.observableList(list);
listView.setItems(observableList);
listView.setPrefWidth(dimensionX);
selectionBox.setMaxWidth(dimensionX);
listView.setMaxWidth(dimensionX);
selectionBox.setItems(observableList);
mainVBox.getChildren().add(selectionBox);
mainVBox.getChildren().add(listRoot);
//mainVBox.getChildren().add(listView);
//listRoot.getChildren().add(listView);
}
预先感谢您的协助!
答案 0 :(得分:3)
这正是documentation中引用的示例&#34;关于将节点插入ComboBox项目列表的警告&#34;。
组合框中的项目列表应表示数据 - 而不是用于显示数据的UI组件。问题是HBox
在场景图中不能出现两次:因此它不会出现在&#34;选定的单元格中。并作为下拉列表中的单元格。
相反,创建一个表示您在ComboBox
中显示的数据的类,并使用单元工厂指示ComboBox
如何显示这些数据。请务必同时设置一个按钮单元格(用于所选项目的单元格)。
答案 1 :(得分:3)
好的,所以我设法解决了这个问题,感谢@James_D非常友好的帮助!
对于像我这样的人,在Java文档中给出的示例稍微有些畏惧。 (虽然,我的描述可能更糟糕!!)
所以,我开始添加HBox
,这是我想直接进入ComboBox
的布局......这是一个坏主意!
因此,在您删除已完成的所有内容之前,请将HBox
保存在某处,然后执行以下操作:
<强> 1 即可。创建一个新类来保存将进入每个单元格的日期(图像和字符串)。让getter / setter来做这件事。我打电话给我IconTextCell
。
<强> 2 即可。将以下代码添加到ComboBox
所在的类:
yourComboBox.setCellFactory(new Callback<ListView<T>, ListCell<T>>() {
@Override public ListCell<T> call(ListView<T> p) {
return new ListCell<T>() {
Label name = new Label();
Label icon = new Label();
private final HBox cell;
{
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
cell = new HBox();
//HERE, ADD YOUR PRE-MADE HBOX CODE
name.setAlignment(Pos.CENTER_RIGHT);
icon.setAlignment(Pos.CENTER_LEFT);
icon.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(icon, Priority.ALWAYS);
cell.getChildren().add(icon);
cell.getChildren().add(name);
}
@Override protected void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setGraphic(null);
} else {
name.setText(item.getLabel());
icon.setGraphic(item.getIcon());
setGraphic(cell);
//HERE IS WHERE YOU GET THE LABEL AND NAME
}
}
};
}
});
您会看到主要内容与我已经制作的内容非常相似,因此不会丢失任何代码。 只需更换&#34; T&#34;使用您自己的类来表示单元格。
第3 即可。这将在列表中显示您的图标和字符串,但您还需要在按钮中显示(combobox
的灰色顶部选择器部分,即button
)。这样做,我们需要添加以下代码:
class IconTextCellClass extends ListCell<T> {
@Override
protected void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (item != null) {
setText(item.getLabel());
}
}
};
selectionBox.setButtonCell(new IconTextCellClass());
......那就是我的表现。我希望这有帮助 - 请将此与我原来的帖子进行比较。实际内容(我创建HBox等)显然不是一般化的。您可以根据需要将其设置为简单或复杂。
再次感谢您的帮助!我希望这篇文章可以帮助别人!