0

I have problem with refreshing scene (JavaFX). I think the main problem is my scene refreshing after onAction Button event was ended not inside it. I try solve this yesterday but I don't have idea how to do this.

Main problem code:src/main/java/MainController.java

    @FXML
    private Button startButton;

    @FXML
    private Text statusText;

    @FXML
    void onClickStartButton(ActionEvent event) {
        startButton.setDisable(true); //this is problem: i don't see this change on window
        String status = "Button isDisable: " + startButton.isDisable();
        System.out.println(status);
        statusText.setText(status); //this is problem: i don't see this change on window

        System.out.println("Function start...");
        myLongTimeMethod(); //my method to copy files
        System.out.println("Function done.");

        startButton.setDisable(false);
        status = "Button isDisable: " + startButton.isDisable();
        System.out.println(status);
        statusText.setText(status);
    }

When i execute this i don't see this first change on my JavaFX scene:

        startButton.setDisable(true); //this is problem: i don't see this change on window
        String status = "Button isDisable: " + startButton.isDisable();

        statusText.setText(status); //this is problem: i don't see this change on window

Picture show problem:

  1. Run program - OK (IMG) Run program

  2. After click start - program inside onClickStartButton() - BAD (IMG) This what i get now

  3. onClickStartButton() - OK (IMG) View after end function onClickStartButton()

View which I want to get in step 2: (IMG) View which i want to get

All my codes: src/main/java/Main.java

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
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 {
        FXMLLoader loader = new FXMLLoader(this.getClass().getResource("/fxml/MainScreen.fxml"));
        Pane pane = loader.load();
        Scene scene = new Scene(pane, 800, 400);
        primaryStage.setScene(scene);
        primaryStage.setResizable(false);
        primaryStage.setTitle("My App");
        primaryStage.show();
    }
}

src/main/java/MainController.java

import java.util.Random;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.text.Text;

public class MainController {

    @FXML
    private Button startButton;

    @FXML
    private Text statusText;

    @FXML
    void onClickStartButton(ActionEvent event) {
        startButton.setDisable(true); //this is problem: i don't see this change on window
        String status = "Button isDisable: " + startButton.isDisable();
        System.out.println(status);
        statusText.setText(status); //this is problem: i don't see this change on window

        System.out.println("Function start...");
        myLongTimeMethod(); //my method to copy files
        System.out.println("Function done.");

        startButton.setDisable(false);
        status = "Button isDisable: " + startButton.isDisable();
        System.out.println(status);
        statusText.setText(status);
    }

    private void myLongTimeMethod(){
        //just for example something what doing long than 1ms (e.g. copy files operation ~ 30 minutes)
        Random random = new Random();
        for(int i=0;i<10000*100000;i++){
            int randomValue = random.nextInt(10);
        }
        System.out.println(" ");
    }
}

src/resources/fxml/MainScreen.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>


<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="MainController">
   <children>
      <Text layoutX="344.0" layoutY="81.0" strokeType="OUTSIDE" strokeWidth="0.0" text="My App">
         <font>
            <Font size="32.0" />
         </font>
      </Text>
      <Text layoutX="214.0" layoutY="173.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Info (status):">
         <font>
            <Font size="18.0" />
         </font>
      </Text>
      <Button fx:id="startButton" layoutX="370.0" layoutY="242.0" mnemonicParsing="false" onAction="#onClickStartButton" text="Start">
         <font>
            <Font size="17.0" />
         </font>
      </Button>
      <Text fx:id="statusText" layoutX="319.0" layoutY="172.0" strokeType="OUTSIDE" strokeWidth="0.0" text="unknown">
         <font>
            <Font size="18.0" />
         </font>
      </Text>
   </children>
</Pane>
misza
  • 13
  • 3
  • 2
    please don't delete and repost a question - instead edit the old and add the required details – kleopatra Jun 16 '20 at 11:54
  • Run your long-running method as a `Task`. See https://stackoverflow.com/questions/30249493/using-threads-to-make-database-requests – James_D Jun 16 '20 at 11:58
  • you __must not__ block the ui thread, never-ever! Instead, let your button disable itself, start a background thread that reports back when finished and disable/enable the button from that notification. Do some research on concurrency support in fx, there are tons of examples/tutorials :) – kleopatra Jun 16 '20 at 11:58

0 Answers0