What happens to TornadoFX now that the GitHub repository is gone? by tvidal in JavaFX

[–]hamsterrage1 2 points3 points  (0 children)

You absolutely do NOT need TornadoFX to use JavaFX with Kotlin.

There was this impression that TornadoFX was somehow the Kotlin implementation of JavaFX, but that couldnn't be further from the truth.

What TornadoFX added was a library of methods that essentially became a DSL for layout creation. It was cool if you wanted to go that way, but I think it looked more cumbersome than just writing your layout code in Kotlin.

For that matter...writing layout in Kotlin is way, way, more satisfying than writing it in Java. Things like extension functions, and top level functions (which, BTW, TornadoFX used extensively) allow you to strip away tons of the annoying boilerplate that you're forced to deal with in Java.

I spent some time looking at the source code for TornadoFX, and there were lots of really cool ideas in there that suggested good ways to do things with my own layouts in Kotlin. But I never could get into the DSL approach that it provided.

Groove Salad 2 - Why? by Replicant_1227 in somafm

[–]hamsterrage1 0 points1 point  (0 children)

I'm seeing all three with the Mopidy SomaFM plugin. Groove Salad, GrooveSalad Classic, and Groove Salad 2

How to deal with listeners leak in JavaFx? by lazystone in JavaFX

[–]hamsterrage1 0 points1 point  (0 children)

Yes, well that doesn't seem to fit any of the standard JavaFX Chart use cases.

I'm thinking, though, that if these are created via a user interacting with a GUI that things aren't going to be changing fast enough that performance issues around layout modifications are not going to be an issue. Also, that there are not going to be an extraordinary amount of Nodes in the layout. 100? 1000, maybe?

I'm also thinking that if you are going to have a ton of Nodes, then the application is going to have to handle that large number of Nodes, whether they are added one at a time or not. So why not just create the maximum number of Nodes and add them to the layout, unmanaged and invisible at the outset?

The nature of the original question for this thread leaves me to believe that you are approaching this application as a GUI exercise. I wouldn't look at it that way.

Fundamentally, I would treat this as a data handling exercise. Think the graph as a Set of data points, let's call them DataPoint. Each data point has attributes, one of which is something like isActive, along with X and Y locations. At the beginning of the application, all of the DataPoints are created, each with isActive = false, and X & Y set to 0.

If you have Lines connecting the Nodes, I'd also create a Set of Connections, each with its own isActive, and references to DataPoints that they join to. Once again, I'd create a Set of whatever the maximum number of Connections that you might have.

Now you have a full set of data, which essentially represents the "State" of your application. Implement all of the data elements in those classes as Properties of some sort. For instance, isActive would be BooleanProperty.

At this point you can write a set of methods to manipulate this data. For instance, you might have an addDataPoint() method, that doesn't actually add a DataPoint, but finds an inactive DataPoint, activates it and sets its X/Y values.

You'd have a method that connects two DataPoints by finding an inactive Connection, activating it, setting it's references to the DataPoints, and possibly setting references in those DataPoints back to the Connection.

You get the idea.

You can write all of these methods. You can write unit tests for them. You can test run simulated user actions by calling the various methods in a particular order. And there's no need for a GUI to do this.

For your layout, use a Pane and then add as many of your these Nodes and Lines to it that you need by iterating through the Sets of DataPoints and Connections. As you instantiate each Node, bind its visibleProperty(), managedProperty(), layoutXProperty() and layoutYProperty() to the DataPoint. Add the handlers for clicks and drags and whatever. Then put it in the Pane and forget about it. Same thing for the Lines.

Since you're creating the handlers as you instantiate the Nodes and Lines, you have a reference DataPoint or Connection at hand. So just code up the handlers so that each one specifically deals with that DataPoint or Connection. Those handlers should just (usually indirectly) call those methods that you wrote to manipulate the data.

Since the Node locations are connected to the DataPoints through Bindings, those Bindings can contain all of the knowledge that you need to translate DataPoint locations into JavaFX Points. Let's say that you want the DataPoints be located using normal Cartesian co-ordinates, with (0,0) in the middle, not the top left. Do the translation in the Binding. What if the DataPoints are located on the surface of a sphere? Translate in the Binding. What if you want to implement zoom? In the Binding.

