[英]JavaFX application freeze when i append log4j to textarea
我已經設法將log4j消息附加到javafx textarea組件,但是,如果運行后台應用程序任務,則GUI將凍結。
因此,實現中的某些內容丟失或配置錯誤。
這是我的自定義log4j附加程序:
public class TextAreaAppender extends WriterAppender {
static Logger log = Logger.getLogger(TextAreaAppender.class.getName());
private static volatile TextArea textArea = null;
public static void setTextArea(final TextArea textArea) {
TextAreaAppender.textArea = textArea;
}
@Override
public void append(final LoggingEvent loggingEvent) {
final String message = this.layout.format(loggingEvent);
try {
Platform.runLater(() -> {
try {
if (textArea != null) {
if (textArea.getText().length() == 0) {
textArea.setText(message);
} else {
textArea.selectEnd();
textArea.insertText(textArea.getText().length(),
message);
}
}
} catch (final Throwable t) {
System.out.println("Unable to append log to text area: "
+ t.getMessage());
}
});
} catch (final IllegalStateException e) {
// ignore case when the platform hasn't yet been iniitialized
}
}
這是我將textarea組件插入我的fxml控制器的方法:
public class FXMLDocumentController implements Initializable {
...
@FXML
private TextArea logText;
...
@Override
@FXML
public void initialize(URL url, ResourceBundle rb) {
...
logText.setEditable(false);
TextAreaAppender.setTextArea(logText);
}
最后是我的log4j配置:
log4j.rootLogger=INFO, file, textarea, stdout
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
# Append the logs to the GUI
log4j.appender.textarea = com.npap.fxutils.TextAreaAppender
log4j.appender.textarea.Target=System.out
log4j.appender.textarea.layout=org.apache.log4j.PatternLayout
log4j.appender.textarea.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
GUI凍結的原因可能是什么?
在后台應用程序中運行多個任務/進程,並且在凍結以下類及其方法時,凍結應用程序的操作是:
class StorageSCP extends StorageService implements AssociationListener {
...
private final DcmRcv dcmrcv;
public StorageSCP(DcmRcv dcmrcv, String[] sopClasses) {
super(sopClasses);
this.dcmrcv = dcmrcv;
}
...
/** Overwrite {@link StorageService#cstore} to send delayed C-STORE RSP
* by separate Thread, so reading of following received C-STORE RQs from
* the open association is not blocked.
*/
@Override
public void cstore(final Association as, final int pcid, DicomObject rq,
PDVInputStream dataStream, String tsuid)
throws DicomServiceException, IOException {
final DicomObject rsp = CommandUtils.mkRSP(rq, CommandUtils.SUCCESS);
onCStoreRQ(as, pcid, rq, dataStream, tsuid, rsp);
if (dcmrcv.getDimseRspDelay() > 0) {
dcmrcv.executor().execute(new Runnable() {
public void run() {
try {
Thread.sleep(dcmrcv.getDimseRspDelay());
as.writeDimseRSP(pcid, rsp);
} catch (Exception e) {
e.printStackTrace();
}
}
});
} else {
as.writeDimseRSP(pcid, rsp);
}
onCStoreRSP(as, pcid, rq, dataStream, tsuid, rsp);
}
...
@Override
protected void onCStoreRQ(Association association, int pcid, DicomObject dcmReqObj,
PDVInputStream dataStream, String transferSyntaxUID,
DicomObject dcmRspObj)
throws DicomServiceException, IOException {
final DicomOutputStream outStream = new DicomOutputStream(new BufferedOutputStream(new FileOutputStream(dicomFile), 600000));
try {
outStream.writeFileMetaInformation(fileMetaDcmObj);
dataStream.copyTo(outStream);
} catch (DicomServiceException e) {
} finally {
outStream.close();
}
...
}
...
@Override
public void associationAccepted(final AssociationAcceptEvent associationAcceptEvent) {
final UUID assocUUID = UUID.randomUUID();
final Association association = associationAcceptEvent.getAssociation();
associationDataMap.put(association, assocUUID);
}
@Override
public void associationClosed(final AssociationCloseEvent associationCloseEvent) {
final Association association = associationCloseEvent.getAssociation();
associationDataMap.remove(association);
final Integer assocInstanceCnt = associationCounterMap.get(association);
removeAssociationCounter(association);
}
private final Map<Association, UUID> associationDataMap = new HashMap<Association, UUID>();
private final Map<Association, Integer> associationCounterMap = new HashMap<Association, Integer>();
偵聽器(偵聽傳入的dicom圖像關聯請求收到此類消息)時,將在后台調用此類及其方法。
我不知道此代碼是否有幫助,但是應用程序的行為類似於以下內容:
希望以上所有信息對您有所幫助...
TextArea不支持大量文本,因為它由一個大文本節點支持。 最好使用虛擬控件之一,例如ListView(如果不可編輯)或StyledText控件之一。
最常用的是:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.