Rendering JavaFX 2 charts in background - charts

I have an application that is used for data analysis. A big part of the application is the ability to be able to show charts based on the data assembled, and to be able to export a large number of tasks in one batch-operation. Up until now I have used JFreeChart, but I would like to use the native JavaFX Charts so that the exported charts will still look the same as they do on-screen in the application.
I am on JavaFX 2.2.1 (jdk 7u6).
I am able to generate the charts in one batch, but that means that I have to freeze the User Interface (UI), as these charts have to be rendered on the JavaFX Application Thread. I use the Platform.runLater(new Runnable() { ... }); command for this, wrapped around the code that generates the charts.
If I instead wrap each individual chart generation into a Platform.runLater(new Runnable() { ... }); The GUI doesn't freeze up as before, but I will also get no feedback because I am unable to detect when each of the individual charts are generated (they are ran at a later stage, and I have no control over when that might happen, and there is no callback available as far as I know either).
For this particular event I would like to show a progress bar to the user, and I want this progress bar to be updated along with the actual chart generation.
Any suggestions or hints as to how this can be achieved ?

This question was solved in the Oracle JavaFX forum thread: Render charts in background.
The solution was to have a SaveChartsTask with three subtasks:
Create charts in an off screen scene graph.
Take snapshots of each off screen chart to an JavaFX image.
Use imageio routines to export the JavaFX images to files.
The workDone properties on tasks allowed the process of the operations to be monitored. By splitting the total work up into subtasks, keeping work off of the JavaFX application thread when possible and making use of CountDownLatches and BlockingQueues as necessary to synchronize operations, the UI was able to remain responsive.

Since it seems that you are new to JavaFX-2. I recommend you to read the JavaFX-2 Concurrency article from oracle documentation.
Your problem is easily solved by using the Task Object to load your charts individually (One Task per Chart for example). Quoting the tutorial page:
Tasks are used to implement the logic of work that needs to be done on a background thread.
Since Task implements the Work Interface, you can use your Tasks to probe for their Worker.State. Quoting the manual:
A reusable Worker will transition from CANCELLED, SUCCEEDED or FAILED back to READY.
This would solve your problem about feedback since you'll always be able to know if a Task is still Running or not since the Worker.State object has the following possible States:
CANCELLED
FAILED
READY
RUNNING
SCHEDULED
SUCCEEDED
As for your progress bar, you can use the updateProgress(double done, double max) to set your Task progress and then simply set the progress of your progress bar by binding the ProgressBar.progressProperty() to Task.progressProperty().
EDIT
Answering to your comment:
The problem is that the work performed inside the Task in this case in the generation of the JavaFX Chart, and that code needs to be executed inside the JavaFX Application Thread
From the tutorial:
Instead, use the JavaFX APIs provided by the javafx.concurrent package, which takes care of multithreaded code that interacts with the UI and ensures that this interaction happens on the correct thread.
Which means the code executed inside the Task object is already being executed in the JavaFX Thread.
I hope it helped. Cheers

To run a JavaFX Task on the JFX thread, you can schedule the task to be run with Platform.runLater(myJFXTask);.

Related

eclipse RCP4 Add Toolbar to Parts

How to model a toolbar ONCE and render it in some Parts/Views (not in the default place which is the window!)? Using the model level (and maybe Addons?)
I have currently
Eclipse 2022.03-4.23
Application.e4xmi with that Toolbar but
Gets added dynamically using an Addon that listens to "PART_ADDED" event topic which
Leads to a NPE due to other event topic "UIEvents.Part.TOPIC_TOOLBAR" within a framework method in a class called LazyStackRenderer
So the guy before me had written an Addon to dynamically add the Toolbar to the parts. Maybe to make the buttons save/print per part or because the main layout has two stacks and only the parts stack is relevant.
Appreciate any help! I searched a lot but no success!
I solved it so far. The dynamically created MParts were not added as children to the container (in my case the PartStack) in the first place and also had to comment the adding of placeholder objects that carry the same information of the parts. This dynamic step was done as a reaction to the topic #UIEventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) in some written Addon.
I am not a 100% sure that discarding the placeholders is safe but still this is the best trail I have ever reached.
I hope this would help others!
Thank you #greg-449

