Mam prosty zwyczaj rejestrowania ramy tak:najbardziej skuteczny sposób wiadomości do JavaFX TextArea zalogować poprzez wątków z prostego niestandardowego rejestrowania Ramki
package something;
import javafx.scene.control.TextArea;
public class MyLogger {
public final TextArea textArea;
private boolean verboseMode = false;
private boolean debugMode = false;
public MyLogger(final TextArea textArea) {
this.textArea = textArea;
}
public MyLogger setVerboseMode(boolean value) {
verboseMode = value;
return this;
}
public MyLogger setDebugMode(boolean value) {
debugMode = value;
return this;
}
public boolean writeMessage(String msg) {
textArea.appendText(msg);
return true;
}
public boolean logMessage(String msg) {
return writeMessage(msg + "\n");
}
public boolean logWarning(String msg) {
return writeMessage("Warning: " + msg + "\n");
}
public boolean logError(String msg) {
return writeMessage("Error: " + msg + "\n");
}
public boolean logVerbose(String msg) {
return verboseMode ? writeMessage(msg + "\n") : true;
}
public boolean logDebug(String msg) {
return debugMode ? writeMessage("[DEBUG] " + msg + "\n") : true;
}
}
Teraz to, co chcę zrobić, to aby ją rozszerzyć tak, że będzie być w stanie prawidłowo obsługiwać rejestrowanie wiadomości za pośrednictwem wątków. Próbowałem rozwiązań takich jak using message queues with an AnimationTimer. Działa, ale spowalnia GUI.
Próbowałem także użyć scheduled service, który uruchamia wątek, który odczytuje wiadomości z kolejki komunikatów, łączy je i dołącza do TextArea (textArea.appendText(stringBuilder.toString())
). Problem polega na tym, że kontrolka TextArea jest niestabilna, tzn. Trzeba zaznaczyć wszystkie teksty za pomocą Ctrl-A
i spróbować zmienić rozmiar okna, aby wyglądały dobrze. Niektóre z nich są wyświetlane na jasnoniebieskim tle, nie wiedząc, co to powoduje. Moim pierwszym przypuszczeniem jest to, że warunki wyścigu mogą nie pozwalać, aby kontrola aktualizowała się dobrze z nowych łańcuchów. Warto również zauważyć, że tekst jest owinięty wokół ScrollPane, więc dodaje zamieszania, jeśli TextArea jest rzeczywiście tym, który ma problem lub ScrollPane. Muszę również wspomnieć, że to podejście nie powoduje szybkiej aktualizacji samej aplikacji TextArea.
myślałem o binding
TextArea.TextProperty()
do czegoś, co robi aktualizację, ale nie jestem pewien, jak to zrobić poprawnie wiedząc, że zbieracz komunikatów (czy to przez usługę lub samotnego gwintem) będzie nadal działa różni się od wątek GUI.
Próbowałem sprawdzić inne znane rozwiązania do obsługi rejestrowania, takie jak log4j i niektóre komunikaty o których mowa here, ale żaden z nich nie wydaje się dać oczywiste podejście do logowania za pośrednictwem wątków do TextArea. Nie podoba mi się również pomysł zbudowania mojego systemu rejestrowania na nich, ponieważ mają już predefiniowane mechanizmy, takie jak poziom rejestrowania itp.
Widziałem również this. Sugeruje użycie SwingUtilities.invokeLater(Runnable)
do zaktualizowania formantu, ale już wypróbowałem podobne podejście przy użyciu javafx.application.platform.runLater()
, które zostanie wykonane w wątku roboczym. Nie jestem pewien, czy było coś, co robiłem źle, ale po prostu wisi. Może generować wiadomości, ale nie wtedy, gdy są wystarczająco agresywne. Szacuję, że wątek roboczy działający w sposób całkowicie synchroniczny może w rzeczywistości generować około 20 lub więcej linii średnich na sekundę i więcej, gdy jest w trybie debugowania. Możliwym obejściem byłoby dodanie do niego także kolejkowania komunikatów, ale to już nie ma sensu.
Nie używaj TextArea, użyj zwirtualizowanych kontrolę, tj [ListView] (http: // docs.oracle.com/javase/8/javafx/api/javafx/scene/control/ListView.html). – jewelsea
@jewelsea Dzięki, mogę to rozważyć. Czy układ ListView może być skonfigurowany tak, aby wyglądał jak TextArea? – konsolebox