不断更新JavaFX GUI

时间:2017-12-07 22:28:21

标签: java user-interface javafx

我目前正在开展一个项目,我将时间转换为10次基本时间(基本上它将显示已经过去的那一天的百分比。例如:中午12点将显示为50.00 in基地10次)。目前,我知道我的算法是正确的,因为如果我将它打印到控制台,它会正确打印出来,但出于某种原因,我无法显示我的GUI。如果我摆脱了我试图不断更新GUI以显示正确数字的部分,GUI显示正常,但没有数字。我的代码如下:

package ClockPackage;

import java.util.Calendar;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class ClockView extends Application {
    Pane background;
    static Text firstDigit;
    static Text secondDigit;
    static Text thirdDigit;
    static Text fourthDigit;
    Text middleDecimal;

    /* Sets the first digit of the base 10 time to the passed through char. */
    static void setFirstDigit(char x1) {
        String digitString = "";
        digitString += x1;
        firstDigit.setText(digitString);
    }

    /* Sets the second digit of the base 10 time to the passed through char. */
    static void setSecondDigit(char x2) {
        String digitString = "";
        digitString += x2;
        secondDigit.setText(digitString);
    }

    /* Sets the third digit of the base 10 time to the passed through char. */
    static void setThirdDigit(char y1) {
        String digitString = "";
        digitString += y1;
        thirdDigit.setText(digitString);
    }

    /* Sets the fourth digit of the base 10 time to the passed through char. */
    static void setFourthDigit(char y2) {
        String digitString = "";
        digitString += y2;
        fourthDigit.setText(digitString);
    }

    /* Main Method that Launches the GUI */
    public static void main(String[] args) {
        Application.launch(args);

    }

    @Override
    public void start(Stage primaryStage) throws Exception {
            final double TEXTFIELD_LAYOUT_Y = 200;

            //Background Pane
            background = new Pane();

            //First digit textField
            firstDigit = new Text();
            firstDigit.setLayoutX(17);
            firstDigit.setLayoutY(TEXTFIELD_LAYOUT_Y);
            firstDigit.setStyle("-fx-font-size: 96pt;");

            //Second digit textField
            secondDigit = new Text();
            secondDigit.setLayoutX(117);
            secondDigit.setLayoutY(TEXTFIELD_LAYOUT_Y);
            secondDigit.setStyle("-fx-font-size: 96pt;");

            //Middle decimal
            middleDecimal = new Text(".");
            middleDecimal.setLayoutX(219);
            middleDecimal.setLayoutY(210);
            middleDecimal.setStyle("-fx-font-size: 72pt;");

            //Third digit textField
            thirdDigit = new Text();
            thirdDigit.setLayoutX(250);
            thirdDigit.setLayoutY(TEXTFIELD_LAYOUT_Y);
            thirdDigit.setStyle("-fx-font-size: 96pt;");

            //Fourth digit textField
            fourthDigit = new Text();
            fourthDigit.setLayoutX(362);
            fourthDigit.setLayoutY(TEXTFIELD_LAYOUT_Y);
            fourthDigit.setStyle("-fx-font-size: 96pt;");

            /* Adding the Nodes to the Pane */
            background.getChildren().addAll(firstDigit, secondDigit, middleDecimal, thirdDigit, fourthDigit);

            /* Setting the Scene */
            Scene scene = new Scene(background, 470, 258);
            primaryStage.setTitle("Base 10 Clock");
            primaryStage.setScene(scene);
            primaryStage.show();

            /*
             * Calculates the time in base 10 time and calls the 4 methods
             * to set the GUI display.
             * 
             * In a constant while loop in order to continuously update
             * the GUI.
             */
            Calendar now;
            double currentTime;
            String timeString;
            long timestamp;
            while(true) {
                /* Sleep for 8.64 seconds since that is how long it is between
                increments of 0.01 in base 10 time. */
                Thread.sleep(8640);
                now = Calendar.getInstance();
                timestamp = now.get(Calendar.HOUR_OF_DAY)*60*60 + now.get(Calendar.MINUTE)*60 + now.get(Calendar.SECOND);
                currentTime = timestamp/86400.0;
                timeString = "" + currentTime;
                setFirstDigit(timeString.charAt(2));
                setSecondDigit(timeString.charAt(3));
                setThirdDigit(timeString.charAt(4));
                setFourthDigit(timeString.charAt(5));
            }
    }
}

有没有人知道如何让GUI显示并不断更新数字?我无法弄清楚如何做到这两点。我已经看到人们使用按钮更新数据的位置,但我还没有看到显示器在哪里不断自动更新。

谢谢!

3 个答案:

答案 0 :(得分:3)

  

替换:

    Calendar now;
    double currentTime;
    String timeString;
    long timestamp;
    while (true)
    {
        /* Sleep for 8.64 seconds since that is how long it is between
            increments of 0.01 in base 10 time. */
        Thread.sleep(8640);
        now = Calendar.getInstance();
        timestamp = now.get(Calendar.HOUR_OF_DAY) * 60 * 60 + now.get(Calendar.MINUTE) * 60 + now.get(Calendar.SECOND);
        currentTime = timestamp / 86400.0;
        timeString = "" + currentTime;
        setFirstDigit(timeString.charAt(2));
        setSecondDigit(timeString.charAt(3));
        setThirdDigit(timeString.charAt(4));
        setFourthDigit(timeString.charAt(5));
    }
  