Eclipse RCP :- If a view contains huge selection like 4000 objects then applications takes time to show context menus

We have built a large scale application over eclipse rcp framework. This issue we are facing across the application if large number are objects are selected say 4000 or 5000 objects. In this case, following actions takes time and UI goes in Not Responding state.
1.Select and Right Click Context menu display
2. Keeping selection, change the view and come back to earlier view.
3. Keeping selection, change the application(like excel, word) and come back to view.
My analysis says, the eclipse rcp takes time to evaluate the menu contributions and handlers for the current selected objects. We are also using Property Testers nested inside Iterate expression which I think is taking time to evaluate. Pain is it does the evaluation every time I switch the view and does not cache the result.
I need your opinion:
Has anyone else encountered this issue before? Is there any good way to handle large selection in handlers, menu contributions which will improve the performance.
Thanks in advanced.
~Prasad
It might be that the main problem are your property testers, because those are evaluated each time something changes visually in your app: new shell (like menu, dialog, wizard etc.) is opened or some panel is expanded/collapsed or you switch perspective or view/editor or you go switch application.
May be as a first step you could try to disable those (or make them dummy and do nothing/or constant action) to see if it affects performance of the application. If it does, then you might think about redesigning your application and replace property testers with, for example combination of org.eclipse.ui.AbstractSourceProvider and org.eclipse.ui.contexts.IContextService.
I am not sure, of course, about your real use cases, but here is some idea:
Source providers can also be used within plugin.xml as a variable.
Then you can register a bunch of contexts (I am not sure, of course, about real use cases, just suggesting here), which can be programmatically activated under some conditions:
final IContextService contextManager = (IContextService) activeWorkbenchWindow.getService(IContextService.class);
contextManager.activateContext("your context id");
Another step would be to register context activation listeners:
final IContextService contextManager = (IContextService) activeWorkbenchWindow.getService(IContextService.class);
contextManager.addContextManagerListener(new IContextManagerListener() {
#Override
public void contextManagerChanged(ContextManagerEvent contextManagerEvent) {
if (!contextManagerEvent.isActiveContextsChanged()) {
return;
}
[process context changes: possibly notify source providers about context changes]
}
});
Make your SourceProvider listen to context changes and refresh state, when something has been actually changed:
#Override
public void contextActivated() {
fireSourceChanged(getSourcePriority(), refreshState());
}
If it is not the case or not possible in you application, then, may be, some other workaround would be to introduce caching in source provider or improve your algorithm performance, by, for example, making some long running operations on parallel with multiple Thread. If you are using Java 8 this should be fairly easy.
Of course there is always a case, that SWT is slow by itself to redraw all the widgets - in this case you may be should look into using alternatives to standard SWT widgets with better performance. For example, using Nattable instead of default SWT/JFace viewers.
I hope this could give you some ideas.

GWT event handlers blocking UI

I'm new to GWT. I creating a MVP based project (as described here) that uses a number of custom events. There are several widgets (10+) that listen for some global events and perform some action (including writing to the DOM) in the event handlers.
What I'm finding is that the UI blocks and doesn't update until each and every one of the handlers for the one event finishes processing. This is causing the UI to perform slowly on page load and for any other events that cause the widget to update.
I created a similar project in plain JavaScript/jQuery and this was not an issue with that project. In fact, the UI was blazing fast. What am I doing wrong here? The documentation states that GWT is very performant, so I have to conclude that I'm just doing it wrong.
One example, I have a drop down that selects a date preset (like Yesterday, or Last Week). When this happens I set the selected preset in the model like so:
public void setDateRange(DatePreset dateRange) {
this.dateRange = dateRange;
eventBus.fireEvent(new DateChangedEvent(dateRange));
}
Each of the widgets has access to the same eventbus and registers to handler DateChanged events. Each of the widgets needs to do a fair amount of logic and processing (including making an ajax call) to then update itself with correct data.
#Override
public void onDateChanged(DateChangedEvent event) {
DatePreset dateRange = event.getDate();
… additional processing and logic
… ajax call
}
I've determined after some basic profiling that each widget requires about 100-150ms to finish processing (which means there's a UI delay of over one to two seconds). When I say blocking, I mean the dropdown where I selected the date preset doesn't even close (and I see the spinny wheel) until everything finishes.
What can I do to make this run faster (and without UI blocking)? I am open to any ideas. Thanks!
Measuring the speed of the project in developer mode can be a reason for this extreme slowness.
You can check out the real speed of the application if you deploy it to an appserver or if you delete the &gwt.codesvr=127.0.0.1:9997 part from the end of the url in devmode.

