Open a new scene before it initializes everything in JavaFX - multithreading

I'm doing some kind of social, it's when i open a post a new scene is created which initializes the elements with the data taken from the database. the problem is that the big photos take time to load, and until they load the program does not respond, I would like a way to be able to open the scene first so as to wait until the image loads without the program crashing
public void init(int idpost) throws SQLException {
this.post = new PostDAOImpl().getPost(idpost);
photo.fitWidthProperty().bind(imgContainer.widthProperty());
photo.fitHeightProperty().bind(imgContainer.heightProperty());
photo.setImage(new Image(post.getPhoto()));
name.setText(post.getProfile().getName());
username.setText("#" + post.getProfile().getUsername());
if (post.getProfile().getAvatar() != null)
avatar.setImage(new Image(post.getProfile().getAvatar()));
description.setText(post.getDescription());
}
here is the code, which is executed as soon as the scene loads. I was thinking of doing another DAO to first fetch all the data except the photo, load the scene and only then fetch the image or something like that, but I don't know how to do it

I think it is always a good idea to create and show a GUI in the empty state quickly first and then launch some background task to collect the data and once this data is available update the GUI. Just think of a word-processor GUI. When you launch it it's in the empty state without any document. Then the user selects a document which gets loaded and as soon as the data is available the GUI changes and displays the document. The only difference in your case is that you already know which data you want to load.

Related

Windows 10 IoT Core, Sharing SPI data

My windows 10 IOT core application uses SPI to collect change notifications of
many entities. There are excellent examples for launching a timer to get SPI data, update data and binding UI elements to this data. The result is anytime SPI gets some data about a changed entity, the data that drives the UI is updated and any UI element bound to this data is updated. I can even change what subset of data is displayed on this page by using two way bindings to track the selected items on a list.
Just like the many examples, my code is structured as follows:
public async void Init_SPI()
{
....
periodicTimer = new Timer(this.TimerCallback, null, 0, 10);
} // public async void Init_SPI()
private void TimerCallback(object state)
{
/* UI updates must be invoked on the UI thread */
var task =
this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{ ... update states of data that many be bound to UI element
My issue / question:
I don't see how to update data for multiple pages based on the above, since this.variable refers to the UI thread of the page that launched the timer.
It would be too inefficient to update a static class and have the multiple pages continuously poll this static data to make the UI track these large number of element.
My only thought at present is to code all the XAML pages in one page and tab between these "virtual" pages. I would rather have multiple pages to keep the functionality of these pages separated.
Any suggestions for how I could update multiple pages from data read on a SPI port would be appreciated.
Regards,
John
Sorry for a very late answer, but my solution would be to still create "real" pages -- but "relayed" the data only to the currently visible page. So whenever a page becomes visible I would have made the internals of the code piece above { ... update states of data [...] to point out that page.
This could be achieved with a simple switch statement, or by a simple interface with a HandleSpiData(TheSpiData) method -- or even a simple Action<YourSpiData>.

Is there a paint or update method (rendering loop) in JavaFX2 so that I can update the UI in a loop?

In Swing you have paint or update(Graphics g) method for each UI component which executes every frame. You can put your drawing logic in the overrided method and draw whatever you want. What is the paint method for JavaFX2 UI?
What I want to do is my UI receives control information from a socket server (another thread). Whenever a control information is received, I should update the UI.
There are two problems:
1. The control information is received from a different thread, it can not access the rendering thread directly.
2. How to update the UI constantly?
For Q1, I have a solution if I know where the update function is (Q2).
I can declare a List object, and insert the new control command received from the socket into the list. In the rendering loop, I can just observe the List object, retrieve the unprocessed command, and delete the already processed command.
However, where can I find such a rendering loop function? I guess maybe I can also do it with javax.concurrent.Task, but I don't find a way to do it.
I think i find the method, I use the following method and it can work. I don't know if there is a better solution
final Duration oneFrameAmt = Duration.millis(1000/10);
final KeyFrame oneFrame = new KeyFrame(oneFrameAmt,new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent actionEvent) {
//put UI update here
}
});
TimelineBuilder.create().cycleCount(Animation.INDEFINITE)
.keyFrames(oneFrame)
.build()
.play();

MonoTouch: How to update a view [duplicate]

I have a problem that the ViewWillAppear method for a UIView does not fire when the application returns from the background. This is a problem, as my main application screen is showing values that are retrieved from the user settings, and if the user has changed these while the application was in the background I need to have the screen refreshed. I have read that one should register for the UIApplicationWillEnterForegroundNotification using NSNotificationCenter.
How do you do this in MonoTouch? Or does anyone know an alternate way of ensuring that the screen is always kept up to date, even when returning from the background?
You could try something along the lines of:
//Register for the notification somewhere in the app
NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.WillEnterForegroundNotification, EnteredForeground);
//snip
void EnteredForeground (NSNotification notification)
{
// do your stuff here
}
Bear in mind you would need to do this for every view controller you'd like to update when enterting from the background!

GXT custom event handler code executes multiple times

