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
}
}
}