本文目录导读:

我来详细介绍 JEditorPane、HTMLEditorKit 和解析器队列处理的相关内容。
JEditorPane 简介
JEditorPane 是 Swing 中的文本组件,支持 HTML 和 RTF 格式的显示和编辑。
JEditorPane editorPane = new JEditorPane();
editorPane.setContentType("text/html");
editorPane.setText("<html><body><h1>Hello World</h1></body></html>");
HTMLEditorKit 解析器
HTMLEditorKit 提供了 HTML 解析和渲染功能:
HTMLEditorKit kit = new HTMLEditorKit(); editorPane.setEditorKit(kit);
自定义 HTML 解析器
public class CustomHTMLEditorKit extends HTMLEditorKit {
@Override
public Document createDefaultDocument() {
HTMLDocument doc = (HTMLDocument) super.createDefaultDocument();
// 自定义文档设置
return doc;
}
@Override
public ViewFactory getViewFactory() {
return new HTMLFactory() {
@Override
public View create(Element elem) {
// 自定义视图创建
return super.create(elem);
}
};
}
}
解析器队列处理
基本队列实现
public class ParserQueue {
private final Queue<HTMLDocument> documentQueue = new LinkedList<>();
private final JEditorPane editorPane;
private boolean processing = false;
public ParserQueue(JEditorPane editorPane) {
this.editorPane = editorPane;
}
public void addToQueue(String htmlContent) {
documentQueue.offer(parseHTML(htmlContent));
if (!processing) {
processQueue();
}
}
private HTMLDocument parseHTML(String html) {
HTMLEditorKit kit = (HTMLEditorKit) editorPane.getEditorKit();
HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument();
try {
kit.read(new StringReader(html), doc, 0);
} catch (Exception e) {
e.printStackTrace();
}
return doc;
}
private void processQueue() {
processing = true;
SwingWorker<Void, HTMLDocument> worker = new SwingWorker<>() {
@Override
protected Void doInBackground() throws Exception {
while (!documentQueue.isEmpty()) {
HTMLDocument doc = documentQueue.poll();
publish(doc);
Thread.sleep(100); // 模拟处理延迟
}
return null;
}
@Override
protected void process(List<HTMLDocument> chunks) {
for (HTMLDocument doc : chunks) {
renderDocument(doc);
}
}
@Override
protected void done() {
processing = false;
}
};
worker.execute();
}
private void renderDocument(HTMLDocument doc) {
editorPane.setDocument(doc);
editorPane.revalidate();
editorPane.repaint();
}
}
带优先级队列
public class PriorityParserQueue {
private final PriorityQueue<DocumentTask> taskQueue =
new PriorityQueue<>((a, b) -> b.priority - a.priority);
private final JEditorPane editorPane;
private Thread processingThread;
public PriorityParserQueue(JEditorPane editorPane) {
this.editorPane = editorPane;
startProcessing();
}
public void addTask(String htmlContent, int priority) {
synchronized (taskQueue) {
taskQueue.offer(new DocumentTask(htmlContent, priority));
taskQueue.notify();
}
}
private void startProcessing() {
processingThread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
DocumentTask task = null;
synchronized (taskQueue) {
while (taskQueue.isEmpty()) {
try {
taskQueue.wait();
} catch (InterruptedException e) {
return;
}
}
task = taskQueue.poll();
}
if (task != null) {
processDocument(task);
}
}
});
processingThread.start();
}
private void processDocument(DocumentTask task) {
try {
HTMLEditorKit kit = (HTMLEditorKit) editorPane.getEditorKit();
HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument();
kit.read(new StringReader(task.htmlContent), doc, 0);
SwingUtilities.invokeLater(() -> {
editorPane.setDocument(doc);
editorPane.revalidate();
});
} catch (Exception e) {
e.printStackTrace();
}
}
static class DocumentTask {
String htmlContent;
int priority;
DocumentTask(String htmlContent, int priority) {
this.htmlContent = htmlContent;
this.priority = priority;
}
}
}
回调式队列处理
public class CallbackParserQueue {
private final BlockingQueue<ParseRequest> requestQueue =
new LinkedBlockingQueue<>();
private final ExecutorService executor = Executors.newSingleThreadExecutor();
public interface ParseCallback {
void onParsed(HTMLDocument document);
void onError(Exception e);
}
public void submitParse(String html, ParseCallback callback) {
requestQueue.offer(new ParseRequest(html, callback));
processNext();
}
private void processNext() {
executor.submit(() -> {
while (!requestQueue.isEmpty()) {
ParseRequest request = requestQueue.poll();
if (request == null) continue;
try {
HTMLEditorKit kit = new HTMLEditorKit();
HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument();
kit.read(new StringReader(request.html), doc, 0);
// 回调到 EDT 线程
final HTMLDocument parsedDoc = doc;
SwingUtilities.invokeLater(() ->
request.callback.onParsed(parsedDoc));
} catch (Exception e) {
SwingUtilities.invokeLater(() ->
request.callback.onError(e));
}
}
});
}
static class ParseRequest {
String html;
ParseCallback callback;
ParseRequest(String html, ParseCallback callback) {
this.html = html;
this.callback = callback;
}
}
}
批量处理队列
public class BatchHTMLQueue {
private final int BATCH_SIZE = 10;
private final List<String> batchBuffer = new ArrayList<>();
private final JEditorPane editorPane;
public BatchHTMLQueue(JEditorPane editorPane) {
this.editorPane = editorPane;
}
public void addHTML(String html) {
batchBuffer.add(html);
if (batchBuffer.size() >= BATCH_SIZE) {
processBatch();
}
}
public void flush() {
if (!batchBuffer.isEmpty()) {
processBatch();
}
}
private void processBatch() {
List<String> batch = new ArrayList<>(batchBuffer);
batchBuffer.clear();
SwingWorker<Void, HTMLDocument> worker = new SwingWorker<>() {
@Override
protected Void doInBackground() throws Exception {
for (String html : batch) {
HTMLEditorKit kit = (HTMLEditorKit) editorPane.getEditorKit();
HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument();
kit.read(new StringReader(html), doc, 0);
publish(doc);
}
return null;
}
@Override
protected void process(List<HTMLDocument> chunks) {
for (HTMLDocument doc : chunks) {
editorPane.setDocument(doc);
// 这里可以添加渲染逻辑
}
}
};
worker.execute();
}
}
使用示例
public class QueueDemo {
public static void main(String[] args) {
JFrame frame = new JFrame("HTML Parser Queue Demo");
JEditorPane editorPane = new JEditorPane();
editorPane.setEditable(false);
editorPane.setContentType("text/html");
// 使用队列
ParserQueue queue = new ParserQueue(editorPane);
// 添加多个 HTML 内容
queue.addToQueue("<html><body><h1>First</h1></body></html>");
queue.addToQueue("<html><body><h2>Second</h2></body></html>");
queue.addToQueue("<html><body><h3>Third</h3></body></html>");
// 使用优先级队列
PriorityParserQueue priorityQueue = new PriorityParserQueue(editorPane);
priorityQueue.addTask("<html><body>Low priority</body></html>", 1);
priorityQueue.addTask("<html><body>High priority</body></html>", 10);
frame.add(new JScrollPane(editorPane));
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
这些队列实现提供了不同的处理策略,可以根据实际需求选择合适的方案来处理 HTML 文档的解析和渲染。