本文目录导读:

我来详细解释JEditorPane、HTMLEditorKit和HTML解析中的十进制处理。
JEditorPane的HTML解析基础
JEditorPane使用HTMLEditorKit来解析和显示HTML内容,默认的解析器在处理十进制数值时有特定行为。
基本使用示例
import javax.swing.*;
import javax.swing.text.html.*;
public class DecimalParserDemo {
public static void main(String[] args) {
JFrame frame = new JFrame("Decimal Parser Demo");
JEditorPane editorPane = new JEditorPane();
// 设置HTML编辑器
editorPane.setEditorKit(new HTMLEditorKit());
// 设置HTML内容
String htmlContent = "<html><body>" +
"<p style='font-size:16px'>Font size: 16px</p>" +
"<p style='margin:10px'>Margin: 10px</p>" +
"</body></html>";
editorPane.setText(htmlContent);
editorPane.setEditable(false);
frame.add(new JScrollPane(editorPane));
frame.setSize(400, 300);
frame.setVisible(true);
}
}
十进制数值处理机制
HTML属性中的十进制值
public class DecimalAttributeHandling {
public static void main(String[] args) {
JEditorPane editorPane = new JEditorPane();
editorPane.setContentType("text/html");
// HTML中不同单位的十进制值
String html = "<html><body>" +
// 像素单位
"<div style='width:100.5px; height:50.3px; background:#f0f0f0;'>" +
"Width: 100.5px, Height: 50.3px</div>" +
// 百分比
"<div style='width:75.5%; background:#e0e0e0;'>Width: 75.5%</div>" +
// em单位
"<div style='font-size:1.2em; margin:0.5em;'>" +
"Font size: 1.2em, Margin: 0.5em</div>" +
// 透明度
"<div style='opacity:0.75; background:blue; color:white;'>" +
"Opacity: 0.75</div>" +
"</body></html>";
editorPane.setText(html);
// 解析并显示结构
HTMLDocument doc = (HTMLDocument) editorPane.getDocument();
System.out.println("HTML Document Structure:");
Element root = doc.getDefaultRootElement();
printElementStructure(root, 0);
}
private static void printElementStructure(Element element, int depth) {
String indent = " ".repeat(depth);
System.out.println(indent + "Element: " + element.getName());
AttributeSet attrs = element.getAttributes();
if (attrs != null) {
Enumeration<?> names = attrs.getAttributeNames();
while (names.hasMoreElements()) {
Object name = names.nextElement();
Object value = attrs.getAttribute(name);
System.out.println(indent + " Attribute: " + name +
" = " + value + " (type: " +
(value != null ? value.getClass().getSimpleName() : "null") + ")");
}
}
for (int i = 0; i < element.getElementCount(); i++) {
printElementStructure(element.getElement(i), depth + 1);
}
}
}
自定义十进制解析器
创建自定义解析器
import javax.swing.text.*;
import javax.swing.text.html.*;
import javax.swing.text.html.parser.*;
import java.awt.*;
public class CustomDecimalHTMLEditorKit extends HTMLEditorKit {
@Override
public ViewFactory getViewFactory() {
return new HTMLFactory() {
@Override
public View create(Element elem) {
AttributeSet attrs = elem.getAttributes();
String tagName = elem.getName();
// 自定义十进制值处理
if (tagName.equals("decimal-value")) {
return new DecimalValueView(elem);
}
return super.create(elem);
}
};
}
// 自定义视图处理十进制值
static class DecimalValueView extends InlineView {
public DecimalValueView(Element elem) {
super(elem);
}
@Override
public float getAlignment(int axis) {
// 处理十进制对齐
AttributeSet attrs = getAttributes();
String alignmentValue = (String) attrs.getAttribute(
javax.swing.text.html.HTML.Attribute.ALIGN);
if (alignmentValue != null && alignmentValue.contains(".")) {
// 自定义十进制对齐逻辑
String[] parts = alignmentValue.split("\\.");
float wholePart = Float.parseFloat(parts[0]);
float decimalPart = Float.parseFloat("0." + parts[1]);
return wholePart + decimalPart;
}
return super.getAlignment(axis);
}
}
}
// 十进制数值处理器
class DecimalValueProcessor {
public static float parseDecimalValue(String value, float defaultValue) {
if (value == null || value.isEmpty()) {
return defaultValue;
}
try {
// 移除单位后缀
String numericPart = value.replaceAll("[^0-9.-]", "");
// 处理不同的小数格式
if (numericPart.contains(",") && !numericPart.contains(".")) {
// 欧洲格式:使用逗号作为小数点
numericPart = numericPart.replace(",", ".");
}
// 处理多个小数点
int firstDotIndex = numericPart.indexOf(".");
int lastDotIndex = numericPart.lastIndexOf(".");
if (firstDotIndex != lastDotIndex) {
// 多个小数点,只保留第一个
numericPart = numericPart.substring(0, firstDotIndex + 1) +
numericPart.substring(firstDotIndex + 1).replace(".", "");
}
return Float.parseFloat(numericPart);
} catch (NumberFormatException e) {
System.err.println("Error parsing decimal value: " + value);
return defaultValue;
}
}
public static int parseDecimalToInt(String value) {
float floatValue = parseDecimalValue(value, 0);
return Math.round(floatValue);
}
public static String formatDecimalValue(float value, int decimalPlaces) {
return String.format("%." + decimalPlaces + "f", value);
}
}
实际应用示例
public class CompleteDecimalHandlingExample {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Complete Decimal Handling");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 使用自定义编辑器
JEditorPane editorPane = new JEditorPane();
editorPane.setEditorKit(new CustomDecimalHTMLEditorKit());
// 包含各种十进制值的HTML
String html = buildDecimalHTML();
editorPane.setText(html);
editorPane.setEditable(false);
// 添加解析信息显示
JTextArea infoArea = new JTextArea(8, 40);
infoArea.setEditable(false);
infoArea.setText(analyzeDecimalValues(html));
JSplitPane splitPane = new JSplitPane(
JSplitPane.VERTICAL_SPLIT,
new JScrollPane(editorPane),
new JScrollPane(infoArea)
);
splitPane.setResizeWeight(0.7);
frame.add(splitPane);
frame.setSize(600, 500);
frame.setVisible(true);
});
}
private static String buildDecimalHTML() {
return "<html><body style='font-family:Arial;'>" +
"<h2>Decimal Value Examples</h2>" +
"<table border='1'>" +
"<tr><th>Property</th><th>Value</th><th>Parsed</th></tr>" +
"<tr><td>Width</td>" +
"<td style='width:100.5px;background:#e0ffe0;'>100.5px</td>" +
"<td>" + DecimalValueProcessor.parseDecimalValue("100.5px", 0) + "</td></tr>" +
"<tr><td>Height</td>" +
"<td style='height:50.3px;background:#e0e0ff;'>50.3px</td>" +
"<td>" + DecimalValueProcessor.parseDecimalValue("50.3px", 0) + "</td></tr>" +
"<tr><td>Margin</td>" +
"<td style='margin:10.5px;background:#ffe0e0;'>10.5px</td>" +
"<td>" + DecimalValueProcessor.parseDecimalValue("10.5px", 0) + "</td></tr>" +
"<tr><td>Opacity</td>" +
"<td style='opacity:0.75;background:blue;color:white;'>0.75</td>" +
"<td>" + DecimalValueProcessor.parseDecimalValue("0.75", 0) + "</td></tr>" +
"<tr><td>Font Size</td>" +
"<td style='font-size:1.2em;'>1.2em</td>" +
"<td>" + DecimalValueProcessor.parseDecimalValue("1.2em", 0) + "</td></tr>" +
"</table>" +
"<h3>Special Decimal Formats</h3>" +
"<p>European format: " +
DecimalValueProcessor.parseDecimalValue("3,14", 0) + "</p>" +
"<p>Multiple decimals: " +
DecimalValueProcessor.parseDecimalValue("1.2.3", 0) + "</p>" +
"</body></html>";
}
private static String analyzeDecimalValues(String html) {
StringBuilder analysis = new StringBuilder("Decimal Value Analysis:\n\n");
// 提取并分析所有数字值
String[] lines = html.split("\n");
java.util.regex.Pattern pattern =
java.util.regex.Pattern.compile("(\\d+\\.\\d+)(px|em|%|)");
for (String line : lines) {
java.util.regex.Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
String value = matcher.group(1);
String unit = matcher.group(2);
float parsed = Float.parseFloat(value);
analysis.append("Found: ").append(value)
.append(" ").append(unit)
.append(" (converted to: ").append(parsed)
.append(")\n");
}
}
return analysis.toString();
}
}
常见问题和解决方案
// 十进制处理中的常见问题
public class DecimalIssuesAndSolutions {
// 问题1: 精度丢失
public static void precisionIssue() {
float value = 0.1f + 0.2f;
System.out.println("Precision issue: 0.1 + 0.2 = " + value);
// 输出: 0.300000004... 而不是 0.3
// 解决方案: 使用BigDecimal
java.math.BigDecimal bd1 = new java.math.BigDecimal("0.1");
java.math.BigDecimal bd2 = new java.math.BigDecimal("0.2");
System.out.println("Using BigDecimal: " + bd1.add(bd2));
}
// 问题2: 本地化格式
public static void localizationIssue() {
String germanValue = "3,14"; // 德国格式
String usValue = "3.14"; // 美国格式
// 解决方案: 根据Locale解析
java.text.NumberFormat format =
java.text.NumberFormat.getNumberInstance(java.util.Locale.GERMANY);
try {
Number parsed = format.parse(germanValue);
System.out.println("German format parsed: " + parsed.doubleValue());
} catch (java.text.ParseException e) {
e.printStackTrace();
}
}
// 问题3: 单位解析
public static void unitParsingIssue() {
String[] values = {
"100.5px",
"1.2em",
"75.5%",
"0.75"
};
for (String value : values) {
// 分离数字和单位
String numericPart = value.replaceAll("[^0-9.-]", "");
String unit = value.replaceAll("[0-9.-]", "");
System.out.println(value + " -> Number: " + numericPart +
", Unit: " + (unit.isEmpty() ? "none" : unit));
// 安全的数值转换
try {
double parsedValue = Double.parseDouble(numericPart);
System.out.println(" Parsed value: " + parsedValue);
} catch (NumberFormatException e) {
System.out.println(" Parse error: " + e.getMessage());
}
}
}
}
这个实现提供了完整的JEditorPane十进制处理解决方案,包括自定义解析器、各种格式处理和实际问题解决方案。