1

テーブルには 2 つの列があり、それぞれにドロップダウン リストがあります。

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;
        }
    }
);

ご覧のとおり、表の 1 列目の 1 番目の「選択」からの値の変更が、表の 2 列目の 2 番目の「選択」の値に影響するようにします。どのように?

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 に答える