Update file watcher
This commit is contained in:
parent
f7d9aff838
commit
ce6da61fcf
@ -31,9 +31,7 @@ interface ValueProvider {
|
|||||||
fun optValue(path: String): Optional<Value>
|
fun optValue(path: String): Optional<Value>
|
||||||
|
|
||||||
|
|
||||||
fun getValue(path: String): Value {
|
fun getValue(path: String): Value = optValue(path).orElseThrow { NameNotFoundException(path) }
|
||||||
return optValue(path).orElseThrow<NameNotFoundException> { NameNotFoundException(path) }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides(BOOLEAN_TARGET)
|
@Provides(BOOLEAN_TARGET)
|
||||||
|
|
||||||
|
@ -57,7 +57,12 @@ interface FileStorageElementType : StorageElementType, Named {
|
|||||||
/**
|
/**
|
||||||
* Read given path as [FileStorageElement] with given parent. Returns null if path does not belong to storage
|
* Read given path as [FileStorageElement] with given parent. Returns null if path does not belong to storage
|
||||||
*/
|
*/
|
||||||
suspend fun read(context: Context, path: Path, parent: StorageElement? = null): FileStorageElement?
|
suspend fun read(
|
||||||
|
context: Context,
|
||||||
|
path: Path,
|
||||||
|
parent: StorageElement? = null,
|
||||||
|
readMeta: Meta? = null,
|
||||||
|
): FileStorageElement?
|
||||||
}
|
}
|
||||||
|
|
||||||
class FileStorage(
|
class FileStorage(
|
||||||
@ -117,15 +122,13 @@ class FileStorage(
|
|||||||
fun resolveMeta(
|
fun resolveMeta(
|
||||||
path: Path,
|
path: Path,
|
||||||
metaReader: (Path) -> Meta? = { EnvelopeType.infer(it)?.reader?.read(it)?.meta },
|
metaReader: (Path) -> Meta? = { EnvelopeType.infer(it)?.reader?.read(it)?.meta },
|
||||||
): Meta? {
|
): Meta? = if (Files.isDirectory(path)) {
|
||||||
return if (Files.isDirectory(path)) {
|
|
||||||
Files.list(path).asSequence()
|
Files.list(path).asSequence()
|
||||||
.find { it.fileName.toString() == "meta.df" || it.fileName.toString() == "meta" }
|
.find { it.fileName.toString() == "meta.df" || it.fileName.toString() == "meta" }
|
||||||
?.let(metaReader)
|
?.let(metaReader)
|
||||||
} else {
|
} else {
|
||||||
metaReader(path)
|
metaReader(path)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun createMetaEnvelope(meta: Meta): Envelope {
|
fun createMetaEnvelope(meta: Meta): Envelope {
|
||||||
return EnvelopeBuilder().meta(meta).setEnvelopeType(META_ENVELOPE_TYPE).build()
|
return EnvelopeBuilder().meta(meta).setEnvelopeType(META_ENVELOPE_TYPE).build()
|
||||||
@ -167,8 +170,13 @@ class FileStorage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun read(context: Context, path: Path, parent: StorageElement?): FileStorageElement? {
|
override suspend fun read(
|
||||||
val meta = resolveMeta(path)
|
context: Context,
|
||||||
|
path: Path,
|
||||||
|
parent: StorageElement?,
|
||||||
|
readMeta: Meta?,
|
||||||
|
): FileStorageElement? {
|
||||||
|
val meta = readMeta ?: resolveMeta(path)
|
||||||
val name = meta?.optString("name").nullable ?: path.fileName.toString()
|
val name = meta?.optString("name").nullable ?: path.fileName.toString()
|
||||||
val type = meta?.optString("type").nullable?.let {
|
val type = meta?.optString("type").nullable?.let {
|
||||||
context.load<StorageManager>().getType(it)
|
context.load<StorageManager>().getType(it)
|
||||||
|
@ -299,7 +299,7 @@ class TableLoaderType : FileStorageElementType {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun read(context: Context, path: Path, parent: StorageElement?): FileStorageElement? {
|
override suspend fun read(context: Context, path: Path, parent: StorageElement?, readMeta: Meta?): FileStorageElement {
|
||||||
val envelope = EnvelopeReader.readFile(path)
|
val envelope = EnvelopeReader.readFile(path)
|
||||||
|
|
||||||
val name = envelope.meta.optString("name").nullable ?: path.fileName.toString()
|
val name = envelope.meta.optString("name").nullable ?: path.fileName.toString()
|
||||||
|
@ -106,13 +106,11 @@ class ProtoNumassPoint(override val meta: Meta, val protoBuilder: () -> NumassPr
|
|||||||
this.data.stream
|
this.data.stream
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fromEnvelope(envelope: Envelope): ProtoNumassPoint {
|
fun fromEnvelope(envelope: Envelope): ProtoNumassPoint = ProtoNumassPoint(envelope.meta) {
|
||||||
return ProtoNumassPoint(envelope.meta) {
|
|
||||||
envelope.dataStream().use {
|
envelope.dataStream().use {
|
||||||
NumassProto.Point.parseFrom(it)
|
NumassProto.Point.parseFrom(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// fun readFile(path: String, context: Context = Global): ProtoNumassPoint {
|
// fun readFile(path: String, context: Context = Global): ProtoNumassPoint {
|
||||||
// return readFile(context.getFile(path).absolutePath)
|
// return readFile(context.getFile(path).absolutePath)
|
||||||
|
@ -34,12 +34,17 @@ import java.nio.file.Path
|
|||||||
class NumassDirectory : FileStorage.Directory() {
|
class NumassDirectory : FileStorage.Directory() {
|
||||||
override val name: String = NUMASS_DIRECTORY_TYPE
|
override val name: String = NUMASS_DIRECTORY_TYPE
|
||||||
|
|
||||||
override suspend fun read(context: Context, path: Path, parent: StorageElement?): FileStorageElement? {
|
override suspend fun read(
|
||||||
val meta = FileStorage.resolveMeta(path){ NumassEnvelopeType.infer(it)?.reader?.read(it)?.meta }
|
context: Context,
|
||||||
|
path: Path,
|
||||||
|
parent: StorageElement?,
|
||||||
|
readMeta: Meta?,
|
||||||
|
): FileStorageElement? {
|
||||||
|
val meta = readMeta ?: FileStorage.resolveMeta(path) { NumassEnvelopeType.infer(it)?.reader?.read(it)?.meta }
|
||||||
return if (Files.isDirectory(path) && meta != null) {
|
return if (Files.isDirectory(path) && meta != null) {
|
||||||
NumassDataLoader(context, parent, path.fileName.toString(), path)
|
NumassDataLoader(context, parent, path.fileName.toString(), path)
|
||||||
} else {
|
} else {
|
||||||
super.read(context, path, parent)
|
super.read(context, path, parent, meta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,8 @@ fun main() {
|
|||||||
Global.output = FXOutputManager()
|
Global.output = FXOutputManager()
|
||||||
JFreeChartPlugin().startGlobal()
|
JFreeChartPlugin().startGlobal()
|
||||||
|
|
||||||
val file = File("C:\\Users\\darksnake\\Desktop\\test-data\\p20211012142003(20s)").toPath()
|
val file = File("D:\\Work\\Numass\\data\\test\\7.df").toPath()
|
||||||
|
println(file)
|
||||||
val point = ProtoNumassPoint.readFile(file)
|
val point = ProtoNumassPoint.readFile(file)
|
||||||
|
|
||||||
point.events.forEach {
|
point.events.forEach {
|
||||||
|
@ -58,6 +58,7 @@ runtime {
|
|||||||
"javafx.controls"
|
"javafx.controls"
|
||||||
)
|
)
|
||||||
jpackage {
|
jpackage {
|
||||||
|
//installerType = "deb"
|
||||||
jvmArgs = addJvmArgs
|
jvmArgs = addJvmArgs
|
||||||
val currentOs = org.gradle.internal.os.OperatingSystem.current()
|
val currentOs = org.gradle.internal.os.OperatingSystem.current()
|
||||||
installerOptions = installerOptions + listOf("--vendor", "MIPT-NPM lab")
|
installerOptions = installerOptions + listOf("--vendor", "MIPT-NPM lab")
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package inr.numass.viewer
|
package inr.numass.viewer
|
||||||
|
|
||||||
|
import hep.dataforge.context.ContextAware
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.storage.tables.TableLoader
|
import hep.dataforge.storage.tables.TableLoader
|
||||||
import hep.dataforge.tables.Adapters
|
import hep.dataforge.tables.Adapters
|
||||||
@ -12,16 +13,22 @@ import inr.numass.data.analyzers.NumassAnalyzer
|
|||||||
import inr.numass.data.analyzers.TimeAnalyzer
|
import inr.numass.data.analyzers.TimeAnalyzer
|
||||||
import inr.numass.data.api.NumassPoint
|
import inr.numass.data.api.NumassPoint
|
||||||
import inr.numass.data.api.NumassSet
|
import inr.numass.data.api.NumassSet
|
||||||
|
import inr.numass.data.storage.NumassDataLoader
|
||||||
|
import javafx.beans.property.SimpleObjectProperty
|
||||||
import javafx.collections.FXCollections
|
import javafx.collections.FXCollections
|
||||||
|
import javafx.collections.ObservableList
|
||||||
import javafx.collections.ObservableMap
|
import javafx.collections.ObservableMap
|
||||||
import kotlinx.coroutines.Deferred
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.async
|
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.StandardWatchEventKinds
|
||||||
|
import java.nio.file.WatchKey
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
|
|
||||||
class DataController : Controller() {
|
class DataController : Controller(), ContextAware {
|
||||||
private val context = app.context
|
override val context get() = app.context
|
||||||
|
|
||||||
val analyzer = TimeAnalyzer()
|
val analyzer = TimeAnalyzer()
|
||||||
|
|
||||||
@ -83,17 +90,73 @@ class DataController : Controller() {
|
|||||||
val points: ObservableMap<String, CachedPoint> = FXCollections.observableHashMap()
|
val points: ObservableMap<String, CachedPoint> = FXCollections.observableHashMap()
|
||||||
val sc: ObservableMap<String, TableLoader> = FXCollections.observableHashMap()
|
val sc: ObservableMap<String, TableLoader> = FXCollections.observableHashMap()
|
||||||
|
|
||||||
|
val files: ObservableList<Path> = FXCollections.observableArrayList()
|
||||||
|
|
||||||
|
val watchPathProperty = SimpleObjectProperty<Path?>()
|
||||||
|
|
||||||
|
private var watchJob: Job? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
watchPathProperty.onChange { watchPath ->
|
||||||
|
watchJob?.cancel()
|
||||||
|
if (watchPath != null) {
|
||||||
|
Files.list(watchPath).toList()
|
||||||
|
.filter {
|
||||||
|
!Files.isDirectory(it) && it.fileName.startsWith(NumassDataLoader.POINT_FRAGMENT_NAME)
|
||||||
|
}
|
||||||
|
.sortedBy { file ->
|
||||||
|
val attr = Files.readAttributes(file, BasicFileAttributes::class.java)
|
||||||
|
attr.creationTime()
|
||||||
|
}.forEach { path ->
|
||||||
|
try {
|
||||||
|
runLater {
|
||||||
|
files.add(path)
|
||||||
|
}
|
||||||
|
} catch (x: Throwable) {
|
||||||
|
app.context.logger.error("Error during dynamic point read", x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val watcher = watchPath.fileSystem.newWatchService()
|
||||||
|
watchJob = app.context.launch(Dispatchers.IO) {
|
||||||
|
watcher.use { watcher ->
|
||||||
|
val key: WatchKey = watchPath.register(watcher,
|
||||||
|
StandardWatchEventKinds.ENTRY_CREATE)
|
||||||
|
coroutineContext[Job]?.invokeOnCompletion {
|
||||||
|
key.cancel()
|
||||||
|
}
|
||||||
|
while (isActive) {
|
||||||
|
try {
|
||||||
|
key.pollEvents().forEach { event ->
|
||||||
|
if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
|
||||||
|
val path: Path = event.context() as Path
|
||||||
|
runLater {
|
||||||
|
files.add(watchPath.resolve(path))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (x: Throwable) {
|
||||||
|
app.context.logger.error("Error during dynamic point read", x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun clear() {
|
fun clear() {
|
||||||
cache.clear()
|
cache.clear()
|
||||||
sets.clear()
|
sets.clear()
|
||||||
points.clear()
|
points.clear()
|
||||||
sc.clear()
|
sc.clear()
|
||||||
|
watchPathProperty.set(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun addPoint(id: String, point: NumassPoint) {
|
fun addPoint(id: String, point: NumassPoint): CachedPoint {
|
||||||
points[id] = getCachedPoint(id, point)
|
val newPoint = getCachedPoint(id, point)
|
||||||
|
points[id] = newPoint
|
||||||
|
return newPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addSet(id: String, set: NumassSet) {
|
fun addSet(id: String, set: NumassSet) {
|
||||||
|
@ -4,89 +4,50 @@ import hep.dataforge.fx.dfIconView
|
|||||||
import hep.dataforge.io.envelopes.Envelope
|
import hep.dataforge.io.envelopes.Envelope
|
||||||
import inr.numass.data.NumassDataUtils
|
import inr.numass.data.NumassDataUtils
|
||||||
import inr.numass.data.NumassEnvelopeType
|
import inr.numass.data.NumassEnvelopeType
|
||||||
|
import inr.numass.data.api.NumassPoint
|
||||||
import inr.numass.data.storage.NumassDataLoader
|
import inr.numass.data.storage.NumassDataLoader
|
||||||
import javafx.beans.property.SimpleObjectProperty
|
|
||||||
import javafx.collections.FXCollections
|
|
||||||
import javafx.collections.MapChangeListener
|
|
||||||
import javafx.scene.control.ContextMenu
|
import javafx.scene.control.ContextMenu
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.isActive
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.StandardWatchEventKinds.ENTRY_CREATE
|
|
||||||
import java.nio.file.WatchKey
|
|
||||||
|
|
||||||
class DirectoryWatchView : View(title = "Numass storage", icon = dfIconView) {
|
class DirectoryWatchView : View(title = "Numass storage", icon = dfIconView) {
|
||||||
|
|
||||||
val pathProperty = SimpleObjectProperty<Path>()
|
|
||||||
private val dataController by inject<DataController>()
|
private val dataController by inject<DataController>()
|
||||||
|
|
||||||
private val ampView: AmplitudeView by inject()
|
private val ampView: AmplitudeView by inject()
|
||||||
private val timeView: TimeView by inject()
|
private val timeView: TimeView by inject()
|
||||||
|
|
||||||
private var watcherProperty = pathProperty.objectBinding {
|
// private val files: ObservableList<DataController.CachedPoint> =
|
||||||
it?.fileSystem?.newWatchService()
|
// FXCollections.observableArrayList<DataController.CachedPoint>().apply {
|
||||||
}
|
// bind(dataController.points) { _, v -> v }
|
||||||
|
// }
|
||||||
|
|
||||||
private val files = FXCollections.observableArrayList<DataController.CachedPoint>()
|
private fun readPointFile(path: Path): NumassPoint {
|
||||||
|
|
||||||
private var watchJob: Job? = null
|
|
||||||
|
|
||||||
init {
|
|
||||||
dataController.points.addListener(MapChangeListener { change ->
|
|
||||||
if (change.wasAdded()) {
|
|
||||||
files.add(change.valueAdded)
|
|
||||||
} else if (change.wasRemoved()) {
|
|
||||||
files.remove(change.valueRemoved)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
watcherProperty.onChange { watchService ->
|
|
||||||
watchJob?.cancel()
|
|
||||||
if (watchService != null) {
|
|
||||||
watchJob = app.context.launch(Dispatchers.IO) {
|
|
||||||
val key: WatchKey = pathProperty.get().register(watchService, ENTRY_CREATE)
|
|
||||||
coroutineContext[Job]?.invokeOnCompletion {
|
|
||||||
key.cancel()
|
|
||||||
}
|
|
||||||
while (isActive) {
|
|
||||||
try {
|
|
||||||
key.pollEvents().forEach { event ->
|
|
||||||
if (event.kind() == ENTRY_CREATE) {
|
|
||||||
val path: Path = event.context() as Path
|
|
||||||
if (path.fileName.toString().startsWith(NumassDataLoader.POINT_FRAGMENT_NAME)) {
|
|
||||||
val envelope: Envelope = NumassEnvelopeType.infer(path)?.reader?.read(path)
|
val envelope: Envelope = NumassEnvelopeType.infer(path)?.reader?.read(path)
|
||||||
?: kotlin.error("Can't read point file")
|
?: kotlin.error("Can't read point file")
|
||||||
val point = NumassDataUtils.read(envelope)
|
return NumassDataUtils.read(envelope)
|
||||||
files.add(dataController.getCachedPoint(path.toString(), point))
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (x: Throwable) {
|
|
||||||
app.context.logger.error("Error during dynamic point read", x)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override val root = splitpane {
|
override val root = splitpane {
|
||||||
listview(files) {
|
listview(dataController.files) {
|
||||||
multiSelect(true)
|
//multiSelect(true)
|
||||||
cellFormat { value: DataController.CachedPoint ->
|
cellFormat { path: Path ->
|
||||||
text = "${value.voltage}[${value.index}]"
|
text = path.fileName.toString()
|
||||||
graphic = null
|
graphic = null
|
||||||
|
if (path.fileName.toString().startsWith(NumassDataLoader.POINT_FRAGMENT_NAME)) {
|
||||||
|
val point = readPointFile(path)
|
||||||
|
val cachedPoint = dataController.addPoint(path.toString(), point)
|
||||||
|
//val point = dataController.getCachedPoint(value.toString())
|
||||||
contextMenu = ContextMenu().apply {
|
contextMenu = ContextMenu().apply {
|
||||||
item("Info") {
|
item("Info") {
|
||||||
action {
|
action {
|
||||||
PointInfoView(value).openModal(escapeClosesWindow = true)
|
PointInfoView(cachedPoint).openModal(escapeClosesWindow = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
contextMenu = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,8 +38,7 @@ class MainView : View(title = "Numass viewer", icon = dfIconView) {
|
|||||||
// addLogHandler(context.logger)
|
// addLogHandler(context.logger)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private val pathProperty = SimpleObjectProperty<Path>()
|
private val pathProperty = SimpleObjectProperty<Path?>()
|
||||||
private var path: Path by pathProperty
|
|
||||||
|
|
||||||
private val contentViewProperty = SimpleObjectProperty<UIComponent>()
|
private val contentViewProperty = SimpleObjectProperty<UIComponent>()
|
||||||
private var contentView: UIComponent? by contentViewProperty
|
private var contentView: UIComponent? by contentViewProperty
|
||||||
@ -54,7 +53,6 @@ class MainView : View(title = "Numass viewer", icon = dfIconView) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override val root = borderpane {
|
override val root = borderpane {
|
||||||
prefHeight = 600.0
|
prefHeight = 600.0
|
||||||
prefWidth = 800.0
|
prefWidth = 800.0
|
||||||
@ -83,9 +81,10 @@ class MainView : View(title = "Numass viewer", icon = dfIconView) {
|
|||||||
if (rootDir != null) {
|
if (rootDir != null) {
|
||||||
NumassProperties.setNumassProperty("numass.viewer.lastPath", rootDir.absolutePath)
|
NumassProperties.setNumassProperty("numass.viewer.lastPath", rootDir.absolutePath)
|
||||||
app.context.launch {
|
app.context.launch {
|
||||||
|
val path = rootDir.toPath()
|
||||||
dataController.clear()
|
dataController.clear()
|
||||||
runLater {
|
runLater {
|
||||||
path = rootDir.toPath()
|
pathProperty.set(path)
|
||||||
contentView = null
|
contentView = null
|
||||||
}
|
}
|
||||||
if (Files.exists(path.resolve(NumassDataLoader.META_FRAGMENT_NAME))) {
|
if (Files.exists(path.resolve(NumassDataLoader.META_FRAGMENT_NAME))) {
|
||||||
@ -108,7 +107,8 @@ class MainView : View(title = "Numass viewer", icon = dfIconView) {
|
|||||||
} else {
|
} else {
|
||||||
//build storage
|
//build storage
|
||||||
app.context.launch {
|
app.context.launch {
|
||||||
val storageElement = NumassDirectory.INSTANCE.read(app.context, path) as Storage
|
val storageElement =
|
||||||
|
NumassDirectory.INSTANCE.read(app.context, path) as? Storage
|
||||||
withContext(Dispatchers.JavaFx) {
|
withContext(Dispatchers.JavaFx) {
|
||||||
contentView = storageView
|
contentView = storageView
|
||||||
storageView.storageProperty.set(storageElement)
|
storageView.storageProperty.set(storageElement)
|
||||||
@ -141,9 +141,10 @@ class MainView : View(title = "Numass viewer", icon = dfIconView) {
|
|||||||
NumassProperties.setNumassProperty("numass.viewer.lastPath",
|
NumassProperties.setNumassProperty("numass.viewer.lastPath",
|
||||||
file.parentFile.absolutePath)
|
file.parentFile.absolutePath)
|
||||||
app.context.launch {
|
app.context.launch {
|
||||||
|
val path = file.toPath()
|
||||||
dataController.clear()
|
dataController.clear()
|
||||||
runLater {
|
runLater {
|
||||||
path = file.toPath()
|
pathProperty.set(file.toPath())
|
||||||
contentView = null
|
contentView = null
|
||||||
}
|
}
|
||||||
//Reading individual file
|
//Reading individual file
|
||||||
@ -199,10 +200,12 @@ class MainView : View(title = "Numass viewer", icon = dfIconView) {
|
|||||||
if (dir != null) {
|
if (dir != null) {
|
||||||
NumassProperties.setNumassProperty("numass.viewer.lastPath", dir.absolutePath)
|
NumassProperties.setNumassProperty("numass.viewer.lastPath", dir.absolutePath)
|
||||||
app.context.launch {
|
app.context.launch {
|
||||||
|
val path = dir.toPath()
|
||||||
dataController.clear()
|
dataController.clear()
|
||||||
runLater {
|
runLater {
|
||||||
path = dir.toPath()
|
pathProperty.set(path)
|
||||||
contentView = null
|
contentView = directoryWatchView
|
||||||
|
dataController.watchPathProperty.set(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user