OVH Cloud OVH Cloud

Repositionnement automatique de la scrollbar

10 réponses
Avatar
Speedster
J'utilise un JScrollPane avec un JTextArea.
Ce dernier me sert de journal. Diverses informations apparaissent au fur et
à mesure dans ce textArea.
Ce textArea n'est pas éditable. Lorsque de nouvelles infos apparaissent dans
le textArea, la scrollbar se repositionne automatiquement à la fin (ce qui
est très bien).
Cependant, si souhaite voir ce qu'il y a plus haut, je déplace la scrollbar.
Mais dès ce moment, même si des informations continuent de s'afficher sur le
textArea, la scrollbar ne se déplace plus automatiquement à la fin.
Elle reste à l'endroit où je l'ai positionnée manuellement.

Que dois-je faire ? N'y a-t-il pas une histoire de focus ?

Merci d'avance pour vos réponses.


--
Click here to answer / cliquez ci dessous pour me repondre
http://www.cerbermail.com/?3LZDlyL6dF

10 réponses

Avatar
Philippe C
Bonjour,

J'utilise un JScrollPane avec un JTextArea.
Ce dernier me sert de journal. Diverses informations apparaissent au fur
et

à mesure dans ce textArea.
Ce textArea n'est pas éditable. Lorsque de nouvelles infos apparaissent
dans

le textArea, la scrollbar se repositionne automatiquement à la fin (ce qui
est très bien).
Cependant, si souhaite voir ce qu'il y a plus haut, je déplace la
scrollbar.

Mais dès ce moment, même si des informations continuent de s'afficher sur
le

textArea, la scrollbar ne se déplace plus automatiquement à la fin.
Elle reste à l'endroit où je l'ai positionnée manuellement.

Que dois-je faire ? N'y a-t-il pas une histoire de focus ?


Pourquoi ne pas lui imposer d'aller à la fin quand tu mets a jour ton texte
:

JScrollPane pane= new JScrollPane(/* ... */);
JScrollBar bar= pane.getVerticalScrollBar();

/* ... */

// deplacement du JTexteArea (lors de sa mis à jour)
bar.setValue(bar.getMaximum());


Merci d'avance pour vos réponses.
De rien !

--
PhilippeC

Avatar
Speedster
Merci pour l'idée.
Etant donné que je mets à jour mon texte dans différents endroits de mon
programme, n'est-il pas possible d'utiliser un listener pour le textArea.
A chaque fois que le texte est mis à jour, le code suivant s'exécute:

bar.setValue(bar.getMaximum());
Avatar
Philippe C
Etant donné que je mets à jour mon texte dans différents endroits de mon
programme, n'est-il pas possible d'utiliser un listener pour le textArea.
A chaque fois que le texte est mis à jour, le code suivant s'exécute:

bar.setValue(bar.getMaximum());


No problemo !

Dans ce cas tu peux modifier (cad surcharger) la méthode "setText(String)"
du JTexteArea pour qu'elle fasse ca que tu veux ...
Seul l'initialisation change, l'utilisation est exactement la même (dérivé
de JTextArea ;o)

********************************************************
<CODE>
import javax.swing.*;

public class JTextAreaEnd extends JTextArea {

private JScrollPane pane;

public JTextAreaEnd() {
super("");
setEditable(false);
}

public JScrollBar getJScrollBar() {
return getJScrollPane().getVerticalScrollBar();
}

public JScrollPane getJScrollPane() {
if (pane == null)
pane= new JScrollPane(this);
return pane;
}

public void setText(String texte) {
super.setText(texte);
JScrollBar bar= getJScrollBar();
bar.setValue(bar.getValue());
}
}
</CODE>
*********************************************************

Un petit exemple pour te convaincre que ça fait le boulot :