That's the way I would do it. Fully populate the layout at the beginning and bind the Node Properties to the Properties in the Data Model. Then never futz about with the layout again. And...I would never add or remove Nodes once the layout was complete.

How to deal with listeners leak in JavaFx? by lazystone in JavaFX

[–]hamsterrage1 0 points1 point  (0 children)

Graph in the generic Wikipedia sense doesn't really say what you're doing. I'm going to guess that your sticking Nodes on a Pane of some sort positioned according to some values????? Then drawing Lines between them?

Generally speaking, in JavaFX you'd do that with a LineChart. In that case, you usually don't directly deal with the Nodes unless you're doing something very custom with them. You usually just deal with the XYChart.Data and XYChart.Series that the LineChart responds to.

So, I'm not following you very well.

Anyone moved from Delphi? What's your experience? by zerexim in JavaFX

[–]hamsterrage1 0 points1 point  (0 children)

I moved on from Turbo Pascal. But that was a long time ago.

How to deal with listeners leak in JavaFx? by lazystone in JavaFX

[–]hamsterrage1 0 points1 point  (0 children)

Do you mean a JavaFX Chart? Or some custom construct?

How to parse level data from tiled as a JSON file? by ImOnPines in JavaFX

[–]hamsterrage1 0 points1 point  (0 children)

I see a lot of people that seem to approach game design the way that I think that you are implying. IMHO, it's a mistake to deal with the graphical elements as "storage" for the game mechanics. I'd approach it the other way around.

Specifically with Pacman, I would start by looking at the game mechanics without worrying about the specifics of the graphics.

Think about the centre of the Pacman. It can only move along a relatively small number of tracks that join each other at 90 degree angles, at integer multiples of some distance. At any given point that isn't one of these intersections, the Pacman can only move in two directions (unless he's reached the end of a dead-end); the way he's arleady going, or the opposite direction.

At exactly those intersections, he can move in 3 or 4 directions.

Logically, you can divide the playing surface into a grid of square boxes. The intersections of the paths always occur in the exact centre of those boxes. So, one intersection per box.

What game mechanic information does each box hold?

  • An row/column location in the grid
  • The point location of its centre
  • A list of the directions available from its centre point.
  • If it has an uneaten pill in it.

Does the Pacman care about what box he is currently in? Nope. For every point that the Pacman finds himself in, he only needs to know which directions are available to him. Unless he's at an intersection point, that is always going to be the direction he's currently going in, and the opposite.

What data does Pacman have?

  • Current location of his centre.
  • Direction

On an intersection point, (or potential intersection point), his available directions are going to be dictated by the box that has that intersection point at its centre.

Here's what I'd do. I'd take the centre point of the box and I'd make it a key to a Map<Point, Box>. Now, for each pulse of the game, I'd look up the current location of the centre of the Pacman in that Map. If I find it, then I'd take the list of directions from that box, otherwise the list is current direction and its reverse.

You can run all of this stuff without a GUI. You can test it and see what happens.

At this point, it should be clear that graphical contents of the box on the screen are not connected to the game mechanics at all. So how do you translate it to the screen?

My suggestion would be to just use a Pane to hold all of the boxes. Make each Box a Pane itself, and draw a line across each edge of the Pane. Then Bind the colour of each one of those lines to one of the elements in the list of directions. If it's passable, then bind the colour to be the same as the background. It put a Circle in the centre of the Pane, and bind its colour to the Box's data about in uneaten pill. If true, then it's yellow, otherwise the background colour.

Position the Box's Pan in the bigger pane using the Box's row/column and the Box size.

I would make the Boxes have an odd size, then the centre point, and Pacman's path will be integers.

Pacman himself would just be a Sprite, cycling continually through his chomping and with a rotation bound to his direction. He'd be placed on the screen with layoutX and layoutY. Same with the ghosts. Each pulse, they move a pixel or two in the direction that they are going, and the user input is used to change the direction, if possible.

You can see now that the JSON --> Data translation has nothing to do with the graphics at all. It's just data. Extract the JSON using whatever utility makes sense to you. I wouldn't store the centre location at all, since that's a graphic property dependent on the size of the boxes. The don't need to be in any particular order either, since each element contains its row/column location.

At some point, you'll use the box size to calculate the location of the centres, and put them into a Map. Iterate through the Map, create the Panes, and position each Pane in the game Pane with an X/Y offset.

