Element Access

From Apache OpenOffice Wiki
Jump to: navigation, search

We have already seen in the section How to get Objects in OpenOffice.org that sets of objects can also be provided through element access methods. The three most important kinds of element access interfaces are com.sun.star.container.XNameContainer, com.sun.star.container.XIndexContainer and com.sun.star.container.XEnumeration.

The three element access interfaces are examples of how the fine-grained interfaces of the OpenOffice.org API allow consistent object design.

All three interfaces inherit from XElementAccess; therefore, they include the methods

  type getElementType()
  boolean hasElements()

for finding out basic information about a set of elements. The method hasElements() tells whether or not a set contains any elements at all; the method getElementType() tells which type a set contains. In Java and C++, you can get information about a UNO type through com.sun.star.uno.Type, cf, the Java UNO and the C++ UNO reference.

The com.sun.star.container.XIndexContainer and com.sun.star.container.XNameContainer interface have a parallel design. Consider both interfaces in UML notation.

Indexed and Named Container

The XIndexAccess/XNameAccess interfaces are about getting an element. The XIndexReplace/XNameReplace interfaces allow you to replace existing elements without changing the number of elements in the set, whereas the XIndexContainer/XNameContainer interfaces allow you to increase and decrease the number of elements by inserting and removing elements.

Many sets of named or indexed objects do not support the whole inheritance hierarchy of XIndexContainer or XNameContainer, because the capabilities added by every subclass are not always logical for any set of elements.

The XEumerationAccess interface works differently from named and indexed containers below the XElementAccess interface. XEnumerationAccess does not provide single elements like XNameAccess and XIndexAccess, but it creates an enumeration of objects which has methods to go to the next element as long as there are more elements.

Enumerated Container

Sets of objects sometimes support all element access methods, some also support only name, index, or enumeration access. Always look up the various types in the API reference to see which access methods are available.

For instance, the method getSheets() at the interface com.sun.star.sheet.XSpreadsheetDocument is specified to return a com.sun.star.sheet.XSpreadsheets interface inherited from XNameContainer. In addition, the API reference tells you that the provided object supports the com.sun.star.sheet.Spreadsheets service, which defines additional element access interfaces besides XSpreadsheets.

Examples that show how to work with XNameAccess, XIndexAccess, and XEnumerationAccess are provided below.

Name Access

The basic interface which hands out elements by name is the com.sun.star.container.XNameAccess interface. It has three methods:

  any getByName( [in] string name)
  sequence< string > getElementNames()
  boolean hasByName( [in] string name)

In the FirstLoadComponent.java example above, the method getSheets() returned a com.sun.star.sheet.XSpreadsheets interface, which inherits from XNameAccess. Therefore, you could use getByName() to obtain the sheet "MySheet" by name from the XSpreadsheets container:

  XSpreadsheets xSpreadsheets = xSpreadsheetDocument.getSheets();
  Object sheet = xSpreadsheets.getByName("MySheet");
  XSpreadsheet xSpreadsheet = (XSpreadsheet)UnoRuntime.queryInterface(
            XSpreadsheet.class, sheet);
  // use XSpreadsheet interface to get the cell A1 at position 0,0 and enter 42 as value
  XCell xCell = xSpreadsheet.getCellByPosition(0, 0);

Since getByName() returns an any, you have to use AnyConverter.toObject() and/or UnoRuntime.queryInterface() before you can call methods at the spreadsheet object.

Index Access

The interface which hands out elements by index is the com.sun.star.container.XIndexAccess interface. It has two methods:

  any getByIndex( [in] long index)
  long getCount()

The FirstLoadComponent example allows to demonstrate XIndexAccess. The API reference tells us that the service returned by getSheets() is a com.sun.star.sheet.Spreadsheet service and supports not only the interface com.sun.star.sheet.XSpreadsheets, but XIndexAccess as well. Therefore, the sheets could have been accessed by index and not just by name by performing a query for the XIndexAccess interface from our xSpreadsheets variable:

  XIndexAccess xSheetIndexAccess = (XIndexAccess)UnoRuntime.queryInterface(
             XIndexAccess.class, xSpreadsheets);
  Object sheet = XSheetIndexAccess.getByIndex(0);

Enumeration Access

The interface com.sun.star.container.XEnumerationAccess creates enumerations that allow traveling across a set of objects. It has one method:

  com.sun.star.container.XEnumeration createEnumeration()

The enumeration object gained from createEnumeration() supports the interface com.sun.star.container.XEnumeration. With this interface we can keep pulling elements out of the enumeration as long as it has more elements. XEnumeration supplies the methods:

  boolean hasMoreElements()
  any nextElement()

which are meant to build loops such as:

  while (xCells.hasMoreElements()) {
      Object cell = xCells.nextElement();
      // do something with cell 

For example, in spreadsheets you have the opportunity to find out which cells contain formulas. The resulting set of cells is provided as XEnumerationAccess.

The interface that queries for cells with formulas is com.sun.star.sheet.XCellRangesQuery, it defines (among others) a method

  XSheetCellRanges queryContentCells(short cellFlags)

which queries for cells having content as defined in the constants group com.sun.star.sheet.CellFlags. One of these cell flags is FORMULA. From queryContentCells() we receive an object with an com.sun.star.sheet.XSheetCellRanges interface, which has these methods:

  XEnumerationAccess getCells()
  String getRangeAddressesAsString()
  sequence< com.sun.star.table.CellRangeAddress > getRangeAddresses()

The method getCells() can be used to list all formula cells and the containing formulas in the spreadsheet document from our FirstLoadComponent example, utilizing XEnumerationAccess.

  XCellRangesQuery xCellQuery = (XCellRangesQuery)UnoRuntime.queryInterface(
      XCellRangesQuery.class, sheet);
  XSheetCellRanges xFormulaCells = xCellQuery.queryContentCells(
  XEnumerationAccess xFormulas = xFormulaCells.getCells();
  XEnumeration xFormulaEnum = xFormulas.createEnumeration();
  while (xFormulaEnum.hasMoreElements()) {
      Object formulaCell = xFormulaEnum.nextElement();
      // do something with formulaCell
      xCell = (XCell)UnoRuntime.queryInterface(XCell.class, formulaCell);
      XCellAddressable xCellAddress = (XCellAddressable)UnoRuntime.queryInterface(
          XCellAddressable.class, xCell);
      System.out.print("Formula cell in column " + xCellAddress.getCellAddress().Column
          + ", row " + xCellAddress.getCellAddress().Row
          + " contains " + xCell.getFormula());
Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages