2017-11-15 8 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를 사용해야합니다.

두보기가 불행하게 연결되어 있으므로 이벤트를 실행하는 것이 좋습니다.하지만 여기서는 예제를 최소한으로 변경 한 실제 해결책이 있습니다. 전 모델에 데이터를 이동했다 및 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 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
}