我需要一个TreeView
,其中某些元素具有RadioButton
。
因此,我环顾四周,使用了here中的一些代码,并在其中提出了一些自己的想法。
因此,结果是一个类(RadioTreeView
)扩展了TreeView
和自定义TreeItem
和TreeCell
的类。
除了一件重要的事情,一切都很好:
在选择了一个TreeView
的情况下滚动浏览RadioButton
时,似乎会选择其他按钮。
此gif演示了问题。(滚动时我没有点击任何地方)
通过一些调试,我发现ToggleGroup
的 selectedItem 属性(由RadioButton
中的所有TreeView
共享),实际上永远不会改变。
而且,当我向每个RadioButton
的 selected -Property添加一个侦听器时,它们都不会触发。
这让我感到困惑和疑惑,这是JavaFX错误还是我遗漏了一些非常明显的东西。
这是我的代码:
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.RadioButton;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.util.Callback;
public class RadioTreeView<T> extends TreeView<T> {
private ToggleGroup toggleGroup; // shared by all radioButtons
public RadioTreeView() {
super();
toggleGroup = new ToggleGroup();
setCellFactory(new Callback<TreeView<T>, TreeCell<T>>() {
@Override
public TreeCell<T> call(TreeView<T> param) {
return new RadioTreeCell<T>(toggleGroup);
}
});
}
public static class RadioTreeItem<T> extends TreeItem<T> {
private final boolean hasRadio; // defines whether a RadioButton should be shown
public RadioTreeItem(boolean hasRadio, T item) {
super(item);
this.hasRadio = hasRadio;
}
public boolean getHasRadio() {
return hasRadio;
}
}
public static class RadioTreeCell<T> extends TreeCell<T> {
private final RadioTreeButton<T> radio = new RadioTreeButton<T>();
private final ToggleGroup toggleGroup;
public RadioTreeCell(ToggleGroup toggleGroup) {
super();
this.toggleGroup = toggleGroup;
}
{
setContentDisplay(ContentDisplay.LEFT);
}
@Override
public void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (!empty && item != null) {
setText(item.toString());
if (((RadioTreeItem<T>) getTreeItem()).getHasRadio()) { // display radioButton as graphic
setGraphic(radio);
radio.setToggleGroup(toggleGroup);
} else {
setGraphic(null);
}
} else {
setGraphic(null);
setText(null);
}
}
}
private static class RadioTreeButton<T> extends RadioButton {
// non-important methods removed
public RadioTreeButton() {
}
}
我们非常感谢您的帮助。
PS:我知道我的代码并不完美
答案 0 :(得分:1)
TreeCell
被重用。这意味着单个RadioButton
可以用于包含不同TreeItem
的单元中。您永远不会基于该项目更新单元格中RadioButton
的选择状态。这将导致其余RadioButton
被选中。滚动时,会将不同的TreeItem
放入不同的单元格中。 TableCell
的文本已更新,但RadioButton
的选择状态未更新。
您需要以某种方式存储所选的TreeItem
,例如使用userData
的{{1}}属性:
ToggleGroup