Disable Javafx TextField and Buttons after a fixed set of days - java

So i have created a Data Entry Application using Javafx and Ms Access, but i wanted to add a feature which i don't know how to implement. I want my application to run for 6 days only and after that all my buttons and textfields will be disabled.
when i click the start button it will setdisable(false) all my buttons and textfields and will start the day count and setdisable(true) Start button forever. I want to store this info in some hidden .txt file so that when the application closes it will remember the start button status and day count and also display the day no. in a label. At the end of 6th day all my buttons and textfields will be disabled forever.
This is my main class:
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
public class DataEntryMain extends Application {
#Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("/application/UI.fxml"));
Scene scene = new Scene(root,1280,700);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
This is my Controller class:
package application;
import java.sql.SQLException;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXTextField;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
public class DataEntryController {
int rn;
#FXML
private JFXTextField t1, t2, t3, t4 , t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15;
#FXML
private JFXButton start;
#FXML
private JFXButton lock;
#FXML
private JFXButton save;
#FXML
private JFXButton update;
#FXML
private Label resultConsole;
#FXML
private JFXTextField searchRowNo;
#FXML
private TableView<DataEntry> tabView;
#FXML
private TableColumn<DataEntry, Integer> rowNumber;
#FXML
private TableColumn<DataEntry, String> c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15;
#FXML
private void insertData(ActionEvent event) throws ClassNotFoundException, SQLException{
try {
DataEntryModel.insertData(t1.getText(), t2.getText(), t3.getText(), t4.getText(), t5.getText(), t6.getText(), t7.getText(), t8.getText(), t9.getText(), t10.getText(), t11.getText(), t12.getText(), t13.getText(), t14.getText(), t15.getText());
resultConsole.setText("Data Added Successfully!");
}
catch(SQLException e) {
System.out.println("Exception Occer In Insertion "+e);
e.printStackTrace();
throw e;
}
}
#FXML
private void updateData(ActionEvent event) throws ClassNotFoundException, SQLException{
rn = Integer.parseInt(searchRowNo.getText());
try {
DataEntryModel.updateData(rn, t1.getText(), t2.getText(), t3.getText(), t4.getText(), t5.getText(), t6.getText(), t7.getText(), t8.getText(), t9.getText(), t10.getText(), t11.getText(), t12.getText(), t13.getText(), t14.getText(), t15.getText());
resultConsole.setText("Data Updated Successfully!");
}
catch(SQLException e) {
System.out.println("Exception Occure In Update "+e);
throw e;
}
}
#FXML
private void intialize()throws Exception{
rowNumber.setCellValueFactory(cellData -> cellData.getValue().getRNo().asObject());
c1.setCellValueFactory(cellData -> cellData.getValue().getText1());
c2.setCellValueFactory(cellData -> cellData.getValue().getText2());
c3.setCellValueFactory(cellData -> cellData.getValue().getText3());
c4.setCellValueFactory(cellData -> cellData.getValue().getText4());
c5.setCellValueFactory(cellData -> cellData.getValue().getText5());
c6.setCellValueFactory(cellData -> cellData.getValue().getText6());
c7.setCellValueFactory(cellData -> cellData.getValue().getText7());
c8.setCellValueFactory(cellData -> cellData.getValue().getText8());
c9.setCellValueFactory(cellData -> cellData.getValue().getText9());
c10.setCellValueFactory(cellData -> cellData.getValue().getText10());
c11.setCellValueFactory(cellData -> cellData.getValue().getText11());
c12.setCellValueFactory(cellData -> cellData.getValue().getText12());
c13.setCellValueFactory(cellData -> cellData.getValue().getText13());
c14.setCellValueFactory(cellData -> cellData.getValue().getText14());
c15.setCellValueFactory(cellData -> cellData.getValue().getText15());
ObservableList<DataEntry> deList = DataEntryModel.getAllRecords();
populateTable(deList);
}
private void populateTable(ObservableList<DataEntry> deList) {
tabView.setItems(deList);
}
}
I have 3 other classes which i have used for database operations and i don't think that's relevant here.This is how the application looks

Make a seperate Thread use TimeUnit.DAYS.sleep(days); in it then run the thing that closes the inputs. You can just disable the entire pane, no need for individual buttons, or make a stack pane with a message on top of everything and show it after x amount of days. You also need to interact with the view from the other thread with Platform.runLater and you need to close the thread if the Window gets closed manually with an onCloseRequest event on your window.
EDIT:
Main
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
public void start(Stage primaryStage) throws Exception {
primaryStage = new Stage();
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/Main.fxml"));
Parent root = loader.load();
var controller = (MainController) loader.getController();
primaryStage.setScene(new Scene(root));
primaryStage.setOnCloseRequest(event -> {
controller.stopThread();
});
primaryStage.show();
}
}
Main Controller
public class MainController {
#FXML
private TextField tfTest;
#FXML
private BorderPane borderPane;
private LeKillerThread thread;
#FXML
public void btStartClick(ActionEvent actionEvent) {
//save time to use in Thread? Does not do that now.
}
public void initialize() {
thread = new LeKillerThread(borderPane);
thread.start();
}
public void stopThread() {
this.thread.interrupt();
}
}
Thread
public class LeKillerThread extends Thread {
private Node nodeToKill;
public LeKillerThread(Node nodeToKill) {
this.nodeToKill = nodeToKill;
}
#Override
public void run() {
try {
//not gonna test this with days...
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
Platform.runLater(() -> {
this.nodeToKill.setDisable(true);
});
}
}
Main.fxml
<BorderPane fx:id="borderPane"
xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="MainController"
prefHeight="400.0" prefWidth="600.0">
<center>
<VBox alignment="CENTER">
<TextField fx:id="tfTest"></TextField>
<Button text="start" onAction="#btStartClick"></Button>
</VBox>
</center>
</BorderPane>
I did not test this for days... but it works. If you want to keep track of the Time then you got to save the time when you press start and load it next time you launch the program and calculate the difference to right when you start the thread to sleep that amount of time instead of a fixed amount. It may be wise to sleep for lower periods of time in a loop though and not a week. So you have a chance to test if the Window somehow disappeared without telling you (the Thread) about it. It should not usually be a issue thought, only if your Window outright crashes.

Related

How to set text to a label on keyboard key press in JavaFX application?

I'm making JavaFX application with Scene Builder. I have Main Class that launch Controller with main window.
I have a label in the Controller class
I need to assign keyboard key press in main window.
Example: if I press '1' on keyboard the text of a label should be set as "key 1 is pressed.
If I press "2" on keyboard the text should be set as "key 2 is pressed"
How Can I do that?
I've tried to use this code in initialize method, but nothing happens:
category1.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent ke) {
KeyCode kc = ke.getCode();
if((kc.equals(KeyCode.D))) {
category1.setText("Key D is pressed");
}
}
});
Main Class:
package src.card;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.input.*;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
try {
Parent root = FXMLLoader.load(getClass().getResource("resources/fxml/card.fxml"));
Scene scene = new Scene(root, 1600, 600);
primaryStage.setScene(scene);
scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());
primaryStage.initStyle(StageStyle.UNDECORATED);
primaryStage.setMaximized(true);
primaryStage.setResizable(true);
primaryStage.getIcons().add(new Image("src/card/resources/logo-icon.png"));
primaryStage.show();
//adding resize and drag primary stage
ResizeHelper.addResizeListener(primaryStage);
//assign ALT+ENTER to maximize window
final KeyCombination kb = new KeyCodeCombination(KeyCode.ENTER, KeyCombination.CONTROL_DOWN);
scene.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if (kb.match(event)) {
primaryStage.setMaximized(!primaryStage.isMaximized());
primaryStage.setResizable(true);
Controller cont = Context.getInstance().getController();
if (!primaryStage.isMaximized()) {
cont.getBtnFont().setPrefWidth(20);
cont.getBtnPalette().setPrefWidth(20);
cont.getBtnQuestCards().setPrefWidth(20);
cont.getBtnNonQuestCards().setPrefWidth(20);
} else if (primaryStage.isMaximized()){
cont.getBtnFont().setPrefWidth(50);
cont.getBtnPalette().setPrefWidth(50);
cont.getBtnQuestCards().setPrefWidth(50);
cont.getBtnNonQuestCards().setPrefWidth(50
);
}
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
Controller:
#FXML private Label category1
#FXML public void initialize(URL location, ResourceBundle resources) {
category1.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent ke) {
KeyCode kc = ke.getCode();
if((kc.equals(KeyCode.D))) {
category1.setText("Key D is pressed");
}
}
});
//register Controller in Context Class
Context.getInstance().setController(this);
}
EDIT:
I've tried to use it in initialize method:
category1.getScene().setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent ke) {
KeyCode kc = ke.getCode();
if((kc.equals(KeyCode.D))) {
category1.setText("Key D is pressed");
}
}
});
and I got errors:
javafx.fxml.LoadException:
/D:/IDEA%20Projects/CategoryCards/out/production/CategoryCards/src/card/resources/fxml/card.fxml
at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
If I remove getScene() from category1 - everything is going fine and application launch
It seems when I use getScene() it try to get fxml file from out folder, not my main folder, but how can I fix this?
You can do so by setting key press event(setOnKeyPressed) to parent of Label
instead of Scene. Trying to add event to Scene will give error because initialize will be called before creation of the Scene.
Let's say you have FXML file called sample.fxml and In that file you have GridPane having id root and a Label having id category1
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.GridPane?>
<GridPane fx:controller="Controller"
xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10" fx:id="root">
<Label text="Category" fx:id="category1"/>
</GridPane>
And you have Controller class called Controller. To change label of category1 when any key is pressed, first you have to set category1 focus traversable by calling setFocusTraversable method on category1 and passing true. And then you have to add key press event on root(parent of category1), As shown below
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable{
#FXML private Label category1;
#FXML private GridPane root;
#Override
public void initialize(URL location, ResourceBundle resources){
category1.setFocusTraversable(true);
root.setOnKeyPressed(this::handle);
}
private void handle(KeyEvent keyEvent){
category1.setText("Key " + keyEvent.getCode().getName() + " is pressed");
}
}
And here is simple version of Main class
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application{
public static void main(String[] args){
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
Scene scene = new Scene(root, 300, 275);
primaryStage.setScene(scene);
primaryStage.show();
}
}

