Caretposition und die richtige Textstelle(???)



  • Wenn ich in einer Textkomponente die Caret-Position abfrage, erhalte ich bei mehrzeiligen Texten nie die richtige Stelle. Beispielsweise versuche ich ein Wort zu ermitteln, das sich genau bei der jetzigen Curor-Position befindet, wobei ich diese Position durch die Methode getCaretPosition() ermitteln kann. Dieser Wert kann aber nicht in einer Methode wie z.B. getText() verwendet werden. Das liegt daran, dass bei einem Zeilenumbruch (ausschließlich auf Windows-Systemen) zwei Zeichen gebraucht werden (13 + 10), die vom Cursor jedoch als eins gesehen werden. Wie kann man die richtige Position ermitteln?



  • Hier mal eine Testapplikation. Abgesehen von ein paar Feinheiten werden da die Wörter schon gefunden? Oder sehe ich dein Problem nicht?

    import javax.swing.*;
    import java.awt.*;
    import javax.swing.event.*;
    import java.awt.event.*;
    
    public class CaretTester extends JFrame implements ActionListener, CaretListener
    {
    	private JTextArea area = new JTextArea();
    	private JLabel lbl = new JLabel("Position: ");
    	private JButton btn = new JButton("Get Word!");
    
    	public CaretTester() {
    		super("Caret-Position");
    		area.addCaretListener(this);
    		btn.addActionListener(this);
    		this.getContentPane().add(area, BorderLayout.CENTER);
    		JPanel layoutPanel = new JPanel();
    		layoutPanel.add(lbl);
    		layoutPanel.add(btn);
    		this.getContentPane().add(layoutPanel, BorderLayout.SOUTH);
    		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    		this.pack();
    	}
    
    	public void caretUpdate(CaretEvent e) {
    		lbl.setText("Position: "+area.getCaretPosition());
    	}
    
    	public void actionPerformed(ActionEvent e) {
    		String currentText = area.getText();
    		String wordFound = "";
    		int currentPosition = area.getCaretPosition();
    		int posOfSpaceBeforeCurrentPosition = -1;
    		int posOfSpaceAfterCurrentPosition = -1;
    		for (int i = currentPosition; i > 0; --i) {
    			if (currentText.charAt(i) == ' ') {
    				posOfSpaceBeforeCurrentPosition = i;
    				break;
    			}
    		}
    		for (int i = currentPosition; i < currentText.length(); ++i) {
    			if (currentText.charAt(i) == ' ') {
    				posOfSpaceAfterCurrentPosition = i;
    				break;
    			}
    		}
    		if (posOfSpaceAfterCurrentPosition > -1 && posOfSpaceBeforeCurrentPosition > -1) {
    			wordFound = new String(currentText.substring(posOfSpaceBeforeCurrentPosition, posOfSpaceAfterCurrentPosition));
    		}
    
    		btn.setText("Get Word! ("+wordFound+")");
    	}
    
    	public static void main (String args[]) {
    		new CaretTester().setVisible(true);
    	}
    }
    


  • So wie du es beschrieben hast, sollte es auch funktionieren. Aber wie gesagt der Zeilenumbruch macht mir zu schaffen.

    import javax.swing.*; 
    import java.awt.*; 
    import javax.swing.event.*; 
    import java.awt.event.*; 
    
    public class CaretTester
    extends JFrame
    implements CaretListener
    {
     JTextPane editfeld = new JTextPane();
     JLabel feld = new JLabel("Position:");
    
     public CaretTester()
     {
      super("Testprogramm");
    
      this.setDefaultCloseOperation(EXIT_ON_CLOSE); 
      this.setSize(400,200);
      this.setLocation(100,100);
    
      this.getContentPane().setLayout(new BorderLayout());
      this.getContentPane().add(editfeld, BorderLayout.CENTER); 
      this.getContentPane().add(feld, BorderLayout.SOUTH); 
      editfeld.addCaretListener(this); 
    
     }
    
     public void caretUpdate(CaretEvent e) 
     { 
      feld.setText("Position: "+ editfeld.getCaretPosition() + " Länge: "+ editfeld.getText().length()); 
     } 
    
     public static void main(String argv[])
     {
      CaretTester f = new CaretTester();
      f.setVisible(true);	
     }	
    
    }
    

    Die Länge des Textes stimmt nict mit der Caret-Position überein (Bei Zeilenumbrüchen).



  • Versteh' ich nicht. Was hast du konkret auszusetzen?



  • CengizS schrieb:

    Versteh' ich nicht. Was hast du konkret auszusetzen?

    Kann auch sein, dass ich nicht richtig durchblicke, aber nochmal: Nehmen wir an, die Cursor-Position einer Textkomponente befindet sich immer am Ende eines geschriebenen Textes, dann ist diese Positionen vom Wert her gleich mit dem Text. Dieses ändert sich wenn ich Enter drücke, da unter Windows-Systemen hier zwei Zeichen gebraucht werden (13 + 10 = "/r/n"), d.h. in der zweiten Zeile - nach dem Zeilenumbruch - ist der Text schon 1 Zeichen länger, als es die Caret-Position anzeigt. Beispiel: ich schreibe "Test" in die erste Zeile, wobei die Caretposition 4 ist (die Textlänge auch); ich mache einen Zeilenumbruch. Jetzt ist die Caretposition 5, die Textlänge jedoch 6. Es stimmt nicht überein.



  • Das kann ich nicht nachvollziehen. Die Position und Länge sind stets gleich wenn der Cursor am Ende des Textes sich befindet. ABER: Die Position ist 0-basiert. D.h. es gibt eine Position 0 (=Textanfang) für das erste Zeichen. Die Länge allerdings beginnt bei vorhandenem Text mit 1.



  • CengizS schrieb:

    Das kann ich nicht nachvollziehen. Die Position und Länge sind stets gleich wenn der Cursor am Ende des Textes sich befindet. ABER: Die Position ist 0-basiert. D.h. es gibt eine Position 0 (=Textanfang) für das erste Zeichen. Die Länge allerdings beginnt bei vorhandenem Text mit 1.

    Also bei mir ist der Wert der Cursor-Position mit der Länge des Textes unterschiedlich (immer davon ausgegangen, dass sich der Cursor am Textende befindet), wenn sich im Text ein Zeilenumbruch (eben diese beiden Zeichen: "/r/n") befindet. Wie gesagt, es kann sein, dass ich irgendetwas nicht blicke, aber es ist so. Probier doch mal mein Programm aus, und drückt z.B. vier mal Enter. Da erscheint bei mir "Position: 4 Länge: 8" (aber nur unter Windows-Systemen!).



  • Hast du mal mein Programm dahingehend abgeändert, dass es dir auch die Länge anzeigt? Wenn nicht dann kann ich dir sagen, dass bei mir nur ein Zeichen für ein Linefeed genutzt wird. Das liegt an folgendem: Du benutzt eine JTextPane und ich eine JTextArea. Die TextPane arbeitet wohl ein wenig anders als die TextArea - lies dir mal die API durch vielleicht findest du eine Möglichkeit.



  • CengizS schrieb:

    Hast du mal mein Programm dahingehend abgeändert, dass es dir auch die Länge anzeigt? Wenn nicht dann kann ich dir sagen, dass bei mir nur ein Zeichen für ein Linefeed genutzt wird. Das liegt an folgendem: Du benutzt eine JTextPane und ich eine JTextArea. Die TextPane arbeitet wohl ein wenig anders als die TextArea - lies dir mal die API durch vielleicht findest du eine Möglichkeit.

    Gut, dank dir erstmal. Ich werde mal weiter stöbern.


Anmelden zum Antworten