package ru.taximaxim.pgsqlblocks.ui;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.log4j.WriterAppender;
import org.apache.log4j.spi.LoggingEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;

public class UIAppender extends WriterAppender{

    private Composite parent;
    private StyledText text;
    private Display display;

    public UIAppender(Composite parent) {
        this.parent = parent;
        this.display = parent.getDisplay();
        createControl();
    }

    private void createControl() {
        text = new StyledText(parent, SWT.MULTI | SWT.READ_ONLY | SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
        text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        text.setMargins(3, 3, 3, 3);
        text.layout(true);
        parent.layout(true, true);
    }

    public void append(LoggingEvent event) {
        boolean displayIsFine = display == null || display.isDisposed();
        boolean parentIsFine = parent == null || parent.isDisposed();
        if(displayIsFine || parentIsFine || text == null) {
            return;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
        Date time = new Date(event.getTimeStamp());
        String dateTime = sdf.format(time);
        String excMessage = "";
        Object message = event.getMessage();
        if (message instanceof String) {
            excMessage = (String) message;
        } else {
            return;
        }
        final String logMessage = String.format("[%s] %s%n", dateTime,excMessage);
        parent.getDisplay().asyncExec(() -> text.append(logMessage));
    }
}
@@ -269,23 +269,16 @@
 swt.
-layout.GridData
+events.*
 ;%0Aim
@@ -302,25 +302,23 @@
 swt.
-widgets.Composite
+layout.GridData
 ;%0Aim
@@ -346,23 +346,17 @@
 widgets.
-Display
+*
 ;%0A%0Apubli
@@ -486,16 +486,221 @@
 display;
+%0A    private ModifyListener modifyListener = new ModifyListener() %7B%0A        @Override%0A        public void modifyText(ModifyEvent e) %7B%0A            text.setTopIndex(text.getLineCount() - 1);%0A        %7D%0A    %7D;
 %0A%0A    pu
@@ -1135,32 +1135,761 @@
     
-parent.layout(true, true
+text.addModifyListener(modifyListener);%0A        parent.layout(true, true);%0A%0A        // add empty string on ENTER pressed%0A        text.addTraverseListener(e -%3E %7B%0A            switch (e.detail) %7B%0A                case SWT.TRAVERSE_RETURN:%0A                    if (!text.isDisposed()) %7B%0A                        text.append(%22%5Cn%22);%0A                        text.setTopIndex(text.getLineCount() - 1);%0A                    %7D%0A                default:%0A                    break;%0A            %7D%0A        %7D);%0A%0A        // wheel up and down%0A        text.addMouseWheelListener(e -%3E %7B%0A            if (e.count %3E 0) %7B%0A                text.removeModifyListener(modifyListener);%0A            %7D else %7B%0A                text.addModifyListener(modifyListener);%0A            %7D%0A        %7D
 );%0A 
@@ -2683,31 +2683,112 @@
  -%3E 
-text.append(logMessage)
+%7B%0A            if (!text.isDisposed()) %7B%0A                text.append(logMessage);%0A            %7D%0A        %7D
 );%0A 

Refactor UIAppender: - autoscrolling - adding empty lines by pushing ENTER