Package org.newdawn.slick.gui

Source Code of org.newdawn.slick.gui.TextField

package org.newdawn.slick.gui;

import org.lwjgl.Sys;
import org.newdawn.slick.Color;
import org.newdawn.slick.Font;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.geom.Rectangle;

/**
* A single text field supporting text entry
*
* @author kevin
*/
public class TextField extends AbstractComponent {
  /** The key repeat interval */
  private static final int INITIAL_KEY_REPEAT_INTERVAL = 400;
  /** The key repeat interval */
  private static final int KEY_REPEAT_INTERVAL = 50;
 
  /** The width of the field */
  private int width;

  /** The height of the field */
  private int height;
 
  /** The location in the X coordinate */
  protected int x;

  /** The location in the Y coordinate */
  protected int y;

  /** The maximum number of characters allowed to be input */
  private int maxCharacter = 10000;

  /** The value stored in the text field */
  private String value = "";

  /** The font used to render text in the field */
  private Font font;

  /** The border color - null if no border */
  private Color border = Color.white;

  /** The text color */
  private Color text = Color.white;

  /** The background color - null if no background */
  private Color background = new Color(0, 0, 0, 0.5f);

  /** The current cursor position */
  private int cursorPos;

  /** True if the cursor should be visible */
  private boolean visibleCursor = true;

  /** The last key pressed */
  private int lastKey = -1;
 
  /** The last character pressed */
  private char lastChar = 0;
 
  /** The time since last key repeat */
  private long repeatTimer;
 
  /** The text before the paste in */
  private String oldText;
 
  /** The cursor position before the paste */
  private int oldCursorPos;
 
  /** True if events should be consumed by the field */
  private boolean consume = true;
 
  /**
   * Create a new text field
   *
   * @param container
   *            The container rendering this field
   * @param font
   *            The font to use in the text field
   * @param x
   *            The x coordinate of the top left corner of the text field
   * @param y
   *            The y coordinate of the top left corner of the text field
   * @param width
   *            The width of the text field
   * @param height
   *            The height of the text field
   * @param listener
   *         The listener to add to the text field
   */
  public TextField(GUIContext container, Font font, int x, int y, int width,
           int height, ComponentListener listener) {
    this(container,font,x,y,width,height);
    addListener(listener);
  }
 
  /**
   * Create a new text field
   *
   * @param container
   *            The container rendering this field
   * @param font
   *            The font to use in the text field
   * @param x
   *            The x coordinate of the top left corner of the text field
   * @param y
   *            The y coordinate of the top left corner of the text field
   * @param width
   *            The width of the text field
   * @param height
   *            The height of the text field
   */
  public TextField(GUIContext container, Font font, int x, int y, int width,
      int height) {
    super(container);

    this.font = font;

    setLocation(x, y);
    this.width = width;
    this.height = height;
  }

  /**
   * Indicate if the input events should be consumed by this field
   *
   * @param consume True if events should be consumed by this field
   */
  public void setConsumeEvents(boolean consume) {
    this.consume = consume;
  }
 
  /**
   * Deactivate the key input handling for this field
   */
  public void deactivate() {
    setFocus(false);
  }
 
  /**
   * Moves the component.
   *
   * @param x
   *            X coordinate
   * @param y
   *            Y coordinate
   */
  public void setLocation(int x, int y) {
    this.x = x;
    this.y = y;
  }

  /**
   * Returns the position in the X coordinate
   *
   * @return x
   */
  public int getX() {
    return x;
  }

  /**
   * Returns the position in the Y coordinate
   *
   * @return y
   */
  public int getY() {
    return y;
  }
 
  /**
   * Get the width of the component
   *
   * @return The width of the component
   */
  public int getWidth() {
    return width;
  }

  /**
   * Get the height of the component
   *
   * @return The height of the component
   */
  public int getHeight() {
    return height;
  }

  /**
   * Set the background color. Set to null to disable the background
   *
   * @param color
   *            The color to use for the background
   */
  public void setBackgroundColor(Color color) {
    background = color;
  }

  /**
   * Set the border color. Set to null to disable the border
   *
   * @param color
   *            The color to use for the border
   */
  public void setBorderColor(Color color) {
    border = color;
  }

  /**
   * Set the text color.
   *
   * @param color
   *            The color to use for the text
   */
  public void setTextColor(Color color) {
    text = color;
  }

  /**
   * @see org.newdawn.slick.gui.AbstractComponent#render(org.newdawn.slick.gui.GUIContext,
   *      org.newdawn.slick.Graphics)
   */
  public void render(GUIContext container, Graphics g) {
    if (lastKey != -1) {
      if (input.isKeyDown(lastKey)) {
        if (repeatTimer < System.currentTimeMillis()) {
          repeatTimer = System.currentTimeMillis() + KEY_REPEAT_INTERVAL;
          keyPressed(lastKey, lastChar);
        }
      } else {
        lastKey = -1;
      }
    }
    Rectangle oldClip = g.getClip();
    g.setWorldClip(x,y,width, height);
   
    // Someone could have set a color for me to blend...
    Color clr = g.getColor();

    if (background != null) {
      g.setColor(background.multiply(clr));
      g.fillRect(x, y, width, height);
    }
    g.setColor(text.multiply(clr));
    Font temp = g.getFont();

    int cpos = font.getWidth(value.substring(0, cursorPos));
    int tx = 0;
    if (cpos > width) {
      tx = width - cpos - font.getWidth("_");
    }

    g.translate(tx + 2, 0);
    g.setFont(font);
    g.drawString(value, x + 1, y + 1);

    if (hasFocus() && visibleCursor) {
      g.drawString("_", x + 1 + cpos + 2, y + 1);
    }

    g.translate(-tx - 2, 0);

    if (border != null) {
      g.setColor(border.multiply(clr));
      g.drawRect(x, y, width, height);
    }
    g.setColor(clr);
    g.setFont(temp);
    g.clearWorldClip();
    g.setClip(oldClip);
  }

