2015-09-22 2 views
0

Я создаю графический интерфейс, где вывод печатается в списке.PrintStream перенаправлен на список SWT

Для этого я расширяю класс OutputStream.

import java.io.IOException; 
import java.io.OutputStream; 
import org.eclipse.swt.widgets.List; 

/** 
//This class extends from OutputStream to redirect output to a SWT List widget 
**/ 
public class CustomOutputStream extends OutputStream { 

    private List list; 

    public CustomOutputStream(List list) { 
     this.list = list; 
    } 

    @Override 
    public void write(int b) throws IOException {  
     // redirects data to the list 
     list.add(String.valueOf((char)b)); 
     // scrolls the text area to the end of data 
     list.select(list.getItemCount() - 1); 
     list.showSelection(); 
     list.deselectAll(); 
    } 
} 

В main классе, список создается и передается в экземпляр CustomOutputStream. Создается поток печати, используя аргумент CustomOutputStream. System.out и System.err предназначены для использования этого потока печати.

Public List list = new List(shell, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); 
Public CustomOutputStream log = new CustomOutputStream(list); 
PrintStream ps = new PrintStream(log); 
System.setOut(ps); 
System.setErr(ps); 

Данные печатаются в личный список графического интерфейса пользователя, но есть один символ в строке! (Каждый элемент списка - один символ). Кроме того, данные не печатаются в списке, так как они генерируются так же, как на консоли, после того, как программа закончит работу, она «сбрасывается» сразу же в список. Как исправить эти проблемы?

ответ

0

Вы получаете один символ за запись в списке, потому что вы вызываете list.add для каждого написанного символа - каждый вызов list.add добавляет новую строку в список. Вам необходимо изменить код write, чтобы скопировать текущую строку (например, в StringBuilder), пока не увидите, что конец строки будет записан, а затем добавьте всю строку).

Пользовательский интерфейс обновляется только при запуске цикла SWT readAndDispatch. Поэтому, если вы используете длинную программу в потоке пользовательского интерфейса, ничего не произойдет, пока она не закончится, потому что readAndDispatch не вызывается.

Для этого вам необходимо запустить код в отдельном потоке, чтобы поток пользовательского интерфейса мог оставаться отзывчивым. Используйте метод Display.asyncExec для обновления списка из фонового потока.

+0

Спасибо, Грег. Как вы предположили, я аккумулировал текущую строку в StringBuilder, пока не увидел, что конец строки написан, а затем добавил всю строку. Прекрасно работает. Однако, когда я использую метод asyncExec, один элемент добавляется в список дважды, затем генерируется исключение нулевого указателя. Любые идеи о том, как исправить? Я объявляю свой CustomOutputStream, передавая его ему классу, который запускается во «втором» потоке, который использует его как аргумент для System.setOut, и этому классу CustomOutputStream предлагается добавлять элементы в список, который был объявлен в «первом " нить. –

+0

Думаю, вам нужно будет задать новый вопрос, показывающий ваш код. –