JRobin显示中文及位置偏移的问题

JRobin的默认字体,不直接中文,要显示中文可以对字体做这样的设置(JRobin1.4)

graphDef.setDefaultFont(new Font("monospaced", Font.PLAIN, 11));
		graphDef.setTitleFont(new Font("SansSerif", Font.BOLD, 14));
 

但是使用RrdGraphDef的line方法,legend的值中含中文时,会发生错位的现象。

public void line( String sourceName, Color color, String legend )
 

产生的原因为,JRboin把在同一行的legend拼成一个字符串,进行绘图,而把legend前面的颜色方框分别绘制,颜色方框的x位置,是根据legend的length和计算的;英文字符的宽度大概相关于字体高的0.5倍,而汉字宽度则大于这个倍数,作者没有考虑中文的问题;所以计算出来的位置不正确。


简单解法:

//中文字符个数+1,中文比英文字符多出来的宽度
				int cnChars = 0;
				char[] charArray = tmpStr.toString().toCharArray();  
				for(int k=0; k<charArray.length;k++){  
				   if ((charArray[k] >= 0x4e00)&&(charArray[k] <= 0x9fbb)){  
					   cnChars++;
				   }       
				}  
				cnChars = (int)(cnChars*0.88);
				markerList.addLast( new LegendMarker( (tmpStr.length()+ cnChars) * nfont_width, ((Legend) clist[i]).getColor() ) );
//上面是对源码的修改
				tmpStr.append( "   " );		// Add 3 spaces where the mark will be
 

 

 

均分各列

LinkedList markerList = new LinkedList();

//add		
LinkedList legendList = new LinkedList();

...

if ( clist[i].commentType == Comment.CMT_LEGEND ) 
			{								
				markerList.addLast( new LegendMarker( tmpStr.length() * nfont_width, ((Legend) clist[i]).getColor() ) );
				tmpStr.append( "   " );		// Add 3 spaces where the mark will be
			} 
			else {
				if ( clist[i].commentType == Comment.CMT_GPRINT )
				{
					((Gprint) clist[i]).setValue( sources, sourceIndex, valueFormat );
				}				
				markerList.addLast( null );				
			}
 ...

ArrayList tknpairs = clist[i].getTokens();			
			
			//add 
			if (tknpairs.size() >0){		
				String legend = (String) tknpairs.get(0);
				if ( clist[i].trimString() )
					legendList.addLast(legend.trim());
				else
					legendList.addLast(legend);
			}

...

//替换graphString( g, tmpStr.toString(), posx, posy );到while循环的代码
tmpStr		= new StringBuffer(""); 
					drawText	= false;

					if (!markerList.isEmpty()){
						//一行有几个legend
						int legendCols = markerList.size();
						//两边分别离posx宽的间距,再均分每个legend的间距
						int legendWidth = (imgWidth - posx*2)/legendCols;
						
						int currentCol = 0;
						// Plot the markers	
						while ( !markerList.isEmpty() ) {										
							//绘制颜色方框
							LegendMarker lm = (LegendMarker) markerList.removeFirst();
							//方框的起始位置
							int startPosx = posx + currentCol*legendWidth;					
							g.setColor( lm.getColor() );
							g.fillRect( startPosx, posy - 9, 10, 10 );
							g.setColor( normalFontColor );
							g.drawRect( startPosx, posy - 9, 10, 10 );
							//绘制legend,颜色方框的宽度约为12
							String legend = (String) legendList.removeFirst();
							graphString( g, legend , startPosx + 12, posy );
							
							currentCol++;
						}
					}

 

紧凑排列

//其他代码与均无各列的相同
if (!markerList.isEmpty()){				
						// Plot the markers	
						int startPosx = posx;
						while ( !markerList.isEmpty() ) {										
							//绘制颜色方框
							LegendMarker lm = (LegendMarker) markerList.removeFirst();
							//方框的起始位置										
							g.setColor( lm.getColor() );
							g.fillRect( startPosx, posy - 9, 10, 10 );
							g.setColor( normalFontColor );
							g.drawRect( startPosx, posy - 9, 10, 10 );
							//绘制legend,颜色方框的宽度约为12
							String legend = (String) legendList.removeFirst();
							int legendStartPosx = startPosx + 12;
							graphString( g, legend , legendStartPosx, posy );							
							
							char[] charArray = legend.toCharArray();  
							//中文字符个数+1,中文是英文字符宽度的两倍
							int cnChars = 1;
							for(int k=0; k<charArray.length;k++){  
							   if ((charArray[k] >= 0x4e00)&&(charArray[k] <= 0x9fbb)){  
								   cnChars++;
							   }       
							}  
							//下一个方框开始的位置为,本legend的起始位置加上legned文字的宽度
							startPosx = legendStartPosx + (legend.length()+ cnChars)*nfont_width;					
						}
					}		
 

 

 

 

