JavaFX - 自动化Textarea清除(滚动策略?)

问题描述 投票:0回答:2

我有一个Textarea组件,用于显示两个应用程序之间的消息(确切地说是HL7消息)。每次成功处理消息时,都会记录消息以及从接收系统发回的确认。这些消息可以由成千上万的人发送,我觉得当这些组件“溢出”时,问题将不可避免地发生。我想实现一个翻转策略,有点像log4j,你可以告诉它只保留10个1MB的文件。我希望有一个用户可以设置的值,我的组件(可能是Textarea组件的扩展)将自动保留该行数,并在添加新行时清除第一行。我是相对较新的JavaFX(来自Swing),我已经查看了选项,但无法弄清楚如何做到这一点。

谢谢

javafx textarea limit
2个回答
0
投票

正如我在问题的评论部分提到的,我建议你使用ListView而不是TextArea。这给您带来了一些好处:

  1. ListView是一个“虚拟”控件 - 它只渲染足够的cells来填充可见空间,并且在滚动时重复使用单元格。这允许人们在ListView中拥有数千个项目而不会使性能受到影响。
  2. ListView的模型是an observable list,这是一种更好的方式来表示单独的消息,而不是在String中有一个巨大的TextArea。向列表中添加元素会使其增长超过任意容量时,您只需从所述列表的开头删除一个项目(如果在顶部而不是底部插入项目,则结束)。
  3. 在显示消息时,ListView提供了更大的灵活性。这是通过自定义cell factory完成的。例如,通过使用TextFlow作为ListCell的图形,您可以将消息的某些范围设置为不同的颜色。但是,请务必阅读Cell.updateItem(Object,boolean)的文档,因为您必须正确覆盖该方法;如果不这样做,可能会因为重复使用单元格而导致伪影。

一个简单的例子:

import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Main extends Application {

    private static void generateMessages(Consumer<String> onNewMessage) {
        AtomicInteger counter = new AtomicInteger();
        PauseTransition pt = new PauseTransition(Duration.seconds(1));
        pt.setOnFinished(e -> {
            onNewMessage.accept(String.format("Message #%,d", counter.incrementAndGet()));
            pt.playFromStart();
        });
        pt.playFromStart();
    }

    @Override
    public void start(Stage primaryStage) {
        ListView<String> listView = new ListView<>();
        primaryStage.setScene(new Scene(listView, 500, 300));
        primaryStage.show();

        generateMessages(message -> {
            listView.getItems().add(message);
            if (listView.getItems().size() > 10) {
                listView.getItems().remove(0);
            }
        });
    }

}

0
投票

我超越了接受的答案(没有它我仍然会尝试使用TextArea!)并构建了这个自定义组件(是的,有一个空的catch块,但我有一个清除日志按钮,当日志是时抛出异常空,处理它:))

public class HL7ListView extends ListView<String>
{
    private int serviceLogMaxEntries;

    public HL7ListView() 
    {
        super();

        getItems().addListener((ListChangeListener<String>) listener ->
        {
            if (getItems().size() > serviceLogMaxEntries)
            {
                Platform.runLater(() -> 
                {
                    try
                    {
                        getItems().remove(0);
                    }
                    catch (Exception ex)
                    {}
                });
            }
        });
    }

    public void setServiceLogMaxEntries(int serviceLogMaxEntries)
    {
        this.serviceLogMaxEntries = serviceLogMaxEntries;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.