我有一个带表的GUI - 该表由InputStreamReader的内容填充。为了做到这一点,我正在创建一个监视InputStream的线程,当有一个新行要读取时,它会将它添加到表中。我遇到的问题是线程的创建似乎挂起了整个应用程序。这种做法的典型方式是什么?
流程如下:
Gui->按钮onUp-> LogCatController.start-> 。gui.getDisplay()asyncExec(AdbThreadReader) - > addLine
public class Gui {
protected Shell shell;
private Display display;
private Table logCatTable;
private Text text;
private LogCatController logCatController;
private TableColumn tblclmnDate;
public void open() {
this.display = Display.getDefault();
createContents();
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
/**
* Create contents of the window.
*/
protected void createContents() {
...
logCatTable = new Table(composite, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI);
FormData fd_logCatTable = new FormData();
fd_logCatTable.left = new FormAttachment(0, 142);
fd_logCatTable.right = new FormAttachment(100);
fd_logCatTable.bottom = new FormAttachment(100);
fd_logCatTable.top = new FormAttachment(0);
logCatTable.setLayoutData(fd_logCatTable);
logCatTable.setHeaderVisible(true);
logCatTable.setLinesVisible(true);
...
Button btnStart = new Button(composite_1, SWT.NONE);
btnStart.addMouseListener(new MouseAdapter() {
@Override
public void mouseUp(MouseEvent arg0) {
try {
logCatController.start();
} catch (IOException e) {
e.printStackTrace();
}
}
});
...
}
public Table getLogCatTable() {
return logCatTable;
}
public Display getDisplay() {
return display;
}
}
public class LogCatController {
private DataBindingContext m_bindingContext;
private static Logger logger = Logger.getLogger(AdbLine.class);
private LogCat logcat;
private Gui gui;
public LogCatController(Gui gui){
this.gui = gui;
logcat = new LogCat();
m_bindingContext = initDataBindings();
}
public void start() throws IOException{
logcat.execute();
BufferedReader read = logcat.getSTDOUT();
BufferedReader error = logcat.getSTDERR();
Runnable readRunnable = new AdbLineReaderThread(read);
gui.getDisplay().asyncExec(readRunnable);
}
private void addLine(AdbLine l){
logger.debug("Adding: " + l);
Table logCatTable = this.gui.getLogCatTable();
TableItem tableItem = new TableItem(logCatTable, SWT.NONE);
tableItem.setText(new String[] {"time", l.getLevel().toString(), String.valueOf(l.getPid()), l.getMessage()});
tableItem.setForeground(SWTResourceManager.getColor(SWT.COLOR_CYAN));
}
public class AdbLineReaderThread implements Runnable {
private BufferedReader read;
public AdbLineReaderThread(BufferedReader read){
this.read = read;
}
public void run() {
logger.debug("AdbLinReaderThread run");
String line = null;
try{
while( (line = read.readLine()) != null){
logger.debug(line);
AdbLine l = new AdbLine(line);
addLine(l);
}
} catch(Exception e) {
System.out.println("Could not parse: " + line);
e.printStackTrace();
}
}
}
}
public class LogCat extends BackgroundCommand{
public LogCat(){
super(...);
}
}
答案 0 :(得分:1)
SWT对象的所有操作必须在SWT事件线程中进行。为了确保这包含addLine的“肉”
logCatTable.getDisplay.syncExec(new Runnable() {
public void run() {
....
}
}
或者,如果您不需要等待结果并且asyncExec(...)
没有任何并发问题,则可以使用AdbLine
...