Eclipse RCP插件中捕获System.out.println输出并修改文本颜色求助
实现方案:Eclipse RCP插件捕获System.out输出并自定义着色
1. 实现System.out输出拦截
Java原生支持重定向System.out输出流,通过自定义PrintStream子类即可拦截所有打印内容,核心实现如下:
1.1 自定义拦截流
import java.io.OutputStream; import java.io.PrintStream; public class ConsoleInterceptor extends PrintStream { private final IConsoleMessageHandler messageHandler; public ConsoleInterceptor(OutputStream originalOut, IConsoleMessageHandler handler) { super(originalOut, true); // 开启自动flush避免输出丢失 this.messageHandler = handler; } @Override public void println(String content) { messageHandler.handle(content + "\n"); // 不需要保留Eclipse默认控制台输出可注释下一行 super.println(content); } @Override public void print(String content) { messageHandler.handle(content); // 不需要保留Eclipse默认控制台输出可注释下一行 super.print(content); } // 按需重载其他print/println方法,比如println(int)、println(Object)等 }
1.2 定义消息处理接口
public interface IConsoleMessageHandler { void handle(String content); }
1.3 替换默认输出流
在插件激活类(Activator)的start方法中替换系统默认的System.out:
@Override public void start(BundleContext context) throws Exception { super.start(context); plugin = this; // 替换默认输出流 System.setOut(new ConsoleInterceptor(System.out, new CustomMessageHandler())); }
2. 自定义带颜色的RCP控制台
使用Eclipse自带的MessageConsole组件即可实现不同颜色的内容输出,无需自定义视图:
2.1 封装控制台工具类
import org.eclipse.ui.console.ConsolePlugin; import org.eclipse.ui.console.IConsole; import org.eclipse.ui.console.MessageConsole; import org.eclipse.ui.console.MessageConsoleStream; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.widgets.Display; public class PluginConsole { private static MessageConsole console; // 预定义输出颜色,使用完毕必须手动释放避免资源泄漏 public static final Color COLOR_ERROR = new Color(Display.getDefault(), 255, 0, 0); public static final Color COLOR_WARN = new Color(Display.getDefault(), 255, 165, 0); public static final Color COLOR_INFO = new Color(Display.getDefault(), 0, 128, 0); public static final Color COLOR_DEFAULT = new Color(Display.getDefault(), 0, 0, 0); public static void init() { console = new MessageConsole("插件专属控制台", null); // 注册到Eclipse控制台管理器 ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[]{console}); } public static void printWithColor(String content, Color color) { MessageConsoleStream stream = console.newMessageStream(); stream.setColor(color); try { stream.print(content); stream.close(); } catch (Exception e) { e.printStackTrace(); } } // 资源释放,在插件stop方法中调用 public static void dispose() { COLOR_ERROR.dispose(); COLOR_WARN.dispose(); COLOR_INFO.dispose(); COLOR_DEFAULT.dispose(); } }
2.2 实现消息着色逻辑
实现之前定义的IConsoleMessageHandler接口,按自定义规则匹配内容设置颜色:
public class CustomMessageHandler implements IConsoleMessageHandler { @Override public void handle(String content) { // 可自行修改匹配规则,比如按关键词、前缀正则匹配等 if (content.contains("ERROR")) { PluginConsole.printWithColor(content, PluginConsole.COLOR_ERROR); } else if (content.contains("WARN")) { PluginConsole.printWithColor(content, PluginConsole.COLOR_WARN); } else if (content.contains("INFO")) { PluginConsole.printWithColor(content, PluginConsole.COLOR_INFO); } else { PluginConsole.printWithColor(content, PluginConsole.COLOR_DEFAULT); } } }
3. 注意事项
- 要在插件的
MANIFEST.MF中添加依赖org.eclipse.ui.console,否则无法调用控制台相关API - 替换
System.out后默认会拦截当前OSGi容器内所有插件的输出,如果只需要拦截当前插件的输出,可以在消息处理逻辑中加入调用栈过滤,判断调用类是否属于当前插件的包名前缀即可 - 如果需要拦截
System.err的输出,用相同的逻辑替换System.setErr()即可 - 所有SWT的Color资源必须手动释放,务必在插件Activator的
stop方法中调用PluginConsole.dispose()避免内存泄漏
内容的提问来源于stack exchange,提问作者steven
相关产品推荐
相关产品推荐

