package sun.lwawt;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Insets;
import java.awt.SystemColor;
import java.awt.TextComponent;
import java.awt.event.TextEvent;
import java.awt.event.InputMethodListener;
import java.awt.event.InputMethodEvent;
import java.awt.im.InputMethodRequests;
import java.awt.peer.TextComponentPeer;
import sun.awt.AWTAccessor;
import javax.swing.JComponent;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
abstract class LWTextComponentPeer<T extends TextComponent, D extends JComponent>
extends LWComponentPeer<T, D>
implements DocumentListener, TextComponentPeer, InputMethodListener {
private volatile boolean firstChangeSkipped;
LWTextComponentPeer(final T target,
final PlatformComponent platformComponent) {
super(target, platformComponent);
if (!getTarget().isBackgroundSet()) {
getTarget().setBackground(SystemColor.text);
}
}
@Override
void initializeImpl() {
super.initializeImpl();
synchronized (getDelegateLock()) {
getTextComponent().getDocument().addDocumentListener(this);
}
setEditable(getTarget().isEditable());
setText(getTarget().getText());
setCaretPosition(getTarget().getCaretPosition());
getTarget().addInputMethodListener(this);
final int start = getTarget().getSelectionStart();
final int end = getTarget().getSelectionEnd();
if (end > start) {
select(start, end);
}
firstChangeSkipped = true;
}
@Override
protected final void disposeImpl() {
synchronized (getDelegateLock()) {
getTextComponent().getCaret().setVisible(false);
}
super.disposeImpl();
}
abstract JTextComponent getTextComponent();
public Dimension getMinimumSize(final int rows, final int columns) {
final Insets insets;
synchronized (getDelegateLock()) {
insets = getTextComponent().getInsets();
}
final int borderHeight = insets.top + insets.bottom;
final int borderWidth = insets.left + insets.right;
final FontMetrics fm = getFontMetrics(getFont());
return new Dimension(fm.charWidth(WIDE_CHAR) * columns + borderWidth,
fm.getHeight() * rows + borderHeight);
}
@Override
public final void setEditable(final boolean editable) {
synchronized (getDelegateLock()) {
getTextComponent().setEditable(editable);
}
}
@Override
public final String getText() {
synchronized (getDelegateLock()) {
return getTextComponent().getText();
}
}
@Override
public final void setText(final String text) {
synchronized (getDelegateLock()) {
final Document document = getTextComponent().getDocument();
document.removeDocumentListener(this);
getTextComponent().setText(text);
revalidate();
if (firstChangeSkipped) {
postEvent(new TextEvent(getTarget(),
TextEvent.TEXT_VALUE_CHANGED));
}
document.addDocumentListener(this);
}
repaintPeer();
}
@Override
public final int getSelectionStart() {
synchronized (getDelegateLock()) {
return getTextComponent().getSelectionStart();
}
}
@Override
public final int getSelectionEnd() {
synchronized (getDelegateLock()) {
return getTextComponent().getSelectionEnd();
}
}
@Override
public final void select(final int selStart, final int selEnd) {
synchronized (getDelegateLock()) {
getTextComponent().select(selStart, selEnd);
}
repaintPeer();
}
@Override
public final void setCaretPosition(final int pos) {
synchronized (getDelegateLock()) {
getTextComponent().setCaretPosition(pos);
}
repaintPeer();
}
@Override
public final int getCaretPosition() {
synchronized (getDelegateLock()) {
return getTextComponent().getCaretPosition();
}
}
@Override
public final InputMethodRequests getInputMethodRequests() {
synchronized (getDelegateLock()) {
return getTextComponent().getInputMethodRequests();
}
}
@Override
public final boolean isFocusable() {
return getTarget().isFocusable();
}
protected final void revalidate() {
synchronized (getDelegateLock()) {
getTextComponent().invalidate();
getDelegate().validate();
}
}
protected final void postTextEvent() {
postEvent(new TextEvent(getTarget(), TextEvent.TEXT_VALUE_CHANGED));
synchronized (getDelegateLock()) {
revalidate();
}
}
@Override
public final void changedUpdate(final DocumentEvent e) {
postTextEvent();
}
@Override
public final void insertUpdate(final DocumentEvent e) {
postTextEvent();
}
@Override
public final void removeUpdate(final DocumentEvent e) {
postTextEvent();
}
@Override
public void inputMethodTextChanged(final InputMethodEvent event) {
synchronized (getDelegateLock()) {
AWTAccessor.getComponentAccessor().processEvent(getTextComponent(), event);
}
}
@Override
public void caretPositionChanged(final InputMethodEvent event) {
synchronized (getDelegateLock()) {
AWTAccessor.getComponentAccessor().processEvent(getTextComponent(), event);
}
}
}