Skip to content

Question: CTRL-Z Behavior with highlighted text #765

@SkyAphid

Description

@SkyAphid

When using InlineCssTextArea, when you style individual parts of the text and highlight them, then try to use CTRL-Z functionality, it'll undo the highlighting rather than undo the text changes you entered.

A potential fix was mentioned in #761:

// plainUndoManager, or whatever that static method is called
UndoManager<PlainTextChange> um = UndoUtils.plainUndoManager(area);
area.setUndoManager(um);

The problem now is that it doesn't appear that InlineCssTextArea is compatible with it. I'm assuming there's an alternative version that is? Or some sort of work around would be appreciated. I'd rather not use StyleClassedTextArea in this case because it'd complicate how my project works a bit, but if I need to, I can probably make the change at some point. I just want to make there's not an easier workaround first.

Reproducible test software:

import java.time.Duration;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import org.fxmisc.flowless.VirtualizedScrollPane;
import org.fxmisc.richtext.InlineCssTextArea;
import org.fxmisc.richtext.LineNumberFactory;
import org.reactfx.Subscription;

public class SyntaxTest extends Application {

	private static final String[] KEYWORDS = new String[] { "[[test]]" };

	private static final String sampleCode = "this is a syntax [[test]]";

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

	@Override
	public void start(Stage primaryStage) {
		InlineCssTextArea textArea = new InlineCssTextArea();
		
		 Subscription cleanupWhenNoLongerNeedIt = textArea
	                .multiPlainChanges()
	                .successionEnds(Duration.ofMillis(100))
	                .subscribe(ignore -> computeHighlighting(textArea, KEYWORDS, "coral"));

		textArea.setParagraphGraphicFactory(LineNumberFactory.get(textArea));
		
		textArea.replaceText(0, 0, sampleCode);

		Scene scene = new Scene(new StackPane(new VirtualizedScrollPane<>(textArea)), 600, 400);
		primaryStage.setScene(scene);
		primaryStage.setTitle("Syntax Test");
		primaryStage.show();
		
		primaryStage.setOnCloseRequest(event ->{
			cleanupWhenNoLongerNeedIt.unsubscribe();
		});
	}

	public static void computeHighlighting(InlineCssTextArea textArea, String[] keywords, String colorFillCode) {
		String text = textArea.getText();
		
		textArea.setStyle(0, textArea.getLength(), "");
		
		for (int i = 0; i < keywords.length; i++) {
			String keyword = keywords[i];
			
			if (keyword.trim().isEmpty() || keyword.startsWith("//")) continue;
			
			boolean containsKeywords = true;
			int lastEnd = 0;
			
			while(containsKeywords) {
				int start = text.indexOf(keyword, lastEnd);
				int end = start + keyword.length();
				
				if (start >= 0) {
					textArea.setStyle(start, end, "-fx-fill: " + colorFillCode + ";");
					lastEnd = end;
				}else {
					containsKeywords = false;
				}
			}
		}
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions