I have an idea to create widgets that perform tasks and can be added to the view but I’m worried I could be approaching the problem from completly the wrong angle. Here is my abstract class
public abstract class AbstractWidget extends AnchorPane
{
private Thread thread;
protected Task<?> task;
public AbstractWidget()
{
}
public void start()
{
this.thread = new Thread(this.task);
this.thread.start();
}
public void stop()
{
this.task.cancel();
}
}
an implementation (widget that tracks how long the program has been running)
public class RuntimeWidget extends AbstractWidget
{
public RuntimeWidget()
{
this.task = new Task<Void>()
{
@Override
public void run()
{
final long startTime = System.currentTimeMillis();
while(true)
{
if (isCancelled())
break;
Platform.runLater(new Runnable()
{
@Override
public void run ()
{
long secs = System.currentTimeMillis() -startTime) / 1000;
String display = String.format("%02d:%02d", (secs % 3600) / 60, (secs % 60));
System.out.println(display);
}
});
try {
Thread.sleep(1000);
} catch ( InterruptedException e ) {
e.printStackTrace();
}
}
}
};
}
}
Using the widget in the FXML controller
public void initialize(URL fxmlFileLocation, ResourceBundle resources)
{
RuntimeWidget runtimeWidget = new RuntimeWidget();
gridPane.add(runtimeWidget, 0, 0);
}
@FXML private void handleRunAction( ActionEvent event ) throws IOException, InterruptedException
{
runtimeWidget.start();
}
Everything works completely fine but is this the right way? I used Task instead of Service because the program’s run action can be stopped and started all over again, but never paused and resumed.
I decided to just use Service. It’s much easier to handle functions that can be run multiple times.
Then you can create a class like: