Bonjour à tous !

Je suis en train de développer un éditeur de fichier ".properties" en java, et je me penche sur le problème de la coloration syntaxique. En fouinant sur internet, j'ai trouvé des sources permettant de refaire la coloration de tout l'éditeur à chaque modification. Ce qui fait que sur des éditeurs très gros (mon fichier d'exemple fait 21209 lignes), je me retrouve à avoir un décalage de quelques secondes entre la saisie du caractère et la mise à jour de la coloration.

J'ai donc essayé de modifier le code pour que seules les lignes visibles de mon JTextPane (qui est dans un JScrollPane) soient actualisées. J'ai donc monté une usine à gaz qui ne fonctionne pas, voici mon source :


Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
 
			final String[] words = {"=", "^#.*$"};
 
 
			StyleContext sc = new StyleContext();
			final Style styleNormal = sc.addStyle("normal", null);
			Style styleEgale = sc.addStyle("egale", null);
			styleEgale.addAttribute(StyleConstants.Foreground, new Color(255,0,0));
			Style styleCommentaire = sc.addStyle("commentaire", null);
			styleCommentaire.addAttribute(StyleConstants.Foreground, new Color(28,147,64));
			final Style[] styles = {styleEgale, styleCommentaire};
 
			this.jTextPane.setDocument( new DefaultStyledDocument(){
				/**
                                 * 
                                 */
				private static final long serialVersionUID = 1L;
 
				@Override
				public void insertString(int arg0, String arg1, AttributeSet arg2) throws BadLocationException
				{
					super.insertString(arg0, arg1, arg2);
					SwingUtilities.invokeLater(new Runnable() {
						@Override
						public void run() {
							try {
								colorise(FenetreEditionPropriete.this.jTextPane);
							} catch (BadLocationException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						};
					});
				}
 
				@Override
				public void remove(int arg0, int arg1) throws BadLocationException
				{
					super.remove(arg0, arg1);
					SwingUtilities.invokeLater(new Runnable() {
						@Override
						public void run() {
							try {
								colorise(FenetreEditionPropriete.this.jTextPane);
							} catch (BadLocationException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						};
 
					});
				}
 
				public void colorise(JTextComponent comp) throws BadLocationException {
					if(words.length<styles.length) {
						throw new ArrayIndexOutOfBoundsException();
					}
 
 
 
					int nbLigne = this.getNombreLigne(comp);
 
 
					int hauteurLigne = 16;
					int hautAffiche = new Double(comp.getVisibleRect().getY()).intValue();
					int basAffiche = new Double(comp.getVisibleRect().getY() + comp.getVisibleRect().getHeight()).intValue();
					double hauteur = basAffiche - hautAffiche;
 
					int ligneDebut = (hautAffiche / hauteurLigne) - 5;
					int ligneFin = (basAffiche / hauteurLigne) + 5;
					if (ligneFin>nbLigne) {
						ligneFin = nbLigne;
					}
					if (ligneDebut<0) {
						ligneDebut = 0;
					}
 
					String texteComplet = comp.getText();
					int indexDebut = texteComplet.indexOf("\n",ligneDebut);
					if (ligneDebut == 0) {
						indexDebut = 0;
					}
 
					int ligneCourante = ligneDebut;
					int indexFin = indexDebut;
					while (ligneCourante < ligneFin) {
						int indexCourant = texteComplet.indexOf("\n",indexFin +1);
						if (indexCourant == -1) {
							indexFin = texteComplet.length() - 1;
							break;
						}
						indexFin = texteComplet.indexOf("\n",indexFin +1);
 
						ligneCourante++;
					}
					int longueur = indexFin - indexDebut;
 
					String texteAffiche = texteComplet.substring(indexDebut, indexFin);
 
					//((DefaultStyledDocument)comp.getDocument()).setCharacterAttributes(0, content.length()-1, styleNormal, true);
					((DefaultStyledDocument)comp.getDocument()).setCharacterAttributes(indexDebut, longueur, styleNormal, true);
 
					for(int i=0;i<words.length;i++)	{
						Pattern pattern = Pattern.compile(words[i],Pattern.MULTILINE);
						Matcher matcher = pattern.matcher(texteAffiche);
 
						while(matcher.find()) {
							int indexDebutStyle = matcher.start() + indexDebut;
							int longueurStyle = matcher.end()-matcher.start();
							((DefaultStyledDocument)comp.getDocument()).setCharacterAttributes(indexDebutStyle, longueurStyle, styles[i], false);
						}
					}
				}
 
				private int getNombreLigne(JTextComponent comp) {
					return comp.getDocument().getDefaultRootElement().getElementCount();
				}
			});
Je pense que je ne m'y prend pas du tout comme il faut pour détecter les lignes affichées (surtout que dans mon code, je suis obligé d'avoir des lignes de hauteur fixes, ce qui dans un champ qui accepte les mises en forme est bien dommage...). Après il me suffira de mettre à jour la coloration quand il y aura du scroll et ça sera bon

Connaissez vous un moyen propre de faire ça (avec un JTextPane ou autre)?

Meci beaucoup !