1

以下のコードでは、JEditorPane に 0 から 10000 までの数字を書き込みたいと思います。ただし、JEditorPane は、完全に完了する (一度に 0 から 10000 のすべてを出力する) か、OS がリフレッシュする時間を与えない限り、何も表示しません。内容を表示します。いずれの場合も、ユーザーがアプリケーションがクラッシュしたと考えるほど、アプリケーションはしばらく応答しなくなります。jEditorPane がまだビジーであっても、更新されたコンテンツを強制的に表示することはできますか? 私は invokeAndWait を試しましたが、イベント ディスパッチャ スレッドからは invokeAndWait を呼び出すことができないため、ここでは役に立ちません。

つまり、 を に置き換えるThread.sleep(0)Thread.sleep(50)、問題なく動作し、結果が発生したときに結果を表示しますが、50 ミリ秒の遅延を追加すると、非常に遅くなります。私が望むのは、JEditorPane を時々更新して、ユーザーがアプリケーションがクラッシュしたと思わないようにすることだけです。updateMessages() のみを変更することを好みます。 これが私のコードです:

import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.text.Document;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;

public class CMessageWindowStack {

    private static final String MESSAGE = "msg";
    private  JScrollPane scrollPane;
    public  JEditorPane  editorPane;
    private  HTMLEditorKit kit;
    private  String msgBuffer=new String("");
    private static CMessageWindowStack window=null;
    private static JFrame frameContainer=null;

    private CMessageWindowStack()
    {
        editorPane  = new JEditorPane ();
        editorPane.setEditable(false);
        editorPane.setContentType("text/html");
        kit = new HTMLEditorKit();
        editorPane.setEditorKit(kit);

        StyleSheet styleSheet = kit.getStyleSheet();
        styleSheet.addRule("."+MESSAGE+" {font: 10px monaco; color: black; }");

        Document doc = kit.createDefaultDocument();
        editorPane.setDocument(doc);
        scrollPane = new JScrollPane(editorPane);
    }
    public static CMessageWindowStack getInstance(){
        if (null==window)
        {window=new CMessageWindowStack();}
        return window;
    }
/**
 * The core
 * @param sMessage
 * @param sType
 */
    private void updateMessages(final String sMessage, final String sType)

    {
        SwingUtilities.invokeLater( new Runnable() {
             public void run() {

        String sMessageHTML=""; 
        String sTypeText="";
        if (!sMessage.equals("\r\n")){ 
            sTypeText = sType+": ";
        }

        sMessageHTML = sMessage.replaceAll("(\r\n|\n)", "<br/>");
        if (!sMessageHTML.equals("<br/>")) 
        {
            sMessageHTML =   "<SPAN CLASS="+sType+">"+ sTypeText+sMessageHTML + "</SPAN>";
        }

        msgBuffer=msgBuffer.concat( sMessageHTML);
        editorPane.setText(msgBuffer);
        if ((editorPane.getDocument()).getLength()>1){
            editorPane.setCaretPosition((editorPane.getDocument()).getLength()-1);
        }  
             }
          });
    }

    public void setContainerFrame(JFrame jFrame){
        frameContainer = jFrame;
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(frameContainer.getContentPane());
        frameContainer.getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(scrollPane)
                );
        layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                        .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 217, Short.MAX_VALUE))
                );
    }

    public void setVisible(boolean bVisible){
        editorPane.setVisible(bVisible);
        scrollPane.setVisible(bVisible);
    }

    public void printMsg(String sMessage){
        String sType = MESSAGE;
        updateMessages(sMessage,sType);
    }

    public void printlnMsg(String sMessage){
        sMessage=sMessage.concat("\r\n");
        printMsg(sMessage);
    }


    public static void main(String args[]){
        CMessageWindowStack m_LogMgr;
        JFrame frame = new JFrame();
        m_LogMgr=CMessageWindowStack.getInstance();
        m_LogMgr.setContainerFrame(frame);
        frame.setVisible(true);
        frame.setSize(500, 500);


        for(int i=0;i<10000;++i){
            try {
                Thread.sleep(0);//becomes unresponsive if sleep(0)
            } catch (Exception e) {
            }
            m_LogMgr.printlnMsg(i+"-----------------------");
        }

    }


}
4

3 に答える 3

3

おそらく SwingWorker を使用する必要があります。最初に、基本的な HTML を使用して JEditorPane をロードすることから始めます。publish次に、データの各行が必要になります。データが公開されたら、テキストをエディター ペインに挿入する必要があります。

基本的な考え方は、一度に HTML 文字列全体を作成することはできないということです。

動的に変化する HTML で JEditorPane を使用する方法を本当に理解できたことはありません。JTextPane を使用することもできます。さまざまなフォントと色がサポートされており、動的に更新する方がはるかに簡単です。

于 2013-05-14T15:27:47.287 に答える
0

Thread を使用して、それに最高の優先順位を付けてみてください。また、java.exe に -XmX2020 オプションを追加することもできます。

の代わりに JTextArea を使用する場合、他の解決策が考えられますJEdiorPane。HTML で行うことは、フォントのスタイリングだけのようです。java.awt.Fontこれは、JTextArea のプロパティを使用して行うことができます。

于 2013-05-14T15:31:29.530 に答える
0

まあ-ハックとして、次のようなことを試すことができます:

    for(int i=0;i<10000;++i){
        try {
            if( i%100 == 0 ) {
                Thread.sleep(10);//becomes unresponsive if sleep(0)
            }
        } catch (Exception e) {
        }
        m_LogMgr.printlnMsg(i+"-----------------------");
    }
于 2013-05-14T15:28:32.163 に答える