jTextArea.setCaretPosition klappt nicht wie erwartet

vfl_freak

Premium-User
Hallo zusammen,

ich habe mal eine Frage zum setzen der Caretposition in einer JTextArea.

Es ist doch meines Wissens so, dass die Positionen, die ich setzen kann über den gesamten Text fortlaufend numeriert sind und nicht nur Zeilenweise, richtig :confused:

Ich habe nun eine JTextArea definiert, in der ich aus DB-technischen Gründen nur 68 Zeichen pro Zeile eingeben darf.

Über einen CaretListener zähle ich mittels 'caretUpdate' die Anzahl der Zeichen :
Java:
void jTextAreaKQT_caretUpdate( CaretEvent e ) 
{
    Element root = jTextAreaKQT.getDocument().getDefaultRootElement();
    int dot = e.getDot();
    int line = root.getElementIndex( dot );
    int col = dot - root.getElement( line ).getStartOffset();
    nActCol = col;

    // nActCol enthält nun stets die aktuelle Position
}

Über einen KeyAdapter werte ich dann die Position (also nActCol) aus:
Java:
public void jTextAreaKQT_keyTyped( KeyEvent e ) 
    { 
        // ist die max. Anzahl der erlaubten Zeichen erreicht, dann wird ein ENTER eingefügt 
        if( nActCol >= 68 )
        {
            Toolkit.getDefaultToolkit().beep();
            jTextAreaKQT.insert( "\r\n", nActCol );
            jTextAreaKQT.setCaretPosition( nActCol );
            jTextAreaKQT.requestFocus();
        }
    } // jTextAreaKQT_keyTyped

Ich muss noch vorausschicken, dass im Textfeld 10 Zeilen Text vorgeblendet werden!
Ich kann nun bspw. die erste Zeile bis auf die 68 Zeichen erweitern. Gebe ich ein 69. Zeichen ein, würde ich erwarten, dass der Zeilenumbruch eingefügt wird und dann der Cursor in dieser neuen Zeile steht
Spannenderweise wird zwar eine neue Zeile in den vorhandenen Text eingefügt, das 69. Zeichen jedoch wird an der ersten Stelle der ersten (also der aktuellen) Zeile eingefügt und auch der Cursor steht dann dahinter.

Erweitere ich wie folgt:
Java:
 jTextAreaKQT.setCaretPosition( nActCol + X);
dann wird das 69. Zeichen an der X-ten Stelle der ersten (aktuellen) Zeile eingefügt und der Cursor steht dahinter !

Irgendwie stehe ich hier auf dem Schlauch und raffe es nicht (auch ein Kollege scheint hilflos zu sein ;) )

Hat irgendwer eine Idee, wo mein Gedankenfehler steckt?

Danke und Gruß
Klaus


[EDIT]: mir gerade noch was eingefallen: in diesem speziellen Programm sind die Cursortasten zum Texteditieren DEAKTIVIERT, da sie hier für einen speziellen Zweck (Telefonsteuerung) missbraucht werden! Kann es damit zusammenhängen?

Ich habe eben noch mal versucht, die gesamte Länge des Textes zu bestimmen und dann das Caret dorthin zu setzen ... das klappt kurioserweise ......
 
Zuletzt bearbeitet:
Hi!
Ich denke mal, der Fehler liegt hier:

Java:
    int currentLine= root.getElementIndex( dot );
   int col = dot - root.getElement( line ).getStartOffset();
    nActCol = col;

    // nActCol enthält nun stets die aktuelle Position
}
hier holst du dir nicht die aktuelle Position des Cursors, sondern die Spalte in der aktuellen Zeile. Wenn ich richtig liege, dürfte nActCol immer nur zwischen 0 und 68 liegen, oder?

Ich habs nicht getestet, aber den Linebreak ,müsste man dann ungefähr so einfügen:
Java:
public void jTextAreaKQT_keyTyped( KeyEvent e ) 
    { 
         if( nActCol >= 68 )
        {
            Toolkit.getDefaultToolkit().beep();
            jTextAreaKQT.insert( "\r\n", nActCol + currentLine*68 );
           
        }
    } // jTextAreaKQT_keyTyped



Übrigens, dies allein
Code:
jTextArea1.setColumns(10);
jTextArea1.setLineWrap(true);
müsste doch auch schon den gewünschten Effekt haben, oder?

Grüße!
 
Guten Morgen Artorius,