<CODE>
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JFrame{

private JTextAreaEnd area;
private JTextField field;

class DisposeOnClose extends WindowAdapter {
public void windowClosing(WindowEvent we) {
dispose();
}
}

class AjoutText implements ActionListener {
public void actionPerformed(ActionEvent ae) {
if (field.getText().length() > 0) {
area.setText(area.getText() + "n" + field.getText());
field.setText("");
}
}
}

public Test() {
Container cp= getContentPane();
cp.setLayout(new BorderLayout());

// center
area= new JTextAreaEnd();
area.setText("Texte:");
JScrollPane scroll= area.getJScrollPane();
cp.add(scroll, BorderLayout.CENTER);

// south
field= new JTextField();
field.addActionListener(new AjoutText());
cp.add(field, BorderLayout.SOUTH);

addWindowListener(new DisposeOnClose());
}

public static void main(String[] args) {
JFrame frame= new Test();
frame.setSize(200,200);
frame.show();
}
}
</CODE>

et le tour est joué !
--
PhilippeC

Avatar
Speedster
Ne serait-il pas plus simple ou simplement possible d'utiliser la classe
CaretListener ?

ex: textArea.addCaretListener(new CaretListener () {
public void caretUpdate(CaretEvent e) {
bar.setValue(bar.getMaximum());
}
});


"Philippe C" a écrit dans le message
de news:bjn699$d9m$
Etant donné que je mets à jour mon texte dans différents endroits de mon
programme, n'est-il pas possible d'utiliser un listener pour le
textArea.


A chaque fois que le texte est mis à jour, le code suivant s'exécute:

bar.setValue(bar.getMaximum());


No problemo !

Dans ce cas tu peux modifier (cad surcharger) la méthode "setText(String)"
du JTexteArea pour qu'elle fasse ca que tu veux ...
Seul l'initialisation change, l'utilisation est exactement la même (dérivé
de JTextArea ;o)

********************************************************
<CODE>
import javax.swing.*;

public class JTextAreaEnd extends JTextArea {

private JScrollPane pane;

public JTextAreaEnd() {
super("");
setEditable(false);
}

public JScrollBar getJScrollBar() {
return getJScrollPane().getVerticalScrollBar();
}

public JScrollPane getJScrollPane() {
if (pane == null)
pane= new JScrollPane(this);
return pane;
}

public void setText(String texte) {
super.setText(texte);
JScrollBar bar= getJScrollBar();
bar.setValue(bar.getValue());
}
}
</CODE>
*********************************************************

Un petit exemple pour te convaincre que ça fait le boulot :

<CODE>
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JFrame{

private JTextAreaEnd area;
private JTextField field;

class DisposeOnClose extends WindowAdapter {
public void windowClosing(WindowEvent we) {
dispose();
}
}

class AjoutText implements ActionListener {
public void actionPerformed(ActionEvent ae) {
if (field.getText().length() > 0) {
area.setText(area.getText() + "n" + field.getText());
field.setText("");
}
}
}

public Test() {
Container cp= getContentPane();
cp.setLayout(new BorderLayout());

// center
area= new JTextAreaEnd();
area.setText("Texte:");
JScrollPane scroll= area.getJScrollPane();
cp.add(scroll, BorderLayout.CENTER);

// south
field= new JTextField();
field.addActionListener(new AjoutText());
cp.add(field, BorderLayout.SOUTH);

addWindowListener(new DisposeOnClose());
}

public static void main(String[] args) {
JFrame frame= new Test();
frame.setSize(200,200);
frame.show();
}
}
</CODE>

et le tour est joué !
--
PhilippeC





Avatar
Philippe C
Ne serait-il pas plus simple ou simplement possible d'utiliser la classe
CaretListener ?

ex: textArea.addCaretListener(new CaretListener () {
public void caretUpdate(CaretEvent e) {
bar.setValue(bar.getMaximum());
}
});


Je ne connaissait pas les CaretListener ...
Mais ça à l'air de faire le boulot !
merci pour l'astuce ;o)

Avatar
Speedster
En fait j'ai essayé les différentes solutions et aucune ne fonctionne...
Je me suis aperçu que la scrollbar ne se déplace plus à la fin uniquement
lorsque j'appuie avec le bouton de la souris dans la zone de texte. Si je
clicke sur les autres composants, il n'y a pas de souci.
J'ai donc pensé à utiliser textArea.setFocusable(false).
Ceci m'empêche de sélectionner le texte mais le fait de toucher la zone
texte provoque tjrs l'arrêt du déplacement automatique de la scrollbar.
J'utilise pour remplir la zone de texte la méthode append et non setText.

