4

这将是一个很长的问题,所以请耐心等待:)

我的应用程序

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

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

问题

前两部分进行得很顺利。然而,当我来到第三部分(格式化输出)时,我不知道如何显示这种特殊格式,所以,

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

注意:格式化 程序不会有帮助,因为它对表格没有适当的支持。

解决方案一:

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

  • 如何访问 html 元素(例如<td></td>)并更改其值?

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

Unicode 字符显示正确,但我无法更改某些元素值(例如,我想将值更改<td> 000,000,000 </td><td> MainController.getCurrentTotalPayment() </td>

解决方案二:

我找到了一种解决方法,其中涉及使用 HTMLDocument 和 HTMLEditorKit,这样我可以使用 HTMLEditorKit 从头开始​​创建 (.html) 并使用kit.insertHTML.

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

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

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

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

其他一些人推荐使用JTidy,但在 Java 的 JDK 中没有办法做到这一点吗?

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

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

主控制器.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;
    }
}

MyFormattedOutputSolutionOne.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){
        }
    }
}

MyFormattedOutputSolutionTwo.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 <head> but it doesn't work!
            //kit.insertHTML(doc, 1, "<meta http-equiv = \"Content-Type\" content = \"text/html; charset=UTF-8\">", 0, 0, HTML.Tag.META);

            kit.insertHTML(doc, doc.getLength(), "<label> السلام عليكم ورحمة الله وبركاته ,,, </label>", 0, 0, null); //Encoding problem
            kit.insertHTML(doc, doc.getLength(), "<br/>", 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:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">

<html>

    <head>

        <meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8">

    </head>

    <body>

        <label> السلام عليكم ورحمة الله وبركاته ,,, </label>
        <br/>
        <label>  الأخوة الكرام نفيدكم بتفاصيل المدفوعات لشهر  </label> XX/143X </label>  هـ كما هو موضح ادناه  </label>
        <br/>
        <table align="right"  border="1" width="600" cellpadding="5" cellspacing="0">
            <tr char="utf-8" bgcolor="cccccc" align="center">
                <td colspan="3">   <label> تفاصيل مدفوعات بنك الرياض </label>  <img src="..\images\riyadh.gif" width="65" height="15"/> </td>
            </tr>
            <tr align="center">
                <td></td>
                <td id="cell1">0,000,000.00</td>
                <td align="right"> معاشات </td>
            </tr>
            <tr align="center">
                <td></td>
                <td id="cell2">0,000,000.00</td>
                <td align="right"> أخطار </td>
            </tr>
            <tr align="center">
                <td bgcolor="cccccc"> المجموع </td>
                <td bgcolor="cccccc">   0,000,000.00 <label> ريال سعودي </label> </td>
                <td></td>
            </tr>
        </table>
        <br/>
        <label> شاكرين لكم حسن تعاونكم ...... </label>
        <br/>
        <label> فريق العمليات بقسم الحاسب الآلي </label>

    </body>

</html>

感谢您阅读我冗长的多个问题线程,迫不及待地等待您的回答。

更新:

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

4

1 回答 1

3

解决方案一

可以编辑加载到 JEditorPane 中的 HTML。这是基于您的 MyFormattedOutputSolutionOne.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();
            }
        });
    }
}

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

顺便说一句,您的 HTML 无效!你应该把它清理干净。当你这样做时,文档元素的索引会改变,你必须调整找到插入点的代码。

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

解决方案二

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

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

解决方案三

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


HTML 可能看起来像这样:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">

<html>
    <head>
        <meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8">
    </head>
    <body>
        <p> السلام عليكم ورحمة الله وبركاته ,,, </p>

        <p>  الأخوة الكرام نفيدكم بتفاصيل المدفوعات لشهر  </p>
        <p>XX/143X </p>
        <p>  هـ كما هو موضح ادناه  </p>

        <table align="right"  border="1" width="600" cellpadding="5" cellspacing="0">
            <tr bgcolor="cccccc" align="center">
                <td colspan="3">تفاصيل مدفوعات بنك الرياض <img src="..\images\riyadh.gif" width="65" height="15"/></td>
            </tr>
            <tr align="center">
                <td></td>
                <td id="cell1">0,000,000.00</td>
                <td align="right">معاشات</td>
            </tr>
            <tr align="center">
                <td></td>
                <td id="cell2">0,000,000.00</td>
                <td align="right">أخطار</td>
            </tr>
            <tr align="center">
                <td bgcolor="cccccc">المجموع</td>
                <td bgcolor="cccccc">0,000,000.00 ريال سعودي</td>
                <td></td>
            </tr>
        </table>
        <p> شاكرين لكم حسن تعاونكم ...... </p>
        <p> فريق العمليات بقسم الحاسب الآلي </p>
    </body>
</html>

由于我一个词都不懂,所以我无法提出更好的格式。首先,<label>元素只允许在<form>. 您在表格上方有一个三个 s 的序列,<label>其中只有一个有开始<label>标签,有三个结束</label>标签。我把它们都变成了<p>;但是,如果您打算将它们用作表格列的标题,则应该使用包含三个<th>元素的表格行。

使用这种 HTML 结构,<table>HTML 树中的元素将位于索引 4,即您应该更改行

Element table = body.getElement(1);

Element table = body.getElement(4);

索引 0-3 现在是<p>元素。


作为旁注,您可以在将 HTML 加载到 之后编辑 HTML,而不是将JEditorPane其加载到 的文本模型中HTMLDocument,而是在传递到之前编辑您的 HTML 文档,setPage以便它已经在<td>元素中包含正确的数据。由于JEditorPane.setPage方法只接受URL,那么您的选择将是read接受一个InputStreamObject描述模型(在您的情况下应该是实例HTMLDocument)。StringBufferInputStream是该任务的最佳候选者,但由于无法正确读取 UTF-8 字符而被弃用。考虑到这一点,您宁愿使用String.getBytes("UTF-8")函数(自 J2SE 6 起),并且ByteArrayInputStream,您的 HTML 声明编码并JEditorPane在阅读时尊重它。

于 2011-08-11T21:07:40.893 回答