2016-12-08 3 views
0
public class TextAreaAppender extends WriterAppender { 

private static volatile TextArea textArea = null; 
private static final Logger log = LoggerFactory.getLogger(TextAreaAppender.class); 

/** 
* Set the target TextArea for the logging information to appear. 
* 
* @param textArea 
*/ 
public static void setTextArea(final TextArea textArea) { 
    TextAreaAppender.textArea = textArea; 
} 

/** 
* Format and then append the loggingEvent to the stored TextArea. 
* 
* @param loggingEvent 
*/ 
@Override 
public void append(final LoggingEvent loggingEvent) { 
    final String message = this.layout.format(loggingEvent); 
    // Append formatted message to text area using the Thread. 
    Task<Void> task = new Task<Void>() { 
     @Override 
     protected Void call() throws Exception { 
      try { 
       if (textArea != null) { 
        if (textArea.getText().length() == 0) { 
         Platform.runLater(() -> { 
          textArea.setText(message); 
         }); 
        } else { 
         textArea.selectEnd(); 
         Platform.runLater(() -> { 
          textArea.insertText(textArea.getText().length(), message); 
         }); 
        } 
       } 

      } catch (final Throwable t) { 
       log.error("Unable to append log to text area: " + t.getMessage()); 
      } 
      return null; 
     } 
    }; 
    new Thread(task).start(); 
} 

Das ist meine Klasse. hat es von http://www.rshingleton.com/javafx-log4j-textarea-log-appender/ Es schreibt die Protokolle, die auch an der Konsole erscheinen, in ein Textfeld. Das Problem ist, dass die Protokolle in einer anderen falschen Reihenfolge als in der Konsole angezeigt werden. warum? Dank im VorausLogs out of order in TextArea

+0

Sie könnten in dieser Frage im Zusammenhang interessieren: [effizienteste Weg, Nachrichten zu JavaFX TextArea- über Gewinde mit einfachen benutzerdefinierten Logging Frameworks log] (http: // stackoverflow.com/questions/24116858/most-efficient-way-to-log-messages-to-javafx-textarea-via-threads-with-simple-cu). – jewelsea

Antwort

2

Sie starten eine Task auf einem anderen Thread die Runnable s mit Platform.runLater posten. Die Runnable s werden in der Reihenfolge ausgeführt, in der sie gebucht werden, aber durch die Veröffentlichung von Thread verlieren Sie die Kontrolle über die Reihenfolge, in der sie übermittelt werden.

Ich bin nicht wirklich sicher, warum Sie hier sowieso einen anderen Thread verwenden. Einfach post direkt aus dem aktuellen Thread. Der Code, der „teuren“ läuft es sowieso sein könnte:

@Override 
public void append(final LoggingEvent loggingEvent) { 
    // create a copy to make sure it's not overwritten somewhere 
    final TextArea target = textArea; 

    if (target != null) { 
     final String message = this.layout.format(loggingEvent); 
     Platform.runLater(() -> { 
      target.selectEnd(); 
      target.appendText(message); 
     }); 
    } 
} 
+0

blöder Fehler ... danke! – jv123