1818
1919import org .openlowcode .tools .misc .SplitString ;
2020
21- import javafx .concurrent .Task ;
2221import com .sun .javafx .scene .text .GlyphList ;
2322import com .sun .javafx .scene .text .HitInfo ;
2423import com .sun .javafx .scene .text .TextLayout ;
2524import com .sun .javafx .text .PrismTextLayout ;
2625import com .sun .javafx .text .TextLine ;
27- import javafx .concurrent .WorkerStateEvent ;
2826import javafx .event .EventHandler ;
2927import javafx .application .Platform ;
3028import javafx .beans .value .ChangeListener ;
@@ -107,6 +105,7 @@ public String dropText() {
107105
108106 private boolean bulletpoint ;
109107 private boolean title ;
108+ private Path thistextflowcaretpath ;
110109
111110 /**
112111 * @return the number of FormattedText sections in this paragraph
@@ -188,11 +187,8 @@ public int getSelectionInTextFlow() {
188187 */
189188 void setCarretAtFirst () {
190189 textflow .requestFocus ();
191- selectionintextflow = 0 ;
190+ this . moveCaretTo ( 0 ) ;
192191
193- this .displayCaretAt (selectionintextflow );
194- logger .finest ("requested set Carret at First for paragraph with bulletpoint=" + bulletpoint + " and title = "
195- + title );
196192 }
197193
198194 /**
@@ -286,7 +282,14 @@ public Paragraph(boolean richtext, boolean editable, RichTextArea parent) {
286282 this .title = false ;
287283 this .textflow = new TextFlow ();
288284 textflow .setLineSpacing (1 );
285+ textflow .heightProperty ().addListener (new ChangeListener <Number >() {
286+
287+ @ Override
288+ public void changed (ObservableValue <? extends Number > arg0 , Number arg1 , Number arg2 ) {
289+ parent .ensureNodeVisible (textflow );
290+ }
289291
292+ });
290293 textlist = new ArrayList <FormattedText >();
291294 this .parent = parent ;
292295 if (editable )
@@ -428,148 +431,139 @@ public void moveCaretTo(int selectionintextflow) {
428431 public void displayCaretAt (int selectionintextflow ) {
429432 this .parent .makeGlow ();
430433 logger .finest (" --------------- Starting Display Caret at " + selectionintextflow + " -------------------" );
434+
431435 Paragraph thisparagraph = this ;
436+ /*
437+ * Task<Void> sleeper = new Task<Void>() {
438+ *
439+ * @Override protected Void call() throws Exception { try { Thread.sleep(5); }
440+ * catch (InterruptedException e) { } return null; } };
441+ * sleeper.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
442+ *
443+ * @Override public void handle(WorkerStateEvent event) {
444+ *
445+ * Platform.runLater(new Runnable() {
446+ *
447+ * @Override public void run() {
448+ */
449+ TextLayout textlayout = (TextLayout ) invoke (getTextLayout , textflow );
432450
433- Task <Void > sleeper = new Task <Void >() {
434- @ Override
435- protected Void call () throws Exception {
436- try {
437- Thread .sleep (5 );
438- } catch (InterruptedException e ) {
439- }
440- return null ;
451+ GlyphList [] glyphlist = textlayout .getRuns ();
452+ logger .finest ("glyphlist found " + glyphlist .length + " for textflow " + textflow + " for paragraph "
453+ + Paragraph .this );
454+ int partialselection = selectionintextflow ;
455+ boolean nullglyphcount = false ;
456+ for (int i = 0 ; i < glyphlist .length ; i ++) {
457+ GlyphList thisglyphlist = glyphlist [i ];
458+ int glyphcount = thisglyphlist .getGlyphCount ();
459+ if (glyphcount == 0 ) {
460+ glyphcount = 1 ; // this is for return carriage
461+ nullglyphcount = true ;
462+ } else {
463+ nullglyphcount = false ;
441464 }
442- };
443- sleeper .setOnSucceeded (new EventHandler <WorkerStateEvent >() {
444- @ Override
445- public void handle (WorkerStateEvent event ) {
446-
447- Platform .runLater (new Runnable () {
448-
449- @ Override
450- public void run () {
451-
452- TextLayout textlayout = (TextLayout ) invoke (getTextLayout , textflow );
453-
454- GlyphList [] glyphlist = textlayout .getRuns ();
455- logger .finest ("glyphlist found " + glyphlist .length );
456- int partialselection = selectionintextflow ;
457- boolean nullglyphcount = false ;
458- for (int i = 0 ; i < glyphlist .length ; i ++) {
459- GlyphList thisglyphlist = glyphlist [i ];
460- int glyphcount = thisglyphlist .getGlyphCount ();
461- if (glyphcount == 0 ) {
462- glyphcount = 1 ; // this is for return carriage
463- nullglyphcount = true ;
464- } else {
465- nullglyphcount = false ;
466- }
467465
468- logger .finest ("glyphlist " + thisglyphlist .getGlyphCount ());
469- if (thisglyphlist .getGlyphCount () >= partialselection ) {
470-
471- if (!nullglyphcount )
472- logger .finest ("found hit (" + thisglyphlist .getPosX (partialselection ) + ","
473- + thisglyphlist .getPosY (partialselection ) + ","
474- + thisglyphlist .getCharOffset (partialselection ) + ")" );
475- if (nullglyphcount )
476- logger .finest ("found hit on null glyphlist (0,0)" );
477- logger .finest ("setting margin for paragraph layout" );
478-
479- PathElement [] caret ;
480- caret = textlayout .getCaretShape (selectionintextflow , true , 0.0f , 0.0f );
481-
482- if (!nullglyphcount ) {
483-
484- logger .finest (" --- *** displaying CaretShape with index = " + selectionintextflow
485- + " *** ---" );
466+ logger .finest ("glyphlist " + thisglyphlist .getGlyphCount ());
467+ if (thisglyphlist .getGlyphCount () >= partialselection ) {
486468
487- } else {
488- logger .finest (" *** --- for null glyphcount - Getting PosX for "
489- + thisglyphlist .toString ());
469+ if (!nullglyphcount )
470+ logger .finest ("found hit (" + thisglyphlist .getPosX (partialselection ) + ","
471+ + thisglyphlist .getPosY (partialselection ) + ","
472+ + thisglyphlist .getCharOffset (partialselection ) + ")" );
473+ if (nullglyphcount )
474+ logger .finest ("found hit on null glyphlist (0,0)" );
475+ logger .finest ("setting margin for paragraph layout" );
490476
491- }
477+ PathElement [] caret ;
478+ caret = textlayout .getCaretShape (selectionintextflow , true , 0.0f , 0.0f );
492479
493- logger .finest (" hit additional info " + thisglyphlist .getLocation ().x + " -"
494- + thisglyphlist .getLocation ().y );
495- logger .finest ("found caret = " + caret .length );
480+ if (!nullglyphcount ) {
496481
497- Path caretpath = new Path ( caret );
482+ logger . finest ( " --- *** displaying CaretShape with index = " + selectionintextflow + " *** ---" );
498483
499- double left = textflow .insetsProperty ().getValue ().getLeft ();
500- logger .finest ("binding X to left = " + left + ", Insets binding left = "
501- + textflow .insetsProperty ().getValue ().getLeft ());
502- caretpath .layoutXProperty ().bind (new DoubleBinding () {
503- {
504- super .bind (textflow .insetsProperty ());
505- }
484+ } else {
485+ logger .finest (" *** --- for null glyphcount - Getting PosX for " + thisglyphlist .toString ());
506486
507- @ Override
508- protected double computeValue () {
509- logger .finest ("computing left in insets binding = "
510- + textflow .insetsProperty ().getValue ().getLeft ());
511- return textflow .insetsProperty ().getValue ().getLeft ();
512- }
487+ }
513488
514- });
489+ logger .finest (
490+ " hit additional info " + thisglyphlist .getLocation ().x + " -" + thisglyphlist .getLocation ().y );
491+ logger .finest ("found caret = " + caret .length );
492+ if (Paragraph .this .thistextflowcaretpath == null ) {
493+ Paragraph .this .thistextflowcaretpath = new Path (caret );
494+ logger .severe (" >>> creating textflow caret " + thistextflowcaretpath );
495+ double left = textflow .insetsProperty ().getValue ().getLeft ();
496+ logger .finest ("binding X to left = " + left + ", Insets binding left = "
497+ + textflow .insetsProperty ().getValue ().getLeft ());
498+ thistextflowcaretpath .layoutXProperty ().bind (new DoubleBinding () {
499+ {
500+ super .bind (textflow .insetsProperty ());
501+ }
515502
516- caretpath .layoutYProperty ().bind (new DoubleBinding () {
517- {
518- super .bind (textflow .insetsProperty ());
519- }
503+ @ Override
504+ protected double computeValue () {
505+ logger .finest ("computing left in insets binding = "
506+ + textflow .insetsProperty ().getValue ().getLeft ());
507+ return textflow .insetsProperty ().getValue ().getLeft ();
508+ }
520509
521- @ Override
522- protected double computeValue () {
523- return textflow .insetsProperty ().getValue ().getTop ();
524- }
510+ });
525511
526- });
512+ thistextflowcaretpath .layoutYProperty ().bind (new DoubleBinding () {
513+ {
514+ super .bind (textflow .insetsProperty ());
515+ }
527516
528- caretpath .getStyleClass ().add ("caret" );
529- caretpath .setStrokeWidth (1 );
530- caretpath .setStroke (Color .BLACK );
531- caretpath .setManaged (false );
532- if (parent .caretpath != null ) {
533- parent .caretpath .setVisible (false );
517+ @ Override
518+ protected double computeValue () {
519+ return textflow .insetsProperty ().getValue ().getTop ();
520+ }
534521
535- }
536- parent .caretpath = caretpath ;
537- parent .activeparagraph = thisparagraph ;
538- textflow .getChildren ().add (caretpath );
539- textflow .requestLayout ();
540- textflow .requestFocus ();
541- // if (parent.getPageActionManager() != null)
542- // parent.getPageActionManager().getClientDisplay().ensureNodeVisible(caretpath);
543-
544- Platform .runLater (new Runnable () {
545-
546- @ Override
547- public void run () {
548- parent .ensureNodeVisible (caretpath );
549-
550- }
551-
552- });
553-
522+ });
554523
555- break ;
556- }
557- partialselection -= glyphcount ;
524+ thistextflowcaretpath .getStyleClass ().add ("caret" );
525+ thistextflowcaretpath .setStrokeWidth (1 );
526+ thistextflowcaretpath .setStroke (Color .BLACK );
527+ thistextflowcaretpath .setManaged (false );
528+ textflow .getChildren ().add (thistextflowcaretpath );
529+ } else {
530+ thistextflowcaretpath .getElements ().setAll (caret );
531+ if (!thistextflowcaretpath .isVisible ())
532+ thistextflowcaretpath .setVisible (true );
533+ }
534+ logger .severe (" >>> parent caretpath " + parent .caretpath + " thistexflowcaretpath = "
535+ + thistextflowcaretpath );
558536
559- }
560- // detect text layout
537+ if (parent .caretpath != thistextflowcaretpath ) {
538+ logger .severe (
539+ "---> replacing parent caret path " + parent .caretpath + " by " + thistextflowcaretpath );
540+ if (parent .caretpath != null )
541+ parent .caretpath .setVisible (false );
542+ parent .caretpath = thistextflowcaretpath ;
561543
562- FormattedText selectedtext = getTextAtCaret ().selectedtext ;
563- parent .setSelection (selectedtext .isBold (), selectedtext .isItalic (),
564- selectedtext .getSpecialcolor (), title , bulletpoint );
544+ }
545+ parent .activeparagraph = thisparagraph ;
565546
566- }
547+ textflow .requestLayout ();
548+ textflow .requestFocus ();
549+ // if (parent.getPageActionManager() != null)
550+ // parent.getPageActionManager().getClientDisplay().ensureNodeVisible(caretpath);
567551
568- }) ;
552+ break ;
569553 }
570- });
571- new Thread (sleeper ).start ();
554+ partialselection -= glyphcount ;
572555
556+ }
557+ // detect text layout
558+
559+ FormattedText selectedtext = getTextAtCaret ().selectedtext ;
560+ parent .setSelection (selectedtext .isBold (), selectedtext .isItalic (), selectedtext .getSpecialcolor (), title ,
561+ bulletpoint );
562+ /*
563+ * }
564+ *
565+ * }); } }); new Thread(sleeper).start();
566+ */
573567 }
574568
575569 private class QualifiedCaretPosition {
@@ -724,8 +718,9 @@ public void setSelectionat(int line, float caretindex) {
724718 for (int i = 0 ; i < glyphlist .length ; i ++) {
725719 GlyphList thisglyphlist = glyphlist [i ];
726720 int glyphcount = thisglyphlist .getGlyphCount ();
727- if (glyphcount == 0 )
728- glyphcount = 1 ;
721+ if (i < glyphlist .length - 1 )
722+ if (glyphcount == 0 )
723+ glyphcount = 1 ;
729724 if (lasty != thisglyphlist .getLocation ().y ) {
730725 lasty = thisglyphlist .getLocation ().y ;
731726 currentline ++;
@@ -1034,8 +1029,9 @@ public void handle(KeyEvent keyevent) {
10341029 // normal paragraph and real carriage return: create new paragraph
10351030 if (richtext )
10361031 if (parent .okToAdd (4 )) {
1032+ logger .finest (" ----> Adding new paragraph" );
10371033 parent .splitparagraphatcurrentchar ();
1038- parent . redrawActiveParagraph ();
1034+
10391035 istreated = true ;
10401036 }
10411037
@@ -1044,7 +1040,7 @@ public void handle(KeyEvent keyevent) {
10441040 if (!istreated ) {
10451041 String character = keyevent .getCharacter ();
10461042 if ((iscarriagereturn ) && (keyevent .isShiftDown ())) {
1047- logger .finest ("Adding backslash n" );
1043+ logger .finest (" ----> Adding backslash n" );
10481044 character = "\n " ;
10491045 }
10501046
@@ -1067,7 +1063,10 @@ public void handle(KeyEvent keyevent) {
10671063 if (caretposition .localcaretindex <= thistext .getTextPayload ().length ())
10681064 after = thistext .getTextPayload ().substring (caretposition .localcaretindex );
10691065 thistext .setString (before + character + after );
1070- selectionintextflow ++;
1066+ selectionintextflow += character .length ();
1067+ logger .finest ("text increase " + selectionintextflow + " >> char '" + character
1068+ + "', before ='" + before + "', after = '" + after + "'" );
1069+
10711070 displayCaretAt (selectionintextflow );
10721071 }
10731072 }
@@ -1470,6 +1469,7 @@ public void giveBackFocus() {
14701469 this .displayCaretAt (selectionintextflow );
14711470 }
14721471 if (this .selectionintextflow == -1 ) {
1472+ logger .severe (" --->>>--->>> Displaying caret with selection = -1 " );
14731473 this .selectionintextflow = 0 ;
14741474 this .textflow .requestFocus ();
14751475 this .displayCaretAt (selectionintextflow );
0 commit comments