1 /************************************************************************* 2 * 3 * The Contents of this file are made available subject to the terms of 4 * the BSD license. 5 * 6 * Copyright 2000, 2010 Oracle and/or its affiliates. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of Sun Microsystems, Inc. nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 30 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 31 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 *************************************************************************/ 34 35 // base classes 36 import com.sun.star.uno.XInterface; 37 import com.sun.star.uno.UnoRuntime; 38 import com.sun.star.uno.Type; 39 import com.sun.star.container.XIndexAccess; 40 import com.sun.star.lib.uno.helper.WeakBase; 41 42 // factories 43 import com.sun.star.lang.XMultiServiceFactory; 44 import com.sun.star.lang.XSingleServiceFactory; 45 46 // graphics stuff 47 import com.sun.star.drawing.*; 48 import com.sun.star.awt.Point; 49 import com.sun.star.awt.Rectangle; 50 import com.sun.star.awt.Size; 51 52 // chart stuff 53 import com.sun.star.chart.*; 54 55 // property access 56 import com.sun.star.beans.*; 57 58 // Add-In stuff 59 import com.sun.star.lang.XInitialization; 60 import com.sun.star.util.XRefreshable; 61 import com.sun.star.lang.XServiceName; 62 import com.sun.star.lang.XServiceInfo; 63 import com.sun.star.lang.XTypeProvider; 64 65 // Exceptions 66 import com.sun.star.uno.Exception; 67 import com.sun.star.uno.RuntimeException; 68 69 import javax.swing.JOptionPane; 70 71 public class JavaSampleChartAddIn extends WeakBase implements 72 XInitialization, 73 XRefreshable, 74 XDiagram, 75 XServiceName, 76 XServiceInfo 77 { 78 public JavaSampleChartAddIn() 79 {} 80 81 // __________ interface methods __________ 82 83 // XInitialization 84 public void initialize( Object[] aArguments ) 85 throws Exception, RuntimeException 86 { 87 if( aArguments.length > 0 ) 88 { 89 maChartDocument = (XChartDocument) UnoRuntime.queryInterface( 90 XChartDocument.class, aArguments[ 0 ]); 91 92 XPropertySet aDocProp = (XPropertySet) UnoRuntime.queryInterface( 93 XPropertySet.class, maChartDocument ); 94 if( aDocProp != null ) 95 { 96 // set base diagram which will be extended in refresh() 97 aDocProp.setPropertyValue( "BaseDiagram", "com.sun.star.chart.XYDiagram" ); 98 } 99 100 // get the draw page 101 XDrawPageSupplier aPageSupp = (XDrawPageSupplier) UnoRuntime.queryInterface( 102 XDrawPageSupplier.class, maChartDocument ); 103 if( aPageSupp != null ) 104 maDrawPage = (XDrawPage) UnoRuntime.queryInterface( 105 XDrawPage.class, aPageSupp.getDrawPage() ); 106 107 // get a factory for creating shapes 108 maShapeFactory = (XMultiServiceFactory) UnoRuntime.queryInterface( 109 XMultiServiceFactory.class, maChartDocument ); 110 } 111 } 112 113 // XRefreshable 114 public void refresh() throws RuntimeException 115 { 116 // recycle shapes in first call, if document was loaded 117 if( maBottomLine == null || 118 maTopLine == null ) 119 { 120 // try to recycle loaded shapes 121 XPropertySet aDocProp = (XPropertySet) UnoRuntime.queryInterface( 122 XPropertySet.class, maChartDocument ); 123 if( aDocProp != null ) 124 { 125 try 126 { 127 XIndexAccess aShapesIA = (XIndexAccess) UnoRuntime.queryInterface( 128 XIndexAccess.class, aDocProp.getPropertyValue( "AdditionalShapes" )); 129 if( aShapesIA != null && 130 aShapesIA.getCount() > 0 ) 131 { 132 XShape aShape; 133 String aName; 134 for( int i = aShapesIA.getCount() - 1; i >= 0; --i ) 135 { 136 aShape = (XShape) UnoRuntime.queryInterface( 137 XShape.class, aShapesIA.getByIndex( i )); 138 if( aShape != null ) 139 { 140 XPropertySet aProp = (XPropertySet) UnoRuntime.queryInterface( 141 XPropertySet.class, aShape ); 142 aName = (String) aProp.getPropertyValue( "Name" ); 143 144 if( aName.equals( "top" )) 145 { 146 maTopLine = aShape; 147 } 148 else if( aName.equals( "bottom" )) 149 { 150 maBottomLine = aShape; 151 } 152 } 153 } 154 } 155 } 156 catch( Exception ex ) 157 { 158 JOptionPane.showMessageDialog( null, ex, "Exception caught", JOptionPane.WARNING_MESSAGE ); 159 } 160 } 161 } 162 163 // create top line if it does not yet exist 164 try 165 { 166 if( maTopLine == null ) 167 { 168 maTopLine = (XShape) UnoRuntime.queryInterface( 169 XShape.class, maShapeFactory.createInstance( "com.sun.star.drawing.LineShape" )); 170 maDrawPage.add( maTopLine ); 171 172 // make line red and thicker 173 XPropertySet aShapeProp = (XPropertySet) UnoRuntime.queryInterface( 174 XPropertySet.class, maTopLine ); 175 176 aShapeProp.setPropertyValue( "LineColor", new Integer( 0xe01010 )); 177 aShapeProp.setPropertyValue( "LineWidth", new Integer( 50 )); 178 aShapeProp.setPropertyValue( "Name", "top" ); 179 } 180 } 181 catch( Exception ex ) 182 { 183 JOptionPane.showMessageDialog( null, ex, "Exception caught", JOptionPane.WARNING_MESSAGE ); 184 } 185 186 // create bottom line if it does not yet exist 187 try 188 { 189 if( maBottomLine == null ) 190 { 191 maBottomLine = (XShape) UnoRuntime.queryInterface( 192 XShape.class, maShapeFactory.createInstance( "com.sun.star.drawing.LineShape" )); 193 maDrawPage.add( maBottomLine ); 194 195 // make line green and thicker 196 XPropertySet aShapeProp = (XPropertySet) UnoRuntime.queryInterface( 197 XPropertySet.class, maBottomLine ); 198 199 aShapeProp.setPropertyValue( "LineColor", new Integer( 0x10e010 )); 200 aShapeProp.setPropertyValue( "LineWidth", new Integer( 50 )); 201 aShapeProp.setPropertyValue( "Name", "bottom" ); 202 } 203 } 204 catch( Exception ex ) 205 { 206 JOptionPane.showMessageDialog( null, ex, "Exception caught", JOptionPane.WARNING_MESSAGE ); 207 } 208 209 if( maTopLine == null || 210 maBottomLine == null ) 211 { 212 JOptionPane.showMessageDialog( null, "One of the lines is still null", "Assertion", JOptionPane.WARNING_MESSAGE ); 213 return; 214 } 215 216 // position lines 217 // -------------- 218 219 // get data 220 XChartDataArray aDataArray = (XChartDataArray) UnoRuntime.queryInterface( 221 XChartDataArray.class, maChartDocument.getData()); 222 double aData[][] = aDataArray.getData(); 223 224 // get axes 225 XDiagram aDiagram = maChartDocument.getDiagram(); 226 XShape aXAxis = (XShape) UnoRuntime.queryInterface( 227 XShape.class, ((XAxisXSupplier) UnoRuntime.queryInterface( 228 XAxisXSupplier.class, aDiagram )).getXAxis() ); 229 XShape aYAxis = (XShape) UnoRuntime.queryInterface( 230 XShape.class, ((XAxisYSupplier) UnoRuntime.queryInterface( 231 XAxisYSupplier.class, aDiagram )).getYAxis() ); 232 233 // calculate points for hull 234 final int nLength = aData.length; 235 int i, j; 236 double fMax, fMin; 237 238 Point aMaxPtSeq[][] = new Point[ 1 ][]; 239 aMaxPtSeq[ 0 ] = new Point[ nLength ]; 240 Point aMinPtSeq[][] = new Point[ 1 ][]; 241 aMinPtSeq[ 0 ] = new Point[ nLength ]; 242 243 for( i = 0; i < nLength; i++ ) 244 { 245 fMin = fMax = aData[ i ][ 1 ]; 246 for( j = 1; j < aData[ i ].length; j++ ) 247 { 248 if( aData[ i ][ j ] > fMax ) 249 fMax = aData[ i ][ j ]; 250 else if( aData[ i ][ j ] < fMin ) 251 fMin = aData[ i ][ j ]; 252 } 253 aMaxPtSeq[ 0 ][ i ] = new Point( getAxisPosition( aXAxis, aData[ i ][ 0 ], false ), 254 getAxisPosition( aYAxis, fMax, true )); 255 aMinPtSeq[ 0 ][ i ] = new Point( getAxisPosition( aXAxis, aData[ i ][ 0 ], false ), 256 getAxisPosition( aYAxis, fMin, true )); 257 } 258 259 // apply point sequences to lines 260 try 261 { 262 XPropertySet aShapeProp = (XPropertySet) UnoRuntime.queryInterface( 263 XPropertySet.class, maTopLine ); 264 aShapeProp.setPropertyValue( "PolyPolygon", aMaxPtSeq ); 265 266 aShapeProp = (XPropertySet) UnoRuntime.queryInterface( 267 XPropertySet.class, maBottomLine ); 268 aShapeProp.setPropertyValue( "PolyPolygon", aMinPtSeq ); 269 } 270 catch( Exception ex ) 271 { 272 JOptionPane.showMessageDialog( null, ex, "Exception caught", JOptionPane.WARNING_MESSAGE ); 273 } 274 } 275 276 public void addRefreshListener( com.sun.star.util.XRefreshListener aListener ) 277 throws RuntimeException 278 { 279 // we don't want this but we have to implement the interface 280 } 281 282 public void removeRefreshListener( com.sun.star.util.XRefreshListener aListener ) 283 throws RuntimeException 284 { 285 // we don't want this but we have to implement the interface 286 } 287 288 289 // XServiceName 290 public String getServiceName() throws RuntimeException 291 { 292 return new String( smServiceName ); 293 } 294 295 // XServiceInfo 296 public boolean supportsService( String aServiceName ) 297 { 298 String[] aServices = getSupportedServiceNames_Static(); 299 int i, nLength = aServices.length; 300 boolean bResult = false; 301 302 for( i = 0; !bResult && i < nLength; ++i ) 303 bResult = aServiceName.equals( aServices[ i ] ); 304 305 return bResult; 306 } 307 308 public String getImplementationName() 309 { 310 return( JavaSampleChartAddIn.class.getName() ); 311 } 312 313 public String[] getSupportedServiceNames() 314 { 315 return getSupportedServiceNames_Static(); 316 } 317 318 // XDiagram 319 public String getDiagramType() throws RuntimeException 320 { 321 return new String( smServiceName ); 322 } 323 324 public XPropertySet getDataRowProperties( int nRow ) 325 throws com.sun.star.lang.IndexOutOfBoundsException, RuntimeException 326 { 327 return maChartDocument.getDiagram().getDataRowProperties( nRow ); 328 } 329 330 public XPropertySet getDataPointProperties( int nCol, int nRow ) 331 throws com.sun.star.lang.IndexOutOfBoundsException, RuntimeException 332 { 333 return maChartDocument.getDiagram().getDataPointProperties( nCol, nRow ); 334 } 335 336 // XShape : XDiagram 337 public Size getSize() throws RuntimeException 338 { 339 return ((XShape) UnoRuntime.queryInterface( XShape.class, maChartDocument.getDiagram())).getSize(); 340 } 341 public void setSize( Size aSize ) throws RuntimeException, PropertyVetoException 342 { 343 ((XShape) UnoRuntime.queryInterface( XShape.class, maChartDocument.getDiagram())).setSize( aSize ); 344 } 345 346 public Point getPosition() throws RuntimeException 347 { 348 return ((XShape) UnoRuntime.queryInterface( XShape.class, maChartDocument.getDiagram())).getPosition(); 349 } 350 public void setPosition( Point aPos ) throws RuntimeException 351 { 352 ((XShape) UnoRuntime.queryInterface( XShape.class, maChartDocument.getDiagram())).setPosition( aPos ); 353 } 354 355 // XShapeDescriptor : XShape : XDiagram 356 public String getShapeType() throws RuntimeException 357 { 358 return new String( "com.sun.star.comp.Chart.JavaSampleDiagramShape" ); 359 } 360 361 362 // __________ private members __________ 363 private com.sun.star.chart.XChartDocument maChartDocument; 364 private com.sun.star.drawing.XDrawPage maDrawPage; 365 private com.sun.star.lang.XMultiServiceFactory maShapeFactory; 366 367 // shapes added by add-in 368 private com.sun.star.drawing.XShape maTopLine; 369 private com.sun.star.drawing.XShape maBottomLine; 370 371 // __________ private methods __________ 372 373 private int getAxisPosition( XShape aAxis, double fValue, boolean bVertical ) 374 { 375 int nResult = 0; 376 377 if( aAxis != null ) 378 { 379 XPropertySet aAxisProp = (XPropertySet) UnoRuntime.queryInterface( 380 XPropertySet.class, aAxis ); 381 382 try 383 { 384 double fMin, fMax; 385 fMin = ((Double) aAxisProp.getPropertyValue( "Min" )).doubleValue(); 386 fMax = ((Double) aAxisProp.getPropertyValue( "Max" )).doubleValue(); 387 double fRange = fMax - fMin; 388 389 if( fMin <= fValue && fValue <= fMax && 390 fRange != 0 ) 391 { 392 if( bVertical ) 393 { 394 nResult = aAxis.getPosition().Y + 395 (int)((double)(aAxis.getSize().Height) * 396 (1.0 - (( fValue - fMin ) / fRange ))); 397 } 398 else 399 { 400 nResult = aAxis.getPosition().X + 401 (int)((double)(aAxis.getSize().Width) * 402 (( fValue - fMin ) / fRange )); 403 } 404 } 405 } 406 catch( Exception ex ) 407 { 408 JOptionPane.showMessageDialog( null, ex, "Exception caught", JOptionPane.WARNING_MESSAGE ); 409 } 410 } 411 return nResult; 412 } 413 414 // __________ static things __________ 415 416 private static final String smServiceName = "com.sun.star.comp.Chart.JavaSampleChartAddIn"; 417 418 public static String[] getSupportedServiceNames_Static() 419 { 420 String[] aResult = { smServiceName, 421 "com.sun.star.chart.Diagram", 422 "com.sun.star.chart.ChartAxisYSupplier" }; 423 return aResult; 424 } 425 426 427 /** 428 * Returns a factory for creating the service. 429 * This method is called by the <code>JavaLoader</code> 430 * <p> 431 * @return returns a <code>XSingleServiceFactory</code> for creating the component 432 * @param implName the name of the implementation for which a service is desired 433 * @param multiFactory the service manager to be used if needed 434 * @param regKey the registryKey 435 * @see com.sun.star.comp.loader.JavaLoader 436 */ 437 public static XSingleServiceFactory __getServiceFactory( 438 String implName, 439 XMultiServiceFactory multiFactory, 440 com.sun.star.registry.XRegistryKey regKey ) 441 { 442 XSingleServiceFactory xSingleServiceFactory = null; 443 444 if( implName.equals( JavaSampleChartAddIn.class.getName()) ) 445 { 446 xSingleServiceFactory = com.sun.star.comp.loader.FactoryHelper.getServiceFactory( 447 JavaSampleChartAddIn.class, smServiceName, 448 multiFactory, regKey ); 449 } 450 451 return xSingleServiceFactory; 452 } 453 454 /** 455 * Writes the service information into the given registry key. 456 * This method is called by the <code>JavaLoader</code> 457 * <p> 458 * @return returns true if the operation succeeded 459 * @param regKey the registryKey 460 * @see com.sun.star.comp.loader.JavaLoader 461 */ 462 // This method not longer necessary since OOo 3.4 where the component registration 463 // was changed to passive component registration. For more details see 464 // http://wiki.services.openoffice.org/wiki/Passive_Component_Registration 465 466 // public static boolean __writeRegistryServiceInfo( com.sun.star.registry.XRegistryKey regKey ) 467 // { 468 // boolean bResult = true; 469 470 // String[] aServices = getSupportedServiceNames_Static(); 471 // int i, nLength = aServices.length; 472 473 // for( i = 0; i < nLength; ++i ) 474 // { 475 // bResult = bResult && com.sun.star.comp.loader.FactoryHelper.writeRegistryServiceInfo( 476 // JavaSampleChartAddIn.class.getName(), aServices[ i ], regKey ); 477 // } 478 // return bResult; 479 // } 480 } 481