2

I have an application that has multiple screens and a process that needs to get UI info from some and update others.

Tried many methods but the result always is always "not a Java FX thread". Without using some kind of thread the UI does not update Because of the multi screen nature of the app (not practical to change) I need to fundamentally change the application architecture which is why I am not posting any code - its all going to change.

What I cant work out is the best way to do this and as any changes are likely to require substantial work I am reluctant to try something that has little chance of success.

I know about Platform.runLater and tried adding that to the updates but that was complex and did not seem to be effective.

I do have the code on GitHub - its a personal leaning project that started in Scala 2 but if you have an interest in learning or pointing out my errors I can provide access.

Hope you have enjoyed a wonderful Christmas.

PS just make the repo public https://github.com/udsl/Processor6502

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
Ian
  • 412
  • 1
  • 4
  • 18
  • Can you describe specific problem that you have? Be more specific than a vague statement "Platform.runLater ... did not seem to be effective". `Platform.runLater` is the right way to run code on the JavaFX application thread - what is the specific issue that you have? – Jarek Dec 28 '21 at 18:41
  • A process that get info from from many controls on multiple screens and updates others. – Ian Dec 29 '21 at 07:16
  • It appears that Platform.runLater does not work because my thread does not yield so the later never happens! Result is an event handler on the update does not fire, fielded not update so same value read process loop processes same data again forever. – Ian Dec 29 '21 at 15:44
  • Can you point to the specific place in your code that you have the problem? – Jarek Dec 30 '21 at 02:45
  • After @Jarek comment which I interpreted as no alternative I focused on that as a solution and realised my thread was not yielding so the JavaFX thread never got a look-in. determined that the problem only occurs on update not on read which is a considerable simplification :) Applying Platform.runLater around the updates fixes the problem after adding the Thread.`yield`() as the last instruction of the thread run loop. – Ian Dec 30 '21 at 11:19

1 Answers1

1

The problem is not that the Platform.runLater was not working its because the process is being called form a loop in a thread and without a yield the JavaFX thread never gets an opportunity to run. It just appeared to be failing – again I fall foul of an assumption.

The thread calls a method from within a loop which terminates on a condition set by the method.

The process is planned to emulate the execution of 6502 processor instructions in 2 modes run and run-slow, run-slow is run with a short delay after each instruction execution.

The updates are to the main screen the PC, status flags and register contents. The run (debug) screen gets the current instruction display updated and other items will be added. In the future.

The BRK instruction with a zero-byte following is captures and set the execution mode to single-step essentially being a break point though in the future it will be possible via the debug screen to set a breakpoint and for the execution of the breakpoint to restore the original contents. This is to enable the debugging of a future hardware item – time and finances permitting – it’s a hobby after all

It terns out that the JavaFX thread issue only happens when a FX control is written to but not when read from. Placing all reads and writes in a Platform.runLater was too complex which is why I was originally searching for an alternative solution but now only needed it protect the writes is much less a hassle.

In the process loop calling Thread.’yield’() enables the code in the Platform.runLater blocks to be executed on the JavaFX thread so the UI updates without an exception.

The code in the Run method:

val thread = new Thread {
  override def run =
    while runMode == RunMode.Running || runMode == RunMode.RunningSlow do
      executeIns
      Thread.`yield`()
      if runMode == RunMode.RunningSlow then
        Thread.sleep(50) // slow the loop down a bit
}
thread.start

Note that because yield is a Scala reserved word needs to quote it!

Ian
  • 412
  • 1
  • 4
  • 18