2 package org.forester.phylogeny.data;
\r
4 import java.awt.Color;
\r
5 import java.awt.Font;
\r
6 import java.io.IOException;
\r
7 import java.io.Writer;
\r
8 import java.util.ArrayList;
\r
9 import java.util.List;
\r
11 import org.forester.phylogeny.data.Property.AppliesTo;
\r
12 import org.forester.util.ForesterUtil;
\r
14 public final class NodeVisualData implements PhylogenyData {
\r
16 public static final String APTX_VISUALIZATION_REF = "style:";
\r
17 public static final int DEFAULT_SIZE = -1;
\r
18 public static final String FONT_COLOR_REF = APTX_VISUALIZATION_REF + "font_color";
\r
19 public static final String FONT_COLOR_TYPE = "xsd:token";
\r
20 public static final String FONT_REF = APTX_VISUALIZATION_REF + "font";
\r
21 public static final String FONT_SIZE_REF = APTX_VISUALIZATION_REF + "font_size";
\r
22 public static final String FONT_SIZE_TYPE = "xsd:unsignedByte";
\r
23 public static final String FONT_STYLE_BOLD = "bold";
\r
24 public static final String FONT_STYLE_BOLD_ITALIC = "bold_italic";
\r
25 public static final String FONT_STYLE_ITALIC = "italic";
\r
26 public static final String FONT_STYLE_PLAIN = "plain";
\r
27 public static final String FONT_STYLE_REF = APTX_VISUALIZATION_REF + "font_style";
\r
28 public static final String FONT_STYLE_TYPE = "xsd:token";
\r
29 public static final String FONT_TYPE = "xsd:token";
\r
30 public static final String NODE_COLOR_REF = APTX_VISUALIZATION_REF + "node_color";
\r
31 public static final String NODE_COLOR_TYPE = "xsd:token";
\r
32 public static final String NODE_FILL_GRADIENT = "gradient";
\r
33 public static final String NODE_FILL_NONE = "none";
\r
34 public static final String NODE_FILL_SOLID = "solid";
\r
35 public static final String NODE_FILL_TYPE_REF = APTX_VISUALIZATION_REF + "node_fill_type";
\r
36 public static final String NODE_FILL_TYPE_TYPE = "xsd:token";
\r
37 public static final String NODE_SHAPE_CIRCLE = "circle";
\r
38 public static final String NODE_SHAPE_RECTANGLE = "rectangle";
\r
39 public static final String NODE_SHAPE_REF = APTX_VISUALIZATION_REF + "node_shape";
\r
40 public static final String NODE_SHAPE_TYPE = "xsd:token";
\r
41 public static final String NODE_SIZE_REF = APTX_VISUALIZATION_REF + "node_size";
\r
42 public static final String NODE_SIZE_TYPE = "xsd:float";
\r
43 public static final String NODE_TRANSPARENCY_REF = APTX_VISUALIZATION_REF + "node_transparency";
\r
44 public static final String NODE_TRANSPARENCY_TYPE = "xsd:float";
\r
45 private static final byte DEFAULT_FONT_SIZE = -1;
\r
46 private static final int DEFAULT_TRANSPARENCY = -1;
\r
47 private NodeFill _fill_type;
\r
49 private Color _font_color;
\r
50 private String _font_name;
\r
51 private byte _font_size;
\r
52 private FontType _font_style;
\r
53 private Color _node_color;
\r
54 private NodeShape _shape;
\r
55 private float _size;
\r
56 private float _transparency;
\r
58 public NodeVisualData() {
\r
62 public NodeVisualData( final String font_name,
\r
63 final FontType font_style,
\r
64 final byte font_size,
\r
65 final Color font_color,
\r
66 final NodeShape shape,
\r
67 final NodeFill fill_type,
\r
68 final Color node_color,
\r
70 final float transparency ) {
\r
71 setFontName( font_name );
\r
72 setFontStyle( font_style );
\r
73 setFontSize( font_size );
\r
74 setFontColor( font_color );
\r
76 setFillType( fill_type );
\r
77 setNodeColor( node_color );
\r
79 setTransparency( transparency );
\r
83 public final StringBuffer asSimpleText() {
\r
88 public final StringBuffer asText() {
\r
89 final StringBuffer sb = new StringBuffer();
\r
94 public final PhylogenyData copy() {
\r
95 return new NodeVisualData( !ForesterUtil.isEmpty( getFontName() ) ? new String( getFontName() ) : null,
\r
98 getFontColor() != null ? new Color( getFontColor().getRed(), getFontColor()
\r
99 .getGreen(), getFontColor().getBlue() ) : null,
\r
102 getNodeColor() != null ? new Color( getNodeColor().getRed(), getNodeColor()
\r
103 .getGreen(), getNodeColor().getBlue() ) : null,
\r
105 getTransparency() );
\r
108 public final NodeFill getFillType() {
\r
112 public final Font getFont() {
\r
113 if ( _font != null ) {
\r
116 else if ( !ForesterUtil.isEmpty( getFontName() ) ) {
\r
117 _font = new Font( getFontName(), getFontStyleInt(), getFontSize() );
\r
123 public final Color getFontColor() {
\r
124 return _font_color;
\r
127 public final String getFontName() {
\r
131 public final byte getFontSize() {
\r
135 public final FontType getFontStyle() {
\r
136 return _font_style;
\r
139 public final int getFontStyleInt() {
\r
140 if ( getFontStyle() == FontType.BOLD ) {
\r
143 else if ( getFontStyle() == FontType.ITALIC ) {
\r
144 return Font.ITALIC;
\r
146 else if ( getFontStyle() == FontType.BOLD_ITALIC ) {
\r
147 return Font.BOLD + Font.ITALIC;
\r
152 public final Color getNodeColor() {
\r
153 return _node_color;
\r
156 public final NodeShape getShape() {
\r
160 public final float getSize() {
\r
164 public final float getTransparency() {
\r
165 return _transparency;
\r
168 public final boolean isEmpty() {
\r
169 return ( ForesterUtil.isEmpty( getFontName() ) && ( getFontStyle() == FontType.PLAIN )
\r
170 && ( getFontSize() == DEFAULT_FONT_SIZE ) && ( getFontColor() == null )
\r
171 && ( getShape() == NodeShape.DEFAULT ) && ( getFillType() == NodeFill.DEFAULT )
\r
172 && ( getNodeColor() == null ) && ( getSize() == DEFAULT_SIZE ) && ( getTransparency() == DEFAULT_TRANSPARENCY ) );
\r
176 public final boolean isEqual( final PhylogenyData data ) {
\r
177 throw new UnsupportedOperationException();
\r
180 public void parseProperty( final Property prop ) {
\r
181 if ( prop.getRef().equals( FONT_REF ) ) {
\r
182 setFontName( prop.getValue().trim() );
\r
184 else if ( prop.getRef().equals( FONT_SIZE_REF ) ) {
\r
187 s = Integer.parseInt( prop.getValue() );
\r
189 catch ( final NumberFormatException e ) {
\r
192 if ( ( s >= 0 ) && ( s < Byte.MAX_VALUE ) ) {
\r
196 else if ( prop.getRef().equals( FONT_STYLE_REF ) ) {
\r
197 setFontStyle( prop.getValue() );
\r
199 else if ( prop.getRef().equals( FONT_COLOR_REF ) ) {
\r
201 setFontColor( Color.decode( prop.getValue() ) );
\r
203 catch ( final NumberFormatException e ) {
\r
207 else if ( prop.getRef().equals( NODE_SIZE_REF ) ) {
\r
210 s = Float.parseFloat( prop.getValue() );
\r
212 catch ( final NumberFormatException e ) {
\r
219 else if ( prop.getRef().equals( NODE_COLOR_REF ) ) {
\r
221 setNodeColor( Color.decode( prop.getValue() ) );
\r
223 catch ( final NumberFormatException e ) {
\r
227 else if ( prop.getRef().equals( NODE_SHAPE_REF ) ) {
\r
228 setShape( prop.getValue() );
\r
230 else if ( prop.getRef().equals( NODE_FILL_TYPE_REF ) ) {
\r
231 setFillType( prop.getValue() );
\r
235 public final void setFillType( final NodeFill fill_type ) {
\r
236 _fill_type = fill_type;
\r
239 public final void setFillType( final String fill ) {
\r
240 if ( fill.equalsIgnoreCase( NODE_FILL_NONE ) ) {
\r
241 setFillType( NodeFill.NONE );
\r
243 else if ( fill.equalsIgnoreCase( NODE_FILL_SOLID ) ) {
\r
244 setFillType( NodeFill.SOLID );
\r
246 else if ( fill.equalsIgnoreCase( NODE_FILL_GRADIENT ) ) {
\r
247 setFillType( NodeFill.GRADIENT );
\r
250 setFillType( NodeFill.DEFAULT );
\r
254 public final void setFontColor( final Color font_color ) {
\r
255 _font_color = font_color;
\r
258 public final void setFontName( final String font_name ) {
\r
259 if ( !ForesterUtil.isEmpty( font_name ) ) {
\r
260 _font_name = font_name;
\r
268 public final void setFontSize( final int font_size ) {
\r
269 if ( ( font_size != DEFAULT_FONT_SIZE ) && ( font_size < 0 ) ) {
\r
270 throw new IllegalArgumentException( "negative font size: " + font_size );
\r
272 else if ( font_size > Byte.MAX_VALUE ) {
\r
273 throw new IllegalArgumentException( "font size is too large: " + font_size );
\r
275 _font_size = ( byte ) font_size;
\r
279 public final void setFontStyle( final FontType font_style ) {
\r
280 _font_style = font_style;
\r
284 public final void setFontStyle( final int font_style ) {
\r
285 if ( ( font_style == ( Font.BOLD + Font.ITALIC ) ) ) {
\r
286 setFontStyle( FontType.BOLD_ITALIC );
\r
288 else if ( font_style == Font.ITALIC ) {
\r
289 setFontStyle( FontType.ITALIC );
\r
291 else if ( font_style == Font.BOLD ) {
\r
292 setFontStyle( FontType.BOLD );
\r
295 setFontStyle( FontType.PLAIN );
\r
299 public final void setFontStyle( final String font_style ) {
\r
300 if ( font_style.equalsIgnoreCase( FONT_STYLE_BOLD ) ) {
\r
301 setFontStyle( FontType.BOLD );
\r
303 else if ( font_style.equalsIgnoreCase( FONT_STYLE_ITALIC ) ) {
\r
304 setFontStyle( FontType.ITALIC );
\r
306 else if ( font_style.equalsIgnoreCase( FONT_STYLE_BOLD_ITALIC ) ) {
\r
307 setFontStyle( FontType.BOLD_ITALIC );
\r
310 setFontStyle( FontType.PLAIN );
\r
314 public final void setNodeColor( final Color node_color ) {
\r
315 _node_color = node_color;
\r
318 public final void setShape( final NodeShape shape ) {
\r
322 public final void setShape( final String shape ) {
\r
323 if ( shape.equalsIgnoreCase( NODE_SHAPE_CIRCLE ) ) {
\r
324 setShape( NodeShape.CIRCLE );
\r
326 else if ( shape.equalsIgnoreCase( NODE_SHAPE_RECTANGLE ) ) {
\r
327 setShape( NodeShape.RECTANGLE );
\r
330 setShape( NodeShape.DEFAULT );
\r
334 public final void setSize( final float size ) {
\r
335 if ( ( size != DEFAULT_SIZE ) && ( size < 0 ) ) {
\r
336 throw new IllegalArgumentException( "negative size: " + size );
\r
341 public final void setTransparency( final float transparency ) {
\r
342 _transparency = transparency;
\r
346 public final StringBuffer toNHX() {
\r
347 throw new UnsupportedOperationException();
\r
351 public final void toPhyloXML( final Writer writer, final int level, final String indentation ) throws IOException {
\r
352 for( final Property p : toProperties() ) {
\r
353 p.toPhyloXML( writer, level, indentation );
\r
358 public final String toString() {
\r
359 return asText().toString();
\r
362 private String colorToHex( final Color c ) {
\r
363 return String.format( "#%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue() );
\r
366 private final void init() {
\r
367 setFontName( null );
\r
368 setFontStyle( FontType.PLAIN );
\r
369 setFontSize( DEFAULT_FONT_SIZE );
\r
370 setFontColor( null );
\r
371 setShape( NodeShape.DEFAULT );
\r
372 setFillType( NodeFill.DEFAULT );
\r
373 setNodeColor( null );
\r
374 setSize( DEFAULT_SIZE );
\r
375 setTransparency( DEFAULT_TRANSPARENCY );
\r
379 private final List<Property> toProperties() {
\r
380 final List<Property> properties = new ArrayList<Property>();
\r
381 if ( !ForesterUtil.isEmpty( getFontName() ) ) {
\r
382 properties.add( new Property( FONT_REF, getFontName(), "", FONT_TYPE, AppliesTo.NODE ) );
\r
384 if ( getFontSize() != DEFAULT_FONT_SIZE ) {
\r
385 properties.add( new Property( FONT_SIZE_REF,
\r
386 String.valueOf( getFontSize() ),
\r
389 AppliesTo.NODE ) );
\r
391 if ( getFontStyle() != FontType.PLAIN ) {
\r
392 String font_style = "";
\r
393 if ( getFontStyle() == FontType.ITALIC ) {
\r
394 font_style = FONT_STYLE_ITALIC;
\r
396 else if ( getFontStyle() == FontType.BOLD ) {
\r
397 font_style = FONT_STYLE_BOLD;
\r
399 else if ( getFontStyle() == FontType.BOLD_ITALIC ) {
\r
400 font_style = FONT_STYLE_BOLD_ITALIC;
\r
403 throw new RuntimeException( "unknown font style" + getShape() );
\r
405 properties.add( new Property( FONT_STYLE_REF, font_style, "", FONT_STYLE_TYPE, AppliesTo.NODE ) );
\r
407 if ( getFontColor() != null ) {
\r
408 properties.add( new Property( FONT_COLOR_REF,
\r
409 colorToHex( getFontColor() ),
\r
412 AppliesTo.NODE ) );
\r
414 if ( getShape() != NodeShape.DEFAULT ) {
\r
415 String shape = null;
\r
416 if ( getShape() == NodeShape.RECTANGLE ) {
\r
417 shape = NODE_SHAPE_RECTANGLE;
\r
419 else if ( getShape() == NodeShape.CIRCLE ) {
\r
420 shape = NODE_SHAPE_CIRCLE;
\r
423 throw new RuntimeException( "unknown node shape" + getShape() );
\r
425 properties.add( new Property( NODE_SHAPE_REF, shape, "", NODE_SHAPE_TYPE, AppliesTo.NODE ) );
\r
427 if ( getSize() != DEFAULT_SIZE ) {
\r
428 properties.add( new Property( NODE_SIZE_REF,
\r
429 String.valueOf( getSize() ),
\r
432 AppliesTo.NODE ) );
\r
434 if ( getNodeColor() != null ) {
\r
435 properties.add( new Property( NODE_COLOR_REF,
\r
436 colorToHex( getNodeColor() ),
\r
439 AppliesTo.NODE ) );
\r
441 if ( getFillType() != NodeFill.DEFAULT ) {
\r
442 String fill = null;
\r
443 if ( getFillType() == NodeFill.GRADIENT ) {
\r
444 fill = NODE_FILL_GRADIENT;
\r
446 else if ( getFillType() == NodeFill.NONE ) {
\r
447 fill = NODE_FILL_NONE;
\r
449 else if ( getFillType() == NodeFill.SOLID ) {
\r
450 fill = NODE_FILL_SOLID;
\r
453 throw new RuntimeException( "unknown fill type " + getFillType() );
\r
455 properties.add( new Property( NODE_FILL_TYPE_REF, fill, "", NODE_FILL_TYPE_TYPE, AppliesTo.NODE ) );
\r
457 if ( getTransparency() != DEFAULT_TRANSPARENCY ) {
\r
458 properties.add( new Property( NODE_TRANSPARENCY_REF,
\r
459 String.valueOf( getTransparency() ),
\r
461 NODE_TRANSPARENCY_TYPE,
\r
462 AppliesTo.NODE ) );
\r
467 public enum FontType {
\r
468 BOLD, BOLD_ITALIC, ITALIC, PLAIN
\r
471 public enum NodeFill {
\r
472 DEFAULT, GRADIENT, NONE, SOLID
\r
475 public enum NodeShape {
\r
476 CIRCLE, DEFAULT, RECTANGLE
\r