1

我有一个类Market,其中包含一个MarketUpdate名为m_updates. 对于 UI,我使用类型安全构建器在 tableview 中创建列,如下所示:

override val root = tableview<Market> {
    val sortedMarketList = SortedList<Market>(markets)
    sortedMarketList.comparatorProperty().bind(this.comparatorProperty())
    items = sortedMarketList
...
column("Strikes", Market::m_strikes)
...

m_strikes属性只是对象直接拥有的 SimpleIntegerProperty Market。但是,我需要能够构建这样的列:

...
column("Created At", Market::m_updates::first::m_time)
...

...
column("Last Update", Market::m_updates::last::m_time)
...

m_time对象拥有的 SimpleLongProperty在哪里MarketUpdate。更新对象时Market,会将新MarketUpdate对象添加到m_updates集合的末尾。这意味着绑定需要自动从一个对象转换到另一个对象,并且需要通知 tableview 并更新自身以反映新对象中的数据。我认为通过上述集合的first()andlast()函数进行绑定以非常简单的方式捕获了这个想法,但它不会编译。

有许多属性,如m_strikesm_time。我怎样才能优雅地做到这一点?

4

1 回答 1

3

如果我了解您的用例,您想要做的是创建一个可观察值,该值表示给定Market对象中第一次和最后一次更新的时间属性。为此,您可以objectBinding基于updates每个Market对象内部的列表创建一个,然后提取first()last()元素的timeProperty. 在下面的示例中,只要您在任何Market对象中增加更新列表,TableView 就会更新。

请记住,该示例要求每个Market人至少有一个更新。如果这不是您的情况,请确保相应地处理 null 。

class Market {
    val updates = FXCollections.observableArrayList<MarketUpdate>()
}

class MarketUpdate {
    val timeProperty = SimpleObjectProperty(LocalDateTime.now())
}

class MarketList : View("Markets") {
    val markets = FXCollections.observableArrayList<Market>()
    val data = SortedFilteredList<Market>(markets)

    override val root = borderpane {
        prefWidth = 500.0

        center {
            tableview(markets) {
                column<Market, LocalDateTime>("Created at", { objectBinding(it.value.updates) { first() }.select { it!!.timeProperty } })
                column<Market, LocalDateTime>("Last update", { objectBinding(it.value.updates) { last() }.select { it!!.timeProperty } })
            }
        }
        bottom {
            toolbar {
                // Click to add an update to the first entry
                button("Add update").action {
                    markets.first().updates.add(MarketUpdate())
                }
            }
        }
    }

    init {
        // Add some test entries
        markets.addAll(
                Market().apply { updates.addAll(MarketUpdate(), MarketUpdate(), MarketUpdate()) },
                Market().apply { updates.addAll(MarketUpdate(), MarketUpdate(), MarketUpdate()) },
                Market().apply { updates.addAll(MarketUpdate(), MarketUpdate(), MarketUpdate()) },
                Market().apply { updates.addAll(MarketUpdate(), MarketUpdate(), MarketUpdate()) }
        )
    }
}

我使用了 SortedFilteredList 来更轻松地处理排序。排序在这里起作用的原因是列实际上由 LocalDateTime 值表示。

生成的 UI

我希望这能给你一些想法:)

于 2017-08-31T08:28:54.140 回答