gpt4 book ai didi

java - 使用SwingWorker动态加载jTable中的大数据

转载 作者:行者123 更新时间:2023-12-02 02:56:40 24 4
gpt4 key购买 nike

在 Netbeans 中,我尝试创建一个桌面应用程序,其 UI 如下所示:

enter image description here

我正在通过 Java 代码执行“adb logcat 命令”,该代码会在几秒钟内加载 1000 行日志,并且我打算通过 NetBeans 中的 jTable 显示所有这些信息。

使用参数:adb logcat -t 100 -> 我现在将日志限制为 100 行。然而,当达到 1000 行或取消行数限制时,小程序就会变得无响应(或卡在 process() 方法中)。

我不确定我的代码中是否正确实现了 SwingWorker 线程。我正在寻找有关如何改进代码以动态加载大量数据而不导致小程序变得无响应的建议。

以下是小程序的实现代码...具有 2 个函数:

  1. 从小程序的 init() 方法调用 viewLogs()。
  2. SwingWorker 实现。

        public void viewLogs() throws IOException {

    String[] command = {"CMD","/C", "adb logcat -t 100"};
    ProcessBuilder probuilder = new ProcessBuilder( command );
    probuilder.directory(new File("c:\\Users\\k.garg\\Desktop\\"));
    Process process = probuilder.start();

    InputStream is = process.getInputStream();
    InputStreamReader isr = new InputStreamReader(is);
    br = new BufferedReader(isr);

    DefaultTableModel model = (DefaultTableModel)jTable1.getModel();
    worker.execute();

    try {
    int exitVal = process.waitFor();
    System.out.println("exitVal = " + exitVal);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    public class TableSwingWorker extends SwingWorker<DefaultTableModel, Object[]>{
    private DefaultTableModel tableModel;
    public TableSwingWorker(DefaultTableModel tableModel){
    this.tableModel = tableModel;
    }

    @Override
    protected DefaultTableModel doInBackground() throws Exception {
    Thread.sleep(2000); //added for initial UI to load
    System.out.println("Start populating");
    String line, date, time, loglevel, PID, TID, tag, message="";
    String log;
    int count = 0;
    while ((log = br.readLine()) != null) {
    count++;

    String[] splitLog = log.trim().split("\\s+");
    line = Integer.toString(count);
    date = splitLog[0];
    time = splitLog[1];
    PID = splitLog[2];
    TID = splitLog[3];
    loglevel = splitLog[4];
    tag = splitLog[5];
    for(int i=6; i<splitLog.length;i++){
    message += splitLog[i];
    }
    publish(new Object[]{line, date, time, PID, TID, loglevel, tag, message});
    }
    return tableModel;
    }

    @Override
    protected void process(List<Object[]> chunks) {
    System.out.println("Adding " + chunks.size() + " rows");
    for(Object[] row: chunks)
    tableModel.insertRow(0,row);
    }

    }

最佳答案

关键问题是......

try {
int exitVal = process.waitFor();
System.out.println("exitVal = " + exitVal);
} catch (InterruptedException e) {
e.printStackTrace();
}

这会阻塞事件调度线程,阻止任何可能的更新发生,直到 Process 完成,这有点违背了使用 SwingWorker 的目的。

您最好直接在 SwingWorker 中执行 Process,例如...

public class TableSwingWorker extends SwingWorker<Integer, Object[]> {

private DefaultTableModel tableModel;
private int count;

public TableSwingWorker(DefaultTableModel tableModel) {
this.tableModel = tableModel;
}

@Override
protected Integer doInBackground() throws Exception {
count = 0;

String[] command = {"CMD", "/C", "adb logcat -t 100"};
ProcessBuilder probuilder = new ProcessBuilder(command);
probuilder.directory(new File("c:\\Users\\k.garg\\Desktop\\"));
Process process = probuilder.start();

InputConsumer consumer = new InputConsumer(process.getInputStream());
consumer.start();

int result = process.waitFor();
consumer.join();

return result;
}

@Override
protected void process(List<Object[]> chunks) {
System.out.println("Adding " + chunks.size() + " rows");
for (Object[] row : chunks) {
tableModel.insertRow(0, row);
}
}

protected void processOutput(String text) {
count++;

String[] splitLog = text.trim().split("\\s+");
String line = Integer.toString(count);
String date = splitLog[0];
String time = splitLog[1];
String PID = splitLog[2];
String TID = splitLog[3];
String loglevel = splitLog[4];
String tag = splitLog[5];

StringBuilder message = new StringBuilder(64);
for (int i = 6; i < splitLog.length; i++) {
message.append(splitLog[i]);
}
publish(new Object[]{line, date, time, PID, TID, loglevel, tag, message});
}

public class InputConsumer extends Thread {

private InputStream is;

public InputConsumer(InputStream is) {
this.is = is;
start();
}

@Override
public void run() {
try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
String text = null;
while ((text = br.readLine()) != null) {
processOutput(text);
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
}

好吧,这可能看起来有点“重”,但它做了两件重要的事情:

  1. 它将进程的 InputStream 的读取任务转移到另一个 Thread,这使我们能够...
  2. waitFor 进程退出,以便我们获得退出值,这对于诊断为什么某些东西有时不起作用

其他观察结果

关于java - 使用SwingWorker动态加载jTable中的大数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42969696/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com