Class TextBox

All Implemented Interfaces:
Component, Interactable, TextGUIElement

public class TextBox extends AbstractInteractableComponent<TextBox>
This component keeps a text content that is editable by the user. A TextBox can be single line or multiline and lets the user navigate the cursor in the text area by using the arrow keys, page up, page down, home and end. For multi-line TextBox:es, scrollbars will be automatically displayed if needed.

Size-wise, a TextBox should be hard-coded to a particular size, it's not good at guessing how large it should be. You can do this through the constructor.

  • Field Details

    • lines

      private final List<String> lines
    • style

      private final TextBox.Style style
    • caretPosition

      private TerminalPosition caretPosition
    • caretWarp

      private boolean caretWarp
    • readOnly

      private boolean readOnly
    • horizontalFocusSwitching

      private boolean horizontalFocusSwitching
    • verticalFocusSwitching

      private boolean verticalFocusSwitching
    • maxLineLength

      private final int maxLineLength
    • longestRow

      private int longestRow
    • mask

      private Character mask
    • validationPattern

      private Pattern validationPattern
    • textChangeListener

      private TextBox.TextChangeListener textChangeListener
  • Constructor Details

    • TextBox

      public TextBox()
      Default constructor, this creates a single-line TextBox of size 10 which is initially empty
    • TextBox

      public TextBox(String initialContent)
      Constructor that creates a TextBox with an initial content and attempting to be big enough to display the whole text at once without scrollbars
      Parameters:
      initialContent - Initial content of the TextBox
    • TextBox

      public TextBox(String initialContent, TextBox.Style style)
      Creates a TextBox that has an initial content and attempting to be big enough to display the whole text at once without scrollbars.
      Parameters:
      initialContent - Initial content of the TextBox
      style - Forced style instead of auto-detecting
    • TextBox

      public TextBox(TerminalSize preferredSize)
      Creates a new empty TextBox with a specific size
      Parameters:
      preferredSize - Size of the TextBox
    • TextBox

      public TextBox(TerminalSize preferredSize, TextBox.Style style)
      Creates a new empty TextBox with a specific size and style
      Parameters:
      preferredSize - Size of the TextBox
      style - Style to use
    • TextBox

      public TextBox(TerminalSize preferredSize, String initialContent)
      Creates a new empty TextBox with a specific size and initial content
      Parameters:
      preferredSize - Size of the TextBox
      initialContent - Initial content of the TextBox
    • TextBox

      public TextBox(TerminalSize preferredSize, String initialContent, TextBox.Style style)
      Main constructor of the TextBox which decides size, initial content and style
      Parameters:
      preferredSize - Size of the TextBox
      initialContent - Initial content of the TextBox
      style - Style to use for this TextBox, instead of auto-detecting
  • Method Details

    • setValidationPattern

      public TextBox setValidationPattern(Pattern validationPattern)
      Sets a pattern on which the content of the text box is to be validated. For multi-line TextBox:s, the pattern is checked against each line individually, not the content as a whole. Partial matchings will not be allowed, the whole pattern must match, however, empty lines will always be allowed. When the user tried to modify the content of the TextBox in a way that does not match the pattern, the operation will be silently ignored. If you set this pattern to null, all validation is turned off.
      Parameters:
      validationPattern - Pattern to validate the lines in this TextBox against, or null to disable
      Returns:
      itself
    • setTextChangeListener

      public TextBox setTextChangeListener(TextBox.TextChangeListener textChangeListener)
      Assigns a change listener for when the TextBox content has changed. This can be either by user interactions with the component or through programmatically adding and removing lines (there is a flag set on the callback to make it possible to distinguish between the two).
      Parameters:
      textChangeListener - Text change listener to invoke when the TextBox content has changed
      Returns:
      Itself
    • setText

      public TextBox setText(String text)
      Updates the text content of the TextBox to the supplied string.
      Parameters:
      text - New text to assign to the TextBox
      Returns:
      Itself
    • getRenderer

      public TextBox.TextBoxRenderer getRenderer()
      Description copied from interface: Component
      Returns the renderer used to draw this component and measure its preferred size. You probably won't need to call this method unless you know exactly which ComponentRenderer implementation is used and you need to customize it.
      Specified by:
      getRenderer in interface Component
      Overrides:
      getRenderer in class AbstractInteractableComponent<TextBox>
      Returns:
      Renderer this component is using
    • addLine

      public TextBox addLine(String line)
      Adds a single line to the TextBox at the end, this only works when in multi-line mode
      Parameters:
      line - Line to add at the end of the content in this TextBox
      Returns:
      Itself
    • removeLine

      public TextBox removeLine(int lineIndex)
      Removes a line from a TextBox component. If the component is single-line, they only valid call to this method is removeLine(0) which has the same effect as calling setText(""). For multi-line text boxes, the line at the specified index will be removed. Will throw ArrayIndexOutOfBoundsException if you specified an incorrect index.
      Parameters:
      lineIndex - Index of the line to remove, has to be 0 or greater and less than the number of lines in the text box
      Returns:
      Itself
    • setCaretWarp

      public TextBox setCaretWarp(boolean caretWarp)
      Sets if the caret should jump to the beginning of the next line if right arrow is pressed while at the end of a line. Similarly, pressing left arrow at the beginning of a line will make the caret jump to the end of the previous line. This only makes sense for multi-line TextBox:es; for single-line ones it has no effect. By default this is false.
      Parameters:
      caretWarp - Whether the caret will warp at the beginning/end of lines
      Returns:
      Itself
    • isCaretWarp

      public boolean isCaretWarp()
      Checks whether caret warp mode is enabled or not. See setCaretWarp for more details.
      Returns:
      true if caret warp mode is enabled
    • getCaretPosition

      public TerminalPosition getCaretPosition()
      Returns the position of the caret, as a TerminalPosition where the row and columns equals the coordinates in a multi-line TextBox and for single-line TextBox you can ignore the row component.
      Returns:
      Position of the text input caret
    • setCaretPosition

      public TextBox setCaretPosition(int column)
      Moves the text caret position horizontally to a new position in the TextBox. For multi-line TextBox:es, this will move the cursor within the current line. If the position is out of bounds, it is automatically set back into range.
      Parameters:
      column - Position, in characters, within the TextBox (on the current line for multi-line TextBox:es) to where the text cursor should be moved
      Returns:
      Itself
    • setCaretPosition

      public TextBox setCaretPosition(int line, int column)
      Moves the text caret position to a new position in the TextBox. For single-line TextBox:es, the line component is not used. If one of the positions are out of bounds, it is automatically set back into range.
      Parameters:
      line - Which line inside the TextBox to move the caret to (0 being the first line), ignored if the TextBox is single-line
      column - What column on the specified line to move the text caret to (0 being the first column)
      Returns:
      Itself
    • getText

      public String getText()
      Returns the text in this TextBox, for multi-line mode all lines will be concatenated together with \n as separator.
      Returns:
      The text inside this TextBox
    • getTextOrDefault

      public String getTextOrDefault(String defaultValueIfEmpty)
      Helper method, it will return the content of the TextBox unless it's empty in which case it will return the supplied default value
      Parameters:
      defaultValueIfEmpty - Value to return if the TextBox is empty
      Returns:
      Text in the TextBox or defaultValueIfEmpty is the TextBox is empty
    • getMask

      public Character getMask()
      Returns the current text mask, meaning the substitute to draw instead of the text inside the TextBox. This is normally used for password input fields so the password isn't shown
      Returns:
      Current text mask or null if there is no mask
    • setMask

      public TextBox setMask(Character mask)
      Sets the current text mask, meaning the substitute to draw instead of the text inside the TextBox. This is normally used for password input fields so the password isn't shown
      Parameters:
      mask - New text mask or null if there is no mask
      Returns:
      Itself
    • isReadOnly

      public boolean isReadOnly()
      Returns true if this TextBox is in read-only mode, meaning text input from the user through the keyboard is prevented
      Returns:
      true if this TextBox is in read-only mode
    • setReadOnly

      public TextBox setReadOnly(boolean readOnly)
      Sets the read-only mode of the TextBox, meaning text input from the user through the keyboard is prevented. The user can still focus and scroll through the text in this mode.
      Parameters:
      readOnly - If true then the TextBox will switch to read-only mode
      Returns:
      Itself
    • isVerticalFocusSwitching

      public boolean isVerticalFocusSwitching()
      If true, the component will switch to the next available component above if the cursor is at the top of the TextBox and the user presses the 'up' array key, or switch to the next available component below if the cursor is at the bottom of the TextBox and the user presses the 'down' array key. The means that for single-line TextBox:es, pressing up and down will always switch focus.
      Returns:
      true if vertical focus switching is enabled
    • setVerticalFocusSwitching

      public TextBox setVerticalFocusSwitching(boolean verticalFocusSwitching)
      If set to true, the component will switch to the next available component above if the cursor is at the top of the TextBox and the user presses the 'up' array key, or switch to the next available component below if the cursor is at the bottom of the TextBox and the user presses the 'down' array key. The means that for single-line TextBox:es, pressing up and down will always switch focus with this mode enabled.
      Parameters:
      verticalFocusSwitching - If called with true, vertical focus switching will be enabled
      Returns:
      Itself
    • isHorizontalFocusSwitching

      public boolean isHorizontalFocusSwitching()
      If true, the TextBox will switch focus to the next available component to the left if the cursor in the TextBox is at the left-most position (index 0) on the row and the user pressed the 'left' arrow key, or vice versa for pressing the 'right' arrow key when the cursor in at the right-most position of the current row.
      Returns:
      true if horizontal focus switching is enabled
    • setHorizontalFocusSwitching

      public TextBox setHorizontalFocusSwitching(boolean horizontalFocusSwitching)
      If set to true, the TextBox will switch focus to the next available component to the left if the cursor in the TextBox is at the left-most position (index 0) on the row and the user pressed the 'left' arrow key, or vice versa for pressing the 'right' arrow key when the cursor in at the right-most position of the current row.
      Parameters:
      horizontalFocusSwitching - If called with true, horizontal focus switching will be enabled
      Returns:
      Itself
    • getLine

      public String getLine(int index)
      Returns the line on the specific row. For non-multiline TextBox:es, calling this with index set to 0 will return the same as calling getText(). If the row index is invalid (less than zero or equals or larger than the number of rows), this method will throw IndexOutOfBoundsException.
      Parameters:
      index - Index of the row to return the contents from
      Returns:
      The line at the specified index, as a String
      Throws:
      IndexOutOfBoundsException - if the row index is less than zero or too large
    • getLineCount

      public int getLineCount()
      Returns the number of lines currently in this TextBox. For single-line TextBox:es, this will always return 1.
      Returns:
      Number of lines of text currently in this TextBox
    • createDefaultRenderer

      protected TextBox.TextBoxRenderer createDefaultRenderer()
      Description copied from class: AbstractComponent
      When you create a custom component, you need to implement this method and return a Renderer which is responsible for taking care of sizing the component, rendering it and choosing where to place the cursor (if Interactable). This value is intended to be overridden by custom themes.
      Specified by:
      createDefaultRenderer in class AbstractInteractableComponent<TextBox>
      Returns:
      Renderer to use when sizing and drawing this component
    • handleKeyStroke

      public Interactable.Result handleKeyStroke(KeyStroke keyStroke)
      Description copied from class: AbstractInteractableComponent
      This method can be overridden to handle various user input (mostly from the keyboard) when this component is in focus. The input method from the interface, handleInput(..) is final in AbstractInteractableComponent to ensure the input filter is properly handled. If the filter decides that this event should be processed, it will call this method.
      Overrides:
      handleKeyStroke in class AbstractInteractableComponent<TextBox>
      Parameters:
      keyStroke - What input was entered by the user
      Returns:
      Result of processing the key-stroke
    • canMoveCaretUp

      private boolean canMoveCaretUp()
    • canMoveCaretDown

      private boolean canMoveCaretDown()
    • performMoveCaretUp

      private void performMoveCaretUp()
    • performMoveCaretDown

      private void performMoveCaretDown()
    • validated

      private boolean validated(String line)
    • handleKeyStrokeReadOnly

      private Interactable.Result handleKeyStrokeReadOnly(KeyStroke keyStroke)
    • fireOnTextChanged

      private void fireOnTextChanged(boolean initiatedByUserInteraction)