I have implemented MVP pattern in my GXT project. The system registers customers as part of it function. Also the system user can search for the registered user providing the id.
i have added an OnClick event to the "search customer" button.
/* On click search button */
view.getBtnSearch().addListener(Events.OnClick, new Listener<BaseEvent>() {
#Override
public void handleEvent(BaseEvent be) {
eventBus.fireEvent(new CustomerRegistrationTabSelectionEvent(0, false));
eventBus.fireEvent(new CustomerFetchEvent(view.getValueCustSearchParameter(), view.getValueCustSearchValue(), true));
}
});
The CustomerRegistrationTabSelectionEvent does select the relevant tab and enables other tabs. Thats all it does.
Here is the handler for the custom event CustomerFetchEvent.
eventBus.addHandler(CustomerFetchEvent.TYPE, new CustomerFetchEventHandler() {
#Override
public void fetchCustomer(CustomerFetchEvent event) {
searchCustomer(event.getParameter(), event.getParameterValue(), event.isOpenFirstTab());
}
});
The issue is the search customer method is executed multiple times and if there is a invalid search the error message dialog shows multiple popups. Within the searchCustomer method i call for service which fetch me the customer data or show the popup error message if the search is invalid.
im using GXT 2.2.5 and JRE 1.6.
Could anyone help me in finding out why the code is executed multiple times?
Added Later:
When i run the application first time the code is only executed only once, therefore only 1 popup. Then i logout of the system and log in again (navigating to the same page where the "search customer" button exists.) and the code is executed twice. Likewise equal to the number of times i create/navigate to the particular page, the code executes. Is it actually adding the event handler code without removing the last one every time i recreate the page?
Yes, it seems that 'addHandler' adds handler multiple times, but stores previous context. Your code should add handlers only once, on initialization phase. You can check the number of handlers with 'getHandlerCount' method.
Ya. I fixed it!Here is the solution Unbinding presenters necessary in GWT
U can read more here. http://draconianoverlord.com/2010/11/23/gwt-handlers.html
what happened actually was, the presenter objects where i have registered with HandlerManager to receive events were not garbage collected. Because though i remove the reference to the presenters still the HandlerManager holds a reference to those objects. So every time i kept on creating new presenters on top of the old presenters of the same class. so a event is listened by multiple objects of the same class. so u need to ensure that the unused presenters are garbage collected by removing the registered handlers
in HandlerManager.

QWebView setContent in a separate thread

I have an application that requires to use QWebView::setContent() to load some HTML content to a QWebView. All of this happens on an embedded device with ARMv5 processor (think 400 MHz). Most of the time, I can load the page in reasonable time (up to 5 seconds), however sometimes I have content that takes long time to load (~30 seconds for 300KB of content).
The problem is that the setContent call blocks the main thread. I need to be able to process events during the loading, and maybe even cancel the load if the user decides not to wait any longer.
I was thinking about running the setContent call in other thread, so that it does not block the event processing and I can cancel it if necessary. However, I get the dreaded "widgets must be created in the GUI thread", and I see no way of solving this easily.
Is it possible to run QWebView::setContent in a separate thread? If so, how? If not, is it possible to handle GUI events while setContent is running? Is it possible to "cancel" the setContent call?
EDIT
To clarify a bit more, what really interests me is how to be able to stop the setContent call and/or handle GUI messages, so that the interface remains responsive, with large amounts of data passed using setContent.
EDIT 2
To clarify even further, I am dealing with long, static content, i.e. no JavaScript, just a lot of static HTML, through which the user wants to scroll even while it is loading more content. The main idea is to allow her/him to go down a page even when the page is not fully loaded.
Some time ago I faced a similar problem. As far as I know, only the main contents of the page is acting synchronously.
The fact is that the GUI core "paints" the page and this is time consuming. So, the main thread gets freezed until the main contents is loaded completely.
In my case, the solution was simple: make the main contents a secondary one and work with local files!!!
So, what is my proposal:
1) Prepare a local file (/tmp/loader.html) that contains something like this:
<html>
<body onload='setTimeout(function() { window.location="contents.html"; }, 1000);'>
Loading...
</body>
</html>
2) Each time you need to load a new content, save it to the secondary file (/tmp/contents.html) and force the update of the loader (maybe also a refresh). Easy:
QFile f("/tmp/contents.html");
if (f.open(QFile::WriteOnly)) {
qint64 pos = 0;
while (pos < contents.length()) {
pos += f.write(contents.mid(pos, 1024)); // chunk of 1024
qApp->processEvents();
}
f.close();
webview->setUrl(QUrl::fromLocalFile("/tmp/loader.html"));
}
Observe that I permit the event loop to process pending events if the file saving is also slow...
3) Anytime you need to cancel the loading, you can load another contents, remove the contents file, or other possible approaches.
Note that, as far as I know, you would never make asynchronous the painting of the contents. And that is the real issue in embedded systems.
Since QWebView::setContent() is a blocking call, I ended up using a work-around. The main idea is that XML processing is much faster than rendering the page. Therefore I do the following:
Parse the document as XML DOM document (a reasonable assumption in my case), and find the body element.
Keep only a pre-defined number of child elements of body (something like 20 elements). Store the remaining elements in another XML DOM document.
Show the initial document (serialized XML) using QWebView::setContent(), which is relatively fast. Start a timer with timeout 0 on SLOT(loadNextChunk()).
loadNextChunk() moves another 20 or so elements from the backup document at the end of the body using body->appendInside(html), where body is a QWebElement.
Stop when no more elements are available.
This works because in between the calls to loadNextChunk(), the GUI has a chance to react to events.
QWebView, as its name suggests, is a widget. QWebPage, on the other hand, is a plain old QObject, with all the threading goodness you could possibly want.
Now tie it together:
void QWebView::setPage ( QWebPage * page )

Resources