Syntax-Highlighting abspeichern

Blackhole16

Bekanntes Mitglied
Guten Tag community,

Es geht wieder um meinen Texteditor den ich schreibe (was für ein Wunder 😛). Aber diesmal um das Abspeichern.

Ich habe verschiedene Varianten, wie ich den Text formatiere: Schriftart, Schriftgröße, Schriftfarbe, Schrifthintergrundfarbe, Italic, Bold, Underlined und alles gemixt. All dies mache ich mit SimpleAttributeSet und StyleConstants.
Nun zu meinem eigentlichen Problem, dem Abspeichern. Ich habe überlegt, dass ich es so in der Art mache, beispielsweise erstmal nur an der Schriftart:
Ich dachte, dass es so in der Art [c]SchritfArt#ZeichnnummerAnfang:Zeichennummerende|nochmalAnfang:nochmalEnde|oderEinfachNurEiner|...[/c] Ich habe eine Funktion dafür geschrieben, di soweit auch super läuft, nur ist die 1. ziemlich lang und 2. eben bisher nur für die FontFamily.
Hier jetzt mein Code dazu:

Java:
	public String getFormatting() {
		String formatting = "";
		String textGet, value;
		ArrayList fontFamily = new ArrayList();
		ArrayList italic = new ArrayList();
		ArrayList bold = new ArrayList();
		ArrayList underline = new ArrayList();
		ArrayList fontSize = new ArrayList();
		ArrayList fgColor = new ArrayList();
		ArrayList bgColor = new ArrayList();
		
		int location = getCaretPosition();
		for (int i = 0; i < getText().length(); i++) {
			setCaretPosition(i);
			AttributeSet sas = getCharacterAttributes();
			textGet = StyleConstants.getFontFamily(sas) + "#";
		  	if (!fontFamily.contains(textGet)) {
		  		fontFamily.add(textGet);
		  		fontFamily.add(getCaretPosition() + "");
		  	} else {
		  		value = fontFamily.get(fontFamily.indexOf(textGet)+1) + "";
		  		int numberBefore = -1;
		  		try {
		  			int j = 1;
		  			while (true) {
		  				if (numberBefore == -1) {
		  					numberBefore = Integer.parseInt(value.charAt(value.length() - j) + "");
		  				} else {
		  					numberBefore = Integer.parseInt(value.charAt(value.length() - j) + "" + numberBefore);
		  				}
		  				j++;
		  			}
		  		} catch (Exception e) {}
		  		
		  		int numberBeforeLength = 1;
		  		
		  		if (numberBefore >= 10)
		  			numberBeforeLength = 2;
		  		else if (numberBefore >= 100)
		  			numberBeforeLength = 3;
		  		else if (numberBefore >= 1000)
		  			numberBeforeLength = 4;
		  		else if (numberBefore >= 10000)
		  			numberBeforeLength = 3; 
		  		
		  		if (numberBefore == i-1) {
		  			try {
			  			if (value.charAt(value.length() - (numberBeforeLength + 1)) == ':') {
			  				value = value.substring(0, value.length() - numberBeforeLength) + i;
			  			} else {
			  				value = value + ":" + i;
			  			}
		  			} catch (IndexOutOfBoundsException e) {
		  				value = value + ":" + i;
		  			}
		  		} else {
		  			value += "|" + i;
		  		}
		  		fontFamily.set(fontFamily.indexOf(textGet)+1, value);
		  	}
		}
		for (int i = 0; i < fontFamily.size(); i++) {
			formatting += fontFamily.get(i);
			if (i%2 == 1) {
				formatting += ";";
			}
		}
		setCaretPosition(location);
		return formatting;
	}

Ich weiß, es ist nicht sehr elegant. War auch ersteinmal nur so eine Idee
Ist mein Code soweit in Ordnung? Kann man das auch noch besser machen?
Wie kann ich, wenn ich es jetzt auch für die 6 weiteren Formatierungen mache, Codevervielfachung vermeiden? Ich würde das nämlich ganz elegant 6X copy-and-pasten 😛

Sagt auch einfach mal so eure Meinung dazu oder wie es anders machen könnte.

mfg
BH16
 
Ich weiß nicht, ob es nicht sinnvoller ist eine XML-Datei zu erstellen. Hast du dann einen Text wie:
"Ich mag Spaghetti, mit Soße"

Wir das zu sowas wie:

[XML]<txt>
<sub>
<style>
<style-bold>false</style-bold>
<style-italic>false</style-italic>
...
<text>Ich mag</text>
</sub>
<sub>
<style>
<style-bold>false</style-bold>
<style-italic>true</style-italic>
...
<text>Spaghetti</text>
</sub>
</txt>[/XML]
 
Kann man das auch noch besser machen?

Java:
      } catch (Exception e) {}
So etwas vermeiden.

