在写入时冻结了TextArea Fx

时间:2019-04-24 13:56:41

标签: java javafx

我尝试列出Java Fx中TextArea中的大量行。问题是滚动条冻结了,不让我向下滚动。我想每次都看到最后一行。还是有另一个组件来显示大量的行。或者更快地完成此过程。

        Service<Void> service = new Service<Void>() {
            @Override
            protected Task<Void> createTask() {
                return new Task<Void>() {           
                    @Override
                    protected Void call() throws Exception {

                        File dir = new File("C:\\");
                        int[] count = {0};
                        try {
                            System.out.println("Inicia Visitador de Directorios");
                            Files.walkFileTree(Paths.get(dir.getPath()), new HashSet<FileVisitOption>(),
                                    Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
                                        @Override
                                        public FileVisitResult visitFile(Path file , BasicFileAttributes attrs) throws IOException {
//                                          System.out.printf("Visiting file %s\n", file);
                                            ++count[0];
                                            final CountDownLatch latch = new CountDownLatch(1);
                                            Platform.runLater(new Runnable() {                          
                                                @Override
                                                public void run() {
                                                    try{
                                                        StringBuffer buf = new StringBuffer(textAreaLog.getText());
                                                        buf.append(count[0]+" File "+file+"\n");
                                                        textAreaLog.setText(buf.toString());
                                                    }finally{
                                                        latch.countDown();
                                                    }
                                                }
                                            });
                                            try {
                                                latch.await();
                                            } catch (InterruptedException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                            }        
                                            return FileVisitResult.CONTINUE;
                                        }

                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }


                        //Keep with the background work
                        return null;
                    }
                };
            }
        };
        service.start();

1 个答案:

答案 0 :(得分:2)

让TextArea滚动到底部是容易的部分。只需使用appendText即可,而不是设置TextArea的整个文本值:

textAreaLog.appendText(count[0] + " File " + file + "\n");

Matt指出,更大的问题是您正在泛滥JavaFX应用程序线程。遍历文件树很快就会列出文件,并且您向应用程序线程发送了很多Runnable,以至于该线程没有时间进行其正常处理,例如绘制窗口和处理用户输入。

有几种方法可以解决此问题。一种简单的方法是添加一个睡眠呼叫:

try {
    latch.await();
    Thread.sleep(200);
} catch (InterruptedException e) {
    e.printStackTrace();
}

另一种方法是创建您自己的缓冲区,因此您将仅以大块添加文本,例如每1,000行:

System.out.println("Inicia Visitador de Directorios");

int maxBufferSize = 1000;
Collection<String> buffer = new ArrayList<>(maxBufferSize);

Files.walkFileTree(dir.toPath(), new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
    throws IOException {
        ++count[0];
        buffer.add(count[0] + " File " + file + "\n");

        if (buffer.size() >= maxBufferSize) {
            String lines = String.join("", buffer);
            buffer.clear();

            Platform.runLater(() -> textAreaLog.appendText(lines));
        }

        return FileVisitResult.CONTINUE;
    }
});

String lines = String.join("", buffer);
Platform.runLater(() -> textAreaLog.appendText(lines));