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