ceklock
ceklock

Reputation: 6353

JavaFX TextArea: how to set tabulation width

How do I set tab width of JavaFX TextArea ?

When I use tabulation (tab key) in TextArea, the width of the tabulation is wide. I want to control the width, i.e., use 4 spaces. In the documentation I could not find a method to do this.

I tried this code (where taInput is a TextArea), but it is not working as it should:

taInput.setOnKeyPressed(new EventHandler<KeyEvent>() {
    @Override
    public void handle(KeyEvent e) {
        if (e.getCode() == KeyCode.TAB) {
            // TAB SPACES
            StringBuilder sb = new StringBuilder(config.getTabSpacesCount());
            for (int i=0; i<config.getTabSpacesCount(); i++) {
                sb.append(' ');
            }
            taInput.insertText(taInput.getCaretPosition(), sb.toString());
            e.consume();
        }
    }
});

Upvotes: 7

Views: 2419

Answers (4)

swpalmer
swpalmer

Reputation: 4371

From JavaFX 14 onward, the best way to deal with this is to use CSS to change the tab width, as shown in my answer to Setting the tab spacing/size visualization for a JavaFX TextArea

Replacing tab characters with multiple spaces doesn't have the same effect as tabs advance to the next tab stop, they don't add a fixed-width gap. Even if you adjusted for the characters preceding the tab, when not using a fixed-width font, an integer number of actual spaces may not give you the correct position.

Upvotes: 1

ncmathsadist
ncmathsadist

Reputation: 4891

Try making what you want displayed as a String. Then use s.replace("\t", " "); if you want four spaces. This worked for me.

Upvotes: 0

invariant
invariant

Reputation: 8900

@tenotron

your code also executes same logic for combination of TAB key with set of modifiers ( shift, control, alt, meta or shortcut). Meaning In TextArea

Pressing TAB key = Ctrl(modifier) + TAB = .... = your logic.

To fix this issue , you have to use KeyCombination

Sample Code :

textArea.addEventFilter(KeyEvent.KEY_PRESSED,
                new EventHandler<KeyEvent>() {
                    final KeyCombination combo = new KeyCodeCombination(
                            KeyCode.TAB);
            @Override
                    public void handle(KeyEvent event) {
                          // check for only tab key
                        if (combo.match(event)) {
                            textArea.insertText(textArea.getCaretPosition(),
                                    "I am not real TAB");
                            event.consume();
                }
            }
        });

now Pressing TAB key results "I am not Real TAB" , ctrl+TAB will highlight the next Node on the scene.

Reference :

Correctly Checking KeyEvents

KeyCombination

Upvotes: 1

ceklock
ceklock

Reputation: 6353

Finally I found a way to do this.

It seems that the setOnKeyPressed() method is not good for this task because the event is handled after the keyPress action is executed.

The addEventFilter() handles the events before their actions are executed, so you can manipulate the events.

My new code:

taInput.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
    @Override
    public void handle(KeyEvent e) {
        if (e.getCode() == KeyCode.TAB) {
            String s = StringUtils.repeat(' ', config.getTabSpacesCount());
            taInput.insertText(taInput.getCaretPosition(), s);
            e.consume();
        }
    }
});

Upvotes: 5

Related Questions