Spenhouet
Spenhouet

Reputation: 7169

Add scrollbar to textfield

Given I have two text fields and both text fields contain a text with the same length. The text can be much bigger than the text field. If someone scrolls through this text field with the cursor or by marking text, both text fields should scroll exactly the same.

I want to add a scrollbar that represents the text of the text fields. If the text is smaller than the text field than the scrollbar should be full (the thumb should not be move able). The text in both text fields and the scrollbar should all behave accordingly when scrolling.

The whole thing does look like this: text fields with scrollbar

How to bind the scroll events of all three controls to each other?

How to set the min and max and bind the value of the scrollbar?

Upvotes: 1

Views: 3350

Answers (1)

SedJ601
SedJ601

Reputation: 13859

Here is one solution. This example takes two TextFields and one horizontal ScrollBar and adds them to a group. Then move the TextFields' cursor position based on the current ScrollBar value.

Controller

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ScrollBar;
import javafx.scene.control.TextField;

/**
 *
 * @author Sedrick
 */
public class FXMLDocumentController implements Initializable {

    @FXML TextField tfOne, tfTwo;
    @FXML ScrollBar sbMain;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
        sbMain.setMin(0);
        sbMain.setMax(tfOne.getText().length());


        tfOne.setOnKeyReleased(keyEvent ->{
            if(tfOne.getText().length() <= tfTwo.getText().length())
            {
                sbMain.setMax(tfOne.getText().length());
            }
        });

        tfTwo.setOnKeyReleased(keyEvent ->{
            if(tfTwo.getText().length() <= tfOne.getText().length())
            {
                 sbMain.setMax(tfOne.getText().length());
            }           
        });

        sbMain.valueProperty().addListener((obs, oldVal, newVal)->{
            System.out.println(newVal);
            tfOne.positionCaret(newVal.intValue());
            tfTwo.positionCaret(newVal.intValue());
        });
    }    

}

FXML

<?import javafx.scene.Group?>
<?import javafx.scene.control.ScrollBar?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane id="AnchorPane" prefHeight="375.0" prefWidth="460.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication34.FXMLDocumentController">
   <children>
      <Group />
      <ScrollBar fx:id="sbMain" layoutX="137.0" layoutY="209.0" prefHeight="18.0" prefWidth="187.0" />
      <TextField fx:id="tfOne" layoutX="137.0" layoutY="178.0" text="SDadsaSasdasASasADSasASDadsadadA" />
      <TextField fx:id="tfTwo" layoutX="137.0" layoutY="147.0" text="SDadsaSasdasASasADSasASDadsadadA" />
   </children>
</AnchorPane>

Upvotes: 1

Related Questions