comparison java/src/uk/ac/qmul/eecs/ccmi/simpletemplate/MultiLineString.java @ 0:9418ab7b7f3f

Initial import
author Fiore Martin <fiore@eecs.qmul.ac.uk>
date Fri, 16 Dec 2011 17:35:51 +0000
parents
children d66dd5880081
comparison
equal deleted inserted replaced
-1:000000000000 0:9418ab7b7f3f
1 /*
2 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
3
4 Copyright (C) 2002 Cay S. Horstmann (http://horstmann.com)
5 Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 package uk.ac.qmul.eecs.ccmi.simpletemplate;
22
23 import java.awt.Dimension;
24 import java.awt.Graphics2D;
25 import java.awt.geom.Rectangle2D;
26 import java.util.Arrays;
27 import java.util.List;
28 import java.util.Set;
29
30 import javax.swing.JLabel;
31
32 import uk.ac.qmul.eecs.ccmi.diagrammodel.NodeProperties.Modifiers;
33
34 /**
35 A string that can extend over multiple lines.
36 */
37 public class MultiLineString {
38 /**
39 Constructs an empty, centered, normal size multiline
40 string.
41 */
42 public MultiLineString(){
43 text = "";
44 arrayText = null;
45 justification = CENTER;
46 size = NORMAL;
47 isSingleLine = true;
48 }
49 /**
50 Sets the value of the text property.
51 @param newValue the text of the multiline string
52 */
53 public void setText(String newValue){
54 setText(newValue,null);
55 }
56
57 public void setText(String newValue, ModifierView[] modifierViews) {
58 isSingleLine = true;
59 text = newValue;
60 this.modifierViews = modifierViews;
61 format();
62 }
63
64 public void setText(String[] newValue, Modifiers modifiers){
65 isSingleLine = false;
66 this.modifiers = modifiers;
67 arrayText = newValue;
68 format();
69 }
70
71 public void setBold(boolean bold){
72 isBold = bold;
73 format();
74 }
75 /**
76 Gets the value of the text property.
77 @return the text of the multiline string
78 */
79 public String getText() {
80 if(isSingleLine)
81 return text;
82 else{
83 StringBuilder builder = new StringBuilder("");
84 for(int i=0; i<arrayText.length; i++){
85 builder.append(arrayText[i]);
86 builder.append('\n');
87 }
88 return builder.toString();
89 }
90 }
91 /**
92 Sets the value of the justification property.
93 @param newValue the justification, one of LEFT, CENTER,
94 RIGHT
95 */
96 public void setJustification(int newValue) { justification = newValue; format(); }
97 /**
98 Gets the value of the justification property.
99 @return the justification, one of LEFT, CENTER,
100 RIGHT
101 */
102 public int getJustification() { return justification; }
103 /**
104 Sets the value of the size property.
105 @param newValue the size, one of SMALL, NORMAL, LARGE
106 */
107 public void setSize(int newValue) { size = newValue; format(); }
108 /**
109 Gets the value of the size property.
110 @return the size, one of SMALL, NORMAL, LARGE
111 */
112 public int getSize() { return size; }
113
114 @Override
115 public String toString(){
116 if(isSingleLine)
117 return text.replace('\n', '|');
118 else
119 return getText().replace('\n', '|');
120 }
121
122 private void format(){
123 StringBuffer prefix = new StringBuffer();
124 StringBuffer suffix = new StringBuffer();
125 StringBuffer htmlText = new StringBuffer();
126 prefix.append("&nbsp;");
127 suffix.insert(0, "&nbsp;");
128 if (size == LARGE){
129 prefix.append("<font size=\"+1\">");
130 suffix.insert(0, "</font>");
131 }
132 if (size == SMALL){
133 prefix.append("<font size=\"-1\">");
134 suffix.insert(0, "</font>");
135 }
136
137 htmlText.append("<html>");
138 if(isSingleLine){
139 if(isBold)
140 prefix.append("<b>");
141 htmlText.append(prefix);
142
143 String formattedText = text;
144 if(modifierViews != null){
145 for(ModifierView view : modifierViews){
146 formattedText = formatFromView(formattedText,view);
147 }
148 }
149 htmlText.append(formattedText);
150
151 if(isBold)
152 suffix.insert(0, "</b>");
153 htmlText.append(suffix);
154 }else{ // multi line
155 boolean first = true;
156 for(int i=0; i<arrayText.length; i++){
157 if (first)
158 first = false;
159 else
160 htmlText.append("<br>");
161 htmlText.append(prefix);
162 String textLine = arrayText[i];
163 Set<Integer> indexes = modifiers.getIndexes(i);
164 for(Integer I : indexes){
165 ModifierView view = (ModifierView)modifiers.getView(modifiers.getTypes().get(I));
166 textLine = formatFromView(textLine, view);
167 }
168 htmlText.append(textLine);
169 htmlText.append(suffix);
170 }
171 }
172 htmlText.append("</html>");
173
174 // replace any < that are not followed by {u, i, b, tt, font, br} with &lt;
175 List<String> dontReplace = Arrays.asList(new String[] { "u", "i", "b", "tt", "font", "br" });
176
177 int ltpos = 0;
178 while (ltpos != -1){
179 ltpos = htmlText.indexOf("<", ltpos + 1);
180 if (ltpos != -1 && !(ltpos + 1 < htmlText.length() && htmlText.charAt(ltpos + 1) == '/')){
181 int end = ltpos + 1;
182 while (end < htmlText.length() && Character.isLetter(htmlText.charAt(end))) end++;
183 if (!dontReplace.contains(htmlText.substring(ltpos + 1, end)))
184 htmlText.replace(ltpos, ltpos+1, "&lt;");
185 }
186 }
187
188 label.setText(htmlText.toString());
189 if (justification == LEFT) label.setHorizontalAlignment(JLabel.LEFT);
190 else if (justification == CENTER) label.setHorizontalAlignment(JLabel.CENTER);
191 else if (justification == RIGHT) label.setHorizontalAlignment(JLabel.RIGHT);
192 }
193
194 private String formatFromView(String text, ModifierView view){
195 if(view == null)
196 return text;
197
198 StringBuilder prefix = new StringBuilder("");
199 StringBuilder suffix = new StringBuilder("");
200
201 prefix.append(view.getPrefix());
202 suffix.append(view.getSuffix());
203
204 if(view.isBold()){
205 prefix.insert(0,"<b>");
206 suffix.append("</b>");
207 }
208
209 if(view.isItalic()){
210 prefix.insert(0,"<i>");
211 suffix.append("</i>");
212 }
213
214 if(view.isUnderline()){
215 prefix.insert(0,"<u>");
216 suffix.append("</u>");
217 }
218 return prefix.append(text).append(suffix).toString();
219 }
220
221 /**
222 Gets the bounding rectangle for this multiline string.
223 @param g2 the graphics context
224 @return the bounding rectangle (with top left corner (0,0))
225 */
226 public Rectangle2D getBounds(){
227 if(isSingleLine){
228 if (text.length() == 0)
229 return new Rectangle2D.Double();
230 }else {
231 if(arrayText.length == 0)
232 return new Rectangle2D.Double();
233 }
234 Dimension dim = label.getPreferredSize();
235 return new Rectangle2D.Double(0, 0, dim.getWidth(), dim.getHeight());
236 }
237
238 /**
239 Draws this multiline string inside a given rectangle
240 @param g2 the graphics context
241 @param r the rectangle into which to place this multiline string
242 */
243 public void draw(Graphics2D g2, Rectangle2D r){
244 label.setFont(g2.getFont());
245 label.setBounds(0, 0, (int) r.getWidth(), (int) r.getHeight());
246 g2.translate(r.getX(), r.getY());
247 label.paint(g2);
248 g2.translate(-r.getX(), -r.getY());
249 }
250
251 public static final int LEFT = 0;
252 public static final int CENTER = 1;
253 public static final int RIGHT = 2;
254 public static final int LARGE = 3;
255 public static final int NORMAL = 4;
256 public static final int SMALL = 5;
257
258 private String text;
259 private String[] arrayText;
260 private Modifiers modifiers;
261 private ModifierView[] modifierViews;
262 private int justification;
263 private int size;
264 private boolean isBold;
265 private transient JLabel label = new JLabel();
266 private boolean isSingleLine;
267 }