使用:

        Timeline overEightSeconsWonder = new Timeline(new KeyFrame(Duration.seconds(8.64), (ActionEvent event) ->
        {
            Calendar now = Calendar.getInstance();
            long timestamp = now.get(Calendar.HOUR_OF_DAY) * 60 * 60 + now.get(Calendar.MINUTE) * 60 + now.get(Calendar.SECOND);
            double currentTime = timestamp / 86400.0;
            String timeString = "" + currentTime;
            setFirstDigit(timeString.charAt(2));
            setSecondDigit(timeString.charAt(3));
            setThirdDigit(timeString.charAt(4));
            setFourthDigit(timeString.charAt(5));
        }));
        overEightSeconsWonder.setCycleCount(Timeline.INDEFINITE);
        overEightSeconsWonder.play();

答案 1 :(得分:0)

您应该使用新线程或使用其他线程的服务调用替换while(true)循环。主线程已经负责更新UI,所以当你有某种阻塞(IO,需要很长时间的循环等等)时,它会阻止UI线程的更新。

Link to the Service interface

创建服务:

public static class TimeService extends Service<String> {

    protected Task createTask() {
        return new Task<String>() {
            protected String call() throws Exception {
                // TODO: Do work - return the date/time as a String
                // If you need a Thread.sleep, use a spawn a new thread
            }
        };
    }
}

然后在你的控制器中:

TimeService timeService = new TimeService();
timeService.restart();

您还可以执行各种操作,例如将UI元素绑定到TimeService中的属性(这样UI将会#34;只需更新&#34;当服务正在运行时)。

答案 2 :(得分:0)

这是一个工作版本。

import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class ClockView extends Application {
    Pane background;
    static Text firstDigit;
    static Text secondDigit;
    static Text thirdDigit;
    static Text fourthDigit;
    Text middleDecimal;

    public final Timer clockTimer = new Timer();


    /* Sets the first digit of the base 10 time to the passed through char. */
    static void setFirstDigit(char x1) {
        String digitString = "";
        digitString += x1;
        firstDigit.setText(digitString);
    }

    /* Sets the second digit of the base 10 time to the passed through char. */
    static void setSecondDigit(char x2) {
        String digitString = "";
        digitString += x2;
        secondDigit.setText(digitString);
    }

    /* Sets the third digit of the base 10 time to the passed through char. */
    static void setThirdDigit(char y1) {
        String digitString = "";
        digitString += y1;
        thirdDigit.setText(digitString);
    }

    /* Sets the fourth digit of the base 10 time to the passed through char. */
    static void setFourthDigit(char y2) {
        String digitString = "";
        digitString += y2;
        fourthDigit.setText(digitString);
    }

    /* Main Method that Launches the GUI */
    public static void main(String[] args) {
        launch(args);
    }


    @Override
    public void start(Stage primaryStage) throws Exception {
        final double TEXTFIELD_LAYOUT_Y = 200;

        //Background Pane
        background = new Pane();

        //First digit textField
        firstDigit = new Text("0");
        firstDigit.setLayoutX(17);
        firstDigit.setLayoutY(TEXTFIELD_LAYOUT_Y);
        firstDigit.setStyle("-fx-font-size: 96pt;");

        //Second digit textField
        secondDigit = new Text("0");
        secondDigit.setLayoutX(117);
        secondDigit.setLayoutY(TEXTFIELD_LAYOUT_Y);
        secondDigit.setStyle("-fx-font-size: 96pt;");

        //Middle decimal
        middleDecimal = new Text(".");
        middleDecimal.setLayoutX(219);
        middleDecimal.setLayoutY(210);
        middleDecimal.setStyle("-fx-font-size: 72pt;");

        //Third digit textField
        thirdDigit = new Text("0");
        thirdDigit.setLayoutX(250);
        thirdDigit.setLayoutY(TEXTFIELD_LAYOUT_Y);
        thirdDigit.setStyle("-fx-font-size: 96pt;");

        //Fourth digit textField
        fourthDigit = new Text("0");
        fourthDigit.setLayoutX(362);
        fourthDigit.setLayoutY(TEXTFIELD_LAYOUT_Y);
        fourthDigit.setStyle("-fx-font-size: 96pt;");

        /* Adding the Nodes to the Pane */
        background.getChildren().addAll(firstDigit, secondDigit, middleDecimal, thirdDigit, fourthDigit);

        /* Setting the Scene */
        Scene scene = new Scene(new Group(), 470, 258);
        Group root = (Group)scene.getRoot();
        root.getChildren().add(background);
        primaryStage.setTitle("Base 10 Clock");
        primaryStage.setScene(scene);
        primaryStage.show();

        clockTimer.scheduleAtFixedRate(new TimerTask() {

                Calendar now;
                double currentTime;
                String timeString;
                long timestamp;

                @Override
                public void run() { 
                    /*
                     * Calculates the time in base 10 time and calls the 4 methods
                     * to set the GUI display.
                     * 
                     * In a constant while loop in order to continuously update
                     * the GUI.
                     */
                    now = Calendar.getInstance();
                    timestamp = now.get(Calendar.HOUR_OF_DAY)*60*60 + now.get(Calendar.MINUTE)*60 + now.get(Calendar.SECOND);
                    currentTime = timestamp/86400.0;
                    timeString = "" + currentTime;
                    Platform.runLater(new Runnable() {
                        @Override  public void run() {
                            setFirstDigit(timeString.charAt(2));
                            setSecondDigit(timeString.charAt(3));
                            setThirdDigit(timeString.charAt(4));
                            setFourthDigit(timeString.charAt(5));
                        }
                    });
                }
            }, 0, 8640  // Sleep for 8.64 seconds since that is how long it is between
        );              // increments of 0.01 in base 10 time.
    }
}