JScrollBar soll weiterscrollen, wenn Inhalt von JTextArea erweitert wird

vinno

Mitglied
Hey,
ich bin gerade dabei ein Programm von mir zu erweitern. Dabei möchte ich einer JTextArea eine JScrollBar hinzufügen. Das klappt auch alles soweit.
Wenn nun die Methode JTextArea.append() verwendet wird, soll automatisch die JScrollBar um die Zeilen, um die die JTextArea erweitert wurde weiterscrollen. Dafür habe ich folgende Methode:
Java:
public void outappend (String msg) {
        JTextArea.append(msg);
        JScrollBar.setValue(JScrollBar.getValue() + JScrollBar.getModel().getExtent());
}
Aber wird nun Text hinzugefügt, wird zwar weitergescrollt aber nicht um die Anzahl der Zeilen.
Auch, bei diesem Code, bei dem bis zum Ende gescrollt werden soll, wird nur bis kurz davor gescrollt:
Code:
public void outappend (String msg) {
        JTextArea.append(msg);
        JScrollBar.setValue(JScrollBar.getMaximum() + JScrollBar.getModel().getExtent());
}
Weis jemand, wo mein Fehler liegt?
 
Falls es was nützt: (Debug Ergebnisse)
nach JTextArea.append(msg); erscheint die Nachricht sofort und die Scrollbar erweitert sich. Also müsste JScrollBar.getMaximum(); wirklich das Maximum inklusive neuer Nachricht bekommen.
 
Falls niemand eine Lösung hat: mit awt habe ich alles hinbekommen, außer dass bei awt keine automatischen Zeilenumbrüche gemacht werden. Wenn jemand weis, wie das ginge, würde mir dies auch helfen, obwohl ich swing lieber nutzen würde.
 
Ich glaube getExtend ist nicht das was du brauchst. Probiers mal so:
Java:
int lineHeight = jTextArea.getFontMetrics( jTextArea.getFont() ).getHeight();
jScrollBar.setValue( jScrollBar.getValue() + anzahlNeueZeilen * lineHeight );

Das beim Scrollen bis zum Ende nicht bis ganz zum Ende gescrollt wird, kann ich mir nur so erklären, dass die Scrollbar erst später mitbekommt, dass sich das Maximum geändert hat. Versuch mal so was:

Java:
        SwingUtilities.invokeLater( new Runnable() {

           @Override
           public void run() {
             jScrollBar.setValue( jScrollBar.getMaximum() );
           }
         } );
 
int lineHeight = jTextArea.getFontMetrics( jTextArea.getFont()).getHeight();
jScrollBar.setValue( jScrollBar.getValue()+ anzahlNeueZeilen * lineHeight );
Habe ich bereits probiert. Selbst wenn ich total unrealistisch große Werte für die Zeilenlänge angebe, landet der Balken nicht am gewünschten Platz.
Was meinst du mit dem 2.? Ich bin wohl noch Anfänger
 
Also das Zweite funktioniert. Abgesehen davon, dass die anzahlNeueZeilen sich mit dem Bildschirmausschnitt verändert (durch automatische Zeilenumbrüche). Ich kann diese also nicht einfach so ermitteln. Deswegen dachte ich mir, dass ScrollBar auf das Maximum gesetzt werden soll, wenn ScrollBar im vorhinein auch auf dem Maximum stand.
Also if(JScrollbar.getValue() == JScrollbar.getMaxiumum()).
Aber dies klappt mal wieder nicht. JScrollbar.getMaximum ist ein viel größerer Wert, als wenn bei JScrollbar.getValue() der Balken am Maximum ist.
 
Das die Werte nicht identisch sind liegt daran, dass getValue die Position des oberen Teils der Scrollbar zurückgibt. Wenn du beispielsweise deine Textarea 200 Pixel hoch ist, die Scrollpane 100 Pixel und du ganz nach unten scrollst, wird getValue 100 sein und getMaximum 200.

Ich hab nochmal eine andre Möglichkeit wie es geht ohne die Anzahl der Zeilen zu kennen:
Java:
        final int oldMaximum = jScrollBar.getMaximum();
         jTextArea.append( msg );
         SwingUtilities.invokeLater( new Runnable() {

           @Override
           public void run() {
             final int spaceAppended = jScrollBar.getMaximum() - oldMaximum;
             jScrollBar.setValue( jScrollBar.getValue() + spaceAppended );
           }
         } );
 

Zurück
Oben