Habe ein kleines Problem mit der Geschwindigkeit der Methode "insertText" von JTextPane.
Ich benutze ein JTextPane als Ausgabekonsole eines skriptfähigen Taschenrechners (http://home.arcor.de/0xdeadbeef/).
JTextPane nehme ich, um farbigen Text auszugeben. Außerdem brauche ich die Funktionalität zum Markieren und Kopieren von Text. Davon abgesehen ist JTextPane und das dahinterliegende Dokument viel zu aufgeblasen und langsam für meinen Anwendungszweck.
Den Text füge ich vom Parserthread aus in die JTextPane in der Oberflächenklasse ein und benutze dazu einen Listener (addListener usw.). Das erzeugt auch eine nicht unwesentliche Menge an Event-Objekten, aber das schien mir die sauberste Lösung zu sein.
Wenn ich mit dem Skriptparser des Taschenrechners in einer Schleife Text ausgebe, verbraucht insertText > 80% der Rechenzeit. Wolhbemerkt: das gesamte Parsen und Interpretieren meiner eigenen Skriptsprache - zumal nicht sonderlich optimiert - fällt überhaupt nicht ins Gewicht gegenüber der Ausgabe per JTextPane.
Trotz katastrophaler Performance könnte ich ja trotzdem noch damit leben, aber es kommt noch schlimmer:
Um so länger der Text im JTextPane wird, um so länger dauert das Einfügen. Dadurch kommt es bei gleichmäßig flotten Einfügen zu einer exponentiellen Verlangsamung der Textausgabe, bis sie schließlich ganz einfriert. Nach einigen tausend Texteinfügungen (jeweils ein paar Zeichen) friert dann offensichtlich das ganze Swing-Rendering ein, obwohl ich ja in einem eigenen Thread rechne und auch von dort aus den Text einfüge. Ich vermute, daß die Request zum Einfügen/Neuzeichnen schneller eintreffen, als sie abgearbeitet werden können, was früher oder später zum Exitus führt.
Daß das überhaupt passiert, muß bedeuten, daß nach dem Aufruf von insertText das Einfügen des Textes noch nicht komplett abgeschlossen ist. Ich vermute mal, daß das Update der Darstellung der JTextPane asynchron in irgendeinem Swing-Thread erfolgt. Und genau das bricht mir den Hals.
Ich habe jetzt wirklich eine Menge probiert (hauptsächlich Buffer-Strategien), aber irgendwie hatte keine Methode so richtig Erfolg. Und zwar wohl deshalb, weil damit zwar die Ausgabe schneller wird, das grundsätzliche Problem (Ausgaben treffen schneller ein als sie abgearbeitet werden) aber nicht gelöst wird.
Die einzige Methode, die Abhilfe schafft, ist es nach der Erzeugung des Listener-Events eine kurze Pause per Sleep einzufügen. Das scheint dem (postulierten) Swing-Thread Zeit zu geben, seine Ausgabe zu beenden, so daß es nicht zu der beschriebenen exponentiellen Anhäufung unausgeführter Insert-Requests kommen kann. Natürlich ist das extrem unsauber und häßlich. Außerdem verlangsamt sich dadurch die Textausgabe nochmals.
Was ich bräuchte, wäre eine Möglichkeit, meinen Parserthread so lange schlafen zu legen, bis der Swing-Thread mit dem Update des JTextPanes fertig ist. Leider habe ich eine solche Möglichkeit bislang nicht gefunden.
Irgendwelche Vorschläge???
Davon abgesehen wäre ich ganz allgemein an einem perfomanteren Ersatz für JTextPane interessiert, wobei ich mit einem extrem simplen Dokumentenmodell zufrieden wäre, solaneg man nur Text einfärben kann. Aber obwohl ich wirklich lange und intensiv rumgesurft bin, habe ich keinen geeigneten Ersatz gefunden. Kann es wirklich sein, daß es keine freie und effizient implementierte Klasse zur Erzeugung einer Konsolenausgabe mit farbigem Text gibt?
Ehrlich gesagt steht mir nicht wirklich de Sinn danach, mir sowas selber zu schreiben. Die Ausgabe wäre ja noch recht einfach, aber das ganze Markier-/Kopierzeugs muß ich nicht unbedingt selber zusammenzimmern...
Mich würde auch interessieren, ob es während des Einfärbens des Textes per setCharacterAttributes (zusätzliches Syntax-Highlighting) eine Möglichkeit gibt, das Neuzeichnen der JTextPane zu unterbinden, um die Geschwindigkeit zu erhöhen. Ich habe mit Doublebuffering mittels zweier Dokumente experimentiert (ins eine Schreiben, während das andere dargestellt wird), aber beim Umschalten kommt es zu unschönem Flackern.
Wäre für zielführende Hinweise dankbar.
Ich benutze ein JTextPane als Ausgabekonsole eines skriptfähigen Taschenrechners (http://home.arcor.de/0xdeadbeef/).
JTextPane nehme ich, um farbigen Text auszugeben. Außerdem brauche ich die Funktionalität zum Markieren und Kopieren von Text. Davon abgesehen ist JTextPane und das dahinterliegende Dokument viel zu aufgeblasen und langsam für meinen Anwendungszweck.
Den Text füge ich vom Parserthread aus in die JTextPane in der Oberflächenklasse ein und benutze dazu einen Listener (addListener usw.). Das erzeugt auch eine nicht unwesentliche Menge an Event-Objekten, aber das schien mir die sauberste Lösung zu sein.
Wenn ich mit dem Skriptparser des Taschenrechners in einer Schleife Text ausgebe, verbraucht insertText > 80% der Rechenzeit. Wolhbemerkt: das gesamte Parsen und Interpretieren meiner eigenen Skriptsprache - zumal nicht sonderlich optimiert - fällt überhaupt nicht ins Gewicht gegenüber der Ausgabe per JTextPane.
Trotz katastrophaler Performance könnte ich ja trotzdem noch damit leben, aber es kommt noch schlimmer:
Um so länger der Text im JTextPane wird, um so länger dauert das Einfügen. Dadurch kommt es bei gleichmäßig flotten Einfügen zu einer exponentiellen Verlangsamung der Textausgabe, bis sie schließlich ganz einfriert. Nach einigen tausend Texteinfügungen (jeweils ein paar Zeichen) friert dann offensichtlich das ganze Swing-Rendering ein, obwohl ich ja in einem eigenen Thread rechne und auch von dort aus den Text einfüge. Ich vermute, daß die Request zum Einfügen/Neuzeichnen schneller eintreffen, als sie abgearbeitet werden können, was früher oder später zum Exitus führt.
Daß das überhaupt passiert, muß bedeuten, daß nach dem Aufruf von insertText das Einfügen des Textes noch nicht komplett abgeschlossen ist. Ich vermute mal, daß das Update der Darstellung der JTextPane asynchron in irgendeinem Swing-Thread erfolgt. Und genau das bricht mir den Hals.
Ich habe jetzt wirklich eine Menge probiert (hauptsächlich Buffer-Strategien), aber irgendwie hatte keine Methode so richtig Erfolg. Und zwar wohl deshalb, weil damit zwar die Ausgabe schneller wird, das grundsätzliche Problem (Ausgaben treffen schneller ein als sie abgearbeitet werden) aber nicht gelöst wird.
Die einzige Methode, die Abhilfe schafft, ist es nach der Erzeugung des Listener-Events eine kurze Pause per Sleep einzufügen. Das scheint dem (postulierten) Swing-Thread Zeit zu geben, seine Ausgabe zu beenden, so daß es nicht zu der beschriebenen exponentiellen Anhäufung unausgeführter Insert-Requests kommen kann. Natürlich ist das extrem unsauber und häßlich. Außerdem verlangsamt sich dadurch die Textausgabe nochmals.
Was ich bräuchte, wäre eine Möglichkeit, meinen Parserthread so lange schlafen zu legen, bis der Swing-Thread mit dem Update des JTextPanes fertig ist. Leider habe ich eine solche Möglichkeit bislang nicht gefunden.
Irgendwelche Vorschläge???
Davon abgesehen wäre ich ganz allgemein an einem perfomanteren Ersatz für JTextPane interessiert, wobei ich mit einem extrem simplen Dokumentenmodell zufrieden wäre, solaneg man nur Text einfärben kann. Aber obwohl ich wirklich lange und intensiv rumgesurft bin, habe ich keinen geeigneten Ersatz gefunden. Kann es wirklich sein, daß es keine freie und effizient implementierte Klasse zur Erzeugung einer Konsolenausgabe mit farbigem Text gibt?
Ehrlich gesagt steht mir nicht wirklich de Sinn danach, mir sowas selber zu schreiben. Die Ausgabe wäre ja noch recht einfach, aber das ganze Markier-/Kopierzeugs muß ich nicht unbedingt selber zusammenzimmern...
Mich würde auch interessieren, ob es während des Einfärbens des Textes per setCharacterAttributes (zusätzliches Syntax-Highlighting) eine Möglichkeit gibt, das Neuzeichnen der JTextPane zu unterbinden, um die Geschwindigkeit zu erhöhen. Ich habe mit Doublebuffering mittels zweier Dokumente experimentiert (ins eine Schreiben, während das andere dargestellt wird), aber beim Umschalten kommt es zu unschönem Flackern.
Wäre für zielführende Hinweise dankbar.