如何在JavaFX的TextFlow容器中显示带颜色编码的日志?
在JavaFX中显示带ANSI颜色编码的日志条目
方法一:解析ANSI转义序列,使用TextFlow构建彩色文本
TextFlow本身不识别ANSI转义码,需要手动解析日志行,将不同颜色的文本段封装成Text节点并设置对应颜色,再添加到TextFlow中。
1. 定义ANSI颜色与JavaFX Color的映射
private static final Map<String, Color> ANSI_COLOR_MAP = new HashMap<>(); static { ANSI_COLOR_MAP.put("30", Color.BLACK); ANSI_COLOR_MAP.put("31", Color.RED); ANSI_COLOR_MAP.put("32", Color.GREEN); ANSI_COLOR_MAP.put("33", Color.YELLOW); ANSI_COLOR_MAP.put("34", Color.BLUE); ANSI_COLOR_MAP.put("35", Color.MAGENTA); ANSI_COLOR_MAP.put("36", Color.CYAN); ANSI_COLOR_MAP.put("37", Color.WHITE); // 可按需扩展亮色系(如90-97)等更多颜色代码 }
2. 编写解析方法,拆分日志为带颜色的Text节点
public static List<Text> parseAnsiLog(String logLine) { List<Text> textNodes = new ArrayList<>(); Pattern pattern = Pattern.compile("\u001B\\[(\\d+)m"); Matcher matcher = pattern.matcher(logLine); int lastIndex = 0; Color currentColor = Color.BLACK; // 默认文本颜色 while (matcher.find()) { // 提取转义序列前的文本段 String textSegment = logLine.substring(lastIndex, matcher.start()); if (!textSegment.isEmpty()) { Text text = new Text(textSegment); text.setFill(currentColor); textNodes.add(text); } // 更新当前颜色 String colorCode = matcher.group(1); currentColor = "0".equals(colorCode) ? Color.BLACK : ANSI_COLOR_MAP.getOrDefault(colorCode, Color.BLACK); lastIndex = matcher.end(); } // 处理日志行末尾剩余的文本 String remainingText = logLine.substring(lastIndex); if (!remainingText.isEmpty()) { Text text = new Text(remainingText); text.setFill(currentColor); textNodes.add(text); } return textNodes; }
3. 加载解析后的文本到TextFlow
TextFlow logTextFlow = new TextFlow(); String logLine = "\u001B[32m日志信息文本\u001B[0m"; logTextFlow.getChildren().addAll(parseAnsiLog(logLine));
方法二:将ANSI转义码转为HTML,用WebView显示
如果更倾向用WebView,可将ANSI颜色序列替换为HTML的<span>标签,再加载生成的HTML内容:
1. 编写转换方法
public static String convertAnsiToHtml(String logLine) { String html = logLine .replace("\u001B[30m", "<span style=\"color:black;\">") .replace("\u001B[31m", "<span style=\"color:red;\">") .replace("\u001B[32m", "<span style=\"color:green;\">") .replace("\u001B[33m", "<span style=\"color:yellow;\">") .replace("\u001B[34m", "<span style=\"color:blue;\">") .replace("\u001B[35m", "<span style=\"color:magenta;\">") .replace("\u001B[36m", "<span style=\"color:cyan;\">") .replace("\u001B[37m", "<span style=\"color:white;\">") .replace("\u001B[0m", "</span>") .replace("\n", "<br>"); // 将换行转为HTML换行 return "<html><body style=\"background:#000; color:#fff; font-family:monospace;\">" + html + "</body></html>"; }
2. 加载到WebView
WebView logWebView = new WebView(); String logLine = "\u001B[32m日志信息文本\u001B[0m"; logWebView.getEngine().loadContent(convertAnsiToHtml(logLine));
内容的提问来源于stack exchange,提问作者GGK stands for Ukraine
相关产品推荐
相关产品推荐