Java:
   } catch (IndexOutOfBoundsException e) {
Macht man in der Regel nicht, da es sich hier um einen Fehler im Code handelt, welcher verhindert werden kann.


Ansonsten würde ich das eher als XML abspeichern als als Text.
 
Zuletzt bearbeitet:
Es es sich wirklich um eine Sytax handelt, welche du da farblich verschönerst, dann brauchst du das nicht abzuspeichern. Denn wenn du eine korrekte Sprachdefinition hast, dann kannst du das ganze beim Laden ja wiederherstellen.
 
würde hier auch das bereits gesagte eigentlich nur wiederholen

Java:
catch(Exception e) { }
davon abgesehen das man nicht dierekt Exception catchen sollte fehlt hier mindestens das Throwable.printStackTrace() ...
also gleich zwei fehler in einer zeile die gerade während der entwicklung zu stunden der fehlersuche führen können einfach nur weil man den fehler schluckt

Java:
catch(IndexOutOfBoundsException e)
ist eine RuntimeException ... und die sollte man eigentlich auch nicht fangen da das auftreten ein zeichen dafür ist das der programmierer irgendwas falsch gemacht hat ...

als beispiel vllt mit der beliebten NPE

anstatt
Java:
try
{
//...
} catch(NullPointerException npe)
zu schreiben sollte man lieber
Java:
if(resource==null)
verwenden ...


ansonsten wie ich es auch bereits in der PN erwähnte : es kommt drauf an WAS für "formatierungen" du speichern willst
wenn es syntaxhighlightning sein soll würde ich das definitiv NICHT mit speichern sondern beim laden jedes mal neu drüber legen ...
klingt jetzt erstmal nach etwas mehr arbeit und weniger performance ... ist aber deutlich besser da du dann 1) das source-file immer noch normal verwenden kannst und 2) bei änderungen nur "live" die anzeige ändern musst ... und nicht das gesamte file ...
wenn es sowas wie "RTF" sein soll ... dann muss natürlich die formatierung mitgespeichert werden ... ist ja der sinn solcher formate ...
 
Übrigens ganz ein anderes Thema: Du hast vermutlichen einen Fehler in:
Java:
   int numberBeforeLength = 1;
   if (numberBefore >= 10)
      numberBeforeLength = 2;
   else if (numberBefore >= 100)
      numberBeforeLength = 3;
   else if (numberBefore >= 1000)
      numberBeforeLength = 4;
   else if (numberBefore >= 10000)
      numberBeforeLength = 3;
Letzte Zeile sollte wahrscheinlich:
Code:
numberBeforeLength = [SIZE="5"][SIZE="3"][U]5[/U][/SIZE][/SIZE];
heißen.

Außerdem könntest du für die ganze Litanei schreiben:
Java:
numberBeforeLength =(int)Math.Log10(numberBefore );
 
Ich weiß nicht, ob es nicht sinnvoller ist eine XML-Datei zu erstellen. Hast du dann einen Text wie:
"Ich mag Spaghetti, mit Soße"

Wir das zu sowas wie:

Das mit dem XML ist eine gute idee, dazu werde ich mal was durchlesen. Mal sehen, wie das meine Probleme löst. *OMG NOCH EINE PRACHE ANSCHAUEN-.-* 😉

So etwas vermeiden.
bei mir ist es 1. die IndexOutOfBoundsException UND die NumberFormatException. Da beide bei mir gewollt passieren, dachte ich, wäre es praktischer einfach die Oberklasse exception abzufangen, um den code kürzer zu halten 😉


Es es sich wirklich um eine Sytax handelt, welche du da farblich verschönerst, dann brauchst du das nicht abzuspeichern. Denn wenn du eine korrekte Sprachdefinition hast, dann kannst du das ganze beim Laden ja wiederherstellen.

AUUUUUUUUUUUU BITTER!!!!! Sry, Wordbedeutung falsch angewendet 😳
Ich meine so etwas in der Art wie in Word.

Sonst hast du natürlich vollkommen recht....

würde hier auch das bereits gesagte eigentlich nur wiederholen

ansonsten wie ich es auch bereits in der PN erwähnte : es kommt drauf an WAS für "formatierungen" du speichern willst
wenn es syntaxhighlightning sein soll würde ich das definitiv NICHT mit speichern sondern beim laden jedes mal neu drüber legen ...
siehe oben, *PEINLICH* 😱
wenn es sowas wie "RTF" sein soll ... dann muss natürlich die formatierung mitgespeichert werden ... ist ja der sinn solcher formate ...
Ja so möchte ich das machen. Aber wie im 1. post: ist mein weg so in ordnung? ich meine, er funzt zwar, aber besonders an dich gerichtet: Wie kann ich diesen code so umschreiben, dass ich es auch mit den anderen 6 ohne codedublizierung (was du ja immer ankreidest 🙂 ) geht.

Übrigens ganz ein anderes Thema: Du hast vermutlichen einen Fehler in:
Letzte Zeile sollte wahrscheinlich:
Code:
numberBeforeLength = [SIZE="5"][SIZE="3"][U]5[/U][/SIZE][/SIZE];
heißen.

Ja, sieht so aus 😳 Copy-and-Paste und dann nur teilweise geändert, ein Fehler, an dem ich wieder EWIG gesucht hätte 😀 thx

Außerdem könntest du für die ganze Litanei schreiben:
[c]numberBeforeLength =(int)Math.Log10(numberBefore );
[/c]
ja, ok, mir war klar, dass es da einen eleganteren weg gibt, aber er fiel mir gerade nicht ein. Werde ich ntürlich so ändern 🙂

Danke schonmal bisher für eure Antworten, und sry, dass ich das falsch benutzt habe. Hier also nochmal:

Es handelt sich um so eine Veränderung wie in Word 🙂

mfg
BH16
 

Zurück
Oben