Difference between syncExec() and asyncExec() of Display class

I'm working on a plugin project in which I'm using Eclipse background processing.
What's the difference between the syncExec() and asyncExec() methods of the Display class? In which situations are they applicable? Any example could be helpful.
from Q: Why do I get the error "org.eclipse.swt.SWTException: Invalid thread access"?
To allow background threads to perform operations on objects belonging to the UI-thread, the methods syncExec(Runnable runnable) and asyncExec(Runnable runnable) of Display are used. These are the only methods in SWT that can be called from any thread. They allow a runnable to be executed by the UI-thread, either synchronously, causing the background thread to wait for the runnable to finish, or asynchronously allowing the background thread to continue execution without waiting for the result. A runnable that is executed using syncExec() most closely matches the equivalent direct call to the UI operation because a Java method call always waits for the result before proceeding, just like syncExec().
Adding to Tom Seidel's answer, here are examples of situations where you might want to use one or the other:
Use asyncExec when you want to update something in the UI without caring about the results. For example updating a label or a progress bar.
Use syncExec where the code following that method call needs to be sure that the UI is in a consistent state, or needs some data from the UI. For example getting some data from a user dialog. Or you update a widget and before doing anything else (e.g. another UI update) you want to know that the widget update has completed.
SWT implements single threaded UI model. In this model, only the UI-thread can invoke UI operations. If you try and access an SWT object from outside the UI-thread, you get the exception "org.eclipse.swt.SWTException: Invalid thread access". So to allow other threads to perform operations on objects belonging to the UI-thread, SWT provides syncExec and asyncExec methods.
This link may help you with an example

How do you update a JFace Viewer from inside a Job?

Caveat: I'm still struggling with proper MVC in Eclipse plugin development, so if you see anything here that is most likely causing me more pain that I should be enduring, please let me know.
The question:
I have a View with a JFace Tree Viewer and a Table (not a table viewer... that will be changed down the road).
I have an action that is initialized with a reference to the View (this seems terrible to me, but I don't yet know how to do it the right way). When the action is run -- via a button on the view -- the action:
1) gets the Tree Viewer from the View
2) gets the underlying model
3) creates a Job
a) inside the job, loops over the model and does various things to it, including adding additional children into the model
b) uses a function exposed in the view that "clears" the Table in the view
4) adds a JobChangeListener that implements "done()".
a) inside the done() method, it expands the treeviewer via this code:
loadMethodsJob.addJobChangeListener(new JobChangeAdapter(){
public void done(IJobChangeEvent event){
view.enableActions();
view.getTestsViewer().expandAll();
}
});
Inside the Job, whenever I attempt to access the elements in the viewer, I get Invalid Thread Access errors. I believe I understand why I get them when running inside the job, but I'm not sure how to work around them correctly if I can't interact with the widgets in the job change listener. I can get it to work if I wrap every interaction with the widgets in a getDisplay().synchExec(....), but I seem to remember reading that this is not preferable.
I feel like I'm on the cusp of a big leap in understanding with Eclipse SWT, so I appreciate any guidance in getting there.
Any UI component in SWT can be accessed only by a UI thread.
Since the done method of the job runs in a separate non-UI thread, the invalid thread access is fired.
By wrapping every interaction in a Display.syncExec , you are making sure that it runs in the display thread (The UI thread).
There shouldn't be any problem with the above approach.