JavaFX-8 Make text visible in readonly textbox

JavaFX text fields do not display text if you have configured readonly mode. Here's an example:

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

public class TextAreaReadOnly extends Application {

    public TextAreaReadOnly() {
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        TextArea textarea = new TextArea();
        textarea.setText("This is all\nreadonly text\nin here.");
        textarea.setEditable(false);
        Scene scene = new Scene(textarea, 600, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }    

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

      

While you can still select text using the Shift + Cursor keys, no caret is displayed. Does anyone know a workaround for this?

+3


source to share


3 answers


Started Neil's answer , I tried to quickly check my suggestion for extending TextAreaSkin and replace the caretVisible property with one that does not check editable. Seems to work (although not fully tested) but requires reflexive access to the super private blink function. Obviously this is dirty and not possible in the context of security constraints ...



public static class MyTextAreaSkin extends TextAreaSkin {

    public MyTextAreaSkin(TextArea textInput) {
        super(textInput);
        caretVisible = new BooleanBinding() {
            { bind(textInput.focusedProperty(), textInput.anchorProperty(), 
                    textInput.caretPositionProperty(),
                    textInput.disabledProperty(), displayCaret , blinkProperty() );}
            @Override protected boolean computeValue() {
                return !blinkProperty().get() &&  displayCaret.get() && textInput.isFocused() &&
                        (isWindows() || (textInput.getCaretPosition() == textInput.getAnchor())) 
                        && !textInput.isDisabled(); 
            }
        };
        // rebind opacity to replaced caretVisible property
        caretPath.opacityProperty().bind(new DoubleBinding() {
            { bind(caretVisible); }
            @Override protected double computeValue() {
                return caretVisible.get() ? 1.0 : 0.0;
            }
        });

    }

    BooleanProperty blinkAlias;

    BooleanProperty blinkProperty() {
        if (blinkAlias == null) {
            Class<?> clazz = TextInputControlSkin.class;
            try {
                Field field = clazz.getDeclaredField("blink");
                field.setAccessible(true);
                blinkAlias = (BooleanProperty) field.get(this);
            } catch (NoSuchFieldException | SecurityException 
                   | IllegalArgumentException | IllegalAccessException e) {
                // TBD: errorhandling
                e.printStackTrace();
            }

        }
        return blinkAlias;
    }

}

// usage in a custom TextArea
TextArea textarea = new TextArea() {

    @Override
    protected Skin<?> createDefaultSkin() {
        return new MyTextAreaSkin(this);
    }

};

      

+3


source


I want the same thing - read only field but visible for navigation. I tried:

.text-input:readonly { -fx-display-caret: true; }

      

But to no avail. Digging into the FX Source Code (for 2.2) I found this:



caretVisible = new BooleanBinding() {
        { bind(textInput.focusedProperty(), textInput.anchorProperty(), textInput.caretPositionProperty(),
                textInput.disabledProperty(), textInput.editableProperty(), displayCaret, blink);}
        @Override protected boolean computeValue() {
            // RT-10682: On Windows, we show the caret during selection, but on others we hide it
            return !blink.get() && displayCaret.get() && textInput.isFocused() &&
                    (isWindows() || (textInput.getCaretPosition() == textInput.getAnchor())) &&
                    !textInput.isDisabled() &&
                    textInput.isEditable();
        }
    };

      

It looks like there is no way to override the isEditable () requirement at the end of this conditional. I can draw the dummy caret as a workaround, which is ugly, but I'm not sure if there is any other way - it looks like you can either fake the caret or fake read-only (reject all changes to the control).

+2


source


Maybe allow edit and override edit events to simulate read-only !?

0


source







All Articles