如何使用rxjava从SWT表中获取选定的项目?

问题描述 投票:0回答:1
我有一个表格和一个按钮,我想在单击按钮时发出一个用表格的事件项目。

按钮不应该知道表,并且只能保留为单击流。 因此,该解决方案被丢弃:

final ETable table = ... PublishSubject<ItemSelected> selected = PublishSubject.create(); button.addSelectionListener(new SelectionListener(){ @Override public void widgetSelected(SelectionEvent e) { for (TableItem item : table.getSelection()) { selected.onNext(new ItemSelected(item)); } } });

我更喜欢使用表的项目选择流组成按钮的单击流,以保持这两个元素之间的松散耦合。
由于表允许多个选择,我必须首先

Scan

为了发出所有项目的事件,选择的项目。类似:

public static class ItemsSelected<T> { final List<T> items = new ArrayList<T>(); } public abstract static class ItemSelection<T> { public abstract void apply(ItemsSelected<T> selection); } public static class ItemUnselected<T> extends ItemSelection<T> { final T item; public ItemUnselected(T item) { this.item = item; } public void apply(ItemsSelected<T> selection) { selection.items.remove(item); } } public static class ItemSelected<T> extends ItemSelection<T> { final T item; public ItemSelected(T item) { this.item = item; } public void apply(ItemsSelected<T> selection) { selection.items.add(item); } } public static class ObservableTable<T> extends Table { private PublishSubject<ItemSelection<T>> clicks = PublishSubject.create(); public Observable<ItemsSelected<T>> selection = clicks.scan(new ItemsSelected<T>(), new Func2<ItemsSelected<T>, ItemSelection<T>, ItemsSelected<T>>() { @Override public ItemsSelected<T> call(ItemsSelected<T> t1, ItemSelection<T> t2) { // breaking events immutability t2.apply(t1); return t1; } }); public ObservableTable(Composite parent, int style) { super(parent, style); this.addSelectionListener(new SelectionListener() { @SuppressWarnings("unchecked") @Override public void widgetSelected(SelectionEvent e) { if (((TableItem) e.item).getChecked()) clicks.onNext(new ItemSelected<T>((T) e.item.getData())); else clicks.onNext(new ItemUnselected<T>((T) e.item.getData())); } @Override public void widgetDefaultSelected(SelectionEvent e) { } }); } }

,然后我必须将表格流与按钮。单击流中的选项流中。这个想法是,当键盘发出纽扣时,只有在以前发出的项目中排放时,才会发出selectionForaction。
-------S1--U1-----S2---S3--------- table.clicks
           (scan)
-------(1)--()---(2)---(2,3)------ table.selection
                           
----O----------O-------------O---- button.clicks
              (?)
-----------------------------(2,3) selectionForAction

,我应该使用哪个操作?

zip:它不起作用,因为如果我单击按钮并以后选择一个项目,它不应该做任何事情,但是使用zip会发出事件。

join:我最终使用

join
    获得了一个“解决方案”,但这似乎不是一个好的。类似:
  • table.selection.join(button.clicks, new Func1<ItemsSelected,Observable<Long>>() { @Override public Observable<Long> call(ItemsSelected t) { // it doesn't seem a good idea return Observable.timer(1, TimeUnit.DAYS); } }, new Func1<ClickEvent, Observable<Long>>() { @Override public Observable<Long> call(ClickEvent t) { // this makes the ClickEvent be dropped if there is no previous ItemsSelected event emitted return Observable.timer(1, TimeUnit.MILLISECONDS); } }, new Func2<ItemsSelected, ClickEvent, SelectionForAction>() { @Override public SelectionForActioncall(ItemsSelected t1, ClickEvent t2) { return new SelectionForAction(t1.items); } }); 任何想法?

我发现了我需要使用非常大的时间单元(示例中的几天)和一个很小的(毫秒)来实现
join
行为所需的操作员。

sample的一个varianiant
events swt rx-java
1个回答
0
投票

在我的示例中,点击充当采样器,流选择会发出我感兴趣的事件。 其他可能的解决方案将使用

截止器(边界) enter image description here点击流将充当边界,我可以避免使用Scan

运算符,因为所选项目列表是由缓冲区运算符创建的。但是,对于此解决方案,我不会考虑不选择。

因此,在示例中,我实现了最初的目标,但是,我对处理项目的方式和所选项目的最终列表不满意。 在这种情况下,我需要维护所选项目的状态,以便在发生Clickevent时对所有操作执行所有操作。

我可以订阅项目选择/取消选择并维护所选项目的列表,但随后我会失去可观察到的可观察到的点击的可能性。

与sscani保持状态并保持可观察力的合成性,但是将当前选择列表表示为事件似乎有些强制,实际上这代表了一个新问题:如果我选择x项目,然后单击按钮,然后单击按钮,随着预期的选择,带有选择的事件正在排放,但是如果未选择项目或选择新项目,然后再次单击按钮,则不会发生任何事情。因此,似乎选择并不适合事件。 enter image description here

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.