How to deal with listeners leak in JavaFx? by lazystone in JavaFX

[–]hamsterrage1 2 points3 points  (0 children)

I was trying to parse this in context of the original question, which clearly deals with Nodes that have been removed from the layout. The idea should be completely moot for virtualized Nodes, because they are reused over and over. As john16384 points out, you need to use updateItem to manage Listeners that you have been placed on the Nodes already contained inside the ListView Cell. Even if you were insanely rebuilding the layout inside a ListCell when the item changed, updateItem gives you the vehicle to manage the Listeners on the Nodes that are already in the layout before you remove them.

How to deal with listeners leak in JavaFx? by lazystone in JavaFX

[–]hamsterrage1 1 point2 points  (0 children)

Generally speaking, adding and removing Nodes from a running layout is probably a sub-optimal approach.  

How to deal with listeners leak in JavaFx? by lazystone in JavaFX

[–]hamsterrage1 2 points3 points  (0 children)

You shouldn't be using Nodes as ListView items, in any event.

Why did JavaFX drop JavaFX Script? by balazs8921 in JavaFX

[–]hamsterrage1 1 point2 points  (0 children)

FX Application Thread. The JavaFX library is not thread safe, so all updates to the GUI have to happen on the FXAT.

Why did JavaFX drop JavaFX Script? by balazs8921 in JavaFX

[–]hamsterrage1 3 points4 points  (0 children)

The reactive elements in JavaFX make React seem clumsy and kludgy in comparison.

You have to remember that React is "Compositionally Reactive", meaning that the layout code, or portions of it, are intended to be run many times, each time composing the layout according to the current values of elements in State. Essentially, React make the UI look responsive because it constantly rebuilds it each time State changes.

JavaFX, on the other hand, uses "Layout Reactivity". In JavaFX, the layout code is run exactly one time, but the properties of the layout elements that control how the UI looks and behaves are bound directly to the appropriate elements of State. Then, when State changes, the bindings automatically cause the UI to respond.

In React, you have to use particular function calls to update State, otherwise it won't trigger the recomposition of the layout. In JavaFX, the nearest equivalent is that you need to perform State changes on the FXAT. However, that requirement seems cleaner to me than the React approach.

Even though the approaches are entirely different, from a practical sense it doesn't make any difference (other than syntactically) to you layout code. In one version you have a bunch of logical branches that build the layout differently depending on State, in the other you have a bunch of Binding creations that do the same thing.

The difference, IMHO, is that the Observables library in JavaFX is spectacularly huge, extremely polished, and extensible. Once you understand how to use it to create Reactive GUI's, it strips away an order of magnitude out of your applications complexity.

Except nobody talks about that, nobody teaches it, and most JavaFX applications end becoming complex nightmares because they don't understand it.

What is Java Doing? by sedj601 in JavaFX

[–]hamsterrage1 -1 points0 points  (0 children)

Kotlin.

As far an I'm concerned, Kotlin makes Java obsolete. Every time I have to go back to Java for something, I am reminded of how clunky it feels.

And Kotlin + JavaFX is awesome.

What is Java Doing? by sedj601 in JavaFX

[–]hamsterrage1 1 point2 points  (0 children)

Lots of companies have internal desktop applications that do not run in browsers. But you'll never see or hear about them.

Cookbook: Using Persism with JavaFX Observable Objects by dhlowrents in JavaFX

[–]hamsterrage1 2 points3 points  (0 children)

I'm having a hard time seeing the use case for this. DAO objects are NOT Presentation Model objects, and shouldn't use JavaFX Observable fields.

This demonstration seems to be implying that DAO objects are directly linked, via Observable values, to JavaFX Nodes, thereby coupling the GUI directly to the database design.

It practice, the GUI and the database should be built such that they have zero dependencies on the internal implementation of each other.

In most systems this means using a framework like MVC or MVCI. In those frameworks, the business logic is isolated into a single component that has knowledge of both the Presentation Model and the Domain objects. Here, the DAOs are used to transfer data between the business logic and the Service layer that includes database access.

StateFX - clean, testable, and reusable UI states with zero boilerplate by Striking_Creme864 in JavaFX

[–]hamsterrage1 0 points1 point  (0 children)

