使用Unicode(Java)访问/更改JEditorPane的html加载元素+ HTMLEditorKit问题

这将是一个很长的问题,所以忍受我:)

我的应用程序

我正在开发一个Java(带有JFrame GUI)桌面应用程序,它执行以下操作:

  1. 扫描(.txt)文件。
  2. 从这些文件中解析一些数字,对它们执行一些计算,最后将结果存储在String变量中。
  3. 以特殊(表格)格式输出这些数字。 (注意:格式包括一些Unicode(阿拉伯语)字符。)

问题

前两部分进展顺利。 但是,当我来到第3部分(格式化输出)时,我不知道如何显示这种特殊格式,所以,

  • 在Java中显示特殊格式化输出(表)的最佳方法是什么?

注意: Formatter 不会提供帮助,因为它没有对表的适当支持。

解决方案一:

我做了我的研究,发现我可以使用JEditorPane,因为它可以显示特殊格式,如“html”。 所以我决定用所需的(表格)格式创建一个“html”页面,然后在[JEditorPane] [4]上显示这个页面。 我这样做了,它顺利进行,直到我想将一些html元素的值更改为那些(.txt)文件中的解析数字。

  • 如何访问html元素(例如

    )并更改其值?

请注意,使用setPage(url)在JEditorPane中加载(.html setPage(url)

Unicode字符显示正常,但我无法更改某些元素值(例如,我想将

000,000,000

的值更改为

MainController.getCurrentTotalPayment()

解决方案二:

我找到了一个解决方法,涉及使用HTMLDocument和HTMLEditorKit,这样我就可以从头开始使用HTMLEditorKit创建(.html)并使用kit.insertHTML在JEditorPane上显示它。

我已经使用上面的方法成功添加了内容,并且我还能够从(.txt)文件中添加解析后的数字,因为我将它们存储在my(MainController)类中。 不幸的是,Unicode阿拉伯字符未正确显示。

  • 如何正确显示这些Unicode字符?

所以第一个解决方案缺乏对html元素的访问权限,第二个解决方案缺乏Unicode支持!

我的同事建议我在html文档中使用JSP代码,该代码可以访问我的MainController.java类。 因此,将页面加载到JEditorPane中已经更改了html元素。 没有JSP的帮助,有没有办法做到这一点?

其他人推荐使用JTidy,但是在Java的JDK中没有办法吗?

我对所有可能的解决方案持开放态度。 请帮忙。

我的代码: 省略了一些代码内容,因为它们不相关

MainController.java

 class MainController { private static String currentTotalPayment; public static void main(String[] args) { CheckBankFilesView cbfView = new CheckBankFilesView(); cbfView.setVisible(true); } public static void setCurrentTotalPayment(String totalPayment) { MainController.currentTotalPayment = totalPayment; } public static String getCurrentTotalPayment() { return currentTotalPayment; } } 

MyFormattedOuputSolutionOne.java:

 public class MyFormattedOuputSolutionOne extends javax.swing.JFrame { private void MyFormattedOuputSolutionOne() { jPanel1 = new javax.swing.JPanel(); jScrollPane1 = new javax.swing.JScrollPane(); myFormattedOuput = new javax.swing.JEditorPane(); myFormattedOuput.setContentType("text/html"); //myFormattedOuput.setContentType("text/html; charset=UTF-8"); //Doesn't seem to work myFormattedOuput.setEditable(false); jScrollPane1.setViewportView(myFormattedOuput); myFormattedOuput.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); try{ myFormattedOuput.setPage(getClass().getResource("resources/emailFormat2.html")); //How can I edit/change html elements loaded in 'myFormattedOuput'? }catch(Exception e){ } } } 

MyFormattedOuputSolutionTwo.java:

 public class MyFormattedOuputSolutionTwo extends javax.swing.JFrame { private void MyFormattedOuputSolutionTwo() { jPanel1 = new javax.swing.JPanel(); jScrollPane1 = new javax.swing.JScrollPane(); myFormattedOuput = new javax.swing.JEditorPane(); myFormattedOuput.setContentType("text/html"); //myFormattedOuput.setContentType("text/html; charset=UTF-8"); //Doesn't seem to work myFormattedOuput.setEditable(false); jScrollPane1.setViewportView(myFormattedOuput); HTMLEditorKit kit = new HTMLEditorKit(); HTMLDocument doc = new HTMLDocument(); myFormattedOuput.setEditorKit(kit); myFormattedOuput.setDocument(doc); myFormattedOuput.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); try{ // Tried to set the charset in  but it doesn't work! //kit.insertHTML(doc, 1, "", 0, 0, HTML.Tag.META); kit.insertHTML(doc, doc.getLength(), "", 0, 0, null); //Encoding problem kit.insertHTML(doc, doc.getLength(), "
", 0, 0, null); // works fine kit.insertHTML(doc, doc.getLength(), MainController.getCurrentTotalPayment(), 0, 0, null); // works fine //How can I solve the Unicode problem above? }catch(Exception e){ } } }

htmlFormatTable.html:

        
XX/143X هـ كما هو موضح ادناه
0,000,000.00 معاشات
0,000,000.00 أخطار
المجموع 0,000,000.00


感谢您阅读我的长多问题主题,不能等待您的回答。

更新:

感谢@Howard的这种见解,如果我用其相应的unicode(例如ب= \ u0628)替换阿拉伯字符,它工作正常,但必须有一种方法可以做到这一点而无需替换每个字符,对吧?

解决方案一

可以编辑加载到JEditorPane中的HTML。 这是基于MyFormattedOuputSolutionOne.java的完整代码:

 import java.awt.ComponentOrientation; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JEditorPane; import javax.swing.JScrollPane; import javax.swing.SwingUtilities; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.Element; import javax.swing.text.SimpleAttributeSet; public class MyFormattedOuputSolutionOne extends javax.swing.JFrame { private MyFormattedOuputSolutionOne() { super("MyFormattedOuputSolutionOne"); setDefaultCloseOperation(DISPOSE_ON_CLOSE); JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); final JEditorPane myFormattedOuput = new javax.swing.JEditorPane(); getContentPane().add(jScrollPane1); myFormattedOuput.setContentType("text/html"); //myFormattedOuput.setContentType("text/html; charset=UTF-8"); //Doesn't seem to work myFormattedOuput.setEditable(false); jScrollPane1.setViewportView(myFormattedOuput); myFormattedOuput.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); try{ myFormattedOuput.setPage(getClass().getResource("htmlFormatTable.html")); myFormattedOuput.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if ("page".equals(evt.getPropertyName())) { Document doc = myFormattedOuput.getDocument(); Element html = doc.getRootElements()[0]; Element body = html.getElement(1); Element table = body.getElement(1); try { Element tr2 = table.getElement(1); Element tr2td1 = tr2.getElement(0); doc.insertString(tr2td1.getStartOffset(), "1: 123,456", SimpleAttributeSet.EMPTY); Element tr3 = table.getElement(2); Element tr3td1 = tr3.getElement(0); doc.insertString(tr3td1.getStartOffset(), "2: 765.123", SimpleAttributeSet.EMPTY); } catch (BadLocationException e) { e.printStackTrace(); } myFormattedOuput.removePropertyChangeListener(this); } } }); //How can I edit/change html elements loaded in 'myFormattedOuput'? } catch(Exception e){ e.printStackTrace(); } pack(); setSize(700, 400); setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new MyFormattedOuputSolutionOne(); } }); } } 

它异步加载文档并等待加载页面 。 加载页面时,它会访问文档的元素以搜索元素 ,并将文本插入到表格第2行和第3行的第一个

中。

顺便说一句,你的HTML无效! 你应该清理它。 执行此操作时,文档元素的索引将更改,您将不得不调整查找插入点的代码。

窗口看起来像这样: 解决方案一个窗口屏幕截图

解决方案二

我发现编码没有问题。 字符显示正确。 但我必须在Eclipse项目中将Java文件的编码设置为UTF-8。

解决方案二,正确显示阿拉伯语

解决方案三

您是否考虑过使用JTable在UI中显示结果表?


HTML可能看起来像这样:

       

السلام عليكم ورحمة الله وبركاته ,,,

الأخوة الكرام نفيدكم بتفاصيل المدفوعات لشهر

XX/143X

هـ كما هو موضح ادناه

تفاصيل مدفوعات بنك الرياض
0,000,000.00 معاشات
0,000,000.00 أخطار
المجموع 0,000,000.00 ريال سعودي

شاكرين لكم حسن تعاونكم ......

فريق العمليات بقسم الحاسب الآلي

由于我不懂一个字,我无法提出更好的格式。 首先, 元素仅允许在

。 您在表格上方有三个序列,其中只有一个标签,有三个结束标签。 我把它们都变成了

; 但是如果你认为它们是表列的标题,你应该使用一个包含三个

元素的表行。

使用HTML的这种结构,HTML树中的

元素将位于索引4处,即您应该更改该行

 Element table = body.getElement(1); 

 Element table = body.getElement(4); 

索引0-3现在是

元素。


作为旁注,在将其加载到JEditorPane (将其加载到HTMLDocument文本模型中)之后,不是编辑HTML,而是可以在传递给setPage之前编辑HTML文档,以便它已经包含

元素中的正确数据。 由于JEditorPane.setPage方法只接受URL ,因此您将选择接受描述模型的InputStreamObject的选择(在您的情况下应该是HTMLDocument的实例)。 StringBufferInputStream是此任务的最佳候选者,但它已被弃用,因为它无法正确读取UTF-8字符。 考虑到这一点,你宁愿使用String.getBytes("UTF-8")函数(因为J2SE 6)ByteArrayInputStream ,你的HTML声明编码, JEditorPane在阅读时会尊重它。