  /**
   * Get the value in the text field
   *
   * @return The value in the text field
   */
  public String getText() {
    return value;
  }

  /**
   * Set the value to be displayed in the text field
   *
   * @param value
   *            The value to be displayed in the text field
   */
  public void setText(String value) {
    this.value = value;
    if (cursorPos > value.length()) {
      cursorPos = value.length();
    }
  }

  /**
   * Set the position of the cursor
   *
   * @param pos
   *            The new position of the cursor
   */
  public void setCursorPos(int pos) {
    cursorPos = pos;
    if (cursorPos > value.length()) {
      cursorPos = value.length();
    }
  }

  /**
   * Indicate whether the mouse cursor should be visible or not
   *
   * @param visibleCursor
   *            True if the mouse cursor should be visible
   */
  public void setCursorVisible(boolean visibleCursor) {
    this.visibleCursor = visibleCursor;
  }

  /**
   * Set the length of the allowed input
   *
   * @param length
   *            The length of the allowed input
   */
  public void setMaxLength(int length) {
    maxCharacter = length;
    if (value.length() > maxCharacter) {
      value = value.substring(0, maxCharacter);
    }
  }

  /**
   * Do the paste into the field, overrideable for custom behaviour
   *
   * @param text The text to be pasted in
   */
  protected void doPaste(String text) {
    recordOldPosition();
   
    for (int i=0;i<text.length();i++) {
      keyPressed(-1, text.charAt(i));
    }
  }
 
  /**
   * Record the old position and content
   */
  protected void recordOldPosition() {
    oldText = getText();
    oldCursorPos = cursorPos;
  }
 
  /**
   * Do the undo of the paste, overrideable for custom behaviour
   *
   * @param oldCursorPos before the paste
   * @param oldText The text before the last paste
   */
  protected void doUndo(int oldCursorPos, String oldText) {
    if (oldText != null) {
      setText(oldText);
      setCursorPos(oldCursorPos);
    }
  }
 
  /**
   * @see org.newdawn.slick.gui.AbstractComponent#keyPressed(int, char)
   */
  public void keyPressed(int key, char c) {
    if (hasFocus()) {
      if (key != -1)
      {
        if ((key == Input.KEY_V) &&
           ((input.isKeyDown(Input.KEY_LCONTROL)) || (input.isKeyDown(Input.KEY_RCONTROL)))) {
          String text = Sys.getClipboard();
          if (text != null) {
            doPaste(text);
          }
          return;
        }
        if ((key == Input.KEY_Z) &&
           ((input.isKeyDown(Input.KEY_LCONTROL)) || (input.isKeyDown(Input.KEY_RCONTROL)))) {
          if (oldText != null) {
            doUndo(oldCursorPos, oldText);
          }
          return;
        }
       
        // alt and control keys don't come through here
        if (input.isKeyDown(Input.KEY_LCONTROL) || input.isKeyDown(Input.KEY_RCONTROL)) {
          return;
        }
        if (input.isKeyDown(Input.KEY_LALT) || input.isKeyDown(Input.KEY_RALT)) {
          return;
        }
      }
     
      if (lastKey != key) {
        lastKey = key;
        repeatTimer = System.currentTimeMillis() + INITIAL_KEY_REPEAT_INTERVAL;
      } else {
        repeatTimer = System.currentTimeMillis() + KEY_REPEAT_INTERVAL;
      }
      lastChar = c;
     
      if (key == Input.KEY_LEFT) {
        if (cursorPos > 0) {
          cursorPos--;
        }
        // Nobody more will be notified
        if (consume) {
          container.getInput().consumeEvent();
        }
      } else if (key == Input.KEY_RIGHT) {
        if (cursorPos < value.length()) {
          cursorPos++;
        }
        // Nobody more will be notified
        if (consume) {
          container.getInput().consumeEvent();
        }
      } else if (key == Input.KEY_BACK) {
        if ((cursorPos > 0) && (value.length() > 0)) {
          if (cursorPos < value.length()) {
            value = value.substring(0, cursorPos - 1)
                + value.substring(cursorPos);
          } else {
            value = value.substring(0, cursorPos - 1);
          }
          cursorPos--;
        }
        // Nobody more will be notified
        if (consume) {
          container.getInput().consumeEvent();
        }
      } else if (key == Input.KEY_DELETE) {
        if (value.length() > cursorPos) {
          value = value.substring(0,cursorPos) + value.substring(cursorPos+1);
        }
        // Nobody more will be notified
        if (consume) {
          container.getInput().consumeEvent();
        }
      } else if ((c < 127) && (c > 31) && (value.length() < maxCharacter)) {
        if (cursorPos < value.length()) {
          value = value.substring(0, cursorPos) + c
              + value.substring(cursorPos);
        } else {
          value = value.substring(0, cursorPos) + c;
        }
        cursorPos++;
        // Nobody more will be notified
        if (consume) {
          container.getInput().consumeEvent();
        }
      } else if (key == Input.KEY_RETURN) {
        notifyListeners();
        // Nobody more will be notified
        if (consume) {
          container.getInput().consumeEvent();
        }
      }

    }
  }

  /**
   * @see org.newdawn.slick.gui.AbstractComponent#setFocus(boolean)
   */
  public void setFocus(boolean focus) {
    lastKey = -1;
   
    super.setFocus(focus);
  }
}
TOP

Related Classes of org.newdawn.slick.gui.TextField

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.