"Philippe C" a écrit dans le message
de news:bjnif4$21r$
Ne serait-il pas plus simple ou simplement possible d'utiliser la classe
CaretListener ?

ex: textArea.addCaretListener(new CaretListener () {
public void caretUpdate(CaretEvent e) {
bar.setValue(bar.getMaximum());
}
});


Je ne connaissait pas les CaretListener ...
Mais ça à l'air de faire le boulot !
merci pour l'astuce ;o)





Avatar
Philippe C
En fait j'ai essayé les différentes solutions et aucune ne fonctionne...
Je me suis aperçu que la scrollbar ne se déplace plus à la fin uniquement
lorsque j'appuie avec le bouton de la souris dans la zone de texte. Si je
clicke sur les autres composants, il n'y a pas de souci.
J'ai donc pensé à utiliser textArea.setFocusable(false).
Ceci m'empêche de sélectionner le texte mais le fait de toucher la zone
texte provoque tjrs l'arrêt du déplacement automatique de la scrollbar.
J'utilise pour remplir la zone de texte la méthode append et non setText.


Le CaretListener ne marche pas...
Je pense que ça a un rapport avec la position de la bar de texte (?)

Par contre l'astuce de redéfinir les méthodes "setText" et par consequent
"append" marche relativement bien !
En fait, j'ai fait une erreur dans le code que je t'es envoyé :

public void setText(String texte) {
super.setText(texte);
JScrollBar bar= getJScrollBar();
bar.setValue(bar.getMaximum());
// ^^^^^^^^^^^^^^^^
}

et non "bar.setValue(bar.getValue());"
qui ne sert à rien dans ce cas ;o)

--
PhilippeC

Avatar
Speedster
J'ai essayé ton code mais cela ne fonctionne pas dans mon programme.
A la différence du tien, je n'insère pas du texte manuellement mais c'est le
programme qui le fait automatiquement par des appels successifs à la méthode
append.
De plus il insert plusieurs lignes d'un coup et je ne sais pas si le prend à
chaque fois le maximum d'avant.
Par défaut, la scrollbar se déplace à condition que je ne clique pas sur la
zone texte.
En ce qui concerne le listener j'ai trouvé le DocumentListener qui pourrait
faire l'affaire.



"Philippe C" a écrit dans le message
de news:bjp7iu$39v$
En fait j'ai essayé les différentes solutions et aucune ne fonctionne...
Je me suis aperçu que la scrollbar ne se déplace plus à la fin
uniquement


lorsque j'appuie avec le bouton de la souris dans la zone de texte. Si
je


clicke sur les autres composants, il n'y a pas de souci.
J'ai donc pensé à utiliser textArea.setFocusable(false).
Ceci m'empêche de sélectionner le texte mais le fait de toucher la zone
texte provoque tjrs l'arrêt du déplacement automatique de la scrollbar.
J'utilise pour remplir la zone de texte la méthode append et non
setText.



Le CaretListener ne marche pas...
Je pense que ça a un rapport avec la position de la bar de texte (?)

Par contre l'astuce de redéfinir les méthodes "setText" et par consequent
"append" marche relativement bien !
En fait, j'ai fait une erreur dans le code que je t'es envoyé :

public void setText(String texte) {
super.setText(texte);
JScrollBar bar= getJScrollBar();
bar.setValue(bar.getMaximum());
// ^^^^^^^^^^^^^^^^
}

et non "bar.setValue(bar.getValue());"
qui ne sert à rien dans ce cas ;o)

--
PhilippeC





Avatar
Speedster
J'ai remarqué qu'avec ton code, la barre se déplace quand même alors
qu'avant elle restait au niveau de l'endroit où j'avais cliqué. Cependant
celle-ci ne se déplace pas à la fin.

"Speedster" a écrit dans le message de
news:3f6070de$0$23500$
J'ai essayé ton code mais cela ne fonctionne pas dans mon programme.
A la différence du tien, je n'insère pas du texte manuellement mais c'est
le

