Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
FigSingleLineText |
|
| 2.2;2.2 | ||||
FigSingleLineText$1 |
|
| 2.2;2.2 |
1 | /* $Id: FigSingleLineText.java 17865 2010-01-12 20:45:26Z linus $ | |
2 | ***************************************************************************** | |
3 | * Copyright (c) 2009 Contributors - see below | |
4 | * All rights reserved. This program and the accompanying materials | |
5 | * are made available under the terms of the Eclipse Public License v1.0 | |
6 | * which accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * mvw | |
11 | ***************************************************************************** | |
12 | * | |
13 | * Some portions of this file was previously release using the BSD License: | |
14 | */ | |
15 | ||
16 | // Copyright (c) 1996-2009 The Regents of the University of California. All | |
17 | // Rights Reserved. Permission to use, copy, modify, and distribute this | |
18 | // software and its documentation without fee, and without a written | |
19 | // agreement is hereby granted, provided that the above copyright notice | |
20 | // and this paragraph appear in all copies. This software program and | |
21 | // documentation are copyrighted by The Regents of the University of | |
22 | // California. The software program and documentation are supplied "AS | |
23 | // IS", without any accompanying services from The Regents. The Regents | |
24 | // does not warrant that the operation of the program will be | |
25 | // uninterrupted or error-free. The end-user understands that the program | |
26 | // was developed for research purposes and is advised not to rely | |
27 | // exclusively on the program for any reason. IN NO EVENT SHALL THE | |
28 | // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, | |
29 | // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, | |
30 | // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF | |
31 | // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF | |
32 | // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY | |
33 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
34 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE | |
35 | // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF | |
36 | // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, | |
37 | // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
38 | ||
39 | package org.argouml.uml.diagram.ui; | |
40 | ||
41 | import java.awt.Dimension; | |
42 | import java.awt.Font; | |
43 | import java.awt.Rectangle; | |
44 | import java.awt.event.KeyEvent; | |
45 | import java.beans.PropertyChangeEvent; | |
46 | import java.util.Arrays; | |
47 | ||
48 | import javax.swing.SwingUtilities; | |
49 | ||
50 | import org.apache.log4j.Logger; | |
51 | import org.argouml.model.AttributeChangeEvent; | |
52 | import org.argouml.model.InvalidElementException; | |
53 | import org.argouml.model.Model; | |
54 | import org.argouml.model.UmlChangeEvent; | |
55 | import org.argouml.uml.diagram.DiagramSettings; | |
56 | import org.tigris.gef.presentation.FigText; | |
57 | ||
58 | /** | |
59 | * A SingleLine FigText to provide consistency across Figs displaying single | |
60 | * lines of text.<ul> | |
61 | * <li>The display area is transparent | |
62 | * <li>Text is center justified | |
63 | * <li>There is no line border | |
64 | * <li>There is space below the line for a "Clarifier", | |
65 | * i.e. a red squiggly line. | |
66 | * </ul><p> | |
67 | * | |
68 | * Some of these have an UML object as owner, others do not. | |
69 | * | |
70 | * @author Bob Tarling | |
71 | */ | |
72 | 119 | public class FigSingleLineText extends ArgoFigText { |
73 | ||
74 | 119 | private static final Logger LOG = |
75 | Logger.getLogger(FigSingleLineText.class); | |
76 | ||
77 | /** | |
78 | * The properties of 'owner' that this is interested in | |
79 | */ | |
80 | private String[] properties; | |
81 | ||
82 | private void initialize() { | |
83 | 1071 | setFillColor(FILL_COLOR); // in case someone turns it on |
84 | 1071 | super.setFilled(false); |
85 | 1071 | setTabAction(FigText.END_EDITING); |
86 | 1071 | setReturnAction(FigText.END_EDITING); |
87 | 1071 | setLineWidth(0); |
88 | 1071 | setTextColor(TEXT_COLOR); |
89 | 1071 | } |
90 | ||
91 | public void setFilled(boolean filled) { | |
92 | // Do not allow fill to change. We should see through | |
93 | // the text to the color of the main FIg background. | |
94 | 1071 | } |
95 | ||
96 | /** | |
97 | * Construct text fig | |
98 | * | |
99 | * @param owner owning UML element | |
100 | * @param bounds position and size | |
101 | * @param settings rendering settings | |
102 | * @param expandOnly true if the Fig should only expand and never contract | |
103 | */ | |
104 | public FigSingleLineText(Object owner, Rectangle bounds, | |
105 | DiagramSettings settings, boolean expandOnly) { | |
106 | ||
107 | 1071 | this(owner, bounds, settings, expandOnly, (String[]) null); |
108 | 1071 | } |
109 | ||
110 | /** | |
111 | * Construct text fig | |
112 | * | |
113 | * @param owner owning UML element | |
114 | * @param bounds position and size | |
115 | * @param settings rendering settings | |
116 | * @param expandOnly true if the Fig should only expand and never contract | |
117 | * @param property name of property to listen to | |
118 | */ | |
119 | public FigSingleLineText(Object owner, Rectangle bounds, | |
120 | DiagramSettings settings, boolean expandOnly, String property) { | |
121 | ||
122 | 0 | this(owner, bounds, settings, expandOnly, new String[] {property}); |
123 | 0 | } |
124 | ||
125 | /** | |
126 | * Constructor for text fig without owner. | |
127 | * Using this constructor shall mean | |
128 | * that this fig will never have an owner. | |
129 | * | |
130 | * @param bounds position and size | |
131 | * @param settings rendering settings | |
132 | * @param expandOnly true if the Fig should only expand and never contract | |
133 | */ | |
134 | public FigSingleLineText(Rectangle bounds, | |
135 | DiagramSettings settings, boolean expandOnly) { | |
136 | ||
137 | 0 | this(null, bounds, settings, expandOnly); |
138 | 0 | } |
139 | ||
140 | /** | |
141 | * Construct text fig | |
142 | * | |
143 | * @param owner owning UML element | |
144 | * @param bounds position and size | |
145 | * @param settings rendering settings | |
146 | * @param expandOnly true if the Fig should only expand and never contract | |
147 | * @param allProperties names of properties to listen to | |
148 | */ | |
149 | public FigSingleLineText(Object owner, Rectangle bounds, | |
150 | DiagramSettings settings, boolean expandOnly, | |
151 | String[] allProperties) { | |
152 | 1071 | super(owner, bounds, settings, expandOnly); |
153 | 1071 | initialize(); |
154 | 1071 | this.properties = allProperties; |
155 | 1071 | addModelListener(); |
156 | 1071 | } |
157 | ||
158 | /** | |
159 | * TODO: This function attempts to optimize the more generic | |
160 | * code in the parent, which also works correctly in this case. | |
161 | * Is this a good idea? | |
162 | */ | |
163 | @Override | |
164 | public Dimension getMinimumSize() { | |
165 | 0 | Dimension d = new Dimension(); |
166 | ||
167 | 0 | Font font = getFont(); |
168 | ||
169 | 0 | if (font == null) { |
170 | 0 | return d; |
171 | } | |
172 | 0 | int maxW = 0; |
173 | 0 | int maxH = 0; |
174 | 0 | if (getFontMetrics() == null) { |
175 | 0 | maxH = font.getSize(); |
176 | } else { | |
177 | 0 | maxH = getFontMetrics().getHeight(); |
178 | 0 | maxW = getFontMetrics().stringWidth(getText()); |
179 | } | |
180 | ||
181 | /* Now force minimum dimensions for the text: */ | |
182 | 0 | maxW = Math.max(maxW, MIN_TEXT_WIDTH); |
183 | ||
184 | /* Now add the areas around the text to return the complete size: */ | |
185 | 0 | int overallH = maxH + getTopMargin() + getBotMargin() |
186 | + 2 * getLineWidth(); | |
187 | 0 | int overallW = maxW + getLeftMargin() + getRightMargin() |
188 | + 2 * getLineWidth(); | |
189 | 0 | d.width = overallW; |
190 | 0 | d.height = overallH; |
191 | 0 | return d; |
192 | } | |
193 | ||
194 | @Override | |
195 | protected boolean isStartEditingKey(KeyEvent ke) { | |
196 | 0 | if ((ke.getModifiers() |
197 | & (KeyEvent.META_MASK | KeyEvent.ALT_MASK)) == 0) { | |
198 | 0 | return super.isStartEditingKey(ke); |
199 | } else { | |
200 | 0 | return false; |
201 | } | |
202 | } | |
203 | ||
204 | private void addModelListener() { | |
205 | 1071 | if (properties != null && getOwner() != null) { |
206 | 0 | Model.getPump().addModelEventListener(this, getOwner(), properties); |
207 | } | |
208 | 1071 | } |
209 | ||
210 | @Override | |
211 | public void removeFromDiagram() { | |
212 | 0 | if (getOwner() != null && properties != null) { |
213 | 0 | Model.getPump().removeModelEventListener( |
214 | this, | |
215 | getOwner(), | |
216 | properties); | |
217 | } | |
218 | 0 | super.removeFromDiagram(); |
219 | 0 | } |
220 | ||
221 | @Override | |
222 | public void propertyChange(PropertyChangeEvent pce) { | |
223 | 0 | if ("remove".equals(pce.getPropertyName()) |
224 | && (pce.getSource() == getOwner())) { | |
225 | 0 | deleteFromModel(); |
226 | } | |
227 | ||
228 | 0 | if (pce instanceof UmlChangeEvent) { |
229 | 0 | final UmlChangeEvent event = (UmlChangeEvent) pce; |
230 | 0 | Runnable doWorkRunnable = new Runnable() { |
231 | public void run() { | |
232 | try { | |
233 | 0 | updateLayout(event); |
234 | 0 | } catch (InvalidElementException e) { |
235 | 0 | if (LOG.isDebugEnabled()) { |
236 | 0 | LOG.debug("event = " |
237 | + event.getClass().getName()); | |
238 | 0 | LOG.debug("source = " + event.getSource()); |
239 | 0 | LOG.debug("old = " + event.getOldValue()); |
240 | 0 | LOG.debug("name = " + event.getPropertyName()); |
241 | 0 | LOG.debug("updateLayout method accessed " |
242 | + "deleted element ", e); | |
243 | } | |
244 | 0 | } |
245 | 0 | } |
246 | }; | |
247 | 0 | SwingUtilities.invokeLater(doWorkRunnable); |
248 | } | |
249 | 0 | } |
250 | ||
251 | /** | |
252 | * This is a template method called by the ArgoUML framework as the result | |
253 | * of a change to a model element. Do not call this method directly | |
254 | * yourself. | |
255 | * <p>Override this in any subclasses in order to redisplay the Fig | |
256 | * due to change of any model element that this Fig is listening to.</p> | |
257 | * <p>This method is guaranteed by the framework to be running on the | |
258 | * Swing/AWT thread.</p> | |
259 | * | |
260 | * @param event the UmlChangeEvent that caused the change | |
261 | */ | |
262 | protected void updateLayout(UmlChangeEvent event) { | |
263 | 0 | assert event != null; |
264 | 0 | if (getOwner() == event.getSource() |
265 | && properties != null | |
266 | && Arrays.asList(properties).contains(event.getPropertyName()) | |
267 | && event instanceof AttributeChangeEvent) { | |
268 | /* TODO: Why does it fail for changing | |
269 | * the name of an associationend? | |
270 | * Why should it pass? */ | |
271 | //assert Arrays.asList(properties).contains( | |
272 | // event.getPropertyName()) | |
273 | // : event.getPropertyName(); | |
274 | // TODO: Do we really always need to do this or only if | |
275 | // notationProvider is null? | |
276 | 0 | setText(); |
277 | } | |
278 | 0 | } |
279 | ||
280 | /** | |
281 | * This function without parameter shall | |
282 | * determine the text of the Fig taking values from the owner, | |
283 | * and then call {@link #setText(String)}. | |
284 | * To be implemented as required by sub classes. | |
285 | */ | |
286 | protected void setText() { | |
287 | 0 | } |
288 | ||
289 | public void renderingChanged() { | |
290 | 0 | super.renderingChanged(); |
291 | /* This is needed for e.g. | |
292 | * guillemet notation change on a class name, | |
293 | * see issue 5419. */ | |
294 | 0 | setText(); |
295 | 0 | } |
296 | } |