Bonjour,

Résumé:
J'aimerais concevoir une interface d'annotation en Java. J'ai des documents HTML en input et j'aimerais concevoir une interface à partir de laquelle il est possible de définir des spans tels que :
  1. Un objet textuel est contenu (dans le document HTML) entre
  2. caractère x
  3. caractère y


Fonctionnement:
Dans cet interface, l'utilisateur sera amené à sélectionner du texte avec la souris et appuyer sur un bouton pour définir son objet textuel. Un objet textuel peut être une liste tel que :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
<h1>Avions</h1>
<p>Bla bla. Il y a trois sortes d avions :</p>
<ul>
<li>Airbus</li>
<li>Tupolef</li>
<li>Concorde</li>
</ul>
Interface Actuelle :


Comme on le voit sur l'interface, il n'y a pas de soucis pour afficher cette liste. Cependant, j'aimerais que la sélection avec le curseur (Caret) me renvoie à la fois :
  • les mots sélectionnés (avec indice de début et fin)
  • les balises HTML (comprises sous la sélectionn)


Problème :
Le code suivant me retourne la position des curseur avant sélection (e.mark) et après sélection (e.dot), mais pas les mots, ni les balises.

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
 
public TextComponentDemo() {
		super("Select structure");
 
		textPane = new JTextPane();
		textPane.setContentType("text/html");
		textPane.setCaretPosition(0);
		// textPane.setText(Tools.getText("wik2_Islam.html"));
		textPane.setText("<h1>Avions</h1><p>Bla bla. Il y a trois sortes d'avions :</p><ul><li>Airbus</li><li>Tupolef</li><li>Concorde</li></ul>");
 
		textPane.setMargin(new Insets(5, 5, 5, 5));
		StyledDocument styledDoc = textPane.getStyledDocument();
		if (styledDoc instanceof AbstractDocument) {
			doc = (AbstractDocument) styledDoc;
			doc.setDocumentFilter(new DocumentSizeFilter(MAX_CHARACTERS));
		} else {
			System.err
					.println("Text pane's document isn't an AbstractDocument!");
			System.exit(-1);
		}
		JScrollPane scrollPane = new JScrollPane(textPane);
		scrollPane.setPreferredSize(new Dimension(400, 200));
 
		JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
				scrollPane, scrollPaneForLog);
 
		// Put the initial text into the text pane.
		// initDocument();
		textPane.setCaretPosition(0);
 
		// Start watching for undoable edits and caret changes.
		doc.addUndoableEditListener(new MyUndoableEditListener());
		textPane.addCaretListener(caretListenerLabel);
		doc.addDocumentListener(new MyDocumentListener());
}
 
	        // This listens for and reports caret movements.
	        protected class CaretListenerLabel extends JLabel implements CaretListener {
		public CaretListenerLabel(String label) {
			super(label);
		}
 
		// Might not be invoked from the event dispatch thread.
		public void caretUpdate(CaretEvent e) {
			displaySelectionInfo(e.getDot(), e.getMark());
		}
 
		// This method can be invoked from any thread. It
		// invokes the setText and modelToView methods, which
		// must run on the event dispatch thread. We use
		// invokeLater to schedule the code for execution
		// on the event dispatch thread.
		protected void displaySelectionInfo(final int dot, final int mark) {
			SwingUtilities.invokeLater(new Runnable() {
 
				public void run() {
					if (dot == mark) { 
						try {
							Rectangle caretCoords = textPane.modelToView(dot);
							// Convert it to view coordinates.
							setText("caret: text position: " + dot
									+ ", view location = [" + caretCoords.x
									+ ", " + caretCoords.y + "]" + newline);
							// setText();
						} catch (BadLocationException ble) {
							setText("caret: text position: " + dot + newline);
						}
						// Si le point suivant est plus petit que le point
						// précédent.
						// Sélection de droite à gauche
					}else {
						try {
							exprimer(dot, mark);
						} catch (BadLocationException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}							
 
					}
				}
			});
		}
 
		public void exprimer(int dot, int mark) throws BadLocationException {
			changeLog.append("selection from: (dot)" + dot + " to (mark)"
					+ mark + newline + textPane.getText());
 
			int pos;
			if(dot < mark){
				pos = dot;
			}else{
				pos = mark;
			}
 
			String text = textPane.getText().replaceAll("\n", "");
			System.out.println(text);
			if (pos + 1 <= text.length()) {
				text = text.substring(0, pos + 1);
			}
			System.out.println(text);
		}
 
	}
Questions :
Même après avoir cherché sur plusieurs sources (StackOverFlow, Google, Developpez.com, etc.), je n'ai rien trouvé de convainquant. Par conséquent, je me tourne vers la communauté Java.
  • Comment faire correspondre l'indice du caractère renvoyé par CaretEvent avec l'indice réel de ce caractère dans le document d'origine?
  • Comment aligner les mots sélectionnés dans l'interface et les mots réllement sélectionnés dans le texte?
  • Comment récupérer les tags HTML compris dans la sélection par le curseur? (Sans trifouiller avec le JEditorPane.getText() ) ?



Ce problème me paraît tellement "bête" que je suis étonné de ne pas trouver de solution native toute faite.

Tout commentaire, avancement, etc. est le bienvenu.

D'avance merci