programme qui le fait automatiquement par des appels successifs à la
méthode

append.
De plus il insert plusieurs lignes d'un coup et je ne sais pas si le prend
à

chaque fois le maximum d'avant.
Par défaut, la scrollbar se déplace à condition que je ne clique pas sur
la

zone texte.
En ce qui concerne le listener j'ai trouvé le DocumentListener qui
pourrait

faire l'affaire.



"Philippe C" a écrit dans le message
de news:bjp7iu$39v$
En fait j'ai essayé les différentes solutions et aucune ne
fonctionne...



Je me suis aperçu que la scrollbar ne se déplace plus à la fin
uniquement


lorsque j'appuie avec le bouton de la souris dans la zone de texte. Si
je


clicke sur les autres composants, il n'y a pas de souci.
J'ai donc pensé à utiliser textArea.setFocusable(false).
Ceci m'empêche de sélectionner le texte mais le fait de toucher la
zone



texte provoque tjrs l'arrêt du déplacement automatique de la
scrollbar.



J'utilise pour remplir la zone de texte la méthode append et non
setText.



Le CaretListener ne marche pas...
Je pense que ça a un rapport avec la position de la bar de texte (?)

Par contre l'astuce de redéfinir les méthodes "setText" et par
consequent


"append" marche relativement bien !
En fait, j'ai fait une erreur dans le code que je t'es envoyé :

public void setText(String texte) {
super.setText(texte);
JScrollBar bar= getJScrollBar();
bar.setValue(bar.getMaximum());
// ^^^^^^^^^^^^^^^^
}

et non "bar.setValue(bar.getValue());"
qui ne sert à rien dans ce cas ;o)

--
PhilippeC









Avatar
Speedster
J'ai trouvé une "solution".
Il suffit que je clicke à nouveau sur la fin de la zone de texte pour que la
barre se mette à nouveau à suivre le texte.

"Speedster" a écrit dans le message de
news:3f607238$0$3559$
J'ai remarqué qu'avec ton code, la barre se déplace quand même alors
qu'avant elle restait au niveau de l'endroit où j'avais cliqué. Cependant
celle-ci ne se déplace pas à la fin.

"Speedster" a écrit dans le message de
news:3f6070de$0$23500$
J'ai essayé ton code mais cela ne fonctionne pas dans mon programme.
A la différence du tien, je n'insère pas du texte manuellement mais
c'est


le
programme qui le fait automatiquement par des appels successifs à la
méthode

append.
De plus il insert plusieurs lignes d'un coup et je ne sais pas si le
prend


à
chaque fois le maximum d'avant.
Par défaut, la scrollbar se déplace à condition que je ne clique pas sur
la

zone texte.
En ce qui concerne le listener j'ai trouvé le DocumentListener qui
pourrait

faire l'affaire.



"Philippe C" a écrit dans le
message


de news:bjp7iu$39v$
En fait j'ai essayé les différentes solutions et aucune ne
fonctionne...



Je me suis aperçu que la scrollbar ne se déplace plus à la fin
uniquement


lorsque j'appuie avec le bouton de la souris dans la zone de texte.
Si




je
clicke sur les autres composants, il n'y a pas de souci.
J'ai donc pensé à utiliser textArea.setFocusable(false).
Ceci m'empêche de sélectionner le texte mais le fait de toucher la
zone



texte provoque tjrs l'arrêt du déplacement automatique de la
scrollbar.



J'utilise pour remplir la zone de texte la méthode append et non
setText.



Le CaretListener ne marche pas...
Je pense que ça a un rapport avec la position de la bar de texte (?)

Par contre l'astuce de redéfinir les méthodes "setText" et par
consequent


"append" marche relativement bien !
En fait, j'ai fait une erreur dans le code que je t'es envoyé :

public void setText(String texte) {
super.setText(texte);
JScrollBar bar= getJScrollBar();
bar.setValue(bar.getMaximum());
// ^^^^^^^^^^^^^^^^
}

et non "bar.setValue(bar.getValue());"
qui ne sert à rien dans ce cas ;o)

--
PhilippeC