text offset versus JTextComponent caret position

  • Themenstarter Themenstarter Roar
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
R

Roar

Gast
hi,

hab problem:
hab nen index der irgendwo in nen string hineinzeigt,
hab JTextComponent mit dem string drin,
will caret an die entsrepchende position in der component setzen, aber:
der caret wird nicht an die richtige position gesetzt, sondern immer ein stück zuweit vor.
woran liegt das? der index ist richtig. gibts da nen problem mit den newlines oder so? blupp

danke
gruß
Roar
 
Öhms, Code?

Also sowas sieht bei mir ganz vernünftig aus:
Code:
public class Test5{

	public static void main( String[] args ) {
		JFrame frame = new JFrame();
		String blupp = new String( "abc\ndef\nghi" );
		
		JTextArea area = new JTextArea();
		area.setText( blupp );
		
		frame.add( new JScrollPane( area ));
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.pack();
		frame.setVisible( true );
		
		area.setCaretPosition( 5 );
		System.out.println( blupp.substring( 5 ) );
	}
}
 
schied, in meiner test klasse funktinoiert das, aber nich in der praxis *grübl*

edit:
hm ok das kann doch nich sein. folgendes funktinoiert:

Code:
	static int index = -1;

	public static void main(String[] args){
		JFrame frame = new JFrame();
		final String blupp = new String( "abc\ndef\nghi\nabc\ndef\nghi\nabc\ndef\nghi\n" );

		final JTextPane area = new JTextPane();
		area.setText( blupp );

		frame.add( new JScrollPane( area ));
		JButton button = new JButton(new AbstractAction("find") {
			public void actionPerformed(java.awt.event.ActionEvent e) {
				index = blupp.indexOf("def", index);
				area.requestFocusInWindow();
				area.select( index, index+3 );
				index++;
			}
		});
		frame.add(button, java.awt.BorderLayout.NORTH);
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.pack();
		frame.setVisible( true );
	}

aber das hier nicht:

Code:
 	protected static int index = -1;
 	protected static String find = null;
 	protected static String text = null;

	public void actionPerformed(ActionEvent e) {
// zeugs auskommentiert
			find = dlg.getText();
			text = comp.getText();
			index = text.indexOf(find);
			find();
	}

	protected void find() {
		JTextComponent comp = getTextComponent();
		text = comp.getText();
		if(index != -1 && find != null && text != null) {
			System.out.println("index: "+index);
			comp.requestFocusInWindow();
			comp.setSelectionStart(index);
			comp.setSelectionEnd(index+find.length());
			index = text.indexOf(find, ++index);
		}
	}

:-/

achja getTextComponent leifert immer eine JTextPane zurück, aber das is ja auch kein problem *heul*
 
Hast du's mal so versucht?
Code:
   protected void find() { 
      JTextComponent comp = getTextComponent(); 
      text = comp.getText(); 
      if(index != -1 && find != null && text != null) { 
         System.out.println("index: "+index); 
         comp.requestFocusInWindow(); 
         comp.setCaretPosition(index); 
         comp.moveCaretPostion(index+find.length()); 
         index = text.indexOf(find, ++index); 
      }
 
Roar hat gesagt.:
... eine JTextPane zurück, aber das is ja auch kein problem *heul*

Du wirst es nicht glauben, aber genau das macht den Unterschied aus. Wenn ich eine JTextPane nehme, gehts nicht, mit JTextArea schon :?

Ich kann dir als Workaround das hier anbieten:
Code:
    public void actionPerformed(ActionEvent e) {
//  zeugs auskommentiert
          find = dlg.getText();
          text = getTextComponent().getText();
          text = text.replace( "\r", "" );
          index = text.indexOf(find);
          find();
    }
... aber das ist vielleicht sogar vom OS abhängig... (funktioniert jedenfalls, wenn man von Hand was eingibt).

Falls ich noch was in der API sehe, melde ich mich.

[Edit: Sach mal Roar, was ist denn das für Code? "protected static..." für Methodenvariablen oder wat?]
 
So, gleich noch eine Variante.
Die erscheint mir sinnvoller: jetzt wird nur noch mit dem String von Document gearbeitet, und diese Klasse wird sicher nicht bei "getText" was anderes zurückgeben, als sie intern benutzt.
Code:
    public void actionPerformed(ActionEvent e) {
//  zeugs auskommentiert
          find = dlg.getText();
          
          Document doc = getTextComponent().getDocument();
          try{
          	text = doc.getText( 0, doc.getLength() );
          
          	index = text.indexOf(find);
          	find();
          }
          catch( BadLocationException ex ){
          	ex.printStackTrace();
          }
    }

Wenn man sich den Code von "getText" in JTextComponent anschaut: das ganze wird an das EditorKit weitergeleitet, welcher dann das ganze mit einer Methode "write" in einen Reader schreibt, welcher anschliessend in einen String verwandelt wird (uf, noch komplizierter konnte das wohl nicht mehr implentiert werden?).
Wenn man sich das StyledEditorKit anschaut (welches bei einem JTextPane benutzt wird), so sieht man, dass hier OS-spezifische Linienumbrüche eingebaut werden :arrow: du bekommst nicht den String zurück, der tatsächlich verwendet wird :arrow: deine berechneten Indices sind falsch.

Der Trick mit dem Document sollte aber überall funktionieren.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben