Eclipse插件开发求助:如何在编辑时读取编辑器内容
解决你的Eclipse插件崩溃问题&实现定时读取编辑器内容的正确方式
嘿,我来帮你捋捋问题出在哪,然后给你一套靠谱的实现方案!
你的代码里的核心问题
首先,最致命的问题是你在UI线程里做了阻塞操作:Handler的execute方法默认是在Eclipse的UI线程执行的,你在里面写了Thread.sleep(10000)还循环10次,直接把UI线程卡死了,这就是应用崩溃的根本原因。除此之外还有几个小问题:
- IO资源处理不严谨:
PrintWriter初始化失败的话,后续调用writer.println会触发空指针异常 - 没有实现真正的启停逻辑:现在的代码是一次性执行10次,没法中途停止,也没有区分启停按钮的逻辑
- 后台线程直接访问UI组件:
getCurrentEditorContent在非UI线程调用的话,会触发线程安全问题(Eclipse的UI组件只能在UI线程操作) - 成员变量
filename没有线程安全保护,多次点击按钮会导致文件名混乱
正确的实现方案:用Eclipse Job框架实现定时任务
Eclipse提供了Job框架专门处理后台任务,既能避免阻塞UI线程,又能方便地控制任务的启停。下面是修正后的完整代码:
import org.eclipse.core.runtime.*; import org.eclipse.jface.text.IDocument; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.ITextEditor; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.handlers.AbstractHandler; import org.eclipse.ui.handlers.HandlerUtil; import org.eclipse.core.commands.*; import java.io.PrintWriter; import java.io.IOException; import org.eclipse.jface.dialogs.MessageDialog; public class SampleHandler extends AbstractHandler { private Job currentJob; private int filenameCounter = 0; @Override public Object execute(ExecutionEvent event) throws ExecutionException { // 判断当前是否有任务在运行 if (currentJob != null && currentJob.getState() == Job.RUNNING) { // 停止任务 currentJob.cancel(); // 在UI线程弹出提示 PlatformUI.getWorkbench().getDisplay().asyncExec(() -> MessageDialog.openInformation( HandlerUtil.getActiveWorkbenchWindowChecked(event).getShell(), "Editor Reader", "已停止定时读取任务" ) ); currentJob = null; return null; } // 创建新的定时任务 currentJob = new Job("定时读取编辑器内容") { @Override protected IStatus run(IProgressMonitor monitor) { while (!monitor.isCanceled()) { // 在UI线程中获取编辑器内容(必须保证UI线程操作!) final String[] content = new String[1]; PlatformUI.getWorkbench().getDisplay().syncExec(() -> { IEditorPart editor = PlatformUI.getWorkbench() .getActiveWorkbenchWindow() .getActivePage() .getActiveEditor(); if (editor instanceof ITextEditor) { ITextEditor textEditor = (ITextEditor) editor; IDocument doc = textEditor.getDocumentProvider() .getDocument(textEditor.getEditorInput()); content[0] = doc.get(); } else { content[0] = "当前激活的不是文本编辑器"; } }); // 写入文件,用try-with-resources自动关闭流,避免资源泄漏 try (PrintWriter writer = new PrintWriter(filenameCounter + "_editor_content.txt", "UTF-8")) { writer.println(content[0]); filenameCounter++; } catch (IOException e) { e.printStackTrace(); } // 等待60秒(对应你要的每分钟一次) try { Thread.sleep(60000); } catch (InterruptedException e) { // 任务被取消时退出循环 Thread.currentThread().interrupt(); break; } } return Status.OK_STATUS; } }; // 启动任务 currentJob.schedule(); // 在UI线程弹出启动提示 PlatformUI.getWorkbench().getDisplay().asyncExec(() -> MessageDialog.openInformation( HandlerUtil.getActiveWorkbenchWindowChecked(event).getShell(), "Editor Reader", "已启动定时读取任务" ) ); return null; } }
关键部分解释
- 用Job替代手动Thread:Job由Eclipse的后台线程池管理,不会阻塞UI线程,还能通过
IProgressMonitor方便地处理任务取消。 - 启停逻辑实现:用
currentJob成员变量保存当前运行的任务,点击按钮时判断任务状态,运行中就取消,否则创建新任务。 - UI线程安全:获取编辑器内容的操作必须用
Display.syncExec包装,确保在UI线程执行,避免线程安全问题。 - IO资源安全:用try-with-resources语法自动关闭
PrintWriter,避免资源泄漏和空指针异常。 - 扩展提示:如果需要两个独立的启停按钮,可以给按钮配置不同的命令ID,或者在command中添加参数,在
execute方法里通过event.getParameter()区分操作类型。
内容的提问来源于stack exchange,提问作者rp73
相关产品推荐
相关产品推荐

