2017-11-15 4 views
1

hello-worldの例がhttps://github.com:JetBrains/kotlin-examples.gitで始まり、TornadoFXを使用するように修正されました。tornadofxアプリケーション内のobservableArrayListにバインドされた項目のフィルタリングを許可するビューをどのようにリファクタリングするのですか?

これは、アイテムのリストを表示するアプリです。あなたはリストに追加することができ、RequestViewは自動的にすべてのアイテムを表示します。

保存されているアイテムがobservableArrayListにバインドされていますが、下部にTextViewを使用してフィルタを実装したいと考えています。しかし、私はRequestViewで内部的に管理されている新しいリストを作成し、そこからフィルタリングする方法、またはそれを行う方法を理解するのが苦労しています。

package demo 

import javafx.collections.FXCollections 
import javafx.geometry.Pos 
import javafx.scene.control.TextField 
import javafx.scene.layout.VBox 
import javafx.scene.text.FontWeight 
import tornadofx.* 

class helloWorldApp : App(HelloWorld::class) { 
} 

class HelloWorld : View() { 

    override val root = VBox() 

    var requestView: RequestView by singleAssign() 
    var filterField: TextField by singleAssign() 

    init { 
     with(root) { 
      requestView = RequestView() 
      this += requestView 
      filterField = TextField() 
      this += filterField 
     } 

     requestView.items.add("Hi there") 
     requestView.items.add("Another one") 

    } 

} 

class RequestView() : View() { 
    var items = FXCollections.observableArrayList<String>() 

    override val root = listview(items) { 
     cellFormat { 
      graphic = cache { 
       form { 
        fieldset { 
         label(it) { 
          alignment = Pos.CENTER_LEFT 
          style { 
           fontSize = 15.px 
           fontWeight = FontWeight.BOLD 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
} 

これは参考になる場合があるので、ここにbuild.gradleファイルがあります。

buildscript { 
    ext.kotlin_version = '1.1.2' 
    repositories { 
    mavenCentral() 
    } 
    dependencies { 
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 
    } 
} 


apply plugin: 'kotlin' 
apply plugin: 'application' 

mainClassName = 'demo.helloWorldApp' 

defaultTasks 'run' 

repositories { 
    mavenCentral() 
} 

tasks.compileKotlin.kotlinOptions.jvmTarget = "1.8" 

dependencies { 
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 
    testCompile 'junit:junit:4.11' 
    testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" 
    compile 'no.tornado:tornadofx:1.7.10' 
} 

task wrapper(type: Wrapper) { 
    gradleVersion = "2.7" 
} 

答えて

2

あなたはObservableListをラップし、エントリを区別するために使用される述語を受け入れSortedFilteredListを使用する必要があります。

2つのビューの間に不幸なつながりがあるので、代わりにイベントを発生させることを検討する必要がありますが、ここでは、あなたの例を少し変更した実用的な解決策があります。私はモデルにデータを移動しなかった、とUIコードをクリーンアップだけでなく、singleAssign文を取り除くと、あなたが見ることができるようにビルダー:)

にいくつかのベストプラクティスを適用してしまった、SortedFilteredListfilterWhen機能を持っていますテキストフィールドのtextProperty()が変更されるたびに呼び出されます。

class HelloWorldApp : App(HelloWorld::class) 

class HelloWorld : View() { 
    val requestView: RequestView by inject() 

    override val root = vbox { 
     add(requestView) 
     textfield { 
      promptText = "Filter" 
      requestView.data.filterWhen(textProperty()) { query, item -> 
       item.contains(query, ignoreCase = true) 
      } 
     } 
    } 
} 

class ItemsModel : ViewModel() { 
    val items = FXCollections.observableArrayList<String>() 

    fun addItem(item: String) = items.add(item) 

    init { 
     addItem("Hi there") 
     addItem("Another one") 
    } 
} 

class RequestView() : View() { 
    val model: ItemsModel by inject() 
    val data = SortedFilteredList(model.items) 

    override val root = listview(data) { 
     cellFormat { 
      graphic = cache { 
       form { 
        fieldset { 
         label(it) { 
          alignment = Pos.CENTER_LEFT 
          style { 
           fontSize = 15.px 
           fontWeight = FontWeight.BOLD 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
} 
関連する問題