1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package hello; 27 28 import javafx.application.Application; 29 import javafx.geometry.Point2D; 30 import javafx.scene.*; 31 import javafx.scene.image.Image; 32 import javafx.scene.image.ImageView; 33 import javafx.scene.paint.*; 34 import javafx.scene.shape.Path; 35 import javafx.scene.text.*; 36 import javafx.stage.Stage; 37 38 import static javafx.scene.paint.Color.*; 39 40 public class HelloTextFlow extends Application { 41 final Path caret = new Path(); 42 final Path highlight = new Path(); 43 44 int caretPos = -1; 45 int anchorPos = -1; 46 47 @Override public void start(Stage stage) { 48 stage.setTitle("Hello TextFlow"); 49 50 Text text1 = mkText(0, 3); 51 Text text2 = mkText(3, 7); 52 53 TextFlow textFlow = 54 new TextFlow(text1, 55 new ImageView(new Image("hello/duke.jpg", 30f, 30f, true, true, false)), 56 text2) { 57 { 58 setCursor(Cursor.TEXT); 59 setOnMousePressed(e -> { 60 HitInfo hit = hitTest(new Point2D(e.getX(), e.getY())); 61 caretPos = anchorPos = hit.getInsertionIndex(); 62 caret.getElements().clear(); 63 highlight.getElements().clear(); 64 text1.setSelectionStart(-1); 65 text1.setSelectionEnd(-1); 66 text2.setSelectionStart(-1); 67 text2.setSelectionEnd(-1); 68 caret.getElements().addAll(caretShape(hit.getCharIndex(), hit.isLeading())); 69 }); 70 setOnMouseDragged(e -> { 71 HitInfo hit = hitTest(new Point2D(e.getX(), e.getY())); 72 caretPos = hit.getInsertionIndex(); 73 caret.getElements().clear(); 74 highlight.getElements().clear(); 75 if (anchorPos >= 0 && caretPos != anchorPos) { 76 int i1 = Math.min(caretPos, anchorPos); 77 int i2 = Math.max(caretPos, anchorPos); 78 int len1 = text1.getText().length(); 79 if (i1 < len1) { 80 text1.setSelectionStart(i1); 81 if (i2 < len1) { 82 text1.setSelectionEnd(i2); 83 } else { 84 text1.setSelectionEnd(len1); 85 } 86 } else { 87 text1.setSelectionStart(-1); 88 text1.setSelectionEnd(-1); 89 } 90 91 if (i2 > len1 + 1) { 92 if (i1 < len1 + 1) { 93 text2.setSelectionStart(0); 94 } else if (i1 >= len1 + 1) { 95 text2.setSelectionStart(i1 - len1 - 1); 96 } 97 text2.setSelectionEnd(i2 - len1 - 1); 98 } else { 99 text2.setSelectionStart(-1); 100 text2.setSelectionEnd(-1); 101 } 102 103 highlight.getElements().addAll(rangeShape(i1, i2)); 104 } else { 105 caret.getElements().addAll(caretShape(hit.getCharIndex(), hit.isLeading())); 106 } 107 }); 108 109 caret.setStrokeWidth(1); 110 caret.setFill(BLACK); 111 caret.setStroke(BLACK); 112 113 highlight.setStroke(null); 114 highlight.setFill(LIGHTBLUE); 115 } 116 117 @Override public void layoutChildren() { 118 super.layoutChildren(); 119 120 caret.getElements().clear(); 121 highlight.getElements().clear(); 122 if (anchorPos >= 0 && caretPos != anchorPos) { 123 highlight.getElements().addAll(rangeShape(Math.min(caretPos, anchorPos), 124 Math.max(caretPos, anchorPos))); 125 } else { 126 caret.getElements().addAll(caretShape(caretPos, true)); 127 } 128 } 129 130 }; 131 132 Scene scene = new Scene(new Group(highlight, textFlow, caret), 600, 400); 133 textFlow.prefWidthProperty().bind(scene.widthProperty()); 134 stage.setScene(scene); 135 stage.show(); 136 } 137 138 private Text mkText(int start, int end) { 139 StringBuilder sb = new StringBuilder(); 140 for (int i = start; i < end; i++) { 141 sb.append(i + ". Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n"); 142 } 143 Text t = new Text(sb.toString()); 144 145 return t; 146 } 147 }