(original) (raw)

/* * Copyright © 2004, 2010 Oracle and/or its affiliates. All Rights Reserved. * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * -Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Oracle and/or its affiliates. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF * THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that Software is not designed, licensed or * intended for use in the design, construction, operation or * maintenance of any nuclear facility. */ import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.font.FontRenderContext; import java.awt.font.TextAttribute; import java.awt.font.TextHitInfo; import java.awt.font.TextLayout; import java.text.AttributedCharacterIterator; import java.text.AttributedString; /** * Implements a very simple lightweight text editing component. * It lets the user edit a single line of text using the keyboard. * The only special character that it knows about is backspace; all other * characters are added to the text. Selections are not supported, so * there's only a simple caret indicating the insertion point. * The component also displays a component name above the editable * text line, and draws a black frame whose thickness indicates whether * the component has the focus. *

* The component can be initialized to enable or disable input * through input methods. Other than that, it doesn't do anything * to support input methods, so input method interaction (if any) * will occur in a separate composition window. However, the * component is designed to be easily extended with full input * method support. It distinguishes between "displayed text" and * "committed text" - here, they're the same, but in a subclass * that supports on-the-spot input, the displayed text would be the * combination of committed text and composed text. The component * also uses TextLayout to draw the text, so it can be easily * extended to handle input method highlights. */ public class LWTextComponent extends Component implements KeyListener, FocusListener { // whether the component currently has the focus private transient boolean haveFocus; // the component name that's displayed at the top of the component's area private String name; // The text the user has entered. The term "committed text" // follows the usage in the input method framework. private StringBuffer committedText = new StringBuffer(); // We use a text layout for drawing and measuring. Since they // are expensive to create, we cache it and invalidate it when // the text is modified. private transient TextLayout textLayout = null; private transient boolean validTextLayout = false; // members that determine where the text is drawn private static final int LINE_OFFSET = 8; private int textOriginX; private int nameOriginY; private int textOriginY; /** * Constructs a LWTextComponent. * @param name the component name to be displayed above the text * @param enableInputMethods whether to enable input methods for this component */ public LWTextComponent(String name, boolean enableInputMethods) { super(); this.name = name; setSize(300, 80); // we have to set the foreground color because otherwise // text may not display correctly when we use an input // method highlight that swaps background and foreground // colors setForeground(Color.black); setBackground(Color.white); setFontSize(12); setVisible(true); setEnabled(true); addKeyListener(this); addFocusListener(this); addMouseListener(new MouseFocusListener(this)); enableInputMethods(enableInputMethods); } public void setFontSize(int size) { setFont(new Font("Dialog", Font.PLAIN, size)); nameOriginY = LINE_OFFSET + size; textOriginX = 10; textOriginY = 2 * (LINE_OFFSET + size); } /** * Draws the component. The following items are drawn: *

*