bind two ToggleButtons to a BooleanProperty

I have two ToggleButtons and I would like them both to be bound to a Boolean property so that when one ToggleButton is selected, the other ToggleButton isn't, and the BooleanProperty is true, and vice versa.
Here's what I tried.
FXML file:
<VBox xmlns:fx="http://javafx.com/fxml" fx:controller="my.package.MainController" styleClass="Tool" fx:id="root">
<HBox spacing="10">
<fx:define>
<ToggleGroup fx:id="modeToggleGroup"/>
</fx:define>
<ToggleButton fx:id="manualModeBtn" text="Manual Mode" selected="true" toggleGroup="$modeToggleGroup"/>
<ToggleButton fx:id="automaticModeBtn" text="Automatic Mode" toggleGroup="$modeToggleGroup"/>
</HBox>
<!-- other stuff -->
</VBox>
Controller file:
public class MainController {
#FXML
private ToggleButton manualModeBtn;
#FXML
private ToggleButton automaticModeBtn;
private BooleanProperty isAutomaticMode;
public void initialize() {
isAutomaticMode = new SimpleBooleanProperty();
automaticModeBtn.selectedProperty.bindBidirectional(isAutomaticMode);
}
}
The ToggleGroup ensures that neither button is selected at the same time, but I can still unselect both of them, which I don't want to be possible.
How do I bind the other ToggleButton to the opposite (i.e. not()) of the Boolean Property?
You could do this by using listeners:
public class MainController {
#FXML
private ToggleButton manualModeBtn;
#FXML
private ToggleButton automaticModeBtn;
public void initialize() {
manualModeBtn.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> automaticModeBtn.setSelected(! isNowSelected));
automaticModeBtn.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> manualModeBtn.setSelected(! isNowSelected));
}
}
Note that RadioButton has almost this functionality already (in the case of a radio button, you can't "deselect" it), so you could simply use RadioButtons instead. Note this question, if it is just a case of how they look.
This can also be done by setting a listener on the ToggleGroup's selectedToggleProperty.
You first have to set an initial button.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class ToggleButtonExperiments extends Application
{
#Override
public void start(Stage primaryStage) throws Exception
{
primaryStage.setTitle("HBox Experiment 1");
ToggleButton toggleButton1 = new ToggleButton("Left");
ToggleButton toggleButton2 = new ToggleButton("Right");
ToggleGroup toggleGroup = new ToggleGroup();
toggleButton1.setSelected(true);//set initial button!!!!!
toggleGroup.selectedToggleProperty().addListener((obs, oldTog, newTog) -> {
if (newTog == null) {
oldTog.setSelected(true);
}
});
toggleButton1.setToggleGroup(toggleGroup);
toggleButton2.setToggleGroup(toggleGroup);
HBox hbox = new HBox(toggleButton1, toggleButton2);
Scene scene = new Scene(hbox, 200, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{
Application.launch(args);
}
}

Opening a TabPane when button is clicked from another view

I have two separate views one which contains a button say view A and another a TabPane with 3 tabs call it view B. These two views are controlled by two separate view controller classes. I want to be able to click a button in view A and be able to to open a specific tab in view B's TabPane.
So far I have tried extending the controller for view A with view B such that I can get the TabPane defined in view B's controller then call myTabPane.getSelectionModel().select(myTab); however this hasn't worked as it throws a NullPointerException.
My question is it possible to click a button in view A such that it opens view B and opens a specific Tab on view B's TabPane.
I have also looked at these links with no luck 1. setting selected tab, 2. switch through tabs programatically, 3. switch between tabs in tabpane
Lets say the above image is view A and when u click right it should open view B and open a specific tab in view B's TabPane.
Lets say the above image is view B and when the button right on view A is clicked it should open view B and set the tab to tab C.
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import javafx.scene.control.SelectionModel;
public class SucessfulCreateProjectViewController extends AdminViewController {
#FXML
private Button OkButton;
#FXML
void handleCreateTasksButtonAction(ActionEvent event) {
try{
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("AdminView.fxml"));
Scene scene = new Scene(fxmlLoader.load());
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
AdminTabPane.getSelectionModel().select(1);;
}catch(Exception e){
ErrorHandlerController.infoBox("Error Opening AdminPage", "Fail", null);
e.printStackTrace();
}
}
#FXML
void handleOKButtonAction(ActionEvent event) {
Stage stage = (Stage) OkButton.getScene().getWindow();
stage.close();
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
} }
Mediator is a design pattern that is used to communicate between objects that do not know each other.
This is an example of a mediator that would have done your job.
public class Mediator {
private static Mediator instance;
private Consumer<String> consumer;
public static Mediator getInstance() {
if(instance == null) {
instance = new Mediator();
}
return instance;
}
private Mediator() {
}
public void register(Consumer<String> consumer) {
this.consumer = consumer;
}
public void fireEvent(String string) {
if(consumer != null) {
consumer.accept(string);
}
}
}
and respectively, the two controllers
public class ViewAController {
#FXML
private Button btnL, btnR;
#FXML
private void initialize() {
btnL.setOnAction(event -> Mediator.getInstance().fireEvent("left"));
btnR.setOnAction(event -> Mediator.getInstance().fireEvent("right"));
}
}
public class ViewBController {
#FXML
private TabPane tabPane;
#FXML
private void initialize() {
Mediator.getInstance().register(s -> {
switch (s) {
case "left":
tabPane.getSelectionModel().select(0);
break;
case "right":
tabPane.getSelectionModel().select(2);
break;
}
});
}
}
and this is a test application that opens two windows at once.
public class Main extends Application {
#Override
public void start(Stage stageA) throws Exception{
Parent viewA = FXMLLoader.load(getClass().getResource("view_a.fxml"));
Parent viewB = FXMLLoader.load(getClass().getResource("view_b.fxml"));
stageA.setTitle("View A");
stageA.setScene(new Scene(viewA));
stageA.show();
Stage stageB = new Stage();
stageB.setTitle("View B");
stageB.setScene(new Scene(viewB));
stageB.show();
}
public static void main(String[] args) {
launch(args);
}
}
if you do not want to use two windows at once, just change the middleman.

javafx Pagination memory leak when replacing buttons

I first noticed this by having a huge memory leak caused by resizing javafx.scene.control.Pagination.
I created a sample app to show the behavior. Every click on any button causes more memory to be consumed. I suppose that the correct way to deal with this is to remove any listeners on the ToggleButtons before clearing them but PaginationSkin isn't doing that.
Have I missed something or is this a real bug in the Pagination code?
Are there any workarounds?
The same behavior is seen it both 8u40 and 8u45. I haven't tried any older versions yet.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class ToggleGroupLeak extends Application {
private HBox hbox;
private ToggleGroup toggleGroup;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
toggleGroup = new ToggleGroup();
hbox = new HBox();
redo();
root.getChildren().add(hbox);
primaryStage.setScene(new Scene(root, 700, 100));
primaryStage.show();
}
private void redo() {
hbox.getChildren().clear();
toggleGroup.getToggles().clear();
for (int i = 0; i < 20; i++) {
addButton(i);
}
}
private void addButton(final int i) {
ToggleButton btn = new ToggleButton("" + i);
btn.setToggleGroup(toggleGroup);
btn.setOnAction(e -> redo());
hbox.getChildren().add(btn);
}
}
Concretely, usage of Pagination in an AnchorPane seems to cause the same leak by resizing the control.
FXML
<Pagination fx:id="pagination" visible="true" AnchorPane.topAnchor="3.0" AnchorPane.leftAnchor="12.0" AnchorPane.rightAnchor="130.0"/>
Java
#FXML
protected Pagination pagination;
// Init method run once
pagination.setMaxPageIndicatorCount(100);
pagination.currentPageIndexProperty().addListener((observable, oldPageIndex, newPageIndex) -> {
if (!oldPageIndex.equals(newPageIndex)) {
if (searchParams.getPage() == newPageIndex.intValue()) {
return;
}
searchParams.setPage(newPageIndex.intValue());
// Code that inits the new page
}
});
EDIT: Added pagination specific code

