content: package com.alphabugx.util;
  
  import javafx.application.Platform;
  import javafx.scene.control.TextArea;
  
  import java.io.*;
  import java.text.SimpleDateFormat;
  import java.util.Date;
  
  /**
   * 日志捕获器 - 拦截System.out和System.err输出并重定向到GUI
   */
  public class LogCapture {
      
      private static LogCapture instance;
      private TextArea logTextArea;
      private PrintStream originalOut;
      private PrintStream originalErr;
      private PrintStream customOut;
      private PrintStream customErr;
      private SimpleDateFormat timeFormat;
      private boolean isCapturing = false;
      
      private LogCapture() {
          this.timeFormat = new SimpleDateFormat("HH:mm:ss.SSS");
          this.originalOut = System.out;
          this.originalErr = System.err;
      }
      
      public static LogCapture getInstance() {
          if (instance == null) {
              instance = new LogCapture();
          }
          return instance;
      }
      
      /**
       * 设置日志输出的TextArea
       */
      public void setLogTextArea(TextArea logTextArea) {
          this.logTextArea = logTextArea;
      }
      
      /**
       * 开始捕获日志
       */
      public void startCapture() {
          if (isCapturing || logTextArea == null) {
              return;
          }
          
          isCapturing = true;
          
          // 创建自定义的输出流
          customOut = new PrintStream(new LogOutputStream(LogLevel.INFO));
          customErr = new PrintStream(new LogOutputStream(LogLevel.ERROR));
          
          // 重定向系统输出
          System.setOut(customOut);
          System.setErr(customErr);
          
          appendToLog("INFO", "日志捕获已启动");
      }
      
      /**
       * 停止捕获日志
       */
      public void stopCapture() {
          if (!isCapturing) {
              return;
          }
          
          isCapturing = false;
          
          // 恢复原始输出
          System.setOut(originalOut);
          System.setErr(originalErr);
          
          if (customOut != null) {
              customOut.close();
          }
          if (customErr != null) {
              customErr.close();
          }
          
          appendToLog("INFO", "日志捕获已停止");
      }
      
      /**
       * 清空日志
       */
      public void clearLog() {
          if (logTextArea != null) {
              Platform.runLater(() -> {
                  logTextArea.clear();
                  appendToLog("INFO", "日志已清空");
              });
          }
      }
      
      /**
       * 手动添加日志
       */
      public void log(String level, String message) {
          appendToLog(level, message);
          // 同时输出到原始控制台
          originalOut.println("[" + timeFormat.format(new Date()) + "] [" + level + "] " + message);
      }
      
      /**
       * 添加信息日志
       */
      public void info(String message) {
          log("INFO", message);
      }
      
      /**
       * 添加错误日志
       */
      public void error(String message) {
          log("ERROR", message);
      }
      
      /**
       * 添加警告日志
       */
      public void warn(String message) {
          log("WARN", message);
      }
      
      /**
       * 添加调试日志
       */
      public void debug(String message) {
          log("DEBUG", message);
      }
      
      /**
       * 向TextArea添加日志
       */
      private void appendToLog(String level, String message) {
          if (logTextArea == null) {
              return;
          }
          
          String timestamp = timeFormat.format(new Date());
          String logEntry = String.format("[%s] [%s] %s\n", timestamp, level, message);
          
          Platform.runLater(() -> {
              logTextArea.appendText(logEntry);
              // 自动滚动到底部
              logTextArea.setScrollTop(Double.MAX_VALUE);
          });
      }
      
      /**
       * 日志级别枚举
       */
      private enum LogLevel {
          INFO, ERROR, WARN, DEBUG
      }
      
      /**
       * 自定义输出流，用于拦截System.out和System.err
       */
      private class LogOutputStream extends OutputStream {
          private LogLevel level;
          private StringBuilder buffer;
          
          public LogOutputStream(LogLevel level) {
              this.level = level;
              this.buffer = new StringBuilder();
          }
          
          @Override
          public void write(int b) throws IOException {
              char c = (char) b;
              if (c == '\n') {
                  // 遇到换行符，输出缓冲区内容
                  if (buffer.length() > 0) {
                      String message = buffer.toString().trim();
                      if (!message.isEmpty()) {
                          appendToLog(level.name(), message);
                          // 同时输出到原始控制台
                          if (level == LogLevel.ERROR) {
                              originalErr.println(message);
                          } else {
                              originalOut.println(message);
                          }
                      }
                      buffer.setLength(0);
                  }
              } else if (c != '\r') {
                  // 忽略回车符，只保留换行符
                  buffer.append(c);
              }
          }
          
          @Override
          public void flush() throws IOException {
              // 刷新时也输出缓冲区内容
              if (buffer.length() > 0) {
                  String message = buffer.toString().trim();
                  if (!message.isEmpty()) {
                      appendToLog(level.name(), message);
                      if (level == LogLevel.ERROR) {
                          originalErr.println(message);
                      } else {
                          originalOut.println(message);
                      }
                  }
                  buffer.setLength(0);
              }
          }
      }
      
      /**
       * 获取当前捕获状态
       */
      public boolean isCapturing() {
          return isCapturing;
      }
  } 