Salve a tutti, ho trovato molte discussioni su questo argomento e ho guardato molti esempi, ma non riesco a metterli in pratica. Sto realizzando un editor per scrivere file xml (o anche html) e vorrei colorare i tag e gli attributi di colori diversi man mano che vengono scritti. Questa è la classe che gestisce l'inserimento:
codice:
public class GTastiera extends KeyAdapter{

	private JTextPane inser;
	private boolean shift;
	private int lung;
	private boolean chiusura;
	private Timer sposta;
	private StyledDocument doc;
	private Style tag;
	private Style attr;

    public GTastiera(JTextPane in,StyledDocument d){
    	doc=d;
    	inser=in;
    }//GTastiera

    public void keyPressed(KeyEvent e){
    	switch(e.getKeyCode()){
    		case KeyEvent.VK_SHIFT: //shift
    			shift=true;
    			break;
    		case KeyEvent.VK_LESS: //<
    			if(!shift)
    				lung=inser.getCaretPosition();
    			else{
    				if(!chiusura){ //se non sto chiudendo manualmente un tag..
	    				int offset=inser.getCaretPosition(); //prendo la posizione del cursore
	    				String tag=inser.getText().substring(lung+1,offset); //prendo il tag
	    				StringBuilder nuovoDoc=new StringBuilder(inser.getText());
	    				inser.setText(new String(nuovoDoc.insert(offset,"</"+levaAttributi(tag)+">"))); //uso StringBuilder per inserire il testo
	    				colora(tag,offset);
	    				shift=false;
	    				chiusura=false;
	    				inser.setCaretPosition(offset); //aggiorno la posizione del cursore
    				}//if
    			}//else
    			break;
    		case KeyEvent.VK_ENTER: //invio
    			if(inser.getCaretPosition()!=inser.getText().length()){
	    			int offset=inser.getCaretPosition();
	    			StringBuilder nuovoDoc=new StringBuilder(inser.getText());
	    			String tab=tabulazioni(offset); //prendo le tabulazioni
	    			if(offset<inser.getText().length() && inser.getText().toCharArray()[offset]!='\n'){ //se sono in un tag aperto/chiuso nella stessa riga
	    				inser.setText(new String(nuovoDoc.insert(offset,"\n"+tab+"\t\n"+tab)).trim());
	    				sposta=new Timer(10,new GTimer(offset+tab.length()+2));
	    			}//if
	    			else{
						inser.setText(new String(nuovoDoc.insert(offset,"\n"+tab)).trim());
						sposta=new Timer(10,new GTimer(offset+tab.length()+1));
	    			}//else
					sposta.start(); //avvio il timer per spostare il cursore
					shift=false;
				}//if
    			break;
    		case KeyEvent.VK_DIVIDE: // '/'
    			chiusura=true; //avverto che sto chiudendo manualmente un tag
    			break;
    		default:
    			shift=false;
    			break;
    	}//switch
    }//keyPressed

    private String tabulazioni(int offset){
		char[] testo=inser.getText().toCharArray();
		int tab=0;
		for(int i=0;i<offset;i++){
			if(testo[i]=='\t')
				tab++; //conto le tabulazioni
			else{
				if(testo[i]=='\n')
					tab=0;
			}//else
		}//for
		String t="";
		for(int i=0;i<tab;i++)
			t=t+"\t"; //creo una stringa che contiene tutte le tabulazioni
		return t;
	}//tabulazioni

	private String levaAttributi(String stringa){
		char[] tag=stringa.toCharArray();
		String app="";
		for(int i=0;i<tag.length;i++){
			if(tag[i]!=' ')
				app=app+tag[i];
			else
				i=tag.length;
		}//for
		return app;
	}//levaAttributi

	private void colora(String parola,int inizio){
		addStylesToDocument(doc);
                doc.setCharacterAttributes(inizio+2,parola.length(),tag,false);
		doc.setCharacterAttributes(inizio-parola.length(),parola.length(),tag,false);
	}//colora

	public void addStylesToDocument(StyledDocument doc){
		Style testo=StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
		tag=doc.addStyle("tag",testo);
		StyleConstants.setForeground(tag,Color.green);
		attr=doc.addStyle("attr",testo);
		StyleConstants.setForeground(attr,Color.red);
	}//addStylesToDocument

	private class GTimer implements ActionListener{

		private int spostamento;

		public GTimer(int s){
			spostamento=s;
		}//GTimer

		public void actionPerformed(ActionEvent e){
			inser.setCaretPosition(spostamento);
			sposta.stop(); //stoppo il timer
		}//actionPerformed
	}//GTimer
}//GTastiera
Quando viene premuto il tasto > il tag viene automaticamente chiuso e con l'invio c'è l'indentazione automatica. Tutto funzionante. Aggiungendo il colore ho però tre problemi.

1) Viene colorato un carattere in più (cioè '>'), ma riducendo di 1 la lunghezza della parola da colorare si colora una lettera in meno. Faccio un esempio: scrivo "<prova>", se uso questa istruzione
codice:
doc.setCharacterAttributes(inizio-parola.length(),parola.length(),tag,false);
si colora "prova>"; se uso quest'altra (tolgo 1 alla lunghezza della parola)
codice:
doc.setCharacterAttributes(inizio-parola.length(),parola.length()-1,tag,false);
si colora "prov".

2) Premendo INVIO e andando a capo si colora tutto.

3) Dopo aver colorato una parola cambia anche il colore di scrittura.

Come posso fare per risolvere questi problemi?? Grazie mille a tutti.