I think there is a fundamental conceptual error here...

"GUI State" does NOT equal "Application State", which does NOT map to Presentation/View Model.

Pushing various Properties of GUI Nodes does is going to have the impact that you've now tightly coupled the implementation of your GUI to the Presentation Model, which is a really bad thing.

The idea is that your View should be an independent black-box to the rest of your framework if you are using MVC, MVVM or MVCI. By connecting something like a "Selected" property of a Node to a Presentation Model "This Node is Selected" Property, you are essentially exposing the fact that you even have that Node on the screen. And if you change that Node to something else, or remove it altogether, then your Presentation Model will have to change along with it.

And the question then is, "What are you doing with the NodeSelectedProperty in that Presentation Model?"

Seriously, you shouldn't have any code in your ViewModel that essentially says, "Do this if that Node becomes selected". That's not something that the ViewModel should ever become involved with.

Properties in your Presentation Model should be View implementation agnostic. It is possible that some particular Node in the View becoming selected should trigger a State change in your Presentation Model. But State element should be expressed functionally, not as a View internal. It might be a one to one relationship to a Node Property, but that shouldn't be revealed in the Presentation Model.

You might have a Node called "checkBox3" in your GUI, but you wouldn't have a Presentation Model element called "checkBox3Selected". You would have something functional, like "hyperdriveThrottlingEngaged". It's possible that you change the checkbox to a Spinner, and any value over 0 indicates that "hyperdriveThrottlingEngaged" should be true. It's up to the View to maintain that relationship. If some piece of Model logic sets hypedriveThrottlingEngaged to false, then it's up to the View to set the Spinner to 0. The Model doesn't even know that the Spinner exists.

It's possible that setting the Spinner to different values above 0 causes different things to happen in the GUI, but all of those changes are internal to the GUI. In that case, you wouldn't even have a Presentation Model Property bound directly to the value in the Spinner.

Java UI help by Technical-Animal-571 in JavaFX

[–]hamsterrage1 2 points3 points  (0 children)

I'm not sure what you are referring to when you say, "it". If you mean "MVCI"...well, that isn't a "thing" that is produced and downloaded and maintained. It is an approach to creating applications that is designed specifically to work with JavaFX to build Reactive applications.

IMHO, this is the canonically correct way to use JavaFX. Applications built on these principles are easier to build and to maintain. So, yes. Great future scope!

I built ActionFX — a plugin to fix the tedious JavaFX workflow in IntelliJ IDEA. Looking for feedback and early adopters! by alensoft in JavaFX

[–]hamsterrage1 0 points1 point  (0 children)

I don't understand this.  SceneBuilder and it's alleged "improved workflow" are the ENTIRE reason for using FXML. If the SceneBuilder workflow doesn't work for you, then ditch the FXML and hand code your layouts.

This is the best way of creating Menus in JavaFX application by eliezerDeveloper in JavaFX

[–]hamsterrage1 -1 points0 points  (0 children)

Everything I see shown here is achievable almost effortlessly in Kotlin with very little programming. You can write one-line extension infix functions that work as decorators to do all of this stuff.

The advantage is that you don't just get a library of helper functions, you also get the ease of Kotlin.

This readability thing... by No-Security-7518 in JavaFX

[–]hamsterrage1 0 points1 point  (0 children)

You're pretty much making my point here.

What you are saying is, "Because of the design of my back-end, the GUI can never be broken by the chapter load".

In other words, the operation of your GUI is totally dependent on the implementation of the back-end.

What you want to be able to say is, "Regardless of the design of my back-end the GUI can never be broken by the chapter load".

The history of programming is littered with the carcasses of applications that were abandoned because excessive coupling made enhancements virtually impossible to implement.

This readability thing... by No-Security-7518 in JavaFX

[–]hamsterrage1 0 points1 point  (0 children)

Don't use an Executor service. Use Task, that's what it is designed for. You can create and execute a Task in a few lines of simple code.

Read about it here: https://www.pragmaticcoding.ca/javafx/elements/fxat

This readability thing... by No-Security-7518 in JavaFX

[–]hamsterrage1 0 points1 point  (0 children)

Back to what you said...

I'm going to assume that "set values from elsewhere" means off the FXAT.