kann mich leider erst heute melden, da mich letzte Woche unverhofft eine bösere Grippe völlig flach gelegt hat ..... :(

Aber herzlichen Dank für Deine Antwort!
Vermutlich hast Du Recht - ich werde mir das Ganze im Laufe des Arbeitstages nochmal in Ruhe anschauen und dann nochmal posten !

Gruß
Klaus
 
Ich denke mal, der Fehler liegt hier:
hier holst du dir nicht die aktuelle Position des Cursors, sondern die Spalte in der aktuellen Zeile. Wenn ich richtig liege, dürfte nActCol immer nur zwischen 0 und 68 liegen, oder?
Ich habs nicht getestet, aber den Linebreakmüsste man dann ungefähr so einfügen:
Java:
public void jTextAreaKQT_keyTyped( KeyEvent e )
    {
         if( nActCol >= 68 )
        {
            Toolkit.getDefaultToolkit().beep();
            jTextAreaKQT.insert( "\r\n", nActCol + currentLine*68 );
           
        }
    } // jTextAreaKQT_keyTyped

Nein, das klappt leider überhaupt nicht und ergibt ganz wilde Effekte .....

Übrigens, dies allein
Code:
jTextArea1.setColumns(10);
jTextArea1.setLineWrap(true);
müsste doch auch schon den gewünschten Effekt haben, oder?

Ja, die beiden Funktionen hatte ich eh schon drin, weil ich gerade bei "setColumns" auch dachte, dass es den Bereich begrenzen würde, es hat aber auch keinerlei Effekt. Ich habe in der Maske noch ein JTextField, dass ich ebenfalls auf 30 Zeichen Länge begrenzen muss, was aber mit der entsprechenden "setColumns"-Methode ebenfalls fehlschlägt .... :-(

Gruß
Klaus
 
Hi,
also folgendes funktioniert, sofern man hintereinander weg schreibt, d.h. irgendwo mittem im Text anzufangen führt zu einem merkwürdigem Verhalten:
Code:
public void keyTyped(KeyEvent arg0) {
        
        if( count > 10 ){
            Toolkit.getDefaultToolkit().beep();
            jTextArea1.insert( "\r\n", position );
        }
    }
}

public void caretUpdate(CaretEvent e) {
        Element root = jTextArea1.getDocument().getDefaultRootElement();
        position = e.getDot();
        line = root.getElementIndex( position );
        count = root.getElement( line ).getEndOffset() - root.getElement( line ).getStartOffset();
 }

Vielleicht hast du ja die Muse, daran noch ein wenig zu basteln ;)
Ansonsten gib es hier noch einen interessanten Thread http://forums.sun.com/thread.jspa?threadID=5326595 ,wo versucht wird das ganze mit einem DocumentFilter zu lösen. Hier müsste man halt noch, sofern du das brauchst, den automatischen Zeilenumbruch einbasteln...

Grüße!
 
Moin Artorius.

irgendwo mittem im Text anzufangen führt zu einem merkwürdigem Verhalten

Obwohl dieses wohl benötigen werde (es sollen in dem Fenster vorgeblendete Texte erweitert werden), werde ich mir dass noch mal anschauen. Auch der Link klingt interessant :)

Muss jetzt allerdings erst einen anderen Fehler im Livesystem suche, so dass eine Antwort etwas dauern kann!

Danke und Gruß
Klaus

EDIT: tja, hab's nicht wirklich ans Laufen bekommen und jetzt - auf Anweisung vom Chef - als schmalen Workaround erstmal oberhalb eine Art Lineal eingeblendet .... und soll mir anderen Aufgaben widmen :rolleyes:
 
Zuletzt bearbeitet:
Moin zusammen,

habe jetzt nach längerem Basteln und Suchen doch noch die optimale Lösung gefunden und möchte sie hier schnelle für Alle, die ggf. auch danach suchen, kundtun.

Die Lösung heißt: KeyEvent.consume() in der zugehörigen KeyTyped-Methode .... :p
Java:
public void jTextAreaKQT_keyTyped( KeyEvent e ) 
{ 
    // Consumes this event so that it will not be processed in the default manner by  the source which originated it. 
    e.consume();
    Toolkit.getDefaultToolkit().beep();  // Gibt ein "Beep" aus 
}

Wichtig ist dabei auch, dass es die KeyTyped-Methode ist - und nicht (wie bei mir anfangs) KeyPressed !

Nun bleibt der Cursor hinter dem letzten gültigen Zeichen stehen ..... und alles wird gut ;)

Gruß
Klaus
 

Neue Beiträge

Zurück