1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sourceforge.jeuclid.swing;
20
21 import java.awt.Color;
22 import java.awt.Font;
23 import java.io.IOException;
24 import java.util.Arrays;
25 import java.util.Collections;
26 import java.util.List;
27 import java.util.Map;
28
29 import javax.swing.JComponent;
30 import javax.swing.SwingConstants;
31 import javax.swing.UIManager;
32 import javax.xml.parsers.ParserConfigurationException;
33
34 import net.sourceforge.jeuclid.DOMBuilder;
35 import net.sourceforge.jeuclid.MathMLParserSupport;
36 import net.sourceforge.jeuclid.MathMLSerializer;
37 import net.sourceforge.jeuclid.MutableLayoutContext;
38 import net.sourceforge.jeuclid.context.LayoutContextImpl;
39 import net.sourceforge.jeuclid.context.Parameter;
40 import net.sourceforge.jeuclid.elements.generic.DocumentElement;
41 import net.sourceforge.jeuclid.elements.support.ClassLoaderSupport;
42
43 import org.apache.commons.logging.Log;
44 import org.apache.commons.logging.LogFactory;
45 import org.w3c.dom.Document;
46 import org.w3c.dom.Node;
47 import org.xml.sax.SAXException;
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 public final class JMathComponent extends JComponent implements
70 SwingConstants {
71
72 private static final String FONT_SEPARATOR = ",";
73
74
75
76
77 private static final Log LOGGER = LogFactory.getLog(JMathComponent.class);
78
79
80 private static final long serialVersionUID = 1L;
81
82 private static String uiClassId;
83
84 private static Class<?> mathComponentUIClass;
85
86 private Node document;
87
88 private int horizontalAlignment = SwingConstants.CENTER;
89
90 private final MutableLayoutContext parameters = new LayoutContextImpl(
91 LayoutContextImpl.getDefaultLayoutContext());
92
93 private int verticalAlignment = SwingConstants.CENTER;
94
95
96
97
98 private final CursorListener cursorListener;
99
100
101
102
103 public JMathComponent() {
104 this(null);
105 }
106
107
108
109
110
111
112
113 public JMathComponent(final CursorListener listener) {
114 this.cursorListener = listener;
115
116 final JMathComponentMouseListener mouseListener = new JMathComponentMouseListener(
117 this);
118 this.addMouseListener(mouseListener);
119
120 this.updateUI();
121 this.fontCompat();
122 this.setDocument(new DocumentElement());
123 }
124
125
126
127
128
129
130 public CursorListener getCursorListener() {
131 return this.cursorListener;
132 }
133
134
135
136
137 private void fontCompat() {
138 final String fontName = this.getFontsSerif().split(
139 JMathComponent.FONT_SEPARATOR)[0];
140 final float fontSize = this.getFontSize();
141 super.setFont(new Font(fontName, 0, (int) fontSize));
142 }
143
144
145
146
147
148
149
150
151
152
153 public String getContent() {
154 return MathMLSerializer.serializeDocument(this.getDocument(), false,
155 false);
156 }
157
158
159
160
161 public Node getDocument() {
162 return this.document;
163 }
164
165 private static String join(final List<String> list) {
166 boolean first = true;
167 final StringBuilder b = new StringBuilder();
168 for (final String s : list) {
169 if (first) {
170 first = false;
171 } else {
172 b.append(JMathComponent.FONT_SEPARATOR);
173 }
174 b.append(s);
175 }
176 return b.toString();
177 }
178
179
180
181
182
183
184
185
186
187 @SuppressWarnings("unchecked")
188 public String getFontsDoublestruck() {
189 return JMathComponent.join((List<String>) this.parameters
190 .getParameter(Parameter.FONTS_DOUBLESTRUCK));
191 }
192
193
194
195
196
197
198
199
200 @SuppressWarnings("unchecked")
201 public String getFontsFraktur() {
202 return JMathComponent.join((List<String>) this.parameters
203 .getParameter(Parameter.FONTS_FRAKTUR));
204 }
205
206
207
208
209 public float getFontSize() {
210 return (Float) this.parameters.getParameter(Parameter.MATHSIZE);
211 }
212
213
214
215
216
217
218
219
220 @SuppressWarnings("unchecked")
221 public String getFontsMonospaced() {
222 return JMathComponent.join((List<String>) this.parameters
223 .getParameter(Parameter.FONTS_MONOSPACED));
224 }
225
226
227
228
229
230
231
232
233 @SuppressWarnings("unchecked")
234 public String getFontsSanserif() {
235 return JMathComponent.join((List<String>) this.parameters
236 .getParameter(Parameter.FONTS_SANSSERIF));
237 }
238
239
240
241
242
243
244
245
246 @SuppressWarnings("unchecked")
247 public String getFontsScript() {
248 return JMathComponent.join((List<String>) this.parameters
249 .getParameter(Parameter.FONTS_SCRIPT));
250 }
251
252
253
254
255
256
257
258
259 @SuppressWarnings("unchecked")
260 public String getFontsSerif() {
261 return JMathComponent.join((List<String>) this.parameters
262 .getParameter(Parameter.FONTS_SERIF));
263 }
264
265
266 @Override
267 public Color getForeground() {
268 return (Color) this.parameters.getParameter(Parameter.MATHCOLOR);
269 }
270
271
272
273
274
275
276
277
278
279
280
281
282 public int getHorizontalAlignment() {
283 return this.horizontalAlignment;
284 }
285
286
287
288
289 public MathComponentUI getUI() {
290 return (MathComponentUI) this.ui;
291 }
292
293
294
295
296 @Override
297 public String getUIClassID() {
298 return JMathComponent.uiClassId;
299 }
300
301
302
303
304
305
306
307
308
309
310
311 public int getVerticalAlignment() {
312 return this.verticalAlignment;
313 }
314
315 private void reval() {
316 this.repaint();
317 this.revalidate();
318 }
319
320
321 @Override
322 public void setBackground(final Color c) {
323 super.setBackground(c);
324 this.reval();
325 }
326
327
328
329
330
331
332
333 public void setContent(final String contentString) {
334 try {
335 final Document stdDomNode = MathMLParserSupport.parseString(contentString);
336 final DocumentElement jEuclidDom = DOMBuilder.getInstance().createJeuclidDom(stdDomNode,
337 true, true);
338 this.setDocument(jEuclidDom);
339 } catch (final SAXException e) {
340 throw new IllegalArgumentException(e);
341 } catch (final ParserConfigurationException e) {
342 throw new IllegalArgumentException(e);
343 } catch (final IOException e) {
344 throw new IllegalArgumentException(e);
345 }
346
347 }
348
349
350
351
352
353
354
355 public void setDebug(final boolean dbg) {
356 this.setParameter(Parameter.DEBUG, dbg);
357 }
358
359
360
361
362
363 public void setDocument(final Node doc) {
364 final Node oldValue = this.document;
365 this.firePropertyChange("document", oldValue, doc);
366 this.document = doc;
367 if (doc != oldValue) {
368 this.revalidate();
369 this.repaint();
370 }
371 }
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387 @Deprecated
388 @Override
389 public void setFont(final Font f) {
390 super.setFont(f);
391 this.setFontSize(f.getSize2D());
392 this.setFontsSerif(f.getFamily() + JMathComponent.FONT_SEPARATOR
393 + this.getFontsSerif());
394 }
395
396 private List<String> splitFonts(final String list) {
397 return Arrays.asList(list.split(JMathComponent.FONT_SEPARATOR));
398 }
399
400
401
402
403
404
405
406
407
408
409 public void setFontsDoublestruck(final String newFonts) {
410 this.setParameter(Parameter.FONTS_DOUBLESTRUCK, this
411 .splitFonts(newFonts));
412 }
413
414
415
416
417
418
419
420
421
422 public void setFontsFraktur(final String newFonts) {
423 this.setParameter(Parameter.FONTS_FRAKTUR, this.splitFonts(newFonts));
424 }
425
426
427
428
429
430
431
432
433
434 public void setParameter(final Parameter key, final Object newValue) {
435 this.setParameters(Collections.singletonMap(key, newValue));
436 }
437
438
439
440
441
442
443
444 public void setParameters(final Map<Parameter, Object> newValues) {
445 for (final Map.Entry<Parameter, Object> entry : newValues.entrySet()) {
446 final Parameter key = entry.getKey();
447 final Object oldValue = this.parameters.getParameter(key);
448 this.parameters.setParameter(key, entry.getValue());
449 this.firePropertyChange(key.name(), oldValue, this.parameters
450 .getParameter(key));
451 }
452 this.revalidate();
453 this.repaint();
454 }
455
456
457
458
459
460
461
462 public void setFontSize(final float fontSize) {
463 this.setParameter(Parameter.MATHSIZE, fontSize);
464 }
465
466
467
468
469
470
471
472
473
474 public void setFontsMonospaced(final String newFonts) {
475 this.setParameter(Parameter.FONTS_MONOSPACED, this
476 .splitFonts(newFonts));
477 }
478
479
480
481
482
483
484
485
486
487 public void setFontsSanserif(final String newFonts) {
488 this.setParameter(Parameter.FONTS_SANSSERIF, this
489 .splitFonts(newFonts));
490 }
491
492
493
494
495
496
497
498
499
500 public void setFontsScript(final String newFonts) {
501 this.setParameter(Parameter.FONTS_SCRIPT, this.splitFonts(newFonts));
502 }
503
504
505
506
507
508
509
510
511
512 public void setFontsSerif(final String newFonts) {
513 this.setParameter(Parameter.FONTS_SERIF, this.splitFonts(newFonts));
514 this.fontCompat();
515 }
516
517
518 @Override
519 public void setForeground(final Color fg) {
520 super.setForeground(fg);
521 this.setParameter(Parameter.MATHCOLOR, fg);
522 }
523
524
525
526
527
528
529
530
531
532
533
534
535
536 public void setHorizontalAlignment(final int hAlignment) {
537 this.horizontalAlignment = hAlignment;
538 }
539
540
541 @Override
542 public void setOpaque(final boolean opaque) {
543 super.setOpaque(opaque);
544 this.reval();
545 }
546
547
548
549
550
551
552
553
554
555
556
557
558 public void setVerticalAlignment(final int vAlignment) {
559 this.verticalAlignment = vAlignment;
560 }
561
562
563 @Override
564 public void updateUI() {
565 if (UIManager.get(this.getUIClassID()) == null) {
566 try {
567 this
568 .setUI((MathComponentUI) JMathComponent.mathComponentUIClass
569 .newInstance());
570 } catch (final InstantiationException e) {
571 JMathComponent.LOGGER.warn(e.getMessage());
572 } catch (final IllegalAccessException e) {
573 JMathComponent.LOGGER.warn(e.getMessage());
574 }
575 } else {
576 this.setUI(UIManager.getUI(this));
577 }
578 }
579
580
581
582
583 public MutableLayoutContext getParameters() {
584 return this.parameters;
585 }
586
587
588 @Override
589 public void setSize(final int width, final int height) {
590
591 super.setSize(width, height);
592 }
593
594 static {
595 Class<?> uiClass;
596 String id;
597 try {
598 uiClass = ClassLoaderSupport.getInstance().loadClass(
599 "net.sourceforge.jeuclid.swing.MathComponentUI16");
600 id = "MathComponentUI16";
601 } catch (final ClassNotFoundException t) {
602 uiClass = MathComponentUI.class;
603 id = "MathComponentUI";
604 }
605 JMathComponent.uiClassId = id;
606 JMathComponent.mathComponentUIClass = uiClass;
607 }
608
609 }