# verschiedene Farben in einem Text/Editfeld



## Tukuan (6. Mrz 2006)

Ich hab nichts gefunden. 
Aber was im Editor von Netbeans funktioniert, müsste doch auch hinzubekommen sein:
Ich brauche einen Editor für ne ini Datei.
Nun möchte ich gerne Sektionen, Parameter und Kommentare anders darstellen.
Kann man dieses mit einem JEditorPane machen?
Ich finde nichts wie - setStyle oder so...

Schon mal vielen Dank vorweg...


----------



## tini (6. Mrz 2006)

ich würde ja mal setFont (für Größe und Style - fett, kursiv, ...) oder setForeground (für Farbe) vorschlagen


----------



## Beni (6. Mrz 2006)

Verschiedene Farben /Grössen /etc in einem Dokument erreichst du mit einem StyledDocument. 

Du benötigst: DefaultStyledDocument, die Methoden "addStyle", "insertString", und die Methoden der Klasse "javax.swing.text.StyleConstants".


----------



## Tukuan (6. Mrz 2006)

und wenn etwas eingegeben wird?
Muss ich dann für jeden KeyPress überprüfen, ob das davor z.B. gerade eine Zahl ist?

Ich kann doch zum Beispiel NetBeans dazu bringen, eine Textzeile im Editor so zu formatieren:

*if* ( sHallo == _"Hallo"_*)*


----------



## tini (6. Mrz 2006)

:?  ups! Da hab ich wohl nicht richtig gelesen. Würde mich deshalb Benis Lösung anschließen!


----------



## Tukuan (6. Mrz 2006)

Fühl mich wie ein Anfänger - ach ja bin ja auch einer   
Hört sich nicht schlecht an - mit dem Def.StyledDoc.
Aber nutzte ich das jEditorPanel und wie verknote ich die beiden?
Und was ist wenn man eingaben tätigte? Läuft dann automatisch.

Habt ihr vielleicht ein Beispiel?


----------



## Beni (6. Mrz 2006)

Man setzt das Document mit "setDocument" dem EditorPane. Wie man dann aber das Syntaxhighlighting geschickt aufbaut, und auf Veränderungen reagiert, kann ich dir leider nicht sagen.

Roar hat sowas mal gebaut, und vielleicht ist er so freundlich...


----------



## Roar (6. Mrz 2006)

du musst einen DocumentListener an dein Document hängen, der auf Veränderungen im Text reagiert. Dort musst du entsprechend intelligent reagieren, den text parsen und die farbattribute mit den von beni genannten methoden setzen für die entsprechenden stellen im text. bei ini dateien soltle das nicht so schwer sein. mal schaun, vielleicht bastel ich ja mal ein beispiel zusammen


----------



## Tukuan (6. Mrz 2006)

Wäre super nett... 


> vielleicht bastel ich ja mal ein beispiel zusammen


----------



## Roar (7. Mrz 2006)

hallo,
folgender code funktioniert, ist aber mehr oder weniger bös zusammengeschustert 
hab ein par dürftige kommentare hinzugefügt.
man könnte das ganze noch intelligenter machen, z.b. regex benutzen, nicht immer die ganze zeile neurendern nicht bei jedem getippten buchstaben neurendern etc.... :roll:
aber ich denke, so ist es eifnacher zu verstehen. und alles andere wäre overkill.


```
import java.awt.Color;

import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;


public class IniDocument extends DefaultStyledDocument {

	// Die AttributeSets, die unsre Farben und sospeichern.
	private MutableAttributeSet section, text, value, comment;

	public IniDocument() {
		initAttributeSets();
	}

	/**
	 * Hier werden Farben und so gesetzt
	 */
	private void initAttributeSets() {
		section = new SimpleAttributeSet();
		StyleConstants.setForeground(section, new Color(176, 48, 96));
		StyleConstants.setBold(section, true);
		text = new SimpleAttributeSet();
		value = new SimpleAttributeSet();
		StyleConstants.setForeground(value, Color.BLUE);
		comment = new SimpleAttributeSet();
		StyleConstants.setForeground(comment, new Color(63, 127, 95));
	}

	@Override
	public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
		super.insertString(offs, str, a);
		render(offs, str.length());
	}

	@Override
	public void remove(int offs, int len) throws BadLocationException {
		super.remove(offs, len);
		render(offs, len);
	}

	/**
	 * Wird bei jeder Änderung aufgerufen, damit eine Zeile neu dargestellt wird.
	 * @param offs Der Offset der Änderung
	 * @param len Die Länge der Änderung
	 * @throws BadLocationException
	 */
	private void render(int offs, int len) throws BadLocationException {
		String s = getText(0, getLength()); // der text
		int beginning = s.lastIndexOf('\n', offs - 1) + 1;
		int end = s.indexOf('\n', offs + len);
		String process = s.substring(beginning, (end != -1 ? end : s.length())); // der textabschnitt
		String[] lines = process.split("\n"); // alle zeilen die neu gerendert werden sollen
		for(String line: lines) {
			renderLine(beginning, line);
			beginning += line.length() + 1;
		}
	}

	/**
	 * Parst und rendert eine Zeile.
	 * @param offs Der Offset im Dokument
	 * @param line Die Zeile
	 */
	private void renderLine(int offs, String line) {
		AttributeSet nextSet = null;
		char[] ar = line.toCharArray();
		for(int i = 0; i < ar.length; i++) {
			AttributeSet a = text; // das zu verwendende AttributeSet
			if(i != 0) // falls das nicht der erste Buchstabe der Zeile ist...
				a = getCharacterElement(offs + i - 1).getAttributes(); // ... benutze das Set des Vorgängers
			if(nextSet != null) {
				a = nextSet;
				nextSet = null;
			}
			char c = line.charAt(i);
			switch(c) { // such nach Zeichen mit Bedeutung
				case '=':
				case ':':
					if(line.lastIndexOf('=', i - 1) == -1 && line.lastIndexOf(':', i - 1) == -1) {
						nextSet = value;
					}
					break;
				case '[':
					a = section;
					break;
				case ']':
					nextSet = text;
					break;
				case ';':
				case '#':
					a = comment;
			}
			if(i != 0 && line.charAt(i - 1) == ']')
				a = text;
			setCharacterAttributes(offs + i, 1, a, true); // setze attribute
		}
	}
}
```


----------



## Tukuan (9. Mrz 2006)

jetzt schon mal - ich werde es mir gleich mal anschauen...

Gruß
Tukuan


----------



## Tukuan (9. Mrz 2006)

Habs nun getestet. Echt super. Konnte es fast schon so einbinden :applaus: 
Vielen Dank


----------

