【发布时间】:2020-02-19 11:10:09
【问题描述】:
我创建了一个有四列的网格。第一列显示一个名称,其他三列代表不同的角色。这三列中的每一列都填充有复选框,以便将特定角色分配给特定名称。这就是我到目前为止所到之处。 在每一列和每一行中,应该只允许一个选中的复选框。所以总的来说,我确实每个复选框列只有一个选择。我该如何实现?
【问题讨论】:
我创建了一个有四列的网格。第一列显示一个名称,其他三列代表不同的角色。这三列中的每一列都填充有复选框,以便将特定角色分配给特定名称。这就是我到目前为止所到之处。 在每一列和每一行中,应该只允许一个选中的复选框。所以总的来说,我确实每个复选框列只有一个选择。我该如何实现?
【问题讨论】:
编辑:我意识到我可能完全误解了这个问题。如果你想有 3 列,每列有多个 CheckBox,每列只能选择 1 个,那么你应该在每列中使用 RadioButtonGroup 并将每列绑定到 griditem 类的不同 Enum 字段。
我将展示一种不同的方式来获得关于该项目的相同信息,而不是展示如何在每列中使用一个 CheckBox 来处理三列,虽然只能选择一个 CheckBox。
这样做的原因是您想要实现的解决方案并不容易实现,因为每个 CheckBox 都定义在一个不知道同一项目的其他 Checkbox 的范围内。因此,您需要在 itemclass 的设置器中实现您的唯一选择规则,这不是最佳的。我的意思是,这是可能的,但我宁愿将结构更改为更贴切的东西。通常你不想把这种业务逻辑放到你的 bean 类中。
我将如何解决手头的问题?
创建一个新的枚举,它将替换您项目类中的所有 3 个布尔字段。现在在您的网格中,您只需要一列让 ComboBox 选择枚举。
我选择了一个 Enum ,因为这完全符合您的需求。使用 Enum,您可能有多个选项,但您只能选择一个(或无)。
为了更好地表达我的意思,让我们为网格项目使用一个示例类,Foo。您的版本有 3 个布尔值,您的三个网格复选框绑定到这些布尔值。我们称他们为isA、isB、isC。
// your version of the griditem class
public class Foo {
private boolean isA, isB, isC = false;
// constructor, getters, setters
}
// how the columns are added in the grid (approximately) (without editor):
Grid<Foo> grid = new Grid<>();
grid.addComponentColumn((item) -> {
CheckBox checkBox = new CheckBox();
checkBox.setValue(item.isA());
checkBox.addValueChangeListener(event -> item.setA(event.getValue()); // inside setA() method you need to set isB and isC to false if the new value is true. No good!
return checkBox;
});
grid.addComponentColumn((item) -> {
CheckBox checkBox = new CheckBox();
checkBox.setValue(item.isB());
checkBox.addValueChangeListener(event -> item.setB(event.getValue()); // inside setB() method you need to set isB and isC to false if the new value is true. No good!
return checkBox;
});
grid.addComponentColumn((item) -> {
CheckBox checkBox = new CheckBox();
checkBox.setValue(item.isC());
checkBox.addValueChangeListener(event -> item.setC(event.getValue()); // inside setC() method you need to set isB and isA to false if the new value is true. No good!
return checkBox;
});
这是我的更改后的样子
public class Foo {
private AbcEnum abcEnum = null;
// constructor, getters, setters
}
public Enum AbcEnum {
A,
B,
C;
}
// how the columns are added (without editor):
Grid<Foo> grid = new Grid<>();
grid.addComponentColumn((item) -> {
ComboBox<AbcEnum> comboBox = new ComboBox<>();
comboBox.setValue(item.getAbcEnum());
comboBox.addValueChangeListener(event -> item.setAbcEnum(item.getValue()));
return comboBox;
});
我在 cmets 中写了关于添加列的“无编辑器”,因为此代码会将 ComboBox/CheckBox 添加为每个网格项目的可点击和功能组件,而无需打开项目的编辑器来更改值。如果您确实在使用editor,您可以将这些功能输入添加为 editorComponents(并将它们绑定到 editor-binder,而不是使用 setValue 和 addValueChangeListener),并仅在普通列中显示当前值(不可编辑 - 因此不需要像 CheckBox 或 ComboBox 这样的输入)
【讨论】: