I'm trying to refactor to `val` my Javafx controls...
# tornadofx
f
I'm trying to refactor to
val
my Javafx controls but I don't get desired result in Type-Safe Builders of Tornadofx. ¿How can return type-safe builder instead javaFx control? My Code: I can't define my label as type-safe builder instead Label
Copy code
class Portal : View("") {
 val lblImgWarn by lazy { label("File not found") {} }
 
 gridpane {
   row {
	 add(lblImgWarn)
     lblImgWarn.graphic = imageview(image) {
      fitHeight = 32.0
      isPreserveRatio = true
     }
   }
 }
 
}
Expected Code:
Copy code
class Portal : View("") {
 val lblImgWarn by lazy { label("File not found") {} } // I don't know how to return a type-safe builder instead Label
 
 gridpane {
   row {
     lblImgWarn{
	   graphic = imageview(image) {
		  fitHeight = 32.0
		  isPreserveRatio = true
       }
	 }
   }
 }
 
}
m
you can use "singleAssign"
Copy code
class Portal : View("") {
 var lblImgWarn: Label by singleAssign()
 gridpane {
   row {
     lblImgWarn = label{
	   graphic = imageview(image) {
		  fitHeight = 32.0
		  isPreserveRatio = true
       }
	 }
   }
 }
}
lblImgWarn is a var but it can only be assigned/initialized once
this will only do run time checking if the var is assigned again which is not as nice as a val with static checking but is better than nothing
something I have learned, if you want to update the content of a control, it's best to use an observable property and only save references to controls when you need to do something special with the control
Copy code
class Portal : View("") {
 val text = simpleStringProperty("Label")
 gridpane {
   row {
     label(text){
	   graphic = imageview(image) {
		  fitHeight = 32.0
		  isPreserveRatio = true
       }
	 }
   }
 }
}
in your case, I'm guessing you want to update the image or something? in that case, you may be able to bind the imageview to the label or something, I would have to look it up
f
@Marshall Thx, I will look for more information about delegated properties One last question: I created object with
Label + input + Btn
for reused controls and also I created extends function in Pane class for to automatically add controls to my Pane without calling the
add()
function. Could this approach give me problems in the future? Suggestions for an alternative? Sample Code:
Copy code
data class InputChooseFolder(val label: Label, val input: TextField, val btnFolder: Button){}
class Portal : View("") { 

fun Pane.inputChooseFolder(txt: String, inputID: String = "", tooltipMsg: String): InputChooseFolder{
    val label = label(txt)
    val input = textfield {
        id = inputID
        promptText = txt
	
        prefWidth = 300.0
        tooltip = tooltip(tooltipMsg) {  }
    }
	
    val btn = btnFolderChooser(input)
    return InputChooseFolder(label, input, btn)
}

vbox {
  row {
    inputRoot = inputChooseFolder("Root Path:", "inputRoot","Insert root Path of files")
  }
	
  row {
    inputDest = inputChooseFolder("Dest Path:", "inputDest", "Path on store JSON generated")
  }
}

}
m
I guess the alternative is Fragment.
m
looks good to me, there are some alternatives
yeah you could use a fragment
also, tornadofx has functions such as "chooseDirectory" and "chooseFile"
Copy code
/**
     * Show a file open dialog for selecting a profile configuration to load.
     *
     * @param fileName The file name with the path for the initial directory
     * @param otherFileName The file name for initial directory if fileName is blank
     */
    private fun browseFile(fileName: String, otherFileName: String = ""): File? {
        val extJson = FileChooser.ExtensionFilter("JSON files (*.json)", "*.json")
        val extAll = FileChooser.ExtensionFilter("All files (*.*)", "*.*")
        val initialFileName = if (fileName.isNotBlank()) fileName else otherFileName
        val f = File(initialFileName)
        val initDir: File? = if (f.exists()) f.parentFile else null
        val files = chooseFile(title = "Open Profile Configuration",
                initialDirectory = initDir,
                filters = arrayOf(extJson, extAll),
                mode = FileChooserMode.Single
        )
        return files.firstOrNull()
    }
that's what I use for action on File->Open menu
f
yes i Know it "chooseDirectory" and "chooseFile" and I used it in btnFolderChooser(input)
👍 1
m
it would probably make sense to make that input choose folder a fragment
f
when you say Fragment you mean Fragment design?
m
Copy code
import tornadofx.*

class ChooseFolderFragment : Fragment() {

    val lblTxt = stringProperty("")
    val txtPath = stringProperty("")

    override val root = flowpane {
        label(lblTxt)
        textfield(txtPath) {
        }
        button {
            chooseFile()
        }
    }
}
then when you want to use it you just do
Copy code
vbox {
    add(ChooseFolderFragment())
}
you can also add argument to ChooseFolderFragment() if you need to
and if you save the reference you can access the properties
Copy code
vbox {
    val chooser = ChooseFolderFragment()
    add(chooser)
    chooser.lblText.set("Test")
}
f
thx to all, I will look for more info.