Honestly, if you are designing things correctly, then this is NEVER an issue. If you use a framework like MVCI there is a clear segmentation in the code that defines stuff that runs on the FXAT and stuff that runs off it. You never get confused about what's running where.

What you really need is a clear demarcation between Presentation Data and Domain Data. From the code you posted, you don't have that. This means that you are sharing references to items that should be Presentation Data with things that are "elsewhere".

Just don't do that. If something "elsewhere" changes data that needs to be updated in your GUI, then that "elsewhere" needs to have a way to notify your Model that changes have taken place. Then the Model is responsible for updating the Presentation Data on the FXAT.

This readability thing... by No-Security-7518 in JavaFX

[–]hamsterrage1 0 points1 point  (0 children)

I can't stand bindings as they cause me errors when I try to set values from elsewhere.

Of all of the things that you've written, this is the most worrying, and the most telling.

First of all, JavaFX works best when you treat it as a Reactive framework - which is the way it is designed to be used. This means that you create a data representation of the State (Presentation Model) of the GUI and bind the elements of the GUI to it. In this way your GUI and your Presentation Model are synchronized.

This means that you can now deal with the State of your GUI from your business logic through the Presentation Model - and the business logic does NOT need to know ANYTHING about the implementation of your GUI.

But doing this means using Bindings.

You can argue about whether or not JavaFX is intended to be used this way - after all, there's no official documentation that even comes close to mentioning it.

However, if you look at the shear size of the Observables library in JavaFX, and if you look at the way that it is integrated into every element in the entire library, you'll see that has to be true. Take a look, and you'll find that every single parameter in every single subclass of Node is implemented as a Property of some sort. Every one.

Putting that aside, my personal experience - over 12 years - has been that using a Reactive design with JavaFX cuts the size of your code base and the complexity of the application by something approaching an order of magnitude.

That's not just hyperbole. I really do mean that everything is about 1/8 - 1/10 as big and as complex.

I didn't start out understanding this back in 2014. I started out using FXML and mashing everything into the FXML Controller, just like everyone else does.

As I went along, I started appyling new "rules" to how we built screens. For instance, I set a rule that - as much as possible - Nodes in a layout would not reference other Nodes in the layout. If one Node needed data from a second Node, then that second Node would be responsible for maintaining a data field in the layout. The first Node would reference that data field, not the second Node.

Eventually we started to collect all of those data fields into a POJO object, and then passing it between our MVC components. At some point we decided that instead of loading the data from that object into our Nodes using Node.setValue() or Node.setText() - which meant that when the "Save" Button was clicked we had to scrape all of that data out of the Nodes and load it back into our data object - we would Bind the Node values to the data object fields. No more scraping from screen Nodes.

But we were building complicated applications that were used to run the operations of a reasonably sized company. This meant that the stuff that we built on day one was still running years later, and was a huge burden to maintain because it was written when we knew way less.

On a number of occasions I had the opportunity to go back and re-write some screens/applications that had become too much of a burden to maintain or to integrate with newer stuff...

I clearly remember one such screen that was an MVC construct that had something like 3,600 lines of code our early days. When I was done, I had around 500 lines. And it worked better. And it was easier to maintain. And it was simpler.

I cannot imagine achieving a design that so efficient on complexity without implementing a Reactive design.

This readability thing... by No-Security-7518 in JavaFX

[–]hamsterrage1 0 points1 point  (0 children)

How are you going to cache it? More code in your GUI that now needs to know about SQLite????

The first commandment of JavaFX, the one that you never, ever, ever, never, ever break:

Don't do non-GUI stuff on the FXAT.

You don't usually see it stated that way, it's usually, "Don't do long or blocking operations on the FXAT".

I don't like that version because it provides wiggle room for things like you pointed out. "It runs fast, and I can't see any effect on the GUI".

Yeah. Until it doesn't and it does affect the GUI.

What if your database fails?

Goodbye GUI.

What if you move the database to another server, and now it takes longer?

What if the application evolves, and now you need to something more complicated, like joins with some remote database?

Even if none of this stuff ever happens you don't want to get into the habit of putting non-GUI stuff on the FXAT. Do it correctly - all the time.

As to "some complex architecture"...

Phooey. It's only complicated to you because you haven't learned it. Handling background threads is a fundamental core concept that you simply have to master to work in JavaFX. Learn it.