tornadofx icon indicating copy to clipboard operation
tornadofx copied to clipboard

A ProgressIndicator in a View cause it to not trigger onDock

Open gabrielpaim opened this issue 5 years ago • 10 comments

This may be a generalization of this issue, apologize me if this has already been solved. But I'm also experiencing some problems with onDock() not being called when the view has a ProgressIndicator, not only in modal stages (as @Romanow88 reported on the other issue).

The following test does not work for me on Tornadofx 1.7.19:

@Test
fun viewWithProgressIndicator() {
    Application.launch(TestApp::class.java)
    assert(TestView.onDockCalled)
}

class TestApp: App(TestView::class) {
    override fun start(stage: Stage) {
        super.start(stage)
        stage.close()
    }
}

class TestView: View() {
    override val root = progressindicator()

    override fun onDock() {
        onDockCalled = true
    }

    companion object {
        var onDockCalled = false
    }
}

From 1.7.19 on, I couldn't see a commit change that targeted that possible issue.

Moreover on that, this behavior was adding a tricky bug on our software, once the EventBus only subscribe events for docked UIComponents. Depending on conditions (for instance, a view has a ProgressIndicator), the event mechanism stops receiving events. As I cannot know which component could also be related with this issue, using the event bus on UI could also cause strange behaviors. Anyway, I just thought others could be facing that.

Any ideas? Thanks a lot.

gabrielpaim avatar Jun 27 '19 18:06 gabrielpaim

I tested this also on last version of tornadofx (on ViewDockingTests), maybe it help to track down the issue.

@Test
fun `view with a progressIndicator should also trigger onDock`() {

    class ViewWithProgressIndicator : PrimaryDockingView() {
        override val root = vbox {
            progressindicator()
        }
    }
    class AppWithProgressIndicator : App(ViewWithProgressIndicator::class)

    FxToolkit.registerPrimaryStage()
    val app = FxToolkit.setupApplication { AppWithProgressIndicator() }

    assertEquals(
            expected = 1,
            actual = find<ViewWithProgressIndicator>().dockCounter,
            message = "view should have docked exactly once"
    )

    FxToolkit.cleanupStages()
    FxToolkit.cleanupApplication(app)
}

gabrielpaim avatar Jun 27 '19 18:06 gabrielpaim

Same thing happening to me on 1.7.19, for now I'm using a workaround:

var progressBarContainer : HBox by singleAssign()
var progressBar: ProgressBar by singleAssign()

fun initialize() {
        progressBar = progressbar(0.0) {
            isVisible = false
        }
        root += progressBar
    }

    override fun onDock() {
        super.onDock()
        initialize()
    }

override val root = hbox {
    progressBarContainer = hbox { }
}

Not the most elegant solution but it gets the job done while it's not fixed.

JoaquinTrinanes avatar Jun 27 '19 22:06 JoaquinTrinanes

Hi, i ran into the same issue as the op using the EventBus. Below is a a simple example working on 1.7.18 but not on 1.7.19, the subscription is never created because attachLocalEventBusListeners is not called because muteDocking is true (set in App.start). So fire has nothing to trigger.

internal fun callOnDock() {
        if (!isInitialized) init()
        // muteDocking is true, so `attachLocalEventBusListeners` is never called
        if (muteDocking) return
        if (!isDocked) attachLocalEventBusListeners()
...
class ZApp : App(ZView::class)
class ZEvent() : FXEvent()
class ZView : View() {
    init { subscribe<ZEvent>{ println(it) } }
    override val root = hbox {
        button("event") { action { fire(ZEvent())  } }
        progressbar()
    }
}

sderosiaux avatar Aug 09 '19 18:08 sderosiaux

I've committed a fix for this now. You're right @sderosiaux, attachLocalEventBusListeners should be called even if muteDocking is true.

edvin avatar Aug 12 '19 08:08 edvin

Same issue, but with ProgressBar. Following code not trigger onDock():

class MainApp : App(MainView::class)

class MainView : View("My View") {
    override fun onDock() {
        exitProcess(0)
    }

    override val root = vbox {
        progressbar()
    }
}

Using Tornado FX 1.7.20

In Tornado FX 1.7.18 this code work properly

analogueBubblebath avatar Apr 16 '20 14:04 analogueBubblebath

got the same issue using tornadofx 1.7.20 even implementations of ProgressBars can cause this issue, such as JFXProgressBar from JFoenix.

fee1-dead avatar May 27 '20 06:05 fee1-dead

It looks like the undock method will not be called as well

fee1-dead avatar May 27 '20 06:05 fee1-dead

same issue using tornadofx 1.7.20

liugangnhm avatar Oct 28 '20 17:10 liugangnhm

same issue using tornadofx 1.7.20

import tornadofx.*

class MainApp : App(MainView::class)

class MainView : View("My View") {
  override fun onDock() {
    super.onDock()
  }

  override val root = vbox {
    progressbar()
  }
}

above code works on windows 10 but not work on ubuntu20.04.1

liugangnhm avatar Oct 29 '20 01:10 liugangnhm

same issue using tornadofx 1.7.20

import tornadofx.*

class MainApp : App(MainView::class)

class MainView : View("My View") {
  override fun onDock() {
    super.onDock()
  }

  override val root = vbox {
    progressbar()
  }
}

above code works on windows 10 but not work on ubuntu20.04.1

I found a way to work on ubuntu:

class MainView : View("My View") {
  override fun onDock() {
    super.onDock()
    println("onDock")

    with(root) {
      progressbar {
        useMaxWidth = true
      }
    }
  }

  override val root = vbox {
    prefWidth = 300.0
  }

  override fun onUndock() {
    super.onUndock()
    println("onUndock")
  }
}

all views that contains progressbar should do this to make ondock work

liugangnhm avatar Nov 09 '20 16:11 liugangnhm