2017-09-24 88 views
3

有沒有辦法在TextArea中以相當快的速度編輯一個相對較大的文本文件(例如10-25 MB)?或者,也許有功能可以禁用,使其更快?有替代組件嗎? (我知道RichTextFX,但我想它會更慢,因爲它做的更多,而我只需要一個基本的編輯器。)使用TextArea使用JavaFX編輯大型文本文件

我寧可不把源文本分成更小的部分,只加載一部分因爲這會破壞文本選擇+複製(即「全選」只會選擇加載的文本而不是整個文件的文本)。

回答

3

一種方法是利用ListView提供的flyweight渲染來創建線條編輯器。從example開始,下面的LineEditor通過設置SelectionMode.MULTIPLE啓用多項選擇。它也可以編輯,如here,@tarrsalah所示。當然,你會想添加額外的控件來滿足你的特定用例。

image

import java.io.*; 
import javafx.application.*; 
import javafx.collections.*; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.scene.control.cell.*; 
import javafx.scene.layout.*; 
import javafx.stage.Stage; 

/** @see https://stackoverflow.com/a/44823611/230513 */ 
public class LineEditor extends Application { 

    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage stage) { 
     VBox pane = new VBox(); 
     Button importButton = new Button("Import"); 
     TextField filePath = new TextField("/usr/share/dict/words"); 
     ObservableList<String> lines = FXCollections.observableArrayList(); 
     ListView<String> listView = new ListView<>(lines); 
     listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); 
     listView.setCellFactory(TextFieldListCell.forListView()); 
     listView.setOnEditCommit(new EventHandler<ListView.EditEvent<String>>() { 
      @Override 
      public void handle(ListView.EditEvent<String> t) { 
       listView.getItems().set(t.getIndex(), t.getNewValue()); 
      } 
     }); 
     listView.setEditable(true); 
     importButton.setOnAction(a -> { 
      listView.getItems().clear(); 
      try { 
       BufferedReader in = new BufferedReader 
        (new FileReader(filePath.getText())); 
       String s; 
       while ((s = in.readLine()) != null) { 
        listView.getItems().add(s); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     }); 
     pane.getChildren().addAll(importButton, filePath, listView); 
     Scene scene = new Scene(pane); 
     stage.setScene(scene); 
     stage.show(); 
    } 
} 
+0

我懷疑是「最佳」答案會是一個全新的自定義TextArea組件需要...但是這是一個有趣的妥協嘗試。 – Manius

+1

@Manius:'ListView'應該符合大小要求,其他視圖也可以承認'IndexedCell',例如'TableView'。對於較大的文件或遠程文件系統,您可能需要一個「任務」。一個類似的問題在這裏被檢查(https://stackoverflow.com/q/27414689/230513)。 – trashgod

+1

不錯的發現,我沒有注意到我的預搜索中的鏈接。 – Manius