Maintenant JTextArea la position de défilement
J'ai un JScrollPane avec un JTextArea définir comme sa vue sur le port.
- Je mettre à jour le (multi-ligne) texte affiché sur le JTextArea en permanence environ une fois par seconde. Chaque fois que le texte des mises à jour, JScrollPane va tout le chemin vers le bas du texte.
Au lieu de cela, j'aimerais comprendre le numéro de la ligne qui est actuellement affichée à la première ligne dans le texte original, et pour que la ligne soit la première ligne affiche lorsque le texte a été mis à jour (ou si le nouveau texte n'a pas que le nombre de lignes, puis faites défiler tout le chemin vers le bas).
Ma première tentative de le faire, c'était d'obtenir la position actuelle de signe, figure la ligne de base, et ensuite définir la zone de texte pour montrer que ligne:
int currentPos = textArea.getCaretPosition();
int currentLine = 0;
try {
for(int i = 0; i < textArea.getLineCount(); i++) {
if((currentPos >= textArea.getLineStartOffset(i)) && (currentPos < gameStateTextArea.getLineEndOffset(i))) {
currentLine = i;
break;
}
}
} catch(Exception e) { }
textArea.setText(text);
int newLine = Math.min(currentLine, textArea.getLineCount());
int newOffset = 0;
try {
newOffset = textArea.getLineStartOffset(newLine);
} catch(Exception e) { }
textArea.setCaretPosition(newOffset);
C'était presque acceptable pour mes besoins, mais oblige l'utilisateur à cliquer à l'intérieur de la zone de texte pour modifier la position du curseur, ainsi que le défilement maintenir l'état (ce qui n'est pas agréable).
Comment pourrais-je faire cela en utilisant l' (vertical) de la position de défilement de la place ?
OK, je l'ai eu à travailler. Voir ma mise à jour 2.
OriginalL'auteur Sami | 2010-01-11
Vous devez vous connecter pour publier un commentaire.
C'est reconstitué, non testé, à partir de la documentation de l'API:
getViewport()
sur votreJScrollPane
d'obtenir une prise de la fenêtre d'affichage.Viewport.getViewPosition()
pour obtenir la partie supérieure gauche de coordonnées. Ce sont absolus, et non pas un pourcentage de défilement de texte.Viewport.addChangeListener()
pour être averti lorsque la partie supérieure gauche des changements de position (entre autres choses). Vous souhaitez peut-être créer un mécanisme permettant de distinguer les modifications de l'utilisateur à partir des changements de votre programme, bien sûr.Viewport.setViewPosition()
pour le jeu en haut à gauche de la position où il était avant la perturbation.Mise à jour:
getScrollableTracksViewport{Height|Width}()
méthodes de retournerfalse
.Mise à jour 2:
Le code suivant fait ce que vous voulez. C'est incroyable de voir comment beaucoup de peine que je devais aller pour le faire fonctionner:
setViewPosition
doit être reportée à l'aide deinvokeLater
parce que si c'est fait trop tôt, le texte mise à jour va venir après lui et annuler son effet.Runnable
classe dans son constructeur. J'avais été en utilisant le "global" de l'instance deorig
et qui a gardé ma position 0,0.[soupir] je peux voir que j'aurais testé. Je vais le faire maintenant et de revenir à vous.
Merci. J'ai joué un peu avec ce un peu, et il ne semble pas que le principal est réellement nécessaire. Je pense que le Point de l'objet renvoyé par getViewPosition() est partagée, au lieu d'une copie, nous avons donc besoin de cloner, pour obtenir le même effet: Point final orig = (Point) composant scrollPane.getViewport().getViewPosition().clone(); textArea.setText(texte); SwingUtilities.invokeLater() { new Runnable() { composant scrollPane.getViewport().setViewPosition(orig); } }); .. Dit que, cette solution fonctionne à 99% du temps, mais de temps en temps, lorsque vous faites des mises à jour rapides, il suffit de faire défiler en arrière tout le chemin vers le bas.
Les œuvres 99% du temps commentaire est à la fois pour le code à l'aide de clone, et le code dans votre réponse. De toute façon, c'est déjà assez bon pour mes fins pratiques, donc je vais accepter la réponse plus tard. De toute façon, toujours à gauche avec la curiosité sur la façon de le faire fonctionner à 100% du temps.
Je sens que j'ai travaillé assez dur sur ce point. Bonne chance!
OriginalL'auteur Carl Smotricz
J'ai rencontré le même problème et a trouvé que cette réponse comprend une belle solution qui fonctionne dans ce cas:
Mais pas pour moi.
Des œuvres. Exemple: tinybrain.de/1001004
Cette solution est beaucoup plus simple que l'on a accepté.
C'est la meilleure réponse, c'est simple et fonctionne très bien
OriginalL'auteur bdumitriu