原代码如下:

private void plotComments( Graphics2D g ) throws RrdException
	{
		if ( !graphDef.showLegend() ) return;
		
		LinkedList markerList = new LinkedList();
		
		// Position the cursor just below the chart area
		int posy			= y_offset + chartHeight + CHART_UPADDING + CHART_BPADDING + ( graphDef.showMajorGridX() ? nfont_height : 0 );
		int posx			= LBORDER_SPACE;

		g.setColor( normalFontColor );
		g.setFont( normal_font );
		
		Comment[] clist		= graphDef.getComments();
		StringBuffer tmpStr	= new StringBuffer("");

		boolean newLine		= false;
		boolean drawText	= false;
		
		for (int i = 0; i < clist.length; i++)
		{
			if ( clist[i].commentType == Comment.CMT_LEGEND ) 
			{
				markerList.addLast( new LegendMarker( tmpStr.length() * nfont_width, ((Legend) clist[i]).getColor() ) );
				tmpStr.append( "   " );		// Add 3 spaces where the mark will be
			} 
			else if ( clist[i].commentType == Comment.CMT_GPRINT )
				((Gprint) clist[i]).setValue( sources, sourceIndex, valueFormat );
			
			ArrayList tknpairs = clist[i].getTokens();
			
			for (int j = 0; j < tknpairs.size(); j++)
			{
				String str 	= (String) tknpairs.get(j++);
				Byte tkn	= (Byte) tknpairs.get(j);
				
				if ( clist[i].trimString() )
					tmpStr.append( str.trim() );
				else
					tmpStr.append( str );
					
				if ( tkn != Comment.TKN_NULL )
				{
					drawText = true;
					if ( tkn == Comment.TKN_ALF ) {
						newLine	= true;
						posx	= LBORDER_SPACE;					
					} 
					else if ( tkn == Comment.TKN_ARF ) {
						newLine	= true;
						posx 	= imgWidth - RBORDER_SPACE - (tmpStr.length() * nfont_width);
					}
					else if ( tkn == Comment.TKN_ACF ) {
						newLine	= true;
						posx 	= imgWidth / 2 - (tmpStr.length() * nfont_width) / 2;
					}
					else if ( tkn == Comment.TKN_AL )
						posx	= LBORDER_SPACE;
					else if ( tkn == Comment.TKN_AR )
						posx 	= imgWidth - RBORDER_SPACE - (tmpStr.length() * nfont_width);
					else if ( tkn == Comment.TKN_AC )
						posx 	= imgWidth / 2 - (tmpStr.length() * nfont_width) / 2;
				}
				
				if ( !newLine && clist[i].addSpacer() )
					tmpStr.append( SPACER );
								
				// Plot the string
				if ( drawText ) {
					
					graphString( g, tmpStr.toString(), posx, posy );
					tmpStr		= new StringBuffer(""); 
					drawText	= false;

					// Plot the markers	
					while ( !markerList.isEmpty() ) {
						LegendMarker lm = (LegendMarker) markerList.removeFirst();
						g.setColor( lm.getColor() );
						g.fillRect( posx + lm.getXPosition(), posy - 9, 10, 10 );
						g.setColor( normalFontColor );
						g.drawRect( posx + lm.getXPosition(), posy - 9, 10, 10 );
					}
				}
				
				if ( newLine ) {
					posy 	+= nfont_height + LINE_PADDING;
					newLine	= false;
				}
				
			}
		}
		
		if ( tmpStr.length() > 0)
		{
			posx		= LBORDER_SPACE;
			graphString( g, tmpStr.toString(), posx, posy );
			tmpStr		= new StringBuffer(""); 
			drawText	= false;

			// Plot the markers	
			while ( !markerList.isEmpty() ) {
				LegendMarker lm = (LegendMarker) markerList.removeFirst();
				g.setColor( lm.getColor() );
				g.fillRect( posx + lm.getXPosition(), posy - 9, 10, 10 );
				g.setColor( normalFontColor );
				g.drawRect( posx + lm.getXPosition(), posy - 9, 10, 10 );
			}			
		}
	}
 

 

 

 

你可能感兴趣的:(J#)