How do I "restart" a JavaFX Application? - graph

I've been coding a simulation in Java and now generate graphs of the results in JavaFX. However, I'm stumped as to how to call the graphs so that when I try to run the simulation (and generate the graphs) for a second time, I don't get the "can't call launch() more than once" error. I read that launch() can only be called once, so what do I need to change to call the graphs successfully on a second run of the simulation?
public class AnswerWorker extends SwingWorker<Void, Integer> {
protected Void doInBackground() throws Exception
{
AMEC.runsimulation();
return null;
}
protected void done()
{
try {
Graphs.launch(Graphs.class, "");
JOptionPane.showMessageDialog(InputGUI.this, AMEC.unsuccesfulpercentage + "% of iterations had trucks that had to sleep over");
AMEC.unsuccesfulpercentage = 0;
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
with a pretty standard graphing class:
public class Graphs extends Application {
#Override public void start(Stage stage) {
....
stage.show();
}
}

Why are you using SwingWorker in a JavaFX application? If your graphs are computed for display in a JavaFX application, there is no reason for you to use the Event Dispatch Thread (AWT). If I'm not mistaken, With the release of JDK 8, the JavaFX Application Thread and the Event Dispatch Thread will become one, so there is no reason (yet) for you to use SwingWorker. If I really am wrong, still, there is no reason for you to use SwingWorker. Although it is possible the coupling of Swing components in JavaFX applications, you should only use EDT when manipulating Swing components, not JavaFX nodes. The following link says this:
...The JavaFX application thread is a different thread from the Swing and AWT Event Dispatch Thread (EDT), so care must be taken when embedding JavaFX code into Swing applications...
Source: http://docs.oracle.com/javafx/2/architecture/jfxpub-architecture.htm
To learn how you can put processes to be done in the background, and also find out which thread is responsible for handling the JavaFX elements, check out this link:
http://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm
Regarding your question, I believe the beginning of a JavaFX application should be called only once. So much is, that when a JavaFX application is started, the thread of main method is captured, and is only returned when the JavaFX application is finalized. Just see the Application DOC (Especially this part). Note also that the life cycle of a JavaFX application is given by the following steps:
Life-cycle
The entry point for JavaFX applications is the Application class. The JavaFX runtime does the following, in order, whenever an application is launched:
Constructs an instance of the specified Application class
Calls the init() method
Calls the start(javafx.stage.Stage) method
Waits for the application to finish, which happens when either of
the following occur:
the application calls Platform.exit()
the last window has been closed and the implicitExit attribute on Platform is true
Calls the stop() method
You might be using the wrong approach. I believe that you should leave your JavaFX application running while you're processing something. Once you have processed what you want in the background, you should make your JavaFX application show the results. The way your JavaFX application run while something is being processed in the background is entirely up to you. Maybe you should hide the window while something is processed, and display it again with your chart done. As I said, this is something you will have to decide. I recommend you to take a look at the documentation of classes referring to the window system, starting with Window, and then Stage.
Any questions, we're here. Good Luck! :)
EDIT:
From what I'm seeing, the user jewelsea is right. Apparently it is not certain that the EDT and the JavaFX Application Thread shall become one (it would be quite interesting if that happened). But anyway, be careful not to confuse yourself with the use of both threads.

Related

Is code run from Platform.runLater thread safe?

If I have code ran entirely from within Platform.runLater, is that code automatically thread safe?
My understanding is that code ran on Platform.runLater is ran on the JavaFX application thread, which there is only one.
For example if I manipulate an hash map entirely in Plaform.runLater, I don't have to worry about multiple threads, right?
Whether or not using Platform#runLater(Runnable) is thread-safe is entirely dependent on how you use it. The example you give is you have a Map visible from a background thread but only ever manipulate it on the JavaFX Application Thread via runLater. Maybe something like:
// executing on background thread
Object newKey = ...;
Object newVal = ...;
Platform.runLater(() -> map.put(newKey, newVal));
This makes the Map "thread-safe" only from the point-of-view of the JavaFX Application Thread. If the background thread later attempts to read the Map (e.g. map.get(newKey)) there is no guarantee said thread will see the new entry. In other words, it may read null because the entry "doesn't exist" or it may read an old value if one was already present. You could of course fix this by reading on the JavaFX Application Thread as well:
Object val = CompletableFuture.supplyAsync(() -> map.get(key), Platform::runLater).join();
Or even by waiting for the JavaFX Application Thread to finish writing to the Map:
CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(() -> {
// write to map
latch.countDown();
});
latch.await();
// writes to map will be visible to background thread from here
That said, actions by the background thread that happened before the call to runLater will be visible to the JavaFX Application Thread. In other words, a happens-before relationship is created. When scheduling the Runnable to execute on the JavaFX Application Thread eventually some inter-thread communication must occur, which in turn requires synchronization in order to be thread-safe. Looking at the Windows implementation of JavaFX I can't say for certain what this synchronization looks like, however, because it appears to invoke a native method.

Submit a task to an ExecutorService using a SheduleExecutorService

I'm developing a JavaFX application for read data from a serial device and show a notification when a new device is connected to the computer.
I have a task DeviceDetectorTask which scans all the ports and creates an event when a new device is connected. This task must be submited every 3 seconds.
When a device is detected the user can press a button to read all the data contained in it. This is performed by another task ReadDeviceTask. At this point and while the ReadDeviceTask is running scan operations should not be performed (I cannot read and scan one port at the same time). So only one of the two task can be running at a time.
My actual solution is:
public class DeviceTaskQueue {
private ExecutorService executorService = Executors.newSingleThreadExecutor();
public void submit(Runnable task) {
executorService.submit(task);
}
}
public class ScanScheduler {
private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
public void start() {
AddScanTask task = new AddScanTask();
executor.scheduleAtFixedRate(task, 0, 3, TimeUnit.SECONDS);
}
}
public class AddScanTask implements Runnable {
#Autowired
DeviceTaskQueue deviceTaskQueue;
#Override
public void run() {
deviceTaskQueue.submit(new DeviceDetectorTask());
}
}
public class ViewController {
#Autowired
DeviceTaskQueue deviceTaskQueue;
#FXML
private readDataFromDevice() {
deviceTaskQueue.submit(new ReadDeviceTask());
}
}
My question is: is it ok to add a task to the ExecutorService from the task AddScanTask which has been scheduled by the ScheduledExecutorService?
Yes, An Executor May Post Task To Another Executor
To answer your simple question in last line:
is it ok to add a task to the ExecutorService from the task AddScanTask which has been scheduled by the ScheduledExecutorService?
Yes. Certainly you can submit a Callable/Runnable from any other code. That the submitting code happens to be running from another executor is irrelevant, as code run from an executor is still “normal” Java code, just running on a different thread.
That is the whole point of the executor, to handle the juggling of threads in a manner convenient to you the programmer. Making multi-threaded coding easier and less error-prone is why these classes were added to Java. See the extremely helpful book, Java Concurrency in Practice by Brian Goetz et al. And see other writings by Goetz.
In your case you have two executors each with their own thread, each executing a series of submitted tasks. One has tasks submitted automatically (timed) while the other has tasks submitted manually (arbitrarily). Each executes on their own thread independent of one another. With multiple cores they may execute simultaneously.
Therein lies the bigger problem: In your scenario you don't want them to be independent. You want the reading tasks to block the scanning tasks.
Bigger Problem
The problem you present is that a regularly occurring activity (scanning) must halt when an arbitrary event (reading) happens. That means the two activities must coordinate with one another. The question is how to coordinate.
Semaphores
When the arbitrary event is happening, it should raise a flag. The recurring activity, when it runs, should always check for that flag. If raised, wait until the flag lowers before proceeding with scan. The ScheduledExecutorService is designed for this, tolerating a task that may run for a time longer than the scheduled period. If one execution of the task runs long, the SES does not run again, so it does not pile up a backlog of executions. That is just the behavior you want.
Vice versa, if the recurring activity is executing, it should raise a flag. The arbitrary event’s first to-do item is to check for that flag. If raised, wait until lowered. Then proceed, first raising its own flag and then proceeding with the task at hand (scanning).
Perhaps your scenario should be designed with a single flag rather than scanner and reader each having their own. I would have to think about it more and probably know more about your scenario.
The technical term for such flags is semaphore.
Unfortunately your comment says you cannot alter the scanner’s source code. So you cannot implement the semaphores and coordinate the activities. So I am stuck, cannot see a solution.
Hack
Given your frozen code, one hack solution, which I do not recommend, is that the regularly occurring activity (the scanning) not actually do the work but instead post a scanning task on another thread (another executor). That other executor would also be the same executor used to post the arbitrary activity (the reading). So there is one single queue of to-do items, a mix of scanning and reading jobs, submitted to a single-thread executor. The single-thread means they get done one at a time in sequence of their submission.
I do not like this hack because if any of the to-do items takes a long while you will begin to accumulate a backlog. That could be a mess.
By the way, no need for the DeviceTaskQueue in your example code. Just call the instance of the ExecutorService directly to submit a task. That is the job of an ExecutorService, and wrapping it adds no value that I can see.

JavaFX chat Application

Im trying to build a Chat Program. i can do it when i use java awt package but with java fx i seem to be a bit confused. when you first build a java fx project all your methods even the public static void main(string args[]) is in there and there's a place where you Start the primaryStage of the coding...I have no problem coding the visual side of my program its just i dont know where i should setup the Network part of my program and where to put it when im done..
**CODE: This is Just a View**
Server extends Application{
public void start(Stage primaryStage){
//Where you setup the visual of your program
}
public static void main(String args[]){
launch(args); // Where the program will run
}
public void ServerConnection(){
//where i put the codes to setup my streams and SOCKET
}
The ServerConnection method contains other methods as well But all of those will go to the ServerConnectionMethod now My question is Where will i place my ServerConnection Method so that it will run along with the my primary Stage
Sorry for the long post..have a String ="potato";
If a JavaFX application is launched correctly, it won't use the main() method at all - you can remove it temporarily (as an experiment) and check, but chances are it's not serving any purpose other than for backwards compatibility. You certainly should not rely on the main method doing anything special in the case of an FX app; it should only call launch() and nothing else.
Instead, your main class should extend Application, and the JavaFX runtime will create an instance of it for you, create a primary stage, and call the start method providing you with a reference to that stage. From this method you can do anything you like, but bear in mind it is on the UI thread (so you should create an additional thread for any long running task, the same as you would in any other toolkit such as Swing.)
You could run this setupConnection method at the beginning of the start(Stage primaryStage) method. This way it will be executed before showing the stage. You could also just run both from the main method, but as berry120 said: You don't need to call the launch(args) method in the main, if it extends Application you're fine with just the start method.
When you are done, you could use a
stage.setOnCloseRequest(e -> {
//code to execute, something like socket.close();
});
And you could change the stage.show() to stage.showAndWait()

Viewpager with fragments screwed up after the system destroyed activity (to recover memory)

I have a viewpager with 3 pages and a fragment (containing inner fragment) on each page. My fragments and the activity communicate directly between each other via saved references (I don’t use interfaces or callback). Also I deactivated rotation, my application is used only in portrait mode so far. I call setOffscreenPageLimit(3) and I never call setRetainInstance().
The application works perfectly when it is launched after being properly destroyed.
But when the application is started after the application was destroyed by the system to recover memory and resources (I do this by pausing my app and launching a few heavy applications), viewpager does not start/attach fragments “normally“ and everything screws up.
I have nullpointerexceptions everywhere. For example, my reference to the activity (saved in onAttach) in a fragment is often null. I used to Runnable to give time but even after 2 seconds, though my traces indicate that all fragment callback functions till onResumed have been called, isAdded() return false and getActivity() return null inside the fragment. Even for the fragment that is supposed to be first displayed. Sometimes some fragments are correctly added.
Of course, the difference between the two scenario above is that in the non-working scenario something happens in onCreate(Bundle) or onRestoreInstanceState(Bundle) . There may be an attempt to reused fragments or whatever. So a workaround is to deactivate the saving of the activity state like that:
#Override
protected void onSaveInstanceState(Bundle outState) {
//super.onSaveInstanceState(outState);
}
This workaround works but I lose the possibility to use onRestoreInstanceState in the future.
If you have run across this issue, what other nicer solutions have you found? Thanks in advance.

How to call plain function from exec()?

I have 2 classes: one maintains some loop (at leas for 2-3 minutes; and is inherited from QObject) and another shows up a progress dialog (inherited from QDialog).
I want to start the loop as soon as the dialog is shown. My first solution was:
int DialogClass::exec()
{
QTimer::singleShot(0, LoopClassPointer, SLOT(start()));
return __super::exec();
}
There is a problem with throwing exceptions from slots. so I considered a possibility to make public slot start() just a public function. But now I don't know how to make it works well. Things like this:
int DialogClass::exec()
{
LoopClassPointer->start();
QApplication::processEvents();
return __super::exec();
}
don't help. The dialog doesn't appears.
Is there a common approach to this kind of situations?
some details, according to questions:
I have to work with system with its own styles, so we have a common approach in creating any dialogs: to inherit them from stytle class, which is inherited from QDialog.
my 'LoopClassPointer' is an exported class from separate dll (there is no UI support in it).
I have a 'start' button in main app, which connected with a slot, which creates progress dialog and 'LoopClassPointer'. at the moment I send 'LoopClassPointer' instance in the dialog and don't whant to make significant changes in the architecture.
Take a look at QtDemo->Concurrent Programming->Run function
e.g. in Qt 4.8: http://qt-project.org/doc/qt-4.8/qtconcurrent-runfunction.html
In this situation, I recommend you separate the logic of the loop from the dialog. Gui elements should always be kept separate.
It's great that your worker class is derived from QObject because that means you can start it running on a separate thread: -
QThread* m_pWorkerThread = new QThread;
Worker* m_pWorkerObject = new Worker; // assuming this object runs the loop mentioned
// Qt 5 connect syntax
connect(m_pWorkerThread, &QThread::started, m_pWorkerObject, &WorkerObject::start);
connect(m_pWorkerThread, &QThread::finished, m_pWorkerThread, &QThread::deleteThis);
m_pWorkerObject->moveToThread(m_pWorkerThread);
m_pWorkerThread->start();
If you're not familiar with using QThread, then start by reading this.
The only other thing you require is to periodically send signals from your worker object with progress of its work and connect that to a slot in the dialog, which updates its display of the progress.

Resources