在Netbeans中,我正在尝试创建一个桌面应用程序,其UI如下所示:
我正在通过Java代码执行“adb logcat命令”,该代码在几秒钟内加载了1000行日志。我打算通过NetBeans中的jTable显示所有这些信息。
使用参数:adb logcat -t 100 - >我现在只将日志限制为100行。 但是,对于1000行或在删除对行数的限制时,applet变得无响应(或卡在process()方法中)。
我不确定我是否在代码中正确实现了SwingWorker线程。我正在寻找有关如何改进代码以动态加载大量数据的建议,而不会让applet变得无法响应。
以下是applet实现的代码...包含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);
}
}
答案 0 :(得分:2)
关键问题是......
try {
int exitVal = process.waitFor();
System.out.println("exitVal = " + exitVal);
} catch (InterruptedException e) {
e.printStackTrace();
}
这阻止了事件调度线程,阻止在Process
完成之前发生任何可能的更新,这有点违背了使用SwingWorker
的目的。
您最好直接执行Process
中的SwingWorker
,例如......
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();
}
}
}
}
好吧,这可能看起来有点重&#34;但它做了两件重要的事情:
InputStream
加载到另一个Thread
,这样我们就可以...... waitFor
要退出的流程,以便我们获得退出值,这可用于诊断为什么某些人不时不工作