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
Related
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);.
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.
I'm currently working on a GWT application and I'm still a little fuzzy on how it all fits together (the joy of having to make changes without first coming to an understanding of the whole framework, although that might be difficult anyway).
We have a few Activities that all correspond to parts of the UI (e.g. main content, a toolbar and a list of things). I'm not really sure whether that's even how Activities are intended but I guess I can't really change that easily now. My problem now is that the list of things holds state (the current selection) that the main content also needs and in a way the toolbar too (at least the toolbar currently has it – I'm beyond asking).
But what would actually be an appropriate place to store that? I guess coupling the actual view implementations together and storing the selection only in the list isn't such a bright idea.
I see two main solutions here:
keep the state within each activity and keep them synchronized through events (on the EventBus). That is: the "list of things" has a current selection, main view has one too, so does the toolbar; and each time that value changes, the activity that's making the change fires an event on the event bus so that the other activities can update their state, so that all activities have the same value in their own state.
use a singleton object (if you're using GIN and dependency injection, simply annotate the object with #Singleton and inject it in all the activities) to keep the state at a central place. The activities register event handlers on the state holder object to be notified when it changes. That is, each time an activity calls setCurrentSelection (for example), an event is fired (for example a ValueChangeEvent), and because all activities listen for it, they can update their view or whatever depending on the new value. You can choose to either dispatch the event on the event bus (similar to the PlaceController) or have the state holder implement HasValueChangeHandlers. Just make sure to unregister the handlers when the activities stop to avoid memory leaks (dispatching on the event bus makes it easier: simply register the handlers on the bus passed as argument to the start method and they'll be unregistered automatically when the activity stops, and you don't even have to think about it).
Actually, PlaceController is a good example of such shared state (the current place).
In our project, we're using gtkmm and we have several classes that extend Gtk::Window in order to display our graphical interface.
I now found out what call produces the behaviour (described in the previous revision. The question now slightly changed.)
We're displaying one window, works like a charm.
Then, we have a window which displays various status messages. Let's call it MessageWindow. It has a method setMessage(Glib::ustring msg) which simply calls a label's set_text().
After some processing, we hide this window again and we now show a toolbar. Just yet another simple window, nothing crazy.
For all windows applies: The main thread calls show() on the window and creates a new thread which calls Gtk::Main::run() (without argument).
That's how it should be, until now.
The problem starts here: The main thread now wants to call MessageWindow::setMessage("any string"). a) if I call this method, the message window reacts completely correctly. But afterwards, the toolbar-window is displayed empty. b) if I don't call it, the message window doesn't change the label (which is absolutely clear), and the toolbar window is displayed as it should.
Seems like the windows are messing up each other.
Now the question:
If my gui-thread is blocking in Gtk::Main::run(), how can I now change the text of a label?
We're using gtkmm-2.4 (and no, we cannot upgrade)
Any help is appreciated.
Wow! That's complicated...
First: you should not manipulate windows from several threads. That is you should have just one GUI thread that does all the GUI work, and let the other threads communicate with it.
It is theoretically possible to make it work (in Linux; in Windows it is impossible) but it is more trouble than it is worth.
Second: the line Gtk::Main main(argc, argv) is not a call, it is an object declaration. The object main should live for the duration of the program, so if you use it in a object constructor, as soon as you return from it, the object will be destroyed! Just put it at the top of the main function and forget about it.
UPDATE: My usual approach here is to create a pipe, a g_io_channel to read, and write bytes on the other end.
Other option, although I didn't test it is to call get the GMainContext of the main thread and then g_idle_source_new() and attach that source to the main context with g_source_attach(). If you try this one and it works, please post your result here!
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.