/*******************************************************************************
* Copyright (c) 2006-2012
* Software Technology Group, Dresden University of Technology
* DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Software Technology Group - TU Dresden, Germany;
* DevBoost GmbH - Berlin, Germany
* - initial API and implementation
******************************************************************************/
/*
* @(#)FloatingTextField.java 3.0 2008-05-24
*
* Copyright (c) 1996-2008 by the original authors of JHotDraw
* and all its contributors.
* All rights reserved.
*
* The copyright of this software is owned by the authors and
* contributors of the JHotDraw project ("the copyright holders").
* You may not use, copy or modify this software, except in
* accordance with the license agreement you entered into with
* the copyright holders. For details see accompanying license terms.
*/
package org.jhotdraw.draw;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import static org.jhotdraw.draw.AttributeKeys.*;
/**
* A text field overlay that is used to edit a TextFigure.
* A FloatingTextField requires a two step initialization:
* In a first step the overlay is created and in a
* second step it can be positioned.
*
* @see org.jhotdraw.draw.TextFigure
*
* @author Werner Randelshofer
* @version 3.0 2008-05-24 Update when attributes of the edited figure change.
* <br>2.0 2006-01-14 Changed to support double precision coordinates.
* <br>1.0 2003-12-01 Derived from JHotDraw 5.4b1.
*/
public class FloatingTextField {
private TextHolderFigure editedFigure;
private JTextField textField;
private DrawingView view;
private FigureListener figureHandler = new FigureAdapter() {
@Override
public void attributeChanged(FigureEvent e) {
updateWidget();
}
};
public FloatingTextField() {
textField = new JTextField(20);
}
/**
* Creates the overlay for the given Component.
*/
public void createOverlay(DrawingView view) {
createOverlay(view, null);
}
public void requestFocus() {
textField.requestFocus();
}
/**
* Creates the overlay for the given Container using a
* specific font.
*/
public void createOverlay(DrawingView view, TextHolderFigure figure) {
view.getComponent().add(textField, 0);
textField.setText(figure.getText());
textField.setColumns(figure.getTextColumns());
textField.selectAll();
textField.setVisible(true);
editedFigure = figure;
editedFigure.addFigureListener(figureHandler);
this.view = view;
updateWidget();
}
protected void updateWidget() {
Font font = editedFigure.getFont();
font = font.deriveFont(font.getStyle(), (float) (editedFigure.getFontSize() * view.getScaleFactor()));
textField.setFont(font);
textField.setForeground(editedFigure.getTextColor());
textField.setBackground(editedFigure.getFillColor());
Rectangle2D.Double fDrawBounds = editedFigure.getBounds();
Point2D.Double fDrawLoc = new Point2D.Double(fDrawBounds.getX(), fDrawBounds.getY());
if (TRANSFORM.get(editedFigure) != null) {
TRANSFORM.get(editedFigure).transform(fDrawLoc, fDrawLoc);
}
Point fViewLoc = view.drawingToView(fDrawLoc);
Rectangle fViewBounds = view.drawingToView(fDrawBounds);
fViewBounds.x = fViewLoc.x;
fViewBounds.y = fViewLoc.y;
Dimension tfDim = textField.getPreferredSize();
Insets tfInsets = textField.getInsets();
float fontBaseline = textField.getGraphics().getFontMetrics(font).getMaxAscent();
double fBaseline = editedFigure.getBaseline() * view.getScaleFactor();
textField.setBounds(
fViewBounds.x - tfInsets.left,
fViewBounds.y - tfInsets.top - (int) (fontBaseline - fBaseline),
Math.max(fViewBounds.width + tfInsets.left + tfInsets.right, tfDim.width),
Math.max(fViewBounds.height + tfInsets.top + tfInsets.bottom, tfDim.height)
);
}
public Insets getInsets() {
return textField.getInsets();
}
/**
* Adds an action listener
*/
public void addActionListener(ActionListener listener) {
textField.addActionListener(listener);
}
/**
* Remove an action listener
*/
public void removeActionListener(ActionListener listener) {
textField.removeActionListener(listener);
}
/**
* Gets the text contents of the overlay.
*/
public String getText() {
return textField.getText();
}
/**
* Gets the preferred size of the overlay.
*/
public Dimension getPreferredSize(int cols) {
textField.setColumns(cols);
return textField.getPreferredSize();
}
/**
* Removes the overlay.
*/
public void endOverlay() {
view.getComponent().requestFocus();
if (textField != null) {
textField.setVisible(false);
view.getComponent().remove(textField);
Rectangle bounds = textField.getBounds();
view.getComponent().repaint(bounds.x, bounds.y, bounds.width, bounds.height);
}
if (editedFigure != null) {
editedFigure.removeFigureListener(figureHandler);
editedFigure = null;
}
}
}