001 /* 002 * @(#)TextTool.java 003 * 004 * Project: JHotdraw - a GUI framework for technical drawings 005 * http://www.jhotdraw.org 006 * http://jhotdraw.sourceforge.net 007 * Copyright: © by the original author(s) and all contributors 008 * License: Lesser GNU Public License (LGPL) 009 * http://www.opensource.org/licenses/lgpl-license.html 010 */ 011 012 package org.objectweb.jac.ide.diagrams; 013 014 import CH.ifa.draw.framework.DrawingEditor; 015 import CH.ifa.draw.framework.Figure; 016 import CH.ifa.draw.standard.TextHolder; 017 import org.objectweb.jac.util.Log; 018 import java.awt.Container; 019 import java.awt.Dimension; 020 import java.awt.Rectangle; 021 import java.awt.event.ActionEvent; 022 import java.awt.event.ActionListener; 023 import java.awt.event.KeyEvent; 024 import java.awt.event.KeyListener; 025 import java.awt.event.MouseEvent; 026 027 /** 028 * Tool to create new or edit existing text figures. 029 * The editing behavior is implemented by overlaying the 030 * Figure providing the text with a FloatingTextField.<p> 031 * A tool interaction is done once a Figure that is not 032 * a TextHolder is clicked. 033 * 034 * @see TextHolder 035 * @see FloatingTextField 036 * 037 * @version <$CURRENT_VERSION$> 038 */ 039 public class TextTool extends CreationTool 040 implements ActionListener, KeyListener 041 { 042 043 private FloatingTextField fTextField; 044 private TextHolder fTypingTarget; 045 046 public TextTool(DrawingEditor newDrawingEditor, Figure prototype) { 047 super(newDrawingEditor, prototype); 048 } 049 050 /** 051 * If the pressed figure is a TextHolder it can be edited otherwise 052 * a new text figure is created. 053 */ 054 public void mouseDown(MouseEvent e, int x, int y) 055 { 056 TextHolder textHolder = null; 057 Figure pressedFigure = drawing().findFigureInside(x, y); 058 if (pressedFigure instanceof TextHolder) { 059 textHolder = (TextHolder) pressedFigure; 060 if (!textHolder.acceptsTyping()) 061 textHolder = null; 062 } 063 if (textHolder != null) { 064 beginEdit(textHolder); 065 return; 066 } 067 if (getTypingTarget() != null) { 068 endEdit(); 069 editor().toolDone(); 070 } else { 071 super.mouseDown(e, x, y); 072 // update view so the created figure is drawn before the floating text 073 // figure is overlaid. (Note, fDamage should be null in StandardDrawingView 074 // when the overlay figure is drawn because a JTextField cannot be scrolled) 075 view().checkDamage(); 076 textHolder = (TextHolder)getCreatedFigure(); 077 beginEdit(textHolder); 078 } 079 } 080 081 public void mouseDrag(MouseEvent e, int x, int y) { 082 } 083 084 public void mouseUp(MouseEvent e, int x, int y) { 085 } 086 087 /** 088 * Terminates the editing of a text figure. 089 */ 090 public void deactivate() { 091 endEdit(); 092 super.deactivate(); 093 } 094 095 /** 096 * Sets the text cursor. 097 */ 098 public void activate() { 099 super.activate(); 100 view().clearSelection(); 101 // JDK1.1 TEXT_CURSOR has an incorrect hot spot 102 //view().setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); 103 } 104 105 /** 106 * Test whether the text tool is currently activated and is displaying 107 * a overlay TextFigure for accepting input. 108 * 109 * @return true, if the text tool has a accepting target TextFigure for its input, false otherwise 110 */ 111 public boolean isActivated() { 112 return getTypingTarget() != null; 113 } 114 115 // ActionListener 116 public void actionPerformed(ActionEvent e) { 117 endEdit(); 118 } 119 120 // KeyListener 121 public void keyPressed(KeyEvent e) { 122 int code = e.getKeyCode(); 123 if (code==KeyEvent.VK_ESCAPE) { 124 abortEdit(); 125 } 126 } 127 public void keyReleased(KeyEvent e) {} 128 public void keyTyped(KeyEvent e) {} 129 130 protected void beginEdit(TextHolder figure) { 131 if (fTextField == null) { 132 fTextField = new FloatingTextField(); 133 } 134 135 if (figure != getTypingTarget() && getTypingTarget() != null) { 136 endEdit(); 137 } 138 139 fTextField.addActionListener(this); 140 fTextField.addKeyListener(this); 141 fTextField.createOverlay((Container)view(), figure.getFont()); 142 fTextField.setBounds(fieldBounds(figure), figure.getText()); 143 144 setTypingTarget(figure); 145 } 146 147 protected void endEdit() { 148 Log.trace("diagram","End edit"); 149 if (getTypingTarget() != null) { 150 if (fTextField.getText().length() > 0) { 151 getTypingTarget().setText(fTextField.getText()); 152 } else { 153 drawing().orphan((Figure)getAddedFigure()); 154 } 155 156 setTypingTarget(null); 157 fTextField.endOverlay(); 158 fTextField.removeActionListener(this); 159 fTextField.removeKeyListener(this); 160 // view().checkDamage(); 161 } 162 } 163 164 protected void abortEdit() { 165 Log.trace("diagram","Abort edit"); 166 if (getTypingTarget() != null) { 167 setTypingTarget(null); 168 fTextField.endOverlay(); 169 fTextField.removeActionListener(this); 170 fTextField.removeKeyListener(this); 171 // view().checkDamage(); 172 } 173 } 174 175 private Rectangle fieldBounds(TextHolder figure) { 176 Rectangle box = figure.textDisplayBox(); 177 int nChars = figure.overlayColumns(); 178 Dimension d = fTextField.getPreferredSize(nChars); 179 return new Rectangle(box.x, box.y, d.width, d.height); 180 } 181 182 protected void setTypingTarget(TextHolder newTypingTarget) { 183 fTypingTarget = newTypingTarget; 184 } 185 186 protected TextHolder getTypingTarget() { 187 return fTypingTarget; 188 } 189 190 } 191