gpt4 book ai didi

当我将 log4j 附加到文本区域时,JavaFX 应用程序卡住

转载 作者:行者123 更新时间:2023-11-30 03:13:50 25 4
gpt4 key购买 nike

我已成功将 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 Controller 中:

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 图像关联请求收到此类请求)时,会在后台调用此类及其方法。

我不知道这段代码是否有帮助,但是应用程序行为如下:

  1. 应用程序启动正常,GUI 工作正常(可以切换选项卡、编辑字段等)。我还可以在我的 log4j 文本区域中看到它的日志
  2. 当我收到一些传入的 dicom 图像进行解析时(关联请求)然后整个应用程序就会卡住。
  3. 后台应用程序运行正常,无异常抛出并且任务运行没有任何问题
  4. 即使所有关联请求都已结束(已接受并已处理)GUI 仍然卡住。

我希望以上所有信息有所帮助...

最佳答案

TextArea 不适合大量文本,因为它由一个大文本节点支持。您最好使用虚拟控件之一,例如 ListView(如果它不可编辑)或可用的 StyledText 控件之一。

最常用的是:

关于当我将 log4j 附加到文本区域时,JavaFX 应用程序卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33078241/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com