JavaFX - Action during event

i am trying to influence a UI-Element during an event in javaFX.
void buttonClicked(ActionEvent e) {
labelInfo.setText("restarting - might take a few seconds");
jBoss.restart();
labelInfo.setText("JBoss successfully restarted");
}
The action "jBoss.restart()" waits till the JBoss is restarted.
The problem:
the text "restarting - ..." is not displayed. The application waits till the JBoss is restarted and then it shows the Text "JBoss successfully restarted".
My thoughts:
the scene is refreshed AFTER the event is completed. So the first label-change will not happen.
How can i show a info message during an event?
The problem it's that the FX Thread has no safe operations. So I'm guessing that jBoss.restart() it's taking a lot of time. So you have to put this command in a Service. Also I recommend to you a progress indicator to show to the user you are making a long operation.
Here it is an example but I encourage you to go to Concurrency in JavaFX and take a deep look on it. Maybe there are other things that can help you.
import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Test extends Application {
public static void main(String[] args) {
launch(args);
}
private Label labelInfo;
private Button button;
private ProgressIndicator progressIndicator;
#Override
public void start(Stage stage) throws Exception {
VBox vbox = new VBox(5);
vbox.setAlignment(Pos.CENTER);
labelInfo = new Label();
button = new Button("Restart");
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
buttonClicked(event);
}
});
progressIndicator = new ProgressIndicator(-1);
progressIndicator.setVisible(false);
vbox.getChildren().addAll(labelInfo, progressIndicator, button);
Scene scene = new Scene(vbox, 300, 200);
stage.setScene(scene);
stage.show();
}
void buttonClicked(ActionEvent e) {
Service<Void> service = new Service<Void>() {
#Override
protected Task<Void> createTask() {
return new Task<Void>() {
#Override
protected Void call() throws Exception {
updateMessage("restarting - might take a few seconds");
// Here the blocking operation
// jBoss.restart();
Thread.sleep(10000);
updateMessage("JBoss successfully restarted");
return null;
}
};
}
};
// Make the progress indicator visible while running
progressIndicator.visibleProperty().bind(service.runningProperty());
// Bind the message of the service to text of the label
labelInfo.textProperty().bind(service.messageProperty());
// Disable the button, to prevent more clicks during the execution of
// the service
button.disableProperty().bind(service.runningProperty());
service.start();
}
}

Categories

Resources