1

在一个表中,有两列,每一列都有一个下拉列表。

final Table archivesTable = new Table();
archivesTable.setTableFieldFactory(new TableFieldFactory() {
    @Override
    public Field createField(Container container, Object itemId,
                             Object propertyId, Component uiContext) {
        Select sel = new Select();
        try (SSEConnector c = CisApplication
                              .generateSseConnector((SseConnection) sseSetupSelect
                              .getValue())) {
            for (String s : c.getListOfArchives())
                sel.addItem(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("yes 2");
        return sel;
    }
});

archivesTable.addGeneratedColumn("reportName",
    new Table.ColumnGenerator() {
        @Override
        public Object generateCell(Table source, final Object itemId, Object columnId) {
            reportSelect = new Select();
            try (SSEConnector c = CisApplication
                                  .generateSseConnector((SseConnection) sseSetupSelect
                                  .getValue())) {
                for (String s : c.getListOfArchives())
                    reportSelect.addItem(s);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("yes 3");
            return reportSelect;
        }
    }
);

正如我们所看到的,我希望表中第一列中第一个“选择”的任何值更改都会影响表中第二列中第二个“选择”中的值。如何?

4

1 回答 1

0

生成的列不会影响 vaadin 表的基础数据容器。它们是即时生成的,不会为它们创建任何属性。因此,没有明显的方法可以直接访问它们。

实现此行为的丑陋方法是为两列预生成所有控件并将它们绑定在一起。将它们存储在绑定到的地图中itemId

Collection itemIds = archivesTable.getItemIds();
final HashMap<Object,Select> firstColumnSelects = new HashMap<Object, Select>();
final HashMap<Object,Select> secondColumnSelects = new HashMap<Object, Select>();
for(Object itemId : itemIds) {
    final Select secondColumnSelect = new Select();
    //initialize select for the second column
    secondColumnSelect.setImmediate(true);
    Select firstColumnSelect = new Select();
    //initialize select for the first column
    firstColumnSelect.addListener(new ValueChangeListener() {

    @Override
    public void valueChange(ValueChangeEvent event) {
        //setting value to the list in second column
        secondColumnSelect.setValue(event.getProperty().getValue());
    }
    });
    firstColumnSelect.setImmediate(true);
    firstColumnSelects.put(itemId, firstColumnSelect);
    secondColumnSelects.put(itemId, secondColumnSelect);
}

然后,无需即时生成控件,只需返回预先生成的列表:

//...
@Override
public Field createField(Container container, final Object itemId, Object propertyId, Component uiContext) {
    return firstColumnSelects.get(itemId);
}
//...
@Override
public Object generateCell(Table source, final Object itemId, Object columnId) {
    return secondColumnSelects.get(itemId);
}

更清洁的方法是根本不使用生成的列。生成的列并不意味着大量参与数据操作。相反,您可以创建一个单独的类来表示表记录并在那里实现所有交互:

public class TableDisplayBean {
    private Select firstSelect;
    private Select secondSelect;

    public TableDisplayBean() {
        //initialization of controls, value change handling goes here
    }

    public Select getFirstColumn() {
        return firstSelect;
    }
    public Select getSecondColumn() {
        return secondSelect;
    }
}

剩下的就是使用BeanItemContainer将一组 bean 绑定到表。

于 2013-03-14T07:40:39.733 回答