如何多线程我现有的javafx应用程序

时间:2013-06-02 07:30:22

标签: java multithreading javafx-2 lag

我正在创建一个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,但信息量不大)

1 个答案:

答案 0 :(得分:2)

  1. 使用预定义的线程池或新的Thread(),您可以在其中提供可运行的数据。
  2. 它会将计算从javafx线程移动到某个单独的线程,以便用户可以继续与应用程序进行交互。

    1. 当结果准备就绪时,使用runLater() - 这个调用将在javafx队列上完成,这样你就不会遇到并发问题。
    2. 这允许您将评估结果返回给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();
      }
      

      单击按钮,禁用文本区域,创建新线程,在其中执行代码,然后在javafx队列上放置runnable,并从JavaFX线程上的第二个runnable执行一段代码,在此处分配新文本并启用文本区域。