Tori
Tori

Reputation: 15

How to control specific text selection in a TextArea (JavaFX)?

I'm using JavaFX and have a TextArea. In the textArea I need some way to ensure the user may only select one line at a time. So for my delete button what I have so far is:

deleteButton.setOnAction(e -> { 
    String s = "DELETE: ";
    s += receipt.getSelectedText();
    receipt.replaceSelection(s); 
}); 

How can I enforce that user can only select one full line at a time? Each line will have \n as a breaker, so I was thinking I can some how use it as a key. An issue is the users ability to select more than one line at a time or a partial line. And yes, I must use textArea. I have right now where the delete button is reading what got deleted and displays it. The readt of my code is working great with this one issue. I have about 15 classes that all take in textAreas as a parameter where, when a button is clicked, it appends it to the TextArea and then it saves it to a specified object as a certain attribute. I just need highlight control, or a way to added a checkbox or a way to read where the user clicks that highlights the entire row (but if the click somewhere else, it highlights/selects that line, or try to highlight themselves, it doesn't let them).

Upvotes: 0

Views: 1488

Answers (1)

James_D
James_D

Reputation: 209339

You can use the filter in a TextFormatter to intercept and modify changes to the selection.

Here is a quick example. You could also modify the change to actually effect the functionality you are looking for on delete as well.

import java.util.function.UnaryOperator;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextFormatter;
import javafx.scene.control.TextFormatter.Change;
import javafx.stage.Stage;

public class TextAreaSelectByLine extends Application {

    @Override
    public void start(Stage primaryStage) {
        TextArea textArea = new TextArea();
        UnaryOperator<Change> filter = c -> {

            int caret = c.getCaretPosition();
            int anchor = c.getAnchor() ;

            if (caret != anchor) {
                int start = caret ;
                int end = caret ;
                String text = c.getControlNewText();
                while (start > 0 && text.charAt(start) != '\n') start-- ;
                while (end < text.length() && text.charAt(end) != '\n') end++ ;
                c.setAnchor(start);
                c.setCaretPosition(end);
            }

            return c ;
        };
        TextFormatter<String> formatter = new TextFormatter<>(filter);
        textArea.setTextFormatter(formatter);

        Scene scene = new Scene(textArea, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Upvotes: 1

Related Questions