2017-09-24 83 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