3

我正在创建一个 javafx 应用程序。它使用一些繁重的编程(重映射)。我需要对它进行多线程处理,因为用户体验变得滞后。
如果可能的话,我不想重写整个代码。但这不是必需的。我需要有人完整地解释生命周期,如何控制线程以及如何要求它做某事。
例如,我在我的 fxml 控制器中提供了完整的映射字符列表:

@FXML
private static final Map <Character, String> myMap = new HashMap <> ();
static {
    myMap.put('a', "5");
    myMap.put('b', "6");
    myMap.put('c', "7");
    myMap.put('d', "8");
    //And so on...
}

然后我在按下按钮时对输入文本进行编码:

    String codedTextOut;                
    textToCode = enteredText.getText();
    StringBuilder encoderTextSB = new StringBuilder();
    for (char codeChar : textToCode.toCharArray()) {
        encoderTextSB.append(myMap.get(codeChar));
    }
    codedTextOut = encoderTextSB.toString();

它提供了滞后的用户体验。我想创建一个单独的线程来执行按钮按下时的编码操作。请帮助并解释线程的各种属性。(我已经检查了http://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm,但信息量不大)

4

1 回答 1

2
  1. 使用预定义的线程池或 new Thread(),您可以在其中提供可运行的数据。

它将计算从 javafx 线程转移到另一个线程,以便用户可以继续与应用程序交互。

  1. 当结果准备好时,使用 runLater() - 这个调用将在 javafx 队列上完成,这样你就不会遇到并发问题。

这允许您将评估结果返回到 UI。(您不应该与来自另一个线程的 UI 组件进行交互)。

可以选择使用 javafx 并发包中的其他功能,例如 Task。

这是一个代码片段:

@Override
public void start(Stage primaryStage) {
    final TextArea ta = new TextArea();
    ta.setMinSize(100, 100);
    Button btn = new Button();
    btn.setText("Encode'");
    btn.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {

            ta.setDisable(true);
            new Thread(new Runnable() {

                @Override
                public void run() {
                    final StringBuilder codedTextOut = new StringBuilder();
                    String textToCode = ta.getText();
                    StringBuilder encoderTextSB = new StringBuilder();
                    for (char codeChar : textToCode.toCharArray()) {
                        encoderTextSB.append(codeChar + 15);
                    }
                    codedTextOut.append(encoderTextSB);
                    Platform.runLater(new Runnable() {

                        @Override
                        public void run() {
                            ta.setText(codedTextOut.toString());
                            ta.setDisable(false);
                        }
                    });
                }
            }).start();
        }
    });

    VBox root = new VBox();
    root.getChildren().addAll(ta, btn);

    Scene scene = new Scene(root, 300, 250);

    primaryStage.setTitle("Encoder");
    primaryStage.setScene(scene);
    primaryStage.show();
}

单击按钮时,禁用文本区域,创建一个新线程,在其中执行代码,然后将 runnable 放入 javafx 队列,并从 JavaFX 线程上的第二个可运行对象执行一段代码,在其中分配新文本并启用文本区回来。

于 2013-06-02T10:57:36.640 回答