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.