/*******************************************************************************
* Copyright (c) 2002, 2010 Innoopract Informationssysteme GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Innoopract Informationssysteme GmbH - initial API and implementation
* EclipseSource - ongoing development
******************************************************************************/
package org.eclipse.swt.widgets;
import org.eclipse.rwt.graphics.Graphics;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.widgets.*;
/**
* Instances of this class represent a selectable user interface object that
* represents a hierarchy of tree items in a tree widget.
* <dl>
* <dt><b>Styles:</b></dt>
* <dd>(none)</dd>
* <dt><b>Events:</b></dt>
* <dd>(none)</dd>
* </dl>
* <p>
* IMPORTANT: This class is <em>not</em> intended to be subclassed.
* </p>
*/
public class TreeItem extends Item {
private final class TreeItemAdapter
implements ITreeItemAdapter, IWidgetFontAdapter, IWidgetColorAdapter
{
public Color getUserBackgound() {
return background;
}
public Color getUserForegound() {
return foreground;
}
public Font getUserFont() {
return font;
}
public Color[] getCellBackgrounds() {
Color[] backgrounds = null;
if( cellBackgrounds != null ) {
backgrounds = ( Color[] )cellBackgrounds.clone();
}
return backgrounds;
}
public Color[] getCellForegrounds() {
Color[] foregrounds = null;
if( cellForegrounds != null ) {
foregrounds = ( Color[] )cellForegrounds.clone();
}
return foregrounds;
}
public Font[] getCellFonts() {
Font[] fonts = null;
if( cellFonts != null ) {
fonts = ( Font[] )cellFonts.clone();
}
return fonts;
}
}
private static final int IMAGE_TEXT_GAP = 2;
private static final int INDENT_WIDTH = 19;
private final TreeItem parentItem;
private final Tree parent;
private final ItemHolder itemHolder;
private final ITreeItemAdapter treeItemAdapter;
private Font font;
private boolean expanded;
private boolean checked;
private Color background, foreground;
private boolean grayed;
private String[] texts;
private Image[] images;
Color[] cellForegrounds, cellBackgrounds;
Font[] cellFonts;
int depth;
private final int index;
/* package */boolean cached;
/* package */int flatIndex;
/**
* Constructs a new instance of this class given its parent (which must be a
* <code>Tree</code> or a <code>TreeItem</code>) and a style value describing
* its behavior and appearance. The item is added to the end of the items
* maintained by its parent.
* <p>
* The style value is either one of the style constants defined in class
* <code>SWT</code> which is applicable to instances of this class, or must be
* built by <em>bitwise OR</em>'ing together (that is, using the
* <code>int</code> "|" operator) two or more of those <code>SWT</code> style
* constants. The class description lists the style constants that are
* applicable to the class. Style bits are also inherited from superclasses.
* </p>
*
* @param parent a tree control which will be the parent of the new instance
* (cannot be null)
* @param style the style of control to construct
* @exception IllegalArgumentException <ul>
* <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the parent</li>
* <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed
* subclass</li>
* </ul>
* @see SWT
* @see Widget#checkSubclass
* @see Widget#getStyle
*/
public TreeItem( final Tree parent, final int style ) {
this( parent, null, style, parent == null
? 0
: parent.getItemCount() );
}
/**
* Constructs a new instance of this class given its parent (which must be a
* <code>Tree</code> or a <code>TreeItem</code>), a style value describing its
* behavior and appearance, and the index at which to place it in the items
* maintained by its parent.
* <p>
* The style value is either one of the style constants defined in class
* <code>SWT</code> which is applicable to instances of this class, or must be
* built by <em>bitwise OR</em>'ing together (that is, using the
* <code>int</code> "|" operator) two or more of those <code>SWT</code> style
* constants. The class description lists the style constants that are
* applicable to the class. Style bits are also inherited from superclasses.
* </p>
*
* @param parent a tree control which will be the parent of the new instance
* (cannot be null)
* @param style the style of control to construct
* @param index the zero-relative index to store the receiver in its parent
* @exception IllegalArgumentException <ul>
* <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
* <li>ERROR_INVALID_RANGE - if the index is not between 0 and
* the number of elements in the parent (inclusive)</li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the parent</li>
* <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed
* subclass</li>
* </ul>
* @see SWT
* @see Widget#checkSubclass
* @see Widget#getStyle
*/
public TreeItem( final Tree parent, final int style, final int index ) {
this( parent, null, style, index );
}
/**
* Constructs a new instance of this class given its parent (which must be a
* <code>Tree</code> or a <code>TreeItem</code>) and a style value describing
* its behavior and appearance. The item is added to the end of the items
* maintained by its parent.
* <p>
* The style value is either one of the style constants defined in class
* <code>SWT</code> which is applicable to instances of this class, or must be
* built by <em>bitwise OR</em>'ing together (that is, using the
* <code>int</code> "|" operator) two or more of those <code>SWT</code> style
* constants. The class description lists the style constants that are
* applicable to the class. Style bits are also inherited from superclasses.
* </p>
*
* @param parentItem a tree control which will be the parent of the new
* instance (cannot be null)
* @param style the style of control to construct
* @exception IllegalArgumentException <ul>
* <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the parent</li>
* <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed
* subclass</li>
* </ul>
* @see SWT
* @see Widget#checkSubclass
* @see Widget#getStyle
*/
public TreeItem( final TreeItem parentItem, final int style ) {
this( parentItem == null
? null
: parentItem.parent,
parentItem,
style,
parentItem == null
? 0
: parentItem.getItemCount() );
}
/**
* Constructs a new instance of this class given its parent (which must be a
* <code>Tree</code> or a <code>TreeItem</code>), a style value describing its
* behavior and appearance, and the index at which to place it in the items
* maintained by its parent.
* <p>
* The style value is either one of the style constants defined in class
* <code>SWT</code> which is applicable to instances of this class, or must be
* built by <em>bitwise OR</em>'ing together (that is, using the
* <code>int</code> "|" operator) two or more of those <code>SWT</code> style
* constants. The class description lists the style constants that are
* applicable to the class. Style bits are also inherited from superclasses.
* </p>
*
* @param parentItem a tree control which will be the parent of the new
* instance (cannot be null)
* @param style the style of control to construct
* @param index the zero-relative index to store the receiver in its parent
* @exception IllegalArgumentException <ul>
* <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
* <li>ERROR_INVALID_RANGE - if the index is not between 0 and
* the number of elements in the parent (inclusive)</li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the parent</li>
* <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed
* subclass</li>
* </ul>
* @see SWT
* @see Widget#checkSubclass
* @see Widget#getStyle
*/
public TreeItem( final TreeItem parentItem, final int style, final int index )
{
this( parentItem == null
? null
: parentItem.parent, parentItem, style, index );
}
private TreeItem( final Tree parent,
final TreeItem parentItem,
final int style,
final int index )
{
super( parent, style );
int numberOfItems;
// if there is a parent item, get the next index of parentItem
if( parentItem != null ) {
numberOfItems = parentItem.getItemCount();
}
// If there is no parent item, get the next index of the tree
else {
numberOfItems = parent.getItemCount();
}
// check range
if( index < 0 || index > numberOfItems ) {
error( SWT.ERROR_INVALID_RANGE );
}
this.parent = parent;
this.parentItem = parentItem;
if( parentItem != null ) {
this.depth = parentItem.depth + 1;
}
if( parentItem != null ) {
ItemHolder.insertItem( parentItem, this, index );
} else {
ItemHolder.insertItem( parent, this, index );
}
this.index = index;
itemHolder = new ItemHolder( TreeItem.class );
treeItemAdapter = new TreeItemAdapter();
int columnCount = parent.columnHolder.size();
texts = new String[ columnCount ];
images = new Image[ columnCount ];
parent.updateFlatIndices();
parent.updateScrollBars();
}
public Object getAdapter( final Class adapter ) {
Object result;
if( adapter == IItemHolderAdapter.class ) {
result = itemHolder;
} else if( adapter == IWidgetFontAdapter.class ) {
result = treeItemAdapter;
} else if( adapter == IWidgetColorAdapter.class ) {
result = treeItemAdapter;
} else if( adapter == ITreeItemAdapter.class ) {
result = treeItemAdapter;
} else {
result = super.getAdapter( adapter );
}
return result;
}
// ///////////////////////
// Parent/child relations
/**
* Returns the receiver's parent, which must be a <code>Tree</code>.
*
* @return the receiver's parent
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public Tree getParent() {
checkWidget();
return parent;
}
/**
* Returns the receiver's parent item, which must be a <code>TreeItem</code>
* or null when the receiver is a root.
*
* @return the receiver's parent item
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public TreeItem getParentItem() {
checkWidget();
return parentItem;
}
// //////////////
// Getter/Setter
/**
* Sets the expanded state of the receiver.
* <p>
*
* @param expanded the new expanded state
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public void setExpanded( final boolean expanded ) {
checkWidget();
if( !expanded || getItemCount() > 0 ) {
this.expanded = expanded;
parent.updateFlatIndices();
parent.updateScrollBars();
}
}
/**
* Returns <code>true</code> if the receiver is expanded, and false otherwise.
* <p>
*
* @return the expanded state
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public boolean getExpanded() {
checkWidget();
return expanded;
}
/**
* Returns a rectangle describing the receiver's size and location relative to
* its parent.
*
* @return the receiver's bounding rectangle
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public Rectangle getBounds() {
checkWidget();
return getBounds( 0 );
}
/**
* Returns a rectangle describing the receiver's size and location relative to
* its parent at a column in the tree.
*
* @param columnIndex the index that specifies the column
* @return the receiver's bounding column rectangle
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public Rectangle getBounds( final int columnIndex ) {
return getBounds( columnIndex, true );
}
Rectangle getBounds( final int columnIndex, final boolean checkData ) {
checkWidget();
Rectangle result;
int columnCount = parent.getColumnCount();
if( columnIndex < 0 || ( columnIndex > columnCount ) ) {
result = new Rectangle( 0, 0, 0, 0 );
} else if( getParentItem() != null && !getParentItem().getExpanded() ) {
result = new Rectangle( 0, 0, 0, 0 );
} else {
Rectangle imageBounds = getImageBounds( columnIndex );
String text = getText( 0, checkData );
Point textWidth = Graphics.stringExtent( getFont(), text );
int width;
if( columnIndex == 0 && columnCount == 0 ) {
int gap = getImageGap( columnIndex );
width = 2 + imageBounds.width + gap + textWidth.x;
} else {
width = parent.getColumn( columnIndex ).getWidth();
if( columnIndex == 0 ) {
width -= ( depth + 1 ) * INDENT_WIDTH;
}
}
// no support for bigger text/images due to qx bug
// int height = Math.max( textWidth.y, imageBounds.height ) + 2;
int left;
if( columnIndex == 0 ) {
left = imageBounds.x;
} else {
left = getItemLeft( columnIndex );
}
result = new Rectangle( left,
getItemTop(),
width,
parent.getItemHeight() );
}
return result;
}
private int getItemLeft( final int columnIndex ) {
int result = 0;
TreeColumn[] cols = parent.getColumns();
for( int i = 0; i < columnIndex; i++ ) {
TreeColumn col = cols[ i ];
result += col.getWidth();
}
return result;
}
private int getItemTop() {
int headerHeight = parent.getHeaderHeight();
int itemHeight = parent.getItemHeight();
return headerHeight + flatIndex * itemHeight - parent.scrollTop;
}
private int getImageGap( final int index ) {
int result = 0;
Image image = getImage( index );
if( image != null ) {
result = IMAGE_TEXT_GAP;
}
return result;
}
/**
* Returns the background color at the given column index in the receiver.
*
* @param columnIndex the column index
* @return the background color
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public Color getBackground( final int columnIndex ) {
checkWidget();
// if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
int validColumnCount = Math.max( 1, parent.columnHolder.size() );
if( !( 0 <= columnIndex && columnIndex < validColumnCount ) ) {
return getBackground();
}
if( cellBackgrounds == null || cellBackgrounds[ columnIndex ] == null ) {
return getBackground();
}
return cellBackgrounds[ columnIndex ];
}
/**
* Returns the font that the receiver will use to paint textual information
* for the specified cell in this item.
*
* @param columnIndex the column index
* @return the receiver's font
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public Font getFont( final int columnIndex ) {
checkWidget();
return getFont( columnIndex, true );
}
Font getFont( final int columnIndex, final boolean checkData ) {
// if (checkData && !parent.checkData (this, true)) error
// (SWT.ERROR_WIDGET_DISPOSED);
int validColumnCount = Math.max( 1, parent.columnHolder.size() );
if( !( 0 <= columnIndex && columnIndex < validColumnCount ) ) {
return getFont( checkData );
}
if( cellFonts == null || cellFonts[ columnIndex ] == null ) {
return getFont( checkData );
}
return cellFonts[ columnIndex ];
}
/**
* Returns the foreground color at the given column index in the receiver.
*
* @param columnIndex the column index
* @return the foreground color
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public Color getForeground( final int columnIndex ) {
checkWidget();
// if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
int validColumnCount = Math.max( 1, parent.columnHolder.size() );
if( !( 0 <= columnIndex && columnIndex < validColumnCount ) ) {
return getForeground();
}
if( cellForegrounds == null || cellForegrounds[ columnIndex ] == null ) {
return getForeground();
}
return cellForegrounds[ columnIndex ];
}
/**
* Sets the background color at the given column index in the receiver to the
* color specified by the argument, or to the default system color for the
* item if the argument is null.
*
* @param columnIndex the column index
* @param value the new color (or null)
* @exception IllegalArgumentException <ul>
* <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed
* </li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public void setBackground( final int columnIndex, final Color value ) {
checkWidget();
if( value != null && value.isDisposed() ) {
error( SWT.ERROR_INVALID_ARGUMENT );
}
int validColumnCount = Math.max( 1, parent.columnHolder.size() );
if( !( 0 <= columnIndex && columnIndex < validColumnCount ) ) {
return;
}
if( cellBackgrounds == null ) {
cellBackgrounds = new Color[ validColumnCount ];
} else if( cellBackgrounds.length < validColumnCount ) {
Color[] newCellBackgrounds = new Color[ validColumnCount ];
System.arraycopy( cellBackgrounds,
0,
newCellBackgrounds,
0,
cellBackgrounds.length );
cellBackgrounds = newCellBackgrounds;
}
if( cellBackgrounds[ columnIndex ] == value ) {
return;
}
if( cellBackgrounds[ columnIndex ] != null
&& cellBackgrounds[ columnIndex ].equals( value ) )
{
return;
}
cellBackgrounds[ columnIndex ] = value;
if( ( parent.style & SWT.VIRTUAL ) != 0 ) {
cached = true;
}
}
/**
* Sets the font that the receiver will use to paint textual information for
* the specified cell in this item to the font specified by the argument, or
* to the default font for that kind of control if the argument is null.
*
* @param columnIndex the column index
* @param value the new font (or null)
* @exception IllegalArgumentException <ul>
* <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed
* </li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public void setFont( final int columnIndex, final Font value ) {
checkWidget();
if( value != null && value.isDisposed() ) {
error( SWT.ERROR_INVALID_ARGUMENT );
}
int validColumnCount = Math.max( 1, parent.columnHolder.size() );
if( !( 0 <= columnIndex && columnIndex < validColumnCount ) ) {
return;
}
if( cellFonts == null ) {
if( value == null ) {
return;
}
cellFonts = new Font[ validColumnCount ];
} else if( cellFonts.length < validColumnCount ) {
Font[] newCellFonts = new Font[ validColumnCount ];
System.arraycopy( cellFonts, 0, newCellFonts, 0, cellFonts.length );
cellFonts = newCellFonts;
}
if( cellFonts[ columnIndex ] == value ) {
return;
}
if( cellFonts[ columnIndex ] != null
&& cellFonts[ columnIndex ].equals( value ) )
{
return;
}
cellFonts[ columnIndex ] = value;
if( ( parent.style & SWT.VIRTUAL ) != 0 ) {
cached = true;
}
}
/**
* Sets the foreground color at the given column index in the receiver to the
* color specified by the argument, or to the default system color for the
* item if the argument is null.
*
* @param columnIndex the column index
* @param value the new color (or null)
* @exception IllegalArgumentException <ul>
* <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed
* </li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public void setForeground( final int columnIndex, final Color value ) {
checkWidget();
if( value != null && value.isDisposed() ) {
error( SWT.ERROR_INVALID_ARGUMENT );
}
int validColumnCount = Math.max( 1, parent.columnHolder.size() );
if( !( 0 <= columnIndex && columnIndex < validColumnCount ) ) {
return;
}
if( cellForegrounds == null ) {
cellForegrounds = new Color[ validColumnCount ];
} else if( cellForegrounds.length < validColumnCount ) {
Color[] newCellForegrounds = new Color[ validColumnCount ];
System.arraycopy( cellForegrounds,
0,
newCellForegrounds,
0,
cellForegrounds.length );
cellForegrounds = newCellForegrounds;
}
if( cellForegrounds[ columnIndex ] == value ) {
return;
}
if( cellForegrounds[ columnIndex ] != null
&& cellForegrounds[ columnIndex ].equals( value ) )
{
return;
}
cellForegrounds[ columnIndex ] = value;
if( ( parent.style & SWT.VIRTUAL ) != 0 ) {
cached = true;
}
}
/**
* Sets the font that the receiver will use to paint textual information for
* this item to the font specified by the argument, or to the default font for
* that kind of control if the argument is null.
*
* @param font the new font (or null)
* @exception IllegalArgumentException <ul>
* <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed
* </li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public void setFont( final Font font ) {
checkWidget();
if( font != null && font.isDisposed() ) {
error( SWT.ERROR_INVALID_ARGUMENT );
}
this.font = font;
if( ( parent.style & SWT.VIRTUAL ) != 0 ) {
cached = true;
}
}
/**
* Returns the font that the receiver will use to paint textual information
* for this item.
*
* @return the receiver's font
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public Font getFont() {
checkWidget();
Font result;
if( font == null ) {
result = getParent().getFont();
} else {
result = font;
}
return result;
}
Font getFont( final boolean checkData ) {
// if( checkData && !parent.checkData( this, true ) )
// error( SWT.ERROR_WIDGET_DISPOSED );
if( font != null ) {
return font;
}
return parent.getFont();
}
/**
* Sets the receiver's background color to the color specified by the
* argument, or to the default system color for the item if the argument is
* null.
*
* @param value the new color (or null)
* @exception IllegalArgumentException <ul>
* <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed
* </li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public void setBackground( final Color value ) {
checkWidget();
if( value != null && value.isDisposed() ) {
error( SWT.ERROR_INVALID_ARGUMENT );
}
if( background == value ) {
return;
}
if( background != null && background.equals( value ) ) {
return;
}
background = value;
if( ( parent.style & SWT.VIRTUAL ) != 0 ) {
cached = true;
}
}
/**
* Returns the receiver's background color.
*
* @return the background color
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public Color getBackground() {
checkWidget();
if( isDisposed() ) {
error( SWT.ERROR_WIDGET_DISPOSED );
}
if( background != null ) {
return background;
}
return parent.getBackground();
}
/**
* Returns the foreground color that the receiver will use to draw.
*
* @return the receiver's foreground color
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public Color getForeground() {
checkWidget();
if( isDisposed() ) {
error( SWT.ERROR_WIDGET_DISPOSED );
}
if( foreground != null ) {
return foreground;
}
return parent.getForeground();
}
/**
* Sets the receiver's foreground color to the color specified by the
* argument, or to the default system color for the item if the argument is
* null.
*
* @param value the new color (or null)
* @since 1.0
* @exception IllegalArgumentException <ul>
* <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed
* </li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public void setForeground( final Color value ) {
checkWidget();
if( value != null && value.isDisposed() ) {
error( SWT.ERROR_INVALID_ARGUMENT );
}
if( foreground == value ) {
return;
}
if( foreground != null && foreground.equals( value ) ) {
return;
}
foreground = value;
if( ( parent.style & SWT.VIRTUAL ) != 0 ) {
cached = true;
}
}
/**
* Sets the checked state of the receiver.
* <p>
*
* @param checked the new checked state
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public void setChecked( final boolean checked ) {
checkWidget();
if( ( parent.getStyle() & SWT.CHECK ) != 0 ) {
this.checked = checked;
}
if( ( parent.style & SWT.VIRTUAL ) != 0 ) {
cached = true;
}
}
/**
* Returns <code>true</code> if the receiver is checked, and false otherwise.
* When the parent does not have the <code>CHECK style, return false.
* <p>
*
* @return the checked state
* @exception SWTException <ul> <li>ERROR_WIDGET_DISPOSED - if the receiver
* has been disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if
* not called from the thread that created the receiver</li>
* </ul>
*/
public boolean getChecked() {
checkWidget();
return checked;
}
/**
* Sets the grayed state of the checkbox for this item. This state change only
* applies if the Tree was created with the SWT.CHECK style.
*
* @param value the new grayed state of the checkbox
* @exception SWTException <ul> <li>ERROR_WIDGET_DISPOSED - if the receiver
* has been disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if
* not called from the thread that created the receiver</li>
* </ul>
*/
public void setGrayed( final boolean value ) {
checkWidget();
if( ( parent.getStyle() & SWT.CHECK ) == 0 ) {
return;
}
if( grayed == value ) {
return;
}
grayed = value;
if( ( parent.style & SWT.VIRTUAL ) != 0 ) {
cached = true;
}
}
/**
* Returns <code>true</code> if the receiver is grayed, and false otherwise.
* When the parent does not have the <code>CHECK style, return false.
* <p>
*
* @return the grayed state of the checkbox
* @exception SWTException <ul> <li>ERROR_WIDGET_DISPOSED - if the receiver
* has been disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if
* not called from the thread that created the receiver</li>
* </ul>
*/
public boolean getGrayed() {
checkWidget();
// if ( !parent.checkData( this, true ) )
// error( SWT.ERROR_WIDGET_DISPOSED );
return grayed;
}
/**
* Returns the text stored at the given column index in the receiver, or empty
* string if the text has not been set.
*
* @param columnIndex the column index
* @return the text stored at the given column index in the receiver
* @exception SWTException <ul> <li>ERROR_WIDGET_DISPOSED - if the receiver
* has been disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if
* not called from the thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public String getText( final int columnIndex ) {
checkWidget();
return getText( columnIndex, true );
}
/**
* Returns the receiver's text, which will be an empty string if it has never
* been set.
*
* @return the receiver's text
* @exception SWTException <ul> <li>ERROR_WIDGET_DISPOSED - if the receiver
* has been disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if
* not called from the thread that created the receiver</li>
* </ul>
*/
public String getText() {
checkWidget();
if( !isCached() ) {
parent.checkData( this, this.index );
}
return super.getText();
}
String getText( final int columnIndex, final boolean checkData ) {
if( checkData && !isCached() ) {
parent.checkData( this, this.index );
}
int validColumnCount = Math.max( 1, parent.columnHolder.size() );
if( !( 0 <= columnIndex && columnIndex < validColumnCount ) ) {
return ""; //$NON-NLS-1$
}
if( columnIndex == 0 ) {
return super.getText(); /* super is intentional here */
}
if( texts[ columnIndex ] == null ) {
return ""; //$NON-NLS-1$
}
return texts[ columnIndex ];
}
/**
* Returns a rectangle describing the size and location
* relative to its parent of the text at a column in the
* tree.
*
* @param index the index that specifies the column
* @return the receiver's bounding text rectangle
*
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
* </ul>
*
* @since 1.3
*/
public Rectangle getTextBounds( final int index ) {
checkWidget();
int left = 0;
int top = 0;
int width = 0;
int height = 0;
int columnCount = parent.getColumnCount();
if( parentItem == null || parentItem.getExpanded() ) {
int indent = index == 0 ? ( depth + 1 ) * INDENT_WIDTH : 0;
if( index == 0 && columnCount == 0 ) {
left = indent
+ getCheckWidth( 0 )
+ getImageBounds( 0 ).width
+ getImageGap( 0 );
width = Graphics.stringExtent( getFont(), getText( 0 ) ).x;
top = getItemTop();
height = parent.getItemHeight();
} else if( index >= 0 && index < columnCount ) {
left = parent.getColumn( index ).getLeft()
+ indent
+ getCheckWidth( index )
+ getImageBounds( index ).width
+ getImageGap( index );
width = parent.getColumn( index ).getWidth()
- indent
- getCheckWidth( index )
- getImageBounds( index ).width
- getImageGap( index );
width = Math.max( 0, width );
top = getItemTop();
height = parent.getItemHeight();
}
}
return new Rectangle( left, top, width, height );
}
/**
* Sets the text for multiple columns in the tree.
*
* @param value the array of new strings
* @exception IllegalArgumentException <ul> <li>ERROR_NULL_ARGUMENT - if the
* text is null</li> </ul>
* @exception SWTException <ul> <li>ERROR_WIDGET_DISPOSED - if the receiver
* has been disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if
* not called from the thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public void setText( final String[] value ) {
checkWidget();
if( value == null ) {
error( SWT.ERROR_NULL_ARGUMENT );
}
// TODO make a smarter implementation of this
for( int i = 0; i < value.length; i++ ) {
if( value[ i ] != null ) {
setText( i, value[ i ] );
}
}
}
/**
* Sets the receiver's text at a column
*
* @param columnIndex the column index
* @param value the new text
* @exception IllegalArgumentException <ul> <li>ERROR_NULL_ARGUMENT - if the
* text is null</li> </ul>
* @exception SWTException <ul> <li>ERROR_WIDGET_DISPOSED - if the receiver
* has been disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if
* not called from the thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public void setText( final int columnIndex, final String value ) {
checkWidget();
if( value == null ) {
error( SWT.ERROR_NULL_ARGUMENT );
}
int validColumnCount = Math.max( 1, parent.columnHolder.size() );
if( !( 0 <= columnIndex && columnIndex < validColumnCount ) ) {
return;
}
if( value.equals( getText( columnIndex, false ) ) ) {
return;
}
if( columnIndex == 0 ) {
super.setText( value );
} else {
texts[ columnIndex ] = value;
}
if( parent.getColumnCount() == 0 ) {
parent.updateScrollBars();
}
if( ( parent.style & SWT.VIRTUAL ) != 0 ) {
cached = true;
}
}
/**
* Sets the receiver's text.
*
* @param text the new text
* @exception IllegalArgumentException <ul> <li>ERROR_NULL_ARGUMENT - if the
* text is null</li> </ul>
* @exception SWTException <ul> <li>ERROR_WIDGET_DISPOSED - if the receiver
* has been disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if
* not called from the thread that created the receiver</li>
* </ul>
*/
public void setText( final String text ) {
checkWidget();
setText( 0, text );
}
/**
* Returns the image stored at the given column index in the receiver, or null
* if the image has not been set or if the column does not exist.
*
* @param columnIndex the column index
* @return the image stored at the given column index in the receiver
* @exception SWTException <ul> <li>ERROR_WIDGET_DISPOSED - if the receiver
* has been disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if
* not called from the thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public Image getImage( final int columnIndex ) {
checkWidget();
return getImage( columnIndex, true );
}
/**
* Returns a rectangle describing the size and location relative to its parent
* of an image at a column in the tree.
*
* @param index the index that specifies the column
* @return the receiver's bounding image rectangle
* @exception SWTException <ul> <li>ERROR_WIDGET_DISPOSED - if the receiver
* has been disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if
* not called from the thread that created the receiver</li>
* </ul>
*/
public Rectangle getImageBounds( final int columnIndex ) {
checkWidget();
// parent.checkData( this, parent.indexOf( this ) );
Rectangle result = null;
int validColumnCount = Math.max( 1, parent.columnHolder.size() );
if( ( 0 <= columnIndex && columnIndex < validColumnCount ) ) {
Image image = getImage( index );
if( image != null ) {
result = image.getBounds();
} else {
result = new Rectangle( 0, 0, 0, 0 );
}
int indent = ( depth + 1 ) * INDENT_WIDTH;
if( columnIndex > 0 ) {
result.x += getItemLeft( columnIndex );
} else {
result.x = indent;
}
// SWT behavior on windows gives the correct y value
// On Gtk the y value is always the same (eg. 1)
// we emulate the default windows behavior here
result.y = getItemTop();
} else {
result = new Rectangle( 0, 0, 0, 0 );
}
return result;
}
Image getImage( final int columnIndex, final boolean checkData ) {
// if( checkData ) parent.checkData( this, this.index );
int validColumnCount = Math.max( 1, parent.columnHolder.size() );
if( !( 0 <= columnIndex && columnIndex < validColumnCount ) ) {
return null;
}
if( columnIndex == 0 ) {
return super.getImage(); /* super is intentional here */
}
return images[ columnIndex ];
}
/*
* Returns the receiver's ideal width for the specified columnIndex.
*/
int getPreferredWidth( final int columnIndex, final boolean checkData ) {
int width = 0;
width += Graphics.stringExtent( parent.getFont(),
getText( columnIndex,
checkData ) ).x;
int orderedIndex = 0;
if( parent.columnHolder.size() > 0 ) {
TreeColumn column = ( TreeColumn )parent.columnHolder.getItem( columnIndex );
orderedIndex = column.getOrderIndex();
}
if( orderedIndex == 0 ) {
width += 19; // TODO find proper solution
width += 3; // Tree.MARGIN_IMAGE;
// Image image = getImage (columnIndex, false);
Image image = getImage();
if( image != null ) {
width += image.getBounds().width;
width += 3; // Tree.MARGIN_IMAGE;
}
}
width += getCheckWidth( columnIndex );
return width;
}
void clear() {
// TODO: [bm] revisit when columns are available
checked = grayed = false;
texts = null;
// textWidths = new int[ 1 ];
// fontHeight = 0;
// fontHeights = null;
images = null;
foreground = background = null;
// displayTexts = null;
cellForegrounds = cellBackgrounds = null;
font = null;
cellFonts = null;
setText( "" );
setImage( ( Image )null );
int columnCount = parent.columnHolder.size();
if( columnCount > 0 ) {
// displayTexts = new String[ columnCount ];
if( columnCount > 1 ) {
texts = new String[ columnCount ];
// textWidths = new int[ columnCount ];
images = new Image[ columnCount ];
}
}
if( ( parent.style & SWT.VIRTUAL ) != 0 ) {
cached = false;
}
parent.updateScrollBars();
}
/**
* Clears the item at the given zero-relative index in the receiver. The text,
* icon and other attributes of the item are set to the default value. If the
* tree was created with the <code>SWT.VIRTUAL</code> style, these attributes
* are requested again as needed.
*
* @param index the index of the item to clear
* @param recursive <code>true</code> if all child items of the indexed item
* should be cleared recursively, and <code>false</code> otherwise
* @exception IllegalArgumentException <ul>
* <li>ERROR_INVALID_RANGE - if the index is not between 0 and
* the number of elements in the list minus 1 (inclusive)</li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @see SWT#VIRTUAL
* @see SWT#SetData
* @since 1.0
*/
public void clear( final int index, final boolean recursive ) {
checkWidget();
if( !( 0 <= index && index < itemHolder.size() ) ) {
error( SWT.ERROR_INVALID_RANGE );
}
TreeItem item = ( TreeItem )itemHolder.getItem( index );
/* clear the item(s) */
item.clear();
if( recursive ) {
item.clearAll( true, false );
}
if( ( parent.style & SWT.VIRTUAL ) == 0 ) {
parent.checkData( item, index );
}
}
/*
* Updates internal structures in the receiver and its child items to handle
* the creation of a new column.
*/
void addColumn( final TreeColumn column ) {
int index = column.getIndex();
int columnCount = parent.columnHolder.size();
if( columnCount > 1 ) {
if( columnCount == 2 ) {
texts = new String[ 2 ];
} else {
String[] newTexts = new String[ columnCount ];
System.arraycopy( texts, 0, newTexts, 0, index );
System.arraycopy( texts, index, newTexts, index + 1, columnCount
- index
- 1 );
texts = newTexts;
}
if( index == 0 ) {
texts[ 1 ] = text;
text = ""; //$NON-NLS-1$
}
if( columnCount == 2 ) {
images = new Image[ 2 ];
} else {
Image[] newImages = new Image[ columnCount ];
System.arraycopy( images, 0, newImages, 0, index );
System.arraycopy( images, index, newImages, index + 1, columnCount
- index
- 1 );
images = newImages;
}
if( index == 0 ) {
images[ 1 ] = image;
image = null;
}
}
/* notify all child items as well */
for( int i = 0; i < itemHolder.size(); i++ ) {
TreeItem child = ( TreeItem )itemHolder.getItem( i );
child.addColumn( column );
}
}
public void setImage( final Image image ) {
checkWidget();
setImage( 0, image );
}
/**
* Sets the receiver's image at a column.
*
* @param columnIndex the column index
* @param value the new image
* @exception IllegalArgumentException <ul>
* <li>ERROR_INVALID_ARGUMENT - if the image has been disposed
* </li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public void setImage( final int columnIndex, final Image value ) {
checkWidget();
if( value != null && value.isDisposed() ) {
error( SWT.ERROR_INVALID_ARGUMENT );
}
TreeColumn[] columns = ( TreeColumn[] )parent.columnHolder.getItems();
int validColumnCount = Math.max( 1, columns.length );
if( !( 0 <= columnIndex && columnIndex < validColumnCount ) ) {
return;
}
Image image = getImage( columnIndex, false );
if( value == image ) {
return;
}
if( value != null && value.equals( image ) ) {
return;
}
if( columnIndex == 0 ) {
super.setImage( value );
} else {
images[ columnIndex ] = value;
}
parent.updateItemImageSize( value );
if( ( parent.style & SWT.VIRTUAL ) != 0 ) {
cached = true;
}
if( parent.getColumnCount() == 0 ) {
parent.updateScrollBars();
}
}
/**
* Sets the image for multiple columns in the tree.
*
* @param value the array of new images
* @exception IllegalArgumentException <ul>
* <li>ERROR_NULL_ARGUMENT - if the array of images is null</li>
* <li>ERROR_INVALID_ARGUMENT - if one of the images has been
* disposed</li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public void setImage( final Image[] value ) {
checkWidget();
if( value == null ) {
error( SWT.ERROR_NULL_ARGUMENT );
}
for( int i = 0; i < value.length; i++ ) {
if( value[ i ] != null && value[ i ].isDisposed() ) {
error( SWT.ERROR_INVALID_ARGUMENT );
}
}
// TODO make a smarter implementation of this
for( int i = 0; i < value.length; i++ ) {
if( value[ i ] != null ) {
setImage( i, value[ i ] );
}
}
}
/**
* Clears all the items in the receiver. The text, icon and other attributes
* of the items are set to their default values. If the tree was created with
* the <code>SWT.VIRTUAL</code> style, these attributes are requested again as
* needed.
*
* @param recursive <code>true</code> if all child items should be cleared
* recursively, and <code>false</code> otherwise
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @see SWT#VIRTUAL
* @see SWT#SetData
* @since 1.0
*/
public void clearAll( final boolean recursive ) {
clearAll( recursive, true );
}
void clearAll( final boolean recursive, final boolean doVisualUpdate ) {
checkWidget();
if( itemHolder.size() == 0 ) {
return;
}
/* clear the item(s) */
for( int i = 0; i < itemHolder.size(); i++ ) {
final TreeItem treeItem = ( ( TreeItem )itemHolder.getItem( i ) );
treeItem.clear();
if( recursive ) {
treeItem.clearAll( true, false );
}
if( ( parent.style & SWT.VIRTUAL ) == 0 ) {
parent.checkData( treeItem, treeItem.index );
}
}
}
// /////////////////////////////////////
// Methods to maintain (sub-) TreeItems
/**
* Returns a (possibly empty) array of <code>TreeItem</code>s which are the
* direct item children of the receiver.
* <p>
* Note: This is not the actual structure used by the receiver to maintain its
* list of items, so modifying the array will not affect the receiver.
* </p>
*
* @return the receiver's items
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public TreeItem[] getItems() {
checkWidget();
return ( TreeItem[] )itemHolder.getItems();
}
/**
* Returns the item at the given, zero-relative index in the receiver. Throws
* an exception if the index is out of range.
*
* @param index the index of the item to return
* @return the item at the given index
* @exception IllegalArgumentException <ul>
* <li>ERROR_INVALID_RANGE - if the index is not between 0 and
* the number of elements in the list minus 1 (inclusive)</li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public TreeItem getItem( final int index ) {
checkWidget();
return ( TreeItem )itemHolder.getItem( index );
}
/**
* Returns the number of items contained in the receiver that are direct item
* children of the receiver.
*
* @return the number of items
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public int getItemCount() {
checkWidget();
return itemHolder.size();
}
/**
* Searches the receiver's list starting at the first item (index 0) until an
* item is found that is equal to the argument, and returns the index of that
* item. If no item is found, returns -1.
*
* @param item the search item
* @return the index of the item
* @exception IllegalArgumentException <ul>
* <li>ERROR_NULL_ARGUMENT - if the tool item is null</li>
* <li>ERROR_INVALID_ARGUMENT - if the tool item has been
* disposed</li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public int indexOf( final TreeItem item ) {
checkWidget();
if( item == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
if( item.isDisposed() ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
return itemHolder.indexOf( item );
}
/**
* Removes all of the items from the receiver.
* <p>
*
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public void removeAll() {
checkWidget();
TreeItem[] items = getItems();
for( int i = 0; i < items.length; i++ ) {
items[ i ].dispose();
}
}
/**
* Sets the number of child items contained in the receiver.
*
* @param count the number of items
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* </li> <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @since 1.0
*/
public void setItemCount( final int count ) {
checkWidget();
parent.setItemCount( count, this );
}
/* package */boolean isCached() {
boolean result = true;
if( ( parent.getStyle() & SWT.VIRTUAL ) != 0 ) {
result = cached;
}
return result;
}
// ///////////////////////////////
// Methods to dispose of the item
final void releaseChildren() {
TreeItem[] items = getItems();
for( int i = 0; i < items.length; i++ ) {
items[ i ].dispose();
}
}
final void releaseParent() {
if( parentItem != null ) {
ItemHolder.removeItem( parentItem, this );
} else {
ItemHolder.removeItem( parent, this );
}
parent.removeFromSelection( this );
parent.updateScrollBars();
super.releaseParent();
}
// ////////////////
// helping methods
/* package */int getInnerHeight() {
int innerHeight = getItemCount() * 16;
for( int i = 0; i < getItemCount(); i++ ) {
TreeItem item = getItem( i );
if( item.getExpanded() ) {
innerHeight += item.getInnerHeight();
}
}
return innerHeight;
}
/* package */int getMaxInnerWidth( final TreeItem[] items, final int level ) {
int maxInnerWidth = 0;
for( int i = 0; i < items.length; i++ ) {
if( items[ i ] != null && items[ i ].isCached() ) {
int itemWidth = items[ i ].getPreferredWidth( 0, false ) + level * 19;
maxInnerWidth = Math.max( maxInnerWidth, itemWidth );
if( items[ i ].getExpanded() ) {
int innerWidth = getMaxInnerWidth( items[ i ].getItems(), level + 1 );
maxInnerWidth = Math.max( maxInnerWidth, innerWidth );
}
}
}
return maxInnerWidth;
}
final int getCheckWidth( final int index ) {
int result = 0;
if( index == 0 && parent.getColumnCount() == 0 ) {
result = parent.getCheckWidth();
} else {
int[] columnOrder = parent.getColumnOrder();
if( columnOrder[ 0 ] == index ) {
result = parent.getCheckWidth();
}
}
return result;
}
}