/**************************************************************************
* Copyright (c) 2001, 2002, 2003 by Acunia N.V. All rights reserved. *
* *
* This software is copyrighted by and is the sole property of Acunia N.V. *
* and its licensors, if any. All rights, title, ownership, or other *
* interests in the software remain the property of Acunia N.V. and its *
* licensors, if any. *
* *
* This software may only be used in accordance with the corresponding *
* license agreement. Any unauthorized use, duplication, transmission, *
* distribution or disclosure of this software is expressly forbidden. *
* *
* This Copyright notice may not be removed or modified without prior *
* written consent of Acunia N.V. *
* *
* Acunia N.V. reserves the right to modify this software without notice. *
* *
* Acunia N.V. *
* Philips-site 5, box 3 info@acunia.com *
* 3001 Leuven http://www.acunia.com *
* Belgium - EUROPE *
**************************************************************************/
package com.acunia.wonka.rudolph.peers;
import java.awt.peer.*;
import java.awt.event.*;
import java.awt.*;
public class DefaultTextField extends DefaultTextComponent implements TextFieldPeer, FocusListener, MouseListener, MouseMotionListener, KeyListener {
private boolean focus;
private String str;
private int cols;
private char echo;
private int xoffset;
private boolean selecting;
private int selstart;
private int selstop;
public DefaultTextField(TextField textField) {
super(textField);
textField.addFocusListener(this);
textField.addMouseListener(this);
textField.addMouseMotionListener(this);
textField.addKeyListener(this);
}
public Dimension getMinimumSize(int cols) {
return getPreferredSize(cols);
}
public Dimension getPreferredSize(int cols) {
Dimension preferredSize;
ToolkitBridge.staticLockAWT();
try {
Font f = component.getFont();
FontMetrics fm = getFontMetrics((f != null) ? f : Component.DEFAULT_FONT);
int cx = Math.max(30, cols * 8);
int cy = Math.max(10, fm.getHeight() + 4);
preferredSize = new Dimension(cx, cy);
} finally {
ToolkitBridge.staticUnlockAWT();
}
return preferredSize;
}
public void setEchoChar(char c) {
echo = c;
setText(text);
}
public void setCaretPosition(int newposition) {
super.setCaretPosition(newposition);
paint(getGraphics());
}
/*
** Deprecated
*/
public Dimension minimumSize(int cols) {
return null;
}
public Dimension preferredSize(int cols) {
return null;
}
public void setEchoCharacter(char c) {
}
/*
** From TextComponent
*/
public void setText(String text) {
str = text;
if (echo != 0) {
this.text = echo(str);
}
else {
this.text = str;
}
super.setText(this.text);
paint(getGraphics());
}
private String echo(String s) {
int length = s.length();
char[] sb = new char[length];
for (int i = 0; i < length; i++) {
sb[i] = echo;
}
return new String(sb);
}
public String getText() {
return (echo != 0) ? str : text;
}
/*
** paint.
*/
public void paint(Graphics g) {
if(g == null) return;
int y = component.getSize().height / 2 - ((g.getFontMetrics().getHeight() + 4) / 2);
int w = component.getSize().width - 1;
int h = g.getFontMetrics().getHeight() + 4;
if(component.getSize().height - 1 < h) h = component.getSize().height - 1;
int ystr = (h - (g.getFontMetrics().getHeight() + 4)) / 2 + g.getFontMetrics().getAscent() + 2;
int carretx = g.getFontMetrics().stringWidth(text.substring(0, getCaretPosition()));
/*
** Make sure the caret is visible.
*/
if(xoffset > (w - 4) - carretx) {
xoffset = (w - 4) - carretx;
}
if(xoffset < - carretx) {
xoffset = w - 4 - carretx;
if(xoffset > 0) {
xoffset = 0;
}
}
/*
** Draw the bounding box.
*/
g.setColor(component.getBackground());
g.fillRect(0, y, w, h);
g.setColor(SystemColor.controlHighlight);
g.drawLine(0, y + h, w, y + h);
g.drawLine(w, y, w, y + h);
g.setColor(SystemColor.controlShadow);
g.drawLine(0, y, w, y);
g.drawLine(0, y, 0, y + h);
/*
** Draw the text.
*/
g.setClip(2, y, w - 4, h);
if(component.isEnabled()) {
g.setColor(component.getForeground());
}
else {
g.setColor(SystemColor.textInactiveText);
}
g.drawString(text, xoffset + 2, y + ystr);
/*
** Draw the selection (if there is any and we have focus)
*/
if(getSelectionEnd() - getSelectionStart() > 0 && focus) {
int sx = g.getFontMetrics().stringWidth(text.substring(0, getSelectionStart()));
int ex = g.getFontMetrics().stringWidth(text.substring(0, getSelectionEnd()));
g.setColor(new Color(80, 80, 80));
g.fillRect(sx + xoffset + 2, y + 2, ex - sx, h - 4);
g.setColor(Color.white);
g.setClip(sx + xoffset + 2, y, ex - sx, h);
g.drawString(text, xoffset + 2, y + ystr);
g.setClip(0, y, w, h);
g.setColor(Color.black);
}
/*
** Draw the cursor
(if we have focus).
*/
if(focus && ((TextField)component).isEditable()) {
g.drawLine(carretx + xoffset + 2, y + 2, carretx + xoffset + 2, y + h - 2);
g.drawLine(carretx + xoffset + 3, y + 2, carretx + xoffset + 3, y + h - 2);
}
super.paint(g);
}
/*
** Focus Events.
*/
public void focusGained(FocusEvent fe) {
focus = true;
paint(getGraphics());
}
public void focusLost(FocusEvent fe) {
focus = false;
paint(getGraphics());
}
/*
** Mouse Events.
*/
private int getNearestPos(int x) {
int i = 0;
Font f = component.getFont();
FontMetrics fm = getFontMetrics((f != null) ? f : Component.DEFAULT_FONT);
int length = text.length();
while(i <= length) {
if(x - 2 - xoffset < fm.stringWidth(text.substring(0, i))) {
return i - 1;
}
i++;
}
return length;
}
private void doSelection() {
if(selstart <= selstop) {
select(selstart, selstop);
}
else {
select(selstop, selstart);
}
}
public void mouseEntered(MouseEvent me) {}
public void mouseExited(MouseEvent me) {}
public void mouseMoved(MouseEvent me) {}
public void mouseClicked(MouseEvent me) {}
public void mousePressed(MouseEvent me) {
selstart = getNearestPos(me.getX());
selstop = getNearestPos(me.getX());
doSelection();
setCaretPosition(selstart);
paint(getGraphics());
}
public void mouseReleased(MouseEvent me) {
selstop = getNearestPos(me.getX());
doSelection();
setCaretPosition(selstop);
paint(getGraphics());
}
public void mouseDragged(MouseEvent me) {
selstop = getNearestPos(me.getX());
doSelection();
setCaretPosition(selstop);
paint(getGraphics());
}
public void keyTyped(KeyEvent evt) {
switch(evt.getKeyCode()) {
case KeyEvent.VK_ENTER:
component.dispatchEvent(new ActionEvent(component, ActionEvent.ACTION_PERFORMED, ""));
break;
default:
super.keyTyped(evt);
}
}
/*
** Overrides the protected function <delete the character after caret> of TextComponent
** reason: if echo character set, we should also delete the according character from the according echo string
*/
protected boolean deleteCaret(int newpos){
if(newpos<0 || newpos>=text.length()) {
return false ;
}
//else {
position = newpos;
selectionStart = newpos;
selectionStop = newpos;
text = new String(new StringBuffer(text).deleteCharAt(newpos));
if (echo != 0) {
str = new String(new StringBuffer(str).deleteCharAt(newpos));
}
return true;
}
/*
** Overrides the protected function <delete the characters between selection start and selection stop> of TextComponent
** reason: if echo character set, we should also delete the according characters from the according echo string
*/
protected void deleteSelection(){
text = new String(new StringBuffer(text).delete(selectionStart, selectionStop));
if (echo != 0) {
str = new String(new StringBuffer(str).delete(selectionStart, selectionStop));
}
position = selectionStart;
//selectionStart = selectionStart;
selectionStop = selectionStart;
}
/*
** Overrides the protected function <insert this character after caret> of TextComponent
** reason: if echo character set, we chould NOT type the given chaqracter but the textfield echo char
*/
protected boolean insertCaret(int newpos, char c){
if(newpos<0 || newpos>text.length()) {
return false ;
}
//else {
position = newpos+1;
selectionStart = position;
selectionStop = position;
if (echo != 0) {
str = new String(new StringBuffer(str).insert(newpos,c));
text = new String(new StringBuffer(text).insert(newpos,echo));
}
else {
text = new String(new StringBuffer(text).insert(newpos,c));
}
return true;
}
/*
** Overrides the protected function <replace this selection by the one given character> of TextComponent
** reason: if echo character set, we chould NOT display the given chaqracter but the Textfield echo char
*/
protected void insertSelection(char c){
StringBuffer buf =new StringBuffer(text);
buf.delete(selectionStart, selectionStop);
if (echo != 0) {
buf.insert(selectionStart,echo);
StringBuffer plain =new StringBuffer(str);
plain.delete(selectionStart, selectionStop);
plain.insert(selectionStart,c);
str=new String(plain);
}
else {
buf.insert(selectionStart,c);
}
text = new String(buf);
position = selectionStart;
selectionStop = selectionStart;
}
public boolean inRange(MouseEvent e) {
return (new Rectangle(
0, // x
component.getSize().height / 2 - ((component.getGraphics().getFontMetrics().getHeight() + 4) / 2), // y
component.getSize().width - 1, // width
component.getGraphics().getFontMetrics().getHeight() + 4 // height
)).contains(e.getX(), e.getY());
}
}