0001: /*
0002: * Stingray Software Objective Blend
0003: * Copyright (C) 1996 Stingray Software, Inc.
0004: * All Rights Reserved
0005: *
0006: * This source code is only intended as a supplement to
0007: * the Stingray Objective Blend product. See the Objective
0008: * Blend html help documentation for detailed information regarding
0009: * using OB classes.
0010: *
0011: * Author : Kerry Smith
0012: * Description : ListBox.java - list box
0013: *
0014: * CHANGELOG:
0015: * 7/09/96 LFW Created
0016: * 3/12/97 JDK1.1
0017: *
0018: */
0019:
0020: /**
0021: ListBox
0022:
0023: This class supports is the base class used for the standalone listbox
0024: control, the sortable and searchable listbox subclasses, and the
0025: Tree control.
0026:
0027: @author Copyright (c) 1997 Stingray Software, Inc., All Rights Reserved
0028: */package ob.listbox;
0029:
0030: import java.awt.*;
0031: import com.sun.portal.log.common.PortalLogger;
0032: import java.awt.event.*;
0033: import java.util.*;
0034: import ob.obbase.*;
0035: import ob.text.*;
0036:
0037: public class ListBox extends OBBase implements ItemSelectable,
0038: ActionListener {
0039:
0040: public static final int LVXC_UNINITIALIZED = -1;
0041:
0042: protected int m_nWidthGap = 11; // indent spacing for text
0043: protected int m_nRowSpace = 0; // spacing between rows
0044:
0045: /**
0046: * Left formatting style
0047: */
0048: public static final int FMT_LEFT = 0; // left alignment
0049:
0050: /**
0051: * Center formatting style
0052: */
0053: public static final int FMT_CENTER = 1; // center alignment
0054:
0055: /**
0056: * Right formatting style
0057: */
0058: public static final int FMT_RIGHT = 2; // right alignment
0059:
0060: /**
0061: * No column resizing style
0062: */
0063: public static final int NONE = 0; // no column resizing
0064:
0065: /**
0066: * Resizing allowed style
0067: */
0068: public static final int RESIZE = 1; // currently resizing
0069:
0070: /**
0071: * Default column width
0072: */
0073: public static final int DEFAULT_COL_WIDTH = 100; // column width used if not specified.
0074:
0075: protected int DottedLineSpace = 1; //default spacing for dotted // line is 1 in pixels
0076: protected int DottedLineFill = 1; //default solid 1
0077:
0078: // members used for drawing & measuring items & subitems
0079: protected Rectangle m_recPCRect = new Rectangle();
0080: protected Column m_colPCol = new Column();
0081: protected int m_lvi_iSubItem = 0;
0082: protected int m_lvi_iItem = 0;
0083: protected int m_PCheight = LVXC_UNINITIALIZED;
0084: protected String m_lvi_pszText = null;
0085: // end members used for drawing & measuring items & subitems
0086:
0087: // Color used for optional grid lines.
0088: protected Color m_colGridLines = SystemColor.windowBorder;
0089: protected Color m_colText = SystemColor.textText;
0090: protected Color m_colHighlightText = SystemColor.textHighlightText;
0091: protected Color m_colHighlightTextBackground = SystemColor.textHighlight;
0092:
0093: protected int m_nStyleGridLines = SOLID;
0094: public static final int DOTTED = 0;
0095: public static final int SOLID = 1;
0096:
0097: protected String commandTopRowChanged = "Top_Row_Changed";
0098: protected String commandDoubleClicked = "Double_Clicked";
0099: protected String commandLeftColChanged = "Left_Col_Changed";
0100: protected String commandItemDeleted = "Item_Deleted";
0101: public static String commandDragDrop = "Drag_Drop";
0102:
0103: /**
0104: * user devined event DRAGDROP for drag/drop action
0105: */
0106: public static final int DRAGDROP = 3001; // User defined Event ID.
0107:
0108: protected ItemListener itemListener;
0109: protected ActionListener actionListener;
0110:
0111: protected int selected[] = new int[0]; // holds selected item indexes
0112: protected int prev = -1; // keeps track of the previously selected item for traversal
0113:
0114: protected boolean m_bMouseDrag = false; // true when dragging
0115:
0116: protected boolean m_bHilightSubItems = true; // selection highlights entire row if true.
0117:
0118: public static Font defaultfont = new Font("TimesRoman", Font.PLAIN,
0119: 18); // font used if item font is not specified.
0120:
0121: protected Vector m_arrColumns = new Vector(); // vector holding columns
0122: protected Vector m_arrItems = new Vector(); // vector holding items
0123: protected int m_nSubItemCount = 0; // number of subItems for each item.
0124: protected int m_nTopRow = 0; // firstVisibleLine
0125: protected Point m_ptViewportOrg = new Point(0, 0); // used for scrolling
0126:
0127: protected int m_nItemsThisPage = 0; // keeps track of items visible on the current page
0128:
0129: protected boolean m_bMultipleSelections = true; // allows multiple selections. default true
0130:
0131: protected boolean m_bColumnHeader = false; // default shows no column header
0132: protected int m_cyHeader = 0; // header height, default shows no column header, so default column height is 0
0133:
0134: // Grid lines. default shows no grid lines
0135: protected boolean m_bColumnLines = false;
0136: protected boolean m_bItemLines = false;
0137:
0138: boolean m_bCaptured = false; // used in column resizing.
0139:
0140: protected boolean m_bEditModeAllowed = false;
0141: protected boolean m_bEditModeEnabled = false;
0142:
0143: protected boolean m_bOverlapEdit = false; //determine whether editing extends beyond the column
0144:
0145: protected int m_nColumnEdit = 0;
0146: protected ListItem m_itemCurrentEdit = new ListItem();
0147: protected ExpandableText m_textEditNode = null;
0148:
0149: protected Vector m_arrImages = null; // holds the images
0150: protected Vector m_arrImageIDs = null; // holds the ids
0151:
0152: protected int m_nOldTargetIndex = -1;
0153:
0154: // members used in resizing columns
0155: int m_nDraggingCurrent;
0156: int m_nDraggingBegin;
0157: int m_nDraggingState = NONE;
0158: Rectangle m_rectDragging = new Rectangle();
0159: // end members used in resizing columns
0160:
0161: protected boolean m_bAutoWrap = true; // default allows word wrapping
0162:
0163: private String OSName;
0164:
0165: protected boolean m_bDragModeEnabled = false; // whether an item is currently dragging
0166: protected boolean m_bDragModeAllowed = true; // whether drag&drop is allowed
0167: protected boolean m_bDrawDragImage = true;
0168:
0169: // members used to draw drag/drop images
0170: protected int m_nXMouse = -100;
0171: protected int m_nYMouse = -100;
0172: // end members used to draw drag/drop images
0173:
0174: protected Image m_imgDragPic = null; // image used when dragging & droppping
0175: protected int m_dropTargetItem = -1; // drop target
0176: protected boolean m_bDragDropDrawn = false; // whether the first image for drag/drop is drawn
0177:
0178: protected boolean m_bAllowDelete = false; // allow removal of items with Delete
0179: protected boolean m_bShowDotRect = true; //false;
0180:
0181: /**
0182: * Default ListBox constructor takes no parameters, sets up for no multiple selections
0183: * as a default.
0184: */
0185: public ListBox() {
0186: this (false);
0187: setLayout(null);
0188: }
0189:
0190: /**
0191: * ListBox constructor
0192: * @param multipleSelections whether multiple selections are allowed or not
0193: */
0194: public ListBox(boolean multipleSelections) {
0195: super (false);
0196: Font font = getFont();
0197: FontMetrics fontMetrics;
0198: if (font != null) {
0199: fontMetrics = getFontMetrics(font);
0200: } else {
0201: fontMetrics = getFontMetrics(defaultfont);
0202: }
0203: m_PCheight = fontMetrics.getHeight();
0204: m_bMultipleSelections = multipleSelections;
0205: m_bAlwaysShowScrollbar = false;
0206: setBackground(Color.white);
0207:
0208: insertColumn(0, "", FMT_LEFT, -1, 0, false);
0209:
0210: OSName = System.getProperty("os.name");
0211:
0212: m_textEditNode = new ExpandableText("");
0213: m_textEditNode.addActionListener(this );
0214: add(m_textEditNode);
0215: m_textEditNode.setVisible(false);
0216: }
0217:
0218: /**
0219: * addNotify is called when the component has been physically added to
0220: * a container
0221: */
0222: public void addNotify() {
0223: super .addNotify();
0224:
0225: if (m_arrColumns.size() == 1) {
0226: if (m_bAutoWrap) {
0227: ((Column) m_arrColumns.elementAt(0)).m_nCX = getInsideRect().width;//getBounds().width;
0228:
0229: reMeasureAllItems();
0230:
0231: } else {
0232: ((Column) m_arrColumns.elementAt(0)).m_nCX = getLogicalSize().x;
0233: if (getLogicalSize().x < getInsideRect().width)
0234: ((Column) m_arrColumns.elementAt(0)).m_nCX = getInsideRect().width;
0235: reMeasureAllItems();
0236: }
0237: }
0238: }
0239:
0240: /**
0241: * getTextColor returns the default text color used for this listbox.
0242: * @return default color as type Color
0243: */
0244: public Color getTextColor() {
0245: return m_colText;
0246: }
0247:
0248: /**
0249: * setTextColor sets the default text color of this listbox.
0250: * @param color the new text color of the listbox.
0251: */
0252: public void setTextColor(Color color) {
0253: m_colText = color;
0254: repaint();
0255: }
0256:
0257: /**
0258: * getMultipleSelections returns whether this listbox can select multiple items
0259: * simultaneously
0260: * @return multiple selection mode as type boolean
0261: */
0262: public boolean getMultipleSelections() {
0263: return m_bMultipleSelections;
0264: }
0265:
0266: /**
0267: * replaceItem replaces the item at the index with a new item.
0268: * @param newValue the new item.
0269: * @param index the position of the item to be replaced.
0270: */
0271: public synchronized void replaceItem(Object newValue, int index) {
0272: deleteItem(index);
0273: addItem(newValue, index, false);
0274: update();
0275: }
0276:
0277: /**
0278: * getSelectedItems returns the selected items on the list.
0279: * @return an array of selected items as an Object[] array.
0280: */
0281: public synchronized Object[] getSelectedItems() {
0282: int sel[] = getSelectedIndexes();
0283: Object obj[] = new Object[sel.length];
0284: for (int i = 0; i < sel.length; i++) {
0285: obj[i] = getItem(sel[i]);
0286: }
0287: return obj;
0288: }
0289:
0290: /**
0291: * Returns the selected items on the list in an array of Objects.
0292: * @see ItemSelectable
0293: * @return an array of selected items as an Object[] array.
0294: */
0295: public Object[] getSelectedObjects() {
0296: return getSelectedItems();
0297: }
0298:
0299: /**
0300: * retrieves the ListItem at the specified index (or which row)
0301: * @param index which position (row) you wish to retrieve the ListItem for
0302: * @return the item associated with the row as type ListItem
0303: * @see ListItem
0304: */
0305: public ListItem getItemAt(int index) {
0306: return (ListItem) (m_arrItems.elementAt(index));
0307: }
0308:
0309: /**
0310: * clear clears all items in the list.
0311: */
0312: public synchronized void clear() {
0313: m_arrItems = new Vector();
0314: selected = new int[0];
0315: prev = -1;
0316: m_nTopRow = 0;
0317:
0318: updateScrollbar();
0319: update();
0320: }
0321:
0322: /**
0323: * deletes the items from the starting to ending rows.
0324: * @param start starting row to delete from
0325: * @param end ending row to delete from
0326: */
0327: public synchronized void delItems(int start, int end) {
0328: deleteItems(start, end);
0329: }
0330:
0331: /**
0332: * deletes a row in the listbox.
0333: * @param nItem offset into the ListItems (or, which row) you want to delete
0334: */
0335: public synchronized void delItem(int nItem) {
0336: deleteItem(nItem);
0337: }
0338:
0339: /**
0340: * deleteItems deletes the items in the given range.
0341: * @param start the first index of the items to be deleted.
0342: * @param end the last index of the items to be deleted.
0343: */
0344: public synchronized void deleteItems(int start, int end) {
0345: // check if the indexes are valid
0346: if (start < 0 || start >= countItems() || end < 0
0347: || end >= countItems())
0348: return;
0349:
0350: // delete the items.
0351: for (int i = end; i >= start; i--)
0352: deleteItem(i);
0353: updateScrollbar();
0354: update();
0355: }
0356:
0357: /**
0358: * deleteItem deletes a single item from the listbox and forces an update
0359: * of the listbox to be drawn
0360: * @param nItem the item (or row) to be deleted
0361: * @return true if the item was successfully deleted, otherwise false
0362: */
0363: public synchronized boolean deleteItem(int nItem) {
0364: return deleteItem(nItem, 1);
0365: }
0366:
0367: /**
0368: * deleteItem deletes a single item from the listbox and optionally
0369: * refreshes the painting of the listbox.
0370: * @param nItem which item (or row) you wish to delete
0371: * @param bUpdate whether you wish to update the drawing after it is deleted
0372: * @return true if the item was successfully deleted, otherwise false
0373: */
0374: public synchronized boolean deleteItem(int nItem, boolean bUpdate) {
0375: return deleteItem(nItem, 1, bUpdate);
0376: }
0377:
0378: /**
0379: * deleteItem allows you to delete a contiguous set of ListItems (or rows).
0380: * If you specify too many items to be deleted, only those items which exist
0381: * will be deleted.
0382: * @param nItem the starting ListItem (or row) you wish to delete.
0383: * @param nCount how many ListItems (rows) you wish to delete
0384: * @return true if the all items were successfully deleted, otherwise false.
0385: */
0386: public synchronized boolean deleteItem(int nItem, int cCount) {
0387: return deleteItem(nItem, cCount, true);
0388: }
0389:
0390: /**
0391: * deleteItem allows you to delete a contiguous set of ListItems (or rows).
0392: * If you specify too many items to be deleted, only those items which exist
0393: * will be deleted. You can also set a parameter for whether the ListBox will
0394: * be automatically updated after the deletion occurs or not.
0395: * @param nItem the starting ListItem (or row) you wish to delete.
0396: * @param nCount how many ListItems (rows) you wish to delete
0397: * @param bUpdate whether you wish to force an update(true) or not (false)
0398: * @return true if the all items were successfully deleted, otherwise false.
0399: */
0400: public synchronized boolean deleteItem(int nItem, int cCount,
0401: boolean bUpdate) {
0402:
0403: ListItem pItem;
0404: int nIndex = 0;
0405: int val;
0406: int nLast, i;
0407:
0408: nLast = nItem + cCount - 1;
0409: //System.out.println("in deletItem.......");
0410: //System.out.println("nLast is ......" + nLast);
0411: if (nLast > m_arrItems.size() - 1) {
0412: nLast = m_arrItems.size() - 1;
0413: }
0414:
0415: //System.out.println("after assign nLast is ......" + nLast);
0416: if (nLast < 0)
0417: return true;
0418: //System.out.println("returning from deleteItem");
0419: Vector predeleteList = new Vector();
0420: for (int j = 0; j < selected.length; j++)
0421: predeleteList.addElement(m_arrItems.elementAt(selected[j]));
0422:
0423: synchronized (m_arrItems) {
0424: for (i = nItem; i <= nLast; i++) {
0425: pItem = (ListItem) m_arrItems.elementAt(i);//getItemAt(i);
0426: if (isSelected(i))
0427: deselect(i);
0428: m_arrItems.removeElementAt(i);
0429: predeleteList.removeElement(pItem);
0430: nLast--;
0431: i--;
0432: }
0433: } // synchronized(m_arrItems)
0434:
0435: // The selection, focus and drop hilite indexes may
0436: // be wrong after the delete. For example, if the
0437: // focus item was just deleted, we have to reset
0438: // m_nFocusIndex accordingly. Also, if items
0439: // preceeding the focus index where deleted, the
0440: // focus index must be adjusted to account for the
0441: // fewer items. The same logic applies to selected
0442: // items and the drop hilite index.
0443: for (int j = 0; j < predeleteList.size(); j++)
0444: select(getIndex((ListItem) predeleteList.elementAt(j)),
0445: false);
0446:
0447: processActionEvent(new ActionEvent(this , Event.ACTION_EVENT,
0448: commandItemDeleted));
0449:
0450: if (bUpdate) {
0451: updateScrollbar();
0452: update();
0453: }
0454: return true;
0455: }
0456:
0457: /**
0458: * deselects all items from the ListBox and force a redraw of the ListBox.
0459: */
0460: public synchronized void deselectAll() {
0461: deselectAll(true);
0462: }
0463:
0464: /**
0465: * deselectAll resets all selected items and optionally redraw the ListBox
0466: * control.
0467: * @param bUpdate determines whether the ListBox is completely redrawn or not.
0468: */
0469: public synchronized void deselectAll(boolean bUpdate) {
0470: selected = new int[0];
0471: prev = -1;
0472: if (bUpdate)
0473: update();
0474: }
0475:
0476: /**
0477: * creates a new ListItem instance
0478: * @return new instance of ListItem
0479: */
0480: public ListItem createNewItem() {
0481: ListItem pItem = new ListItem();
0482: return pItem;
0483: }
0484:
0485: /**
0486: * addItem adds a new "row" into the ListBox. For a multiple column
0487: * listbox, this will create a new item in column 0 of the ListBox with
0488: * a string entry you specify. The new row will be added as the last row.
0489: * @param item The string you wish to place in the left-most column.
0490: * @param bRepaint whether you wish to force a repaint of the ListBox after you
0491: * add the item
0492: */
0493: public synchronized void addItem(String item, boolean bRepaint) {
0494: addItem(item, -1, bRepaint);
0495: }
0496:
0497: /**
0498: * addItem adds a new "row" into the ListBox. For a multiple column
0499: * listbox, this will create a new item in column 0 of the ListBox with
0500: * a string entry you specify. The new row will be added as the last row.
0501: * @param item The string you wish to place in the left-most column.
0502: */
0503: public synchronized void addItem(String item) {
0504: addItem(item, -1, true);
0505: }
0506:
0507: /**
0508: * addItem adds a new "row" into the ListBox. For a multiple column
0509: * listbox, this will create a new item in column 0 of the ListBox with
0510: * a string entry you specify. The new row will be added as the last row.
0511: * @param item The string you wish to place in the left-most column.
0512: * @param iImage which image you wish to place with the item. The image is
0513: * an int offset into the stored array of images that the ListBox references.
0514: * @param bRepaint forces a repaint of the ListBox after you add the item
0515: */
0516: public synchronized void addItem(String item, int iImage,
0517: boolean bRepaint) {
0518: ListItem pItem = new ListItem();
0519: pItem.setText(item);
0520: pItem.setImage(iImage);
0521:
0522: m_arrItems.addElement(pItem);
0523:
0524: if (m_nSubItemCount > pItem.getSubItemCount() + 1) {
0525: for (int i = pItem.getSubItemCount(); i < m_nSubItemCount - 1; i++) {
0526: ((ListItem) m_arrItems.elementAt(m_arrItems.size() - 1))
0527: .addSubItem();
0528: }
0529: }
0530:
0531: updateScrollbar();
0532: if (bRepaint)
0533: update();
0534: }
0535:
0536: /**
0537: * adds a new "row" at the end of the ListBox based on the object being passed
0538: * in.
0539: * @param o the Object being passed in; must either be an instance of String or ListItem
0540: * @see ob.listbox.ListBox#createNewItem
0541: */
0542: public synchronized void addItem(Object o) {
0543: addItem(o, -1, true);
0544: }
0545:
0546: /**
0547: * adds a new "row" at the end of the ListBox based on the object being passed in.
0548: * @param o the Object being passed in; must either be an instance of String or ListItem
0549: * @param bRepaint forces a repaint of the ListBox after the item is added
0550: * @see ob.listbox.ListBox#createNewItem
0551: */
0552: public synchronized void addItem(Object o, boolean bRepaint) {
0553: addItem(o, -1, bRepaint);
0554: }
0555:
0556: /**
0557: * adds a new "row" at the end of the ListBox based on the object being passed in.
0558: * @param o the Object being passed in; must either be an instance of String or ListItem
0559: * @param iImage a reference to the image list stored in the ListBox class; specifying
0560: * a value will place an image with the new item.
0561: * @param bRepaint forces a repaint of the ListBox after the item is added
0562: * @see ob.listbox.ListBox#createNewItem
0563: */
0564: public synchronized void addItem(Object o, int iImage,
0565: boolean bRepaint) {
0566: /*ListItem listitem = new ListItem();
0567: listitem.copy((ListItem)o);
0568: listitem.m_rcText = new Rectangle();
0569: listitem.m_nCY = LVXC_UNINITIALIZED;
0570: addItem(listitem,iImage);*/
0571: if (o != null && o instanceof String)
0572: addItem((String) o, iImage, bRepaint);
0573: else if (o != null && o instanceof ListItem)
0574: addItem((ListItem) o, iImage, bRepaint);
0575: }
0576:
0577: /**
0578: * adds a new "row" at the end of the ListBox based on the object being passed in.
0579: * @param item the ListItem instance you wish to add.
0580: * @param bRepaint forces a repaint of the ListBox after the item is added
0581: * @see ob.listbox.ListBox#createNewItem
0582: */
0583: public synchronized void addItem(ListItem item, boolean bRepaint) {
0584: addItem(item, -1, bRepaint);
0585: }
0586:
0587: /**
0588: * adds a new "row" at the end of the ListBox based on the object being passed in.
0589: * @param item the ListItem instance you wish to add.
0590: * @see ob.listbox.ListBox#createNewItem
0591: */
0592: public synchronized void addItem(ListItem item) {
0593: addItem(item, -1, true);
0594: }
0595:
0596: /**
0597: * adds a new "row" at the end of the ListBox based on the object being passed in.
0598: * @param item the ListItem instance you wish to add.
0599: * @param iImage a reference to the image list stored in the ListBox class; specifying
0600: * a value will place an image with the new item.
0601: * @param bRepaint forces a repaint of the ListBox after the item is added
0602: * @see ob.listbox.ListBox#createNewItem
0603: */
0604: public synchronized void addItem(ListItem item, int iImage,
0605: boolean bRepaint) {
0606: item.setImage(iImage);
0607: m_arrItems.insertElementAt(item, m_arrItems.size());
0608:
0609: if (m_nSubItemCount > item.getSubItemCount() + 1) {
0610: for (int i = item.getSubItemCount(); i < m_nSubItemCount - 1; i++) {
0611: ((ListItem) m_arrItems.elementAt(m_arrItems.size() - 1))
0612: .addSubItem();
0613: }
0614: }
0615:
0616: updateScrollbar();
0617: if (bRepaint)
0618: update();
0619:
0620: }
0621:
0622: /**
0623: * inserts a ListItem (or inserts a new row) into the ListBox at the position
0624: * you specify.
0625: * @param nIndex which position (or row) you wish to insert at
0626: * @param item an instance of the ListItem to place in.
0627: * @see ob.listbox.ListBox#createNewItem
0628: */
0629: public synchronized void insertItem(int nIndex, ListItem item) {
0630: m_arrItems.insertElementAt(item, nIndex);
0631:
0632: if (m_nSubItemCount > item.getSubItemCount() + 1) {
0633: for (int i = item.getSubItemCount(); i < m_nSubItemCount - 1; i++) {
0634: ((ListItem) m_arrItems.elementAt(nIndex)).addSubItem();
0635: }
0636: } else {
0637: if (m_nSubItemCount < item.getSubItemCount() + 1) {
0638: for (int i = m_nSubItemCount; i < item
0639: .getSubItemCount() + 1; i++)
0640: insertColumn(i, "", FMT_LEFT, -1, -1, true);
0641: }
0642: }
0643: }
0644:
0645: /**
0646: * adds a new item (or row) to the ListBox with the specified string and font type.
0647: * @param item the String you wish to be placed in the rows header column (usually the leftmost column)
0648: * @param font which Font you wish the text to be displayed in.
0649: * @see ob.listbox.ListBox#createNewItem
0650: * @see ob.listbox.ListItem
0651: */
0652: public synchronized void addItem(String item, Font font) {
0653: addItem(item, font, -1);
0654: }
0655:
0656: /**
0657: * adds a new item (or row) to the ListBox with the specified string and font type.
0658: * @param item the String you wish to be placed in the rows header column (usually the leftmost column)
0659: * @param font which Font you wish the text to be displayed in.
0660: * @param iImage a reference to the image list stored in the ListBox class; specifying
0661: * a value will place an image with the new item.
0662: * @see ob.listbox.ListBox#createNewItem
0663: * @see ob.listbox.ListItem
0664: */
0665: public synchronized void addItem(String item, Font font, int iImage) {
0666:
0667: ListItem pItem = new ListItem();
0668: pItem.setText(item);
0669: pItem.setFont(font);
0670: pItem.setImage(iImage);
0671:
0672: m_arrItems.addElement(pItem);
0673: if (m_nSubItemCount > pItem.getSubItemCount() + 1) {
0674: for (int i = pItem.getSubItemCount(); i < m_nSubItemCount - 1; i++) {
0675:
0676: ((ListItem) m_arrItems.elementAt(m_arrItems.size() - 1))
0677: .addSubItem();
0678: }
0679: }
0680: updateScrollbar();
0681: update();
0682: }
0683:
0684: /**
0685: * adds a new subitem to the ListItem. A subitem corresponds to the data that is
0686: * stored in a column of a row. addSubItem simply attaches a new column of data
0687: * to the row you specify. The subitem will be displayed in a visible state.
0688: * @param item which ListItem (or which row) you wish to append to
0689: * @param subitem the text you wish to associate with the column
0690: * @see ob.listbox.ListSubItem
0691: * @see ob.listbox.ListItem
0692: */
0693: public synchronized void addSubItem(int item, String subitem) {
0694: addSubItem(item, subitem, true);
0695: }
0696:
0697: /**
0698: * adds a new subitem to the ListItem. A subitem corresponds to the data that is
0699: * stored in a column of a row. addSubItem simply attaches a new column of data
0700: * to the row you specify.
0701: * @param item which ListItem (or which row) you wish to append to
0702: * @param subitem the text you wish to associate with the column
0703: * @param bShowSubItem whether the new subitem is displayed or not.
0704: * @see ob.listbox.ListSubItem
0705: * @see ob.listbox.ListItem
0706: */
0707: public synchronized void addSubItem(int item, String subitem,
0708: boolean bShowSubItem) {
0709: if (item <= m_arrItems.size() - 1) {
0710:
0711: ((ListItem) m_arrItems.elementAt(item)).addSubItem(subitem);
0712: if (bShowSubItem) {
0713: if (m_arrColumns.size() - 1 < ((ListItem) m_arrItems
0714: .elementAt(item)).getSubItemCount()/*+1*/) {
0715: int nSubItems = ((ListItem) m_arrItems
0716: .elementAt(item)).getSubItemCount();
0717: for (int i = m_arrColumns.size() - 1; i < nSubItems; i++) {
0718: insertColumn(i, "", FMT_LEFT, -1, -1, false);
0719: }
0720: }
0721:
0722: }
0723:
0724: }
0725:
0726: }
0727:
0728: /**
0729: * modifies the String contents of a given subitem.
0730: * @param item which item (row) you are modifying
0731: * @param subitem which subitem (column) you wish to modify
0732: * @param newSubitem the new String to place in the subitem
0733: * @see ob.listbox.ListSubItem
0734: * @see ob.listbox.ListItem
0735: */
0736: public void modifySubItem(int item, int subitem, String newSubitem) {
0737: if (item <= m_arrItems.size() - 1) {
0738: if (subitem <= ((ListItem) m_arrItems.elementAt(item))
0739: .getSubItemCount()) {
0740: ((ListItem) m_arrItems.elementAt(item))
0741: .getSubItem(subitem).pszText = newSubitem;
0742: }
0743: }
0744: }
0745:
0746: /**
0747: * add a new image to image list. The ListBox stores an internal Vectored list
0748: * of images which are used when you wish to display an image. When you wish to
0749: * display an image in a ListItem, you can specify an integer reference to this
0750: * Vectored list. It is up to you to keep track of which reference ID is associated
0751: * with each image. In this particular method, the default ID refers to the position
0752: * of the Image in the Vectored list. So, if you have 4 Images in the Vector already
0753: * and you add a new Image to the list by calling setImageList; your Image reference
0754: * number would simply be 5. It is possible to associate unique ID numbers to the
0755: * images as well (see the setImageList with 2 parameters).
0756: * @param image the image to add
0757: */
0758: public int setImageList(Image image) {
0759: if (m_arrImages == null) {
0760: m_arrImages = new Vector();
0761: m_arrImageIDs = new Vector();
0762: }
0763:
0764: int imageID = m_arrImages.size();
0765: setImageList(image, imageID);
0766:
0767: return imageID;
0768: }
0769:
0770: /**
0771: * add a new image to image list. The ListBox stores an internal Vectored list
0772: * of images which are used when you wish to display an image, as well as a mirrored
0773: * vectored list of integer ID values associated with those Images. When you wish to
0774: * display an image in a ListItem, you can specify an integer reference which is looked up
0775: * to find the correct Image. It is up to you to keep track of which reference ID is associated
0776: * with each image.
0777: * @param image the image to add
0778: * @param imageID the integer ID that is used to reference the Image you've just added.
0779: */
0780: public void setImageList(Image image, int imageID) {
0781:
0782: if (m_arrImages == null) {
0783: m_arrImages = new Vector();
0784: m_arrImageIDs = new Vector();
0785: }
0786: m_arrImages.addElement(image);
0787: m_arrImageIDs.addElement(new Integer(imageID));
0788: }
0789:
0790: /**
0791: * retrieves an Image from the Image Vectored list of the ListBox based on
0792: * the reference ID you pass in.
0793: * @param imageID the reference ID of the image you wish to retrieve
0794: * @return the matched Image.
0795: */
0796: public Image getImageList(int imageID) {
0797: int imageIndex = m_arrImageIDs.indexOf(new Integer(imageID));
0798: Image img = (Image) m_arrImages.elementAt(imageIndex);
0799:
0800: return img;
0801: }
0802:
0803: protected int getImageIndex(int imageID) {
0804: if (m_arrImageIDs == null)
0805: return -1;
0806:
0807: return m_arrImageIDs.indexOf(new Integer(imageID));
0808: }
0809:
0810: /**
0811: * retrieves the reference to the Image stored in the ListItem
0812: * @param ListItem which ListItem you are retrieving from
0813: * @return the index of item's image
0814: * @see ob.listbox.ListItem
0815: */
0816: public int getItemImage(ListItem item) {
0817: return item.getImage();
0818: }
0819:
0820: /**
0821: * sets the color to use for the grid lines if drawn.
0822: * @param c Color to use when drawing grid lines
0823: * @see ob.listbox.ListBox#setGridLines
0824: */
0825: public void setGridLineColor(Color c) {
0826: m_colGridLines = c;
0827: }
0828:
0829: /**
0830: * sets the color to use for highlighted text.
0831: * @param c Color to use when drawing highlighted text
0832: */
0833: public void setHighlightTextColor(Color c) {
0834: m_colHighlightText = c;
0835: }
0836:
0837: /**
0838: * retrieves the default color of the highlighted text
0839: * @return highlighted text color as type Color
0840: */
0841: public Color getHighlightTextColor() {
0842: return m_colHighlightText;
0843: }
0844:
0845: /**
0846: * sets the background color to use for highlighted text
0847: * @param c Color to use when drawing background of highlighted text
0848: */
0849: public void setHighlightTextBgColor(Color c) {
0850: m_colHighlightTextBackground = c;
0851: }
0852:
0853: /**
0854: * gets the default background color of the highlighted text
0855: * @return highlighted background text color as type Color
0856: */
0857: public Color getHighlightTextBgColor() {
0858: return m_colHighlightTextBackground;
0859: }
0860:
0861: /**
0862: * sets whether grid lines are drawn or not
0863: * @param bDraw true if grid lines should be drawn, otherwise false.
0864: * @see ob.listbox.ListBox#setColumnLines
0865: * @see ob.listbox.ListBox#setGridLineColor
0866: */
0867: public void setGridLines(boolean bDraw) {
0868: m_bColumnLines = bDraw;
0869: m_bItemLines = bDraw;
0870: }
0871:
0872: /**
0873: * sets whether column lines are drawn or not
0874: * @param bDraw true if column lines should be drawn, otherwise false
0875: * @see ob.listbox.ListBox#setGridLines
0876: * @see ob.listbox.ListBox#setItemLines
0877: */
0878: public void setColumnLines(boolean bDraw) {
0879: m_bColumnLines = bDraw;
0880: }
0881:
0882: /**
0883: * sets whether row lines are drawn or not
0884: * @param bDraw true if row lines should be drawn, otherwise false
0885: * @see ob.listbox.ListBox#setColumnLines
0886: * @see ob.listbox.ListBox#setGridLines
0887: */
0888: public void setItemLines(boolean bDraw) {
0889: m_bItemLines = bDraw;
0890: }
0891:
0892: /**
0893: * sets the grid line style
0894: * @param style can either be DOTTED for dotted line, or SOLID for solid line.
0895: * @see ob.listbox.ListBox#setGridLineColor
0896: */
0897: public void setGridLineStyle(int style) {
0898: if (style == DOTTED)
0899: m_nStyleGridLines = DOTTED;
0900: else
0901: m_nStyleGridLines = SOLID;
0902: }
0903:
0904: /**
0905: * sets whether the items are autowrapped or not. If there is not enough
0906: * space to display the full text of an item or subitem and autowrap mode
0907: * is on, the size of the row will dynamically expand or collapse to include
0908: * enough space to display the text.
0909: * @param bWrap true if autowrap is to be turned on, otherwise false.
0910: */
0911: public void setAutoWrap(boolean bWrap) {
0912: m_bAutoWrap = bWrap;
0913: }
0914:
0915: /**
0916: * gets whether the items are autowrapped or not. If there is not enough
0917: * space to display the full text of an item or subitem and autowrap mode
0918: * is on, the size of the row will dynamically expand or collapse to include
0919: * enough space to display the text.
0920: * @return true if autowrap is to be turned on, otherwise false.
0921: */
0922: public boolean getAutoWrap() {
0923: return m_bAutoWrap;
0924: }
0925:
0926: /**
0927: * sets whether list items or subitems can have their text edited or not.
0928: * @param bAllowEdit true if editing is allowed, otherwise false.
0929: */
0930: public void setEditMode(boolean bAllowEdit) {
0931: m_bEditModeAllowed = bAllowEdit;
0932: }
0933:
0934: /**
0935: * If the ListBox is in edit mode, this determines whether the editing will
0936: * extend beyond the boundaries of the edited column.
0937: * @param bOverlap true if overlap should occur, otherwise false
0938: * @see ob.listbox.ListBox#setEditMode
0939: * @see ob.listbox.ListBox#isOverlapEditMode
0940: */
0941: public void setOverlapEditMode(boolean bOverlap) {
0942: m_bOverlapEdit = bOverlap;
0943: }
0944:
0945: /**
0946: * determines whether the overlap editing mode is set.
0947: * @return true if overlap mode is on, otherwise false.
0948: * @see ob.listbox.ListBox#setOverlapEditMode
0949: */
0950: public boolean isOverlapEditMode() {
0951: return m_bOverlapEdit;
0952: }
0953:
0954: /**
0955: * sets whether List items can be dragged and dropped
0956: * into other areas.
0957: * @param bAllowDrag true if drag and drop allowed, otherwise false
0958: */
0959: public void setDragDrop(boolean bAllowDrag) {
0960: m_bDragModeAllowed = bAllowDrag;
0961: }
0962:
0963: /**
0964: * sets whether an image is shown during a drag and drop operation.
0965: * @param bShowImage true if image should be displayed during drag and drop,
0966: * otherwise false.
0967: */
0968: public void setDrawDragImage(boolean bShowImage) {
0969: m_bDrawDragImage = bShowImage;
0970: }
0971:
0972: /**
0973: * sets whether the end user has the ability to delete items (rows) in the listbox.
0974: * @param bAllowDelete true if deletions allowed, otherwise false.
0975: */
0976: public void setAllowDelete(boolean bAllowDelete) {
0977: m_bAllowDelete = bAllowDelete;
0978: }
0979:
0980: /**
0981: * sets the space between items (or space between rows).
0982: * @param nSpace how much space in pixels should be between items (rows).
0983: */
0984: public void setLineSpacing(int nSpace) {
0985: m_nRowSpace = nSpace;
0986: reMeasureAllItems();
0987: }
0988:
0989: /**
0990: * retrieves the space between lines (rows)
0991: * @return the space between lines as type int.
0992: */
0993: public int getLineSpacing() {
0994: return m_nRowSpace;
0995: }
0996:
0997: /**
0998: * sets the amount of space between "dots" when dotted line styles are used.
0999: * @param nSpace space in pixels between dots.
1000: * @see ob.listbox.ListBox#setGridLineStyle
1001: */
1002: public void setDottedLineSpace(int nSpace) {
1003: DottedLineSpace = nSpace;
1004: }
1005:
1006: /**
1007: * retrieves the amount of space between "dots" when dotted line styles are used.
1008: * @return space in pixels as type int.
1009: * @see ob.listbox.ListBox#setGridLineStyle
1010: */
1011: public int getDottedLineSpace() {
1012: return DottedLineSpace;
1013: }
1014:
1015: /**
1016: * sets dotted line fill space.
1017: * @param nFill amount of fill space used for dotted lines
1018: */
1019: public void setDottedLineFill(int nFill) {
1020: DottedLineFill = nFill;
1021: }
1022:
1023: /**
1024: * get the fill space for dotted line styles
1025: * @return fill space as type int
1026: */
1027: public int getDottedLineFill() {
1028: return DottedLineFill;
1029: }
1030:
1031: public void setShowDotRect(boolean bShowDotRect) {
1032: m_bShowDotRect = bShowDotRect;
1033: }
1034:
1035: public boolean isShowDotRect() {
1036: return m_bShowDotRect;
1037: }
1038:
1039: /**
1040: * sets whether subitems are highlighted or not.
1041: * @param bHighlight true if subitems should be highlighted when selected,
1042: * otherwise false.
1043: */
1044: public void setHilightSubItems(boolean bHighlight) {
1045: m_bHilightSubItems = bHighlight;
1046: }
1047:
1048: /**
1049: * retrieves whether the subitems are highlighted or not.
1050: * @return true if subitems are highlighted; otherwise false
1051: */
1052: public boolean getHilightSubItems() {
1053: return m_bHilightSubItems;
1054: }
1055:
1056: /**
1057: * retrieves the default font used for the ListBox
1058: * @return default font as type Font
1059: * @see ob.listbox.ListBox#setDefaultFont
1060: * @see ob.listbox.ListItem#setFont
1061: */
1062: public Font getDefaultFont() {
1063: return defaultfont;
1064: }
1065:
1066: /**
1067: * sets the default font for the entire ListBox
1068: * @param font default font as type Font
1069: * @see ob.listbox.ListBox#getDefaultFont
1070: * @see ob.listbox.ListItem#setFont
1071: */
1072: public void setDefaultFont(Font font) {
1073: defaultfont = font;
1074: }
1075:
1076: /**
1077: * sets whether column headers should be displayed or not.
1078: * @param bHeaders true if headers should be displayed , otherwise false
1079: */
1080: public void setColumnHeader(boolean bHeaders) {
1081: m_bColumnHeader = bHeaders;
1082: if (!bHeaders) {
1083: m_cyHeader = 0;
1084: } else
1085:
1086: update();
1087: }
1088:
1089: /**
1090: * determines whether column headers are being displayed or not.
1091: * @return true if column headers are being used, otherwise false.
1092: */
1093: public boolean isColumnHeader() {
1094: return m_bColumnHeader;
1095: }
1096:
1097: /**
1098: * sets the pixel height of Column headers if they are displayed.
1099: * @param nHeight height of the column headers as type int
1100: */
1101: public void setColumnHeaderHeight(int nHeight) {
1102: m_cyHeader = nHeight;
1103: update();
1104: }
1105:
1106: /**
1107: * returns the height of the column header in pixels
1108: * @return column pixel height as type int
1109: */
1110: public int getColumnHeaderHeight() {
1111: return m_cyHeader;
1112: }
1113:
1114: /**
1115: * retrieves the number of items (rows) in the list
1116: * @return number of items as type int
1117: */
1118: public int countItems() {
1119: return getItemCount();
1120: }
1121:
1122: /**
1123: * retrieves the number of items (rows) in the list
1124: * @return number of items as type int
1125: */
1126: public int getItemCount() {
1127: return m_arrItems.size();
1128: }
1129:
1130: /**
1131: * sets the default text indentation used in the listbox. This
1132: * is the spacing between the border of the column and where the
1133: * text and/or image is actually drawn, in pixels.
1134: * @param nIndent number of pixels indented as type int
1135: */
1136: public void setTextIndent(int nIndent) {
1137: m_nWidthGap = nIndent;
1138: }
1139:
1140: /**
1141: * retrieves the default text indentation used in the listbox.
1142: * @return default indentation used for text/images in a ListItem as type int
1143: * @see ob.listbox.ListBox#setTextIndent
1144: */
1145: public int getTextIndent() {
1146: return m_nWidthGap;
1147: }
1148:
1149: // NOT CURRENTLY IMPLEMENTED
1150: public void setTopIndent(int nIndent) {
1151: }
1152:
1153: public void setLeftIndent(int nIndent) {
1154: }
1155:
1156: public int getTopIndent() {
1157: return 0;
1158: }
1159:
1160: public int getLeftIndent() {
1161: return 0;
1162: }
1163:
1164: /**
1165: * inserts a new column into the ListBox in the position you indicate.
1166: * @param nCol which column position you wish to insert at
1167: * @param pColNew the new Column instance to insert
1168: * @param bUpdate true if you wish to refresh the drawing of the listbox after insertion
1169: * @return true if successfully inserted, otherwise false
1170: * @see ob.listbox.Column
1171: */
1172: public boolean insertColumn(int nCol, Column pColNew,
1173: boolean bUpdate) {
1174: ListItem pItem = new ListItem();
1175:
1176: int cSubItems; // mfc
1177: int nIndex; // mfc
1178:
1179: m_arrColumns.addElement(pColNew);
1180:
1181: cSubItems = m_nSubItemCount;
1182: // Set the subitem id
1183: if (pColNew.m_iSubItem == LVXC_UNINITIALIZED
1184: || pColNew.m_iSubItem > cSubItems) {
1185: // We must create a new sub item
1186: pColNew.m_iSubItem = cSubItems;// + 1;
1187:
1188: // Insert sub items for all existing items
1189: for (nIndex = 0; nIndex < m_arrItems.size(); nIndex++) {
1190: pItem = (ListItem) m_arrItems.elementAt(nIndex);
1191:
1192: if (pItem.getSubItemCount() < pColNew.m_iSubItem) {
1193: ((ListItem) m_arrItems.elementAt(nIndex))
1194: .addSubItem();
1195:
1196: }
1197: }
1198:
1199: // If the column width was unspecified, choose a default
1200: }
1201:
1202: if (pColNew.m_nCX == LVXC_UNINITIALIZED)
1203: ((Column) m_arrColumns.elementAt(m_arrColumns.size() - 1)).m_nCX = DEFAULT_COL_WIDTH;
1204:
1205: reMeasureAllItems();
1206:
1207: if (bUpdate)
1208: update();
1209:
1210: m_nSubItemCount++;
1211:
1212: return true;
1213: }
1214:
1215: /**
1216: * inserts a new column into the ListBox in the position you indicate with the
1217: * parameters you specify.
1218: * @param nCol which column position you wish to insert at
1219: * @param strHeader the String you wish placed in the column header
1220: * @param fmt the justification of the column; possible values include FMT_CENTER, FMT_LEFT, FMT_RIGHT
1221: * @param widthCol the column width in pixels
1222: * @param iSubItem width used for the subitem
1223: * @param bUpdate true if you wish to refresh the drawing of the listbox after insertion
1224: * @return true if successfully inserted, otherwise false
1225: */
1226: public boolean insertColumn(int nCol, String strHeader, int fmt,
1227: int widthCol, int iSubItem, boolean bUpdate) {
1228: Column pCol = new Column();
1229:
1230: pCol.m_nCX = widthCol;
1231:
1232: pCol.m_strText = strHeader;
1233: pCol.m_nFmt = fmt;
1234: pCol.m_iSubItem = iSubItem;
1235: return insertColumn(nCol, pCol, bUpdate);
1236: }
1237:
1238: // end column control
1239:
1240: /**
1241: * retrieves the size of the "inside" rectangle; that is, the size of the viewable
1242: * area of the ListBox.
1243: * @return inside rectangle as type Rectangle
1244: */
1245: public Rectangle getInsideRect() {
1246: Rectangle lpRect = getBounds();
1247:
1248: if (isHeaderCtrlEnabled()) {
1249: lpRect.y += m_cyHeader;
1250: lpRect.height -= (m_cyHeader);
1251: }
1252:
1253: if (vs != null /*&& vs.isShowing()*/)
1254: lpRect.width -= m_nVScrollbarWidth - 1;
1255: if (hs != null /*&& hs.isShowing()*/)
1256: lpRect.height -= m_nHScrollbarHeight - 1;
1257:
1258: return lpRect;
1259:
1260: }
1261:
1262: /**
1263: * determines whether the header control is enabled or not
1264: * @return true if header control is enabled; otherwise false
1265: */
1266: public boolean isHeaderCtrlEnabled() {
1267: return m_bColumnHeader;
1268: }
1269:
1270: /**
1271: * sets the width of a specified column in pixels
1272: * @param nCol which column to set
1273: * @param nWidth the width in pixels
1274: */
1275: public void setColumnWidth(int nCol, int nWidth) {
1276: if (nCol < m_arrColumns.size()) {
1277: ((Column) m_arrColumns.elementAt(nCol)).setWidth(nWidth);
1278: reMeasureAllItems();
1279: update();
1280: }
1281:
1282: }
1283:
1284: /**
1285: * sets whether multiple selections are allowed or not.
1286: * @param bMultipleSelections true if multiple selections should be used; otherwise false.
1287: */
1288: public void setMultipleSelections(boolean bMultipleSelections) {
1289: if (bMultipleSelections != m_bMultipleSelections) {
1290: m_bMultipleSelections = bMultipleSelections;
1291: }
1292: }
1293:
1294: /**
1295: * forces all items to remeasure themselves
1296: */
1297: public void reMeasureAllItems() {
1298: ListItem pItem = new ListItem();
1299: int i, c;
1300:
1301: c = m_arrItems.size();
1302: for (i = 0; i < c; i++) {
1303: ((ListItem) m_arrItems.elementAt(i)).m_nCY = LVXC_UNINITIALIZED;
1304: ((ListItem) m_arrItems.elementAt(i)).m_rcText.height = LVXC_UNINITIALIZED;
1305: }
1306:
1307: updateScrollbar();
1308: }
1309:
1310: protected int measureSubItem(Graphics g) {
1311:
1312: Rectangle rcItem;
1313:
1314: rcItem = new Rectangle(0, 0, m_colPCol.m_nCX, 0);
1315:
1316: if (m_lvi_pszText != null) {
1317: //measure the text height.
1318: Font font = ((ListItem) m_arrItems.elementAt(m_lvi_iItem))
1319: .getFont();
1320: FontMetrics fontMetrics;
1321: if (font != null) {
1322: fontMetrics = getFontMetrics(font);
1323: } else {
1324: fontMetrics = getFontMetrics(defaultfont);
1325: }
1326:
1327: if (m_bAutoWrap && m_lvi_pszText != null) {
1328:
1329: Vector wrapLines = new Vector();
1330: if (m_lvi_iSubItem == 0) {
1331: wrapLines = Text.wrapText(m_lvi_pszText,
1332: ((Column) m_arrColumns
1333: .elementAt(m_lvi_iSubItem)).m_nCX
1334: - m_nWidthGap
1335: * 2
1336: - ((ListItem) m_arrItems
1337: .elementAt(m_lvi_iItem))
1338: .getImageBounds().width,
1339: true, fontMetrics);
1340: } else
1341: wrapLines = Text.wrapText(m_lvi_pszText,
1342: ((Column) m_arrColumns
1343: .elementAt(m_lvi_iSubItem)).m_nCX
1344: - m_nWidthGap * 2, true,
1345: fontMetrics);
1346: rcItem.height = wrapLines.size()
1347: * (fontMetrics.getHeight());
1348:
1349: } else
1350: rcItem.height = fontMetrics.getHeight();
1351:
1352: m_PCheight = rcItem.height;
1353: m_recPCRect.height = rcItem.height;
1354:
1355: ((ListItem) m_arrItems.elementAt(m_lvi_iItem)).m_rcText.height = rcItem.height;
1356:
1357: if (m_arrColumns.size() > 1) {
1358: rcItem.width = ((Column) m_arrColumns
1359: .elementAt(m_lvi_iSubItem)).m_nCX;
1360: ((ListItem) m_arrItems.elementAt(m_lvi_iItem)).m_rcText.width = ((Column) m_arrColumns
1361: .elementAt(m_lvi_iSubItem)).m_nCX;
1362: } else {
1363: ((ListItem) m_arrItems.elementAt(m_lvi_iItem)).m_rcText.width = fontMetrics
1364: .stringWidth(m_lvi_pszText)
1365: + 2 * m_nWidthGap;
1366: rcItem.width = fontMetrics.stringWidth(m_lvi_pszText)
1367: + 2 * m_nWidthGap;
1368: if (rcItem.width > ((Column) m_arrColumns.elementAt(0)).m_nCX
1369: && !m_bAutoWrap)
1370: ((Column) m_arrColumns.elementAt(0)).m_nCX = Math
1371: .max(rcItem.width, getInsideRect().width);
1372:
1373: }
1374: }
1375:
1376: if (m_lvi_iSubItem == 0) {
1377: ((ListItem) m_arrItems.elementAt(m_lvi_iItem)).m_rcText = new Rectangle(
1378: rcItem);
1379: m_recPCRect = new Rectangle(rcItem);
1380: } else {
1381: ((ListItem) m_arrItems.elementAt(m_lvi_iItem))
1382: .getSubItem(m_lvi_iSubItem).rcText = new Rectangle(
1383: rcItem);//new rectangle added
1384: }
1385:
1386: return m_PCheight;
1387: }
1388:
1389: // returns the new height of the item.
1390: protected int measureItem(Graphics g) {
1391: int cySubItem;
1392: int cColumns;
1393: ListItem tempItem = new ListItem();
1394: tempItem = (ListItem) m_arrItems.elementAt(m_lvi_iItem);
1395: tempItem.m_nCY = 0;
1396: tempItem.m_rcText.height = 0;
1397: cySubItem = 0;
1398:
1399: cColumns = m_arrColumns.size();
1400:
1401: Image tempImage = null;
1402: int imageHeight = 0;
1403: int imageWidth = 0;
1404:
1405: for (int nCol = 0; nCol < cColumns; nCol++) {
1406: m_colPCol = (Column) m_arrColumns.elementAt(nCol);
1407:
1408: m_lvi_iSubItem = m_colPCol.m_iSubItem;
1409: if (m_lvi_iSubItem == 0) {
1410: int nImageID = ((ListItem) m_arrItems
1411: .elementAt(m_lvi_iItem)).getImage();
1412: int nIndex = getImageIndex(nImageID);
1413: if (m_lvi_iSubItem == 0 && m_arrImages != null
1414: && m_arrImages.size() > 0 && nIndex != -1
1415: && nIndex < m_arrImages.size()) {
1416:
1417: tempImage = (Image) m_arrImages.elementAt(nIndex);
1418: imageHeight = tempImage.getHeight(this );
1419: imageWidth = tempImage.getWidth(this );
1420: }
1421:
1422: ((ListItem) m_arrItems.elementAt(m_lvi_iItem))
1423: .setImageBounds(new Rectangle(0, 0, imageWidth,
1424: imageHeight));
1425: }
1426:
1427: if (m_colPCol.m_iSubItem > 0)
1428: m_lvi_pszText = (((ListItem) m_arrItems
1429: .elementAt(m_lvi_iItem))
1430: .getSubItem(m_lvi_iSubItem)).pszText;
1431: else
1432: m_lvi_pszText = ((ListItem) m_arrItems
1433: .elementAt(m_lvi_iItem)).m_pszText;
1434:
1435: if (imageHeight > tempItem.m_nCY)
1436: tempItem.m_nCY = imageHeight;
1437:
1438: cySubItem = measureSubItem(g);
1439:
1440: tempItem.m_nCY = Math.max(tempItem.m_nCY, cySubItem);
1441: tempItem.m_rcText.height = tempItem.m_nCY;
1442:
1443: ((ListItem) m_arrItems.elementAt(m_lvi_iItem)).m_nCY = tempItem.m_nCY;
1444:
1445: }
1446:
1447: m_PCheight = tempItem.m_nCY;
1448: m_recPCRect.height = tempItem.m_nCY;
1449: return m_PCheight;
1450: }
1451:
1452: /**
1453: * measures the height of a specified item in pixels
1454: * @param nItem which item(row) to measure
1455: * @param g current Graphics context
1456: * @return height of the item (row) in pixels as type int.
1457: */
1458: public int measureItem(int nItem, Graphics g) {
1459: m_lvi_iItem = nItem;
1460: return measureItem(g);
1461: }
1462:
1463: protected int itemsThisPage(Graphics g) {
1464: ListItem pItem = new ListItem();
1465:
1466: int cyRange;
1467: int cCount, i;
1468:
1469: Rectangle rcInside;
1470: rcInside = getInsideRect();
1471: rcInside.y = rcInside.y - getBounds().y;
1472: cyRange = 0;
1473: cCount = 0;
1474:
1475: for (i = m_nTopRow; i < m_arrItems.size(); i++, cCount++) {
1476: pItem = (ListItem) m_arrItems.elementAt(i);
1477: if (pItem.m_nCY == LVXC_UNINITIALIZED) {
1478: ((ListItem) m_arrItems.elementAt(i)).m_nCY = measureItem(
1479: i, g);
1480: pItem.m_nCY = ((ListItem) m_arrItems.elementAt(i)).m_nCY;
1481:
1482: }
1483:
1484: cyRange += pItem.m_nCY;
1485: FontMetrics fontmetrics = getFontMetrics(defaultfont);
1486: if (pItem.getFont() != null)
1487: fontmetrics = getFontMetrics(pItem.getFont());
1488: //AAB cyRange += (fontmetrics.getHeight())/4;
1489: cyRange += m_nRowSpace;
1490: if (cyRange > rcInside.height)
1491: break;
1492: }
1493:
1494: if (cyRange < rcInside.height) {
1495: i = m_nTopRow - 1;
1496:
1497: if (i >= 0) {
1498: for (; i >= 0; i--, cCount++) {
1499: pItem = (ListItem) m_arrItems.elementAt(i);
1500:
1501: if (pItem.m_nCY == LVXC_UNINITIALIZED) {
1502: ((ListItem) m_arrItems.elementAt(i)).m_nCY = measureItem(
1503: i, g);
1504: pItem.m_nCY = ((ListItem) m_arrItems
1505: .elementAt(i)).m_nCY;
1506: }
1507: cyRange += pItem.m_nCY;
1508: if (cyRange > rcInside.height)
1509: break;
1510: }
1511: }
1512: }
1513: m_nItemsThisPage = cCount;
1514: return cCount;
1515: }
1516:
1517: // returns a point
1518: // x coordinate is the width, y coordinate is the height.
1519: protected Point getLogicalSize() {
1520: int i, c;
1521: Point szLog = new Point(0, 0);
1522:
1523: szLog.y = m_arrItems.size();
1524: if (m_arrColumns.size() > 1) {
1525: c = m_arrColumns.size();
1526: for (i = 0; i < c; i++)
1527: szLog.x += ((Column) m_arrColumns.elementAt(i)).m_nCX;
1528: szLog.x = Math.max(szLog.x, getInsideRect().width);
1529: } else {//single column.
1530: Rectangle rcInside = new Rectangle();
1531: ListItem pItem = new ListItem();
1532: int cyRange;
1533:
1534: c = m_arrItems.size();
1535:
1536: int cxTextMax = 0;
1537: cyRange = 0;
1538: rcInside = getInsideRect();
1539:
1540: for (i = m_nTopRow; i < c && cyRange < rcInside.height; i++) {
1541: pItem = (ListItem) m_arrItems.elementAt(i);
1542:
1543: if (pItem.m_nCY == LVXC_UNINITIALIZED) {
1544: ((ListItem) m_arrItems.elementAt(i)).m_nCY = measureItem(
1545: i, getGraphics());
1546: pItem.m_nCY = ((ListItem) m_arrItems.elementAt(i)).m_nCY;
1547: }
1548:
1549: if (!m_bAutoWrap) {
1550:
1551: cxTextMax = Math.max(cxTextMax, pItem.m_rcText.x
1552: - getBounds().x + pItem.m_rcText.width
1553: + m_nWidthGap);//+ m_nWidthGap);
1554: } else {
1555: cxTextMax = Math.max(getInsideRect().width,
1556: ((Column) m_arrColumns.elementAt(0)).m_nCX);
1557: }
1558:
1559: cyRange += pItem.m_nCY;
1560: }
1561: szLog.x = Math.max(cxTextMax, ((Column) m_arrColumns
1562: .elementAt(0)).getWidth());
1563: }
1564: return szLog;
1565: }
1566:
1567: /**
1568: * retrieves the item number (row) of the last fully visible item
1569: * @return last visible item (row) as type int
1570: */
1571: public int getLastFullyVisibleItem() {
1572: ListItem pItem = new ListItem();
1573: int cyRange;
1574: int i;
1575:
1576: Rectangle rcInside = getInsideRect();
1577:
1578: cyRange = 0;
1579: for (i = m_nTopRow; i < m_arrItems.size(); i++) {
1580: pItem = (ListItem) m_arrItems.elementAt(i);
1581:
1582: if (pItem.m_nCY == LVXC_UNINITIALIZED)
1583: measureItem(i, getGraphics());
1584: cyRange += pItem.m_nCY;
1585:
1586: if (cyRange > rcInside.height)
1587: break;
1588: }
1589:
1590: return i - 1;
1591: }
1592:
1593: public synchronized void doLayout() {
1594:
1595: Scrollbar vs = getVScrollbar();
1596: Scrollbar hs = getHScrollbar();
1597:
1598: Rectangle rectInside;
1599: rectInside = getInsideRect();
1600: Rectangle bounds = getBounds();
1601: int w = bounds.width;
1602: int h = bounds.height;
1603: if (m_bAlwaysShowScrollbar || getMaxTopRow() != 0) {
1604: if (getMaxLeftCol() != 0 || m_bAlwaysShowScrollbar)
1605: hs.setBounds(0, h - m_nHScrollbarHeight, w
1606: - m_nVScrollbarWidth, m_nHScrollbarHeight);
1607:
1608: else {
1609: hs = null;
1610: }
1611: } else {
1612:
1613: if (getMaxLeftCol() != 0 || m_bAlwaysShowScrollbar)
1614: hs.setBounds(0, h - m_nHScrollbarHeight, w,
1615: m_nHScrollbarHeight);
1616:
1617: else {
1618: hs = null;
1619: }
1620: }
1621:
1622: if (m_bAlwaysShowScrollbar || getMaxLeftCol() != 0)
1623: if (getMaxTopRow() > 0 || m_bAlwaysShowScrollbar)
1624: vs.setBounds(w - m_nVScrollbarWidth, 0,
1625: m_nVScrollbarWidth, h - m_nHScrollbarHeight);
1626:
1627: else {
1628: vs = null;
1629: }
1630: else {
1631: if (getMaxTopRow() > 0 || m_bAlwaysShowScrollbar)
1632: vs.setBounds(w - m_nVScrollbarWidth, 0,
1633: m_nVScrollbarWidth, h);
1634:
1635: else {
1636: vs = null;
1637: }
1638: }
1639:
1640: }
1641:
1642: /**
1643: * updates the scrollbars based on the current area of the ListBox being displayed.
1644: */
1645: public void updateScrollbar() {
1646: Rectangle rcInside = new Rectangle();
1647:
1648: Point szLog = getLogicalSize();
1649: int cItemsThisPage = itemsThisPage(getGraphics());
1650: rcInside = getInsideRect();
1651: if (szLog.y > cItemsThisPage) {
1652: if (m_nTopRow > (szLog.y - cItemsThisPage))
1653: scrollVert((szLog.y - cItemsThisPage) - m_nTopRow);
1654:
1655: vs.setValues(m_nTopRow, cItemsThisPage, 0, m_arrItems
1656: .size());
1657: vs.setBlockIncrement(Math.max(cItemsThisPage, 1));
1658: showVScrollbar();
1659: } else {
1660: if (m_nTopRow > 0)
1661: scrollVert(-m_nTopRow);
1662: hideVScrollbar();
1663:
1664: }
1665:
1666: if (szLog.x > rcInside.width) {
1667: if (m_ptViewportOrg.x > (szLog.x - rcInside.width))
1668: scrollHorz((szLog.x - rcInside.width)
1669: - m_ptViewportOrg.x);
1670:
1671: hs.setValues(m_ptViewportOrg.x, rcInside.width, 0, szLog.x);//maximum problem
1672:
1673: hs.setBlockIncrement(Math.max(getInsideRect().width - 10,
1674: 10));
1675: hs.setUnitIncrement(10);
1676: showHScrollbar();
1677:
1678: }
1679:
1680: else {
1681: m_ptViewportOrg.x = 0;
1682: onLeftColChanged(m_ptViewportOrg.x);
1683: hideHScrollbar();
1684: }
1685:
1686: doLayout();
1687: }
1688:
1689: /**
1690: * This function scrolls the list up or down. The nScrollItems
1691: * argument indicates how many items to scroll the list by.
1692: * There is a complication: each item in the list can have a
1693: * different height. Therefore, it becomes ambiguous as to which
1694: * item's you mean to scroll. For example, you can scroll three
1695: * items off of the top of the list or three items into view from
1696: * the bottom of the list. These two cases may scroll the list
1697: * by different pixel deltas since the items at the top of the
1698: * list may have different heights than the items at the bottom.
1699: * This is what the bFromBottom flag is all about. If true, the
1700: * height of the items just off the bottom of the display are
1701: * summed in computing the total distance to scroll. If false,
1702: * the items at the top of the display are summed instead.
1703: * @param nScrollItems how many items you wish to scroll
1704: */
1705:
1706: public void scrollVert(int nScrollItems) {
1707: scrollVert(nScrollItems, false);
1708: }
1709:
1710: /**
1711: * This function scrolls the list up or down. The nScrollItems
1712: * argument indicates how many items to scroll the list by.
1713: * There is a complication: each item in the list can have a
1714: * different height. Therefore, it becomes ambiguous as to which
1715: * item's you mean to scroll. For example, you can scroll three
1716: * items off of the top of the list or three items into view from
1717: * the bottom of the list. These two cases may scroll the list
1718: * by different pixel deltas since the items at the top of the
1719: * list may have different heights than the items at the bottom.
1720: * This is what the bFromBottom flag is all about. If true, the
1721: * height of the items just off the bottom of the display are
1722: * summed in computing the total distance to scroll. If false,
1723: * the items at the top of the display are summed instead.
1724: * @param nScrollItems how many items you wish to scroll
1725: * @param bFromBottom count the items from the bottom
1726: */
1727: public void scrollVert(int nScrollItems, boolean bFromBottom) {
1728: int nFirst, nLast;
1729:
1730: if (!bFromBottom) {
1731: nFirst = m_nTopRow;
1732:
1733: nLast = nFirst + nScrollItems;
1734: nLast = Math.max(nLast, 0);
1735: nLast = Math.min(nLast, m_arrItems.size() - 1);//used to be size()-1
1736:
1737: nScrollItems = nLast - nFirst;
1738:
1739: if (nScrollItems != 0) {
1740: // Since we scroll by items (i.e. item granularity), all
1741: // we really have to do to scroll is increment/decrement
1742: // the value of m_nTopRow.
1743:
1744: m_nTopRow += nScrollItems;
1745: update();
1746: }
1747: } else {
1748: nFirst = getLastFullyVisibleItem();
1749: nLast = nFirst + nScrollItems;
1750: int cyScroll = calcRangeHeight(nFirst, nLast, true);
1751: nScrollItems = calcItemsInRange(cyScroll, m_nTopRow, true);
1752: scrollVert(nScrollItems, false);
1753: }
1754: }
1755:
1756: /**
1757: * scrolls the horizontal scrollbar by the number of pixels you specify
1758: * @param nPixels how many pixels you wish to scroll
1759: */
1760: public void scrollHorz(int nPixels) {
1761: Rectangle rcInside = getInsideRect();
1762: Point szLog;
1763:
1764: szLog = getLogicalSize();
1765:
1766: int xOrig = m_ptViewportOrg.x;
1767: m_ptViewportOrg.x -= nPixels;
1768: m_ptViewportOrg.x = Math.max(0, m_ptViewportOrg.x);
1769:
1770: m_ptViewportOrg.x = Math.min((szLog.x - rcInside.width),
1771: m_ptViewportOrg.x);
1772:
1773: onLeftColChanged(m_ptViewportOrg.x);
1774: nPixels = xOrig - m_ptViewportOrg.x;
1775: update();
1776:
1777: // Scroll the header too
1778: if (isHeaderCtrlEnabled()) {
1779: Rectangle rcClient, rcHeader;
1780: rcClient = getBounds();
1781: rcHeader = new Rectangle();
1782: rcHeader.y = rcClient.y;
1783: rcHeader.x = rcClient.x;
1784: rcHeader.width = rcClient.width;
1785: rcHeader.height = 0;
1786: update();
1787: }
1788:
1789: hs.setUnitIncrement(10);
1790: hs.setBlockIncrement(getInsideRect().width - 10);
1791: hs.setValue(m_ptViewportOrg.x);
1792: }
1793:
1794: protected int getMaxTopRow() {
1795: Rectangle rcInside = getInsideRect();
1796:
1797: int nLastIndex = m_arrItems.size() - 1;
1798: int i;
1799: ListItem pItem = new ListItem();
1800: int nTotalHeight = 0;
1801:
1802: for (i = nLastIndex; i >= 0; i--) {
1803: pItem = (ListItem) m_arrItems.elementAt(i);
1804: m_lvi_iItem = i;
1805: nTotalHeight += measureItem(i, getGraphics());
1806: if (nTotalHeight > rcInside.height)
1807: break;
1808:
1809: }
1810:
1811: return Math.max(0, i + 1);
1812: }
1813:
1814: protected int getMaxLeftCol() {
1815:
1816: Rectangle rcInside = getInsideRect();
1817: Point szLog = getLogicalSize();
1818: return ((szLog.x) - rcInside.width);
1819: }
1820:
1821: /**
1822: * sets the text for the column header
1823: * @param nCol which column you will be modifying
1824: * @param text the new text for the column header
1825: */
1826: public void setColumnText(int nCol, String text) {
1827: //sets the text for the column header
1828: ((Column) m_arrColumns.elementAt(nCol)).setText(text);
1829:
1830: }
1831:
1832: protected int getColumnHit(int xPos) {
1833: int col = 0;
1834: int width = 0;
1835:
1836: xPos = xPos + m_ptViewportOrg.x;
1837:
1838: while (width <= xPos && col < m_arrColumns.size()) {
1839: width += ((Column) m_arrColumns.elementAt(col++)).m_nCX;
1840: }
1841:
1842: return (col < m_arrColumns.size()) ? col - 1 : m_arrColumns
1843: .size() - 1;
1844: }
1845:
1846: protected int getPosFromCol(int nCol) {
1847: int xPos = 0 - m_ptViewportOrg.x;
1848: for (int i = 0; i < nCol + 1; i++) {
1849: xPos += ((Column) m_arrColumns.elementAt(i)).m_nCX;
1850: }
1851: return (xPos - 1);
1852: }
1853:
1854: /* DEPRECATED
1855: void setCursor(int cursorType) {
1856: Component frame;
1857: for ( frame=this; frame!=null; frame = frame.getParent())
1858: {
1859: Frame frame2;
1860: try { frame2 = (Frame) frame; }
1861: catch (ClassCastException cce)
1862: { continue; }
1863: frame2.setCursor(cursorType);
1864: break;
1865: }
1866: }
1867: */
1868:
1869: /**
1870: * This is function will tell you how many items will fit in a given height.
1871: * Since the list control allows variable height items, we must explicit
1872: * sum the heights of items to determine how many will fit within a pixel
1873: * range.
1874: *
1875: * @param cyRange The pixel height to count the number of items fitting.
1876: * @param nStartItem The index of the item to start the computation with.
1877: * @param bDown Indicates whether we should scan downward or upward from
1878: * the starting item in computing item count within range.
1879: */
1880:
1881: public int calcItemsInRange(int cyRange, int nStartItem,
1882: boolean bDown) {
1883:
1884: ListItem pItem = new ListItem();
1885: int cy;
1886: int nItems;
1887: int i;
1888:
1889: cy = 0;
1890: nItems = 0;
1891: if (bDown) {
1892: for (i = nStartItem; i < m_arrItems.size(); i++) {
1893: pItem = (ListItem) m_arrItems.elementAt(i);
1894:
1895: cy += pItem.m_nCY;
1896: nItems++;
1897: if (cy >= cyRange)
1898: break;
1899: }
1900: } else // up
1901: {
1902: for (i = nStartItem; i >= 0; i--) {
1903: pItem = (ListItem) m_arrItems.elementAt(i);
1904: cy += pItem.m_nCY;
1905: nItems++;
1906: if (cy >= cyRange)
1907: break;
1908: }
1909: }
1910:
1911: return nItems;
1912: }
1913:
1914: /**
1915: * This is function will tell you how many items will fit in a given height.
1916: * Since the list control allows variable height items, we must explicit
1917: * sum the heights of items to determine how many will fit within a pixel
1918: * range.
1919: *
1920: * @param nFirst The index of the first item to start the computation with
1921: * @param nLast The index of the last item to start the computation with.
1922: * @param bInclusive Indicates whether we should include the last item in
1923: * the calculation.
1924: * @return the range height in pixels as type int.
1925: */
1926: public int calcRangeHeight(int nFirst, int nLast, boolean bInclusive) {
1927:
1928: ListItem pItem = new ListItem();
1929: int cyRange;
1930: int i;
1931:
1932: boolean bNeg = false;
1933:
1934: if (nFirst > nLast) {
1935: int nSwap;
1936: nSwap = nFirst;
1937: nFirst = nLast;
1938: nLast = nSwap;
1939: bNeg = true;
1940: }
1941:
1942: cyRange = 0;
1943: for (i = nFirst; i < nLast || (bInclusive && i <= nLast); i++) {
1944: pItem = (ListItem) m_arrItems.elementAt(i);
1945: if (pItem.m_nCY == LVXC_UNINITIALIZED)
1946: measureItem(i, getGraphics());
1947: cyRange += pItem.m_nCY;
1948: }
1949:
1950: if (bNeg)
1951: cyRange *= -1;
1952:
1953: return cyRange;
1954: }
1955:
1956: // DRAWING FUNCTIONS
1957: /**
1958: * called when drawing an item (a full row)
1959: * @param g Graphics device
1960: */
1961: public void drawItem(Graphics g) {
1962: Rectangle rcCell = new Rectangle();
1963: int cColumns;
1964: Rectangle rcRow;
1965:
1966: rcRow = m_recPCRect;
1967:
1968: rcCell.y = rcRow.y;
1969: rcCell.height = rcRow.height;
1970: rcCell.x = rcRow.x;
1971: rcCell.width = 0;
1972:
1973: // Draw columns
1974: cColumns = m_arrColumns.size();
1975: for (int nCol = 0; nCol < cColumns; nCol++) {
1976: m_colPCol = (Column) m_arrColumns.elementAt(nCol);//++);
1977: if (cColumns > 1)
1978: rcCell.width = m_colPCol.m_nCX;
1979:
1980: else {
1981: rcCell.width = Math
1982: .max(
1983: m_colPCol.m_nCX,/*ELIMINATING m_LIPItem*/
1984: ((ListItem) m_arrItems
1985: .elementAt(m_lvi_iItem)).m_rcText.width);
1986: }
1987: if (rcCell.intersects(rcRow)) {
1988: m_lvi_iSubItem = m_colPCol.m_iSubItem;
1989: if (m_lvi_iSubItem != 0) {
1990: m_lvi_pszText = (((ListItem) m_arrItems
1991: .elementAt(m_lvi_iItem))
1992: .getSubItem(m_lvi_iSubItem))./*ELIMINATING m_LSIPSubItem*/pszText;
1993: } else
1994: m_lvi_pszText = ((ListItem) m_arrItems
1995: .elementAt(m_lvi_iItem)).m_pszText;
1996:
1997: m_recPCRect = new Rectangle(rcCell);
1998: drawSubItem(g);
1999:
2000: }
2001: rcCell.x = rcCell.x + rcCell.width;
2002:
2003: m_recPCRect.x = rcCell.x;
2004: }
2005:
2006: if (m_bItemLines)
2007: drawItemLines(g, rcRow);
2008:
2009: }
2010:
2011: /**
2012: * called when drawing a subitem (a single column of a single row)
2013: * @param g Graphics device
2014: */
2015: public void drawSubItem(Graphics g) {
2016:
2017: Rectangle bounds = getBounds();
2018:
2019: if (m_lvi_pszText != null) {
2020:
2021: if (((ListItem) m_arrItems.elementAt(m_lvi_iItem))
2022: .getFont() != null)
2023: g
2024: .setFont(((ListItem) m_arrItems
2025: .elementAt(m_lvi_iItem)).getFont());
2026: else
2027: g.setFont(defaultfont);
2028:
2029: int xp = m_recPCRect.x;
2030: FontMetrics fm = g.getFontMetrics();
2031: int nTextHigh = fm.getHeight();
2032:
2033: if (!m_bAutoWrap) {
2034: String str = "";
2035: int nImgWidth = 0;
2036: if (m_lvi_iSubItem == 0)
2037: nImgWidth = ((ListItem) m_arrItems
2038: .elementAt(m_lvi_iItem)).getImageBounds().width
2039: + m_nWidthGap;
2040:
2041: int nTotalWidth = fm.stringWidth(m_lvi_pszText)
2042: + nImgWidth;
2043: if (nTotalWidth > m_recPCRect.width - 2 * m_nWidthGap
2044: - (bounds.width - getInsideRect().width)) {
2045: int nDotWidth = fm.stringWidth(".");
2046: if (nImgWidth + m_nWidthGap + nDotWidth > m_recPCRect.width
2047: - (bounds.width - getInsideRect().width)) {//-2*m_nOffset)
2048: nTotalWidth = nImgWidth;
2049: str = " ";
2050: } else if (nImgWidth + m_nWidthGap + 2 * nDotWidth > m_recPCRect.width
2051: - (bounds.width - getInsideRect().width)) {//-2*m_nOffset) {
2052: nTotalWidth = nImgWidth + m_nWidthGap
2053: + nDotWidth;
2054: str = ".";
2055: } else if (nImgWidth + m_nWidthGap + 3 * nDotWidth > m_recPCRect.width
2056: - (bounds.width - getInsideRect().width)) {//-2*m_nOffset) {
2057: nTotalWidth = nImgWidth + m_nWidthGap + 2
2058: * nDotWidth;
2059: str = "..";
2060: } else {
2061: int j = 0;
2062: for (j = 1; j < m_lvi_pszText.length(); j++) {
2063: nTotalWidth = nImgWidth
2064: + 2
2065: * m_nWidthGap
2066: + fm.stringWidth(m_lvi_pszText
2067: .substring(0, j - 1)) + 3
2068: * nDotWidth;
2069: if (nTotalWidth > m_recPCRect.width)
2070: break;
2071: }
2072:
2073: if (j - 2 < 0)
2074: j = 2;
2075: str = m_lvi_pszText.substring(0, j - 2) + "...";
2076: nTotalWidth = nImgWidth + m_nWidthGap
2077: + fm.stringWidth(str);
2078: }
2079: }
2080: if (fm.stringWidth(m_lvi_pszText) + nImgWidth > m_recPCRect.width
2081: - 2 * m_nWidthGap)//-nImgWidth)
2082: m_lvi_pszText = str;
2083:
2084: if (!isSelected(m_lvi_iItem)
2085: || (m_lvi_iSubItem != 0 && !m_bHilightSubItems)) {
2086: g.setColor(m_colText);
2087: }
2088:
2089: else {
2090:
2091: if (m_bHasFocus) {
2092: g.setColor(m_colHighlightTextBackground);
2093: g.fillRect(m_recPCRect.x + 1, m_recPCRect.y
2094: - bounds.y + 1, m_recPCRect.width - 3,
2095: m_recPCRect.height - 1);
2096: if (m_bShowDotRect)
2097: drawDottedRect(g, m_recPCRect.x,
2098: m_recPCRect.y - bounds.y,
2099: m_recPCRect.width - 1,
2100: m_recPCRect.height);
2101: g.setColor(m_colHighlightText);
2102: } else {
2103: g.setColor(m_colText);
2104: drawDottedRect(g, m_recPCRect.x, m_recPCRect.y
2105: - bounds.y, m_recPCRect.width - 1,
2106: m_recPCRect.height);
2107: }
2108: }
2109:
2110: int xPos = m_recPCRect.x;
2111: if (m_lvi_iSubItem == 0)
2112: xPos += m_nWidthGap
2113: + ((ListItem) m_arrItems
2114: .elementAt(m_lvi_iItem))
2115: .getImageBounds().width;
2116: else
2117: xPos += m_nWidthGap;
2118:
2119: int yPos = m_recPCRect.y
2120: + ((ListItem) m_arrItems.elementAt(m_lvi_iItem)).m_rcText.height
2121: - bounds.y
2122: - /*ELIMINATING m_LIPItem*/((ListItem) m_arrItems
2123: .elementAt(m_lvi_iItem)).m_rcText.height
2124: / 4;
2125: int sLen = m_nWidthGap + fm.stringWidth(m_lvi_pszText);
2126: Column tempCol = ((Column) m_arrColumns
2127: .elementAt(m_lvi_iSubItem));
2128:
2129: if (tempCol.m_nFmt == FMT_CENTER) {
2130: if (sLen < tempCol.m_nCX)
2131: xPos = tempCol.m_nCX / 2 - (sLen - m_nWidthGap)
2132: / 2 + xPos - m_nWidthGap;
2133: } else if (tempCol.m_nFmt == FMT_RIGHT) {
2134: if (sLen < tempCol.m_nCX)
2135: xPos = tempCol.m_nCX - (sLen - m_nWidthGap)
2136: + xPos - 2 * m_nWidthGap;
2137: }
2138:
2139: int nImageID = ((ListItem) m_arrItems
2140: .elementAt(m_lvi_iItem)).getImage();
2141: int nIndex = getImageIndex(nImageID);
2142: if (m_lvi_iSubItem == 0 && nIndex != -1
2143: && m_arrImages != null
2144: && m_arrImages.size() > 0
2145: && nIndex < m_arrImages.size()) {
2146: int tempxPos = m_recPCRect.x + m_nWidthGap;
2147: int tempyPos = m_recPCRect.y - bounds.y;
2148: int nTextHeight = ((ListItem) m_arrItems
2149: .elementAt(m_lvi_iItem)).getTextBounds().height;
2150: int nImageHeight = ((ListItem) m_arrItems
2151: .elementAt(m_lvi_iItem)).getImageBounds().height;
2152: if (nTextHeight > nImageHeight) {
2153: tempyPos += ((nTextHeight - nImageHeight) / 2);
2154:
2155: }
2156:
2157: Image img = (Image) m_arrImages.elementAt(nIndex);
2158: if (img != null)
2159: g.drawImage(img, tempxPos, tempyPos, this );
2160: xPos += m_nWidthGap;
2161: }
2162: //System.out.println("Bina..... Drawing String in ListBox.java");
2163: g.drawString(m_lvi_pszText, xPos, yPos);
2164: } else { // autowrap true
2165:
2166: Vector nodeText = new Vector();
2167: if (m_lvi_iSubItem == 0)
2168: nodeText = Text.wrapText(m_lvi_pszText,
2169: ((Column) m_arrColumns
2170: .elementAt(m_lvi_iSubItem)).m_nCX
2171: - m_nWidthGap
2172: * 2
2173: - ((ListItem) m_arrItems
2174: .elementAt(m_lvi_iItem))
2175: .getImageBounds().width,
2176: true, fm);
2177: else
2178: nodeText = Text
2179: .wrapText(
2180: m_lvi_pszText,
2181: ((Column) m_arrColumns
2182: .elementAt(m_lvi_iSubItem)).m_nCX
2183: - m_nWidthGap * 2/*-((ListItem)m_arrItems.elementAt(m_lvi_iItem)).getImageBounds().width*/,
2184: true, fm);
2185: if (!isSelected(m_lvi_iItem)
2186: || (m_lvi_iSubItem != 0 && !m_bHilightSubItems)) {
2187: g.setColor(m_colText);
2188: } else {
2189: if (m_bHasFocus) {
2190: g.setColor(m_colHighlightTextBackground);
2191: g.fillRect(m_recPCRect.x + 1, m_recPCRect.y
2192: - bounds.y + 1, m_recPCRect.width - 3,
2193: m_recPCRect.height - 1);//KLS commented out height/4 and -2
2194: if (m_bShowDotRect)
2195: drawDottedRect(g, m_recPCRect.x,
2196: m_recPCRect.y - bounds.y,
2197: m_recPCRect.width - 1,
2198: m_recPCRect.height); //KLS commented out height/4
2199: g.setColor(m_colHighlightText);
2200: } else {
2201: g.setColor(m_colText);
2202: drawDottedRect(g, m_recPCRect.x, m_recPCRect.y
2203: - bounds.y, m_recPCRect.width - 1,
2204: m_recPCRect.height); //KLS commented out height/4
2205: }
2206: }
2207:
2208: int tempY = m_recPCRect.y;
2209: int xPos = m_recPCRect.x + m_nWidthGap;
2210: int yPos = nTextHigh - bounds.y - nTextHigh / 4;
2211: int sLen = 0;//m_nWidthGap + fm.stringWidth(m_lvi_pszText);
2212: Column tempCol = ((Column) m_arrColumns
2213: .elementAt(m_lvi_iSubItem));
2214: int nImageID = ((ListItem) m_arrItems
2215: .elementAt(m_lvi_iItem)).getImage();
2216: int nIndex = getImageIndex(nImageID);
2217:
2218: if (m_lvi_iSubItem == 0 && nIndex != -1
2219: && m_arrImages != null
2220: && m_arrImages.size() > 0
2221: && nIndex < m_arrImages.size()) {
2222: int tempxPos = m_recPCRect.x + m_nWidthGap;
2223: int tempyPos = m_recPCRect.y - bounds.y;
2224: int nTextHeight = fm.getHeight();//((ListItem)m_arrItems.elementAt(m_lvi_iItem)).getTextBounds().height;
2225: int nImageHeight = ((ListItem) m_arrItems
2226: .elementAt(m_lvi_iItem)).getImageBounds().height;
2227: if (nTextHeight > nImageHeight) {
2228: tempyPos += ((nTextHeight - nImageHeight) / 2);
2229: }
2230:
2231: Image img = (Image) m_arrImages.elementAt(nIndex);
2232: if (img != null)
2233: g.drawImage(img, tempxPos, tempyPos, this );
2234: xPos += m_nWidthGap;
2235: }
2236:
2237: for (int i = 0; i < nodeText.size(); i++) {
2238: xPos = m_recPCRect.x + m_nWidthGap;
2239: if (m_lvi_iSubItem == 0)
2240: xPos += ((ListItem) m_arrItems
2241: .elementAt(m_lvi_iItem))
2242: .getImageBounds().width;
2243: int imageID = ((ListItem) m_arrItems
2244: .elementAt(m_lvi_iItem)).getImage();
2245: if (m_lvi_iSubItem == 0 && imageID != -1
2246: && m_arrImages != null
2247: && m_arrImages.size() > 0
2248: && imageID < m_arrImages.size())
2249: xPos += m_nWidthGap;
2250: sLen = m_nWidthGap
2251: + fm.stringWidth((String) nodeText
2252: .elementAt(i));
2253: if (tempCol.m_nFmt == FMT_CENTER) {
2254: if (sLen < tempCol.m_nCX)
2255: xPos = tempCol.m_nCX / 2
2256: - (sLen - m_nWidthGap) / 2 + xPos
2257: - m_nWidthGap;
2258: } else if (tempCol.m_nFmt == FMT_RIGHT) {
2259: if (sLen < tempCol.m_nCX)
2260: xPos = tempCol.m_nCX - (sLen - m_nWidthGap)
2261: + xPos - 2 * m_nWidthGap;
2262: }
2263:
2264: //System.out.println("Trying to drawing string : .... Bina ListBox");
2265: g.drawString((String) nodeText.elementAt(i), xPos,
2266: tempY + yPos);
2267: tempY = tempY + nTextHigh + m_nRowSpace;
2268: }
2269:
2270: }
2271: }
2272: }
2273:
2274: protected void drawDottedLine(Graphics g, int x1, int y1, int x2,
2275: int y2) {
2276: //x1 -= bounds.x;
2277: //x2 -= bounds.x;
2278: int length = Math.abs(x1 - x2);
2279: boolean xSame = false;
2280: if (length == 0) {
2281: length = Math.abs(y1 - y2);
2282: xSame = true;
2283: }
2284:
2285: for (int i = 0; i <= length; i = i
2286: + (DottedLineSpace + DottedLineFill)) {
2287: if (xSame) {
2288: if (y1 < y2)
2289: g.drawLine(x1, y1 + i, x1, y1 + i + DottedLineFill
2290: - 1);
2291: else
2292: g.drawLine(x1, y2 + i, x1, y2 + i + DottedLineFill
2293: - 1);
2294: } else {
2295: if (x1 < x2)
2296: g.drawLine(x1 + i, y1, x1 + i + DottedLineFill - 1,
2297: y1);
2298: else
2299: g.drawLine(x2 + i, y1, x2 + i + DottedLineFill - 1,
2300: y1);
2301: }
2302: }
2303: }
2304:
2305: protected void drawDottedRect(Graphics g, int x1, int y1,
2306: int width, int height) {
2307: drawDottedLine(g, x1 + 1, y1, x1 + width, y1);
2308: drawDottedLine(g, x1, y1, x1, y1 + height);
2309: drawDottedLine(g, x1 + width, y1, x1 + width, y1 + height);
2310: drawDottedLine(g, x1, y1 + height, x1 + width, y1 + height);
2311: }
2312:
2313: public void drawInvalidItems(Graphics g) {
2314: Rectangle rcInside;
2315: Rectangle rcRow = new Rectangle();
2316: Point szLog;
2317:
2318: int cItemsThisPage;
2319: int c;
2320:
2321: c = m_arrItems.size();
2322:
2323: // Initialize the row bounding rectangle
2324: rcInside = getInsideRect();
2325: szLog = getLogicalSize();
2326: rcRow.y = rcInside.y;
2327: rcRow.y += 2;
2328: rcRow.x = -m_ptViewportOrg.x;
2329:
2330: rcRow.width = szLog.x;
2331:
2332: rcRow.height = 0;
2333: // Iterate through all rows and draw on the visible and
2334: // invalid ones
2335: cItemsThisPage = 0;
2336:
2337: for (m_lvi_iItem = m_nTopRow; m_lvi_iItem < c; m_lvi_iItem++, cItemsThisPage++) {
2338:
2339: if (((ListItem) m_arrItems.elementAt(m_lvi_iItem)).m_nCY == LVXC_UNINITIALIZED) {
2340: ((ListItem) m_arrItems.elementAt(m_lvi_iItem)).m_nCY = measureItem(g);
2341: }
2342: rcRow.height += ((ListItem) m_arrItems
2343: .elementAt(m_lvi_iItem)).m_nCY;
2344:
2345: Rectangle temp = getBounds();
2346: temp.x = 0;
2347: temp.width *= 2;
2348: boolean bDraw = rcRow.intersects(temp);
2349:
2350: if (bDraw) {
2351: m_recPCRect = rcRow;
2352: ((ListItem) m_arrItems.elementAt(m_lvi_iItem)).m_rcText.y = rcRow.y;
2353: drawItem(g);
2354:
2355: } else
2356: break;
2357:
2358: rcRow.y = rcRow.y + rcRow.height;// + rcRow.height/4; //+rcRow.height/4; LWang
2359: rcRow.y = rcRow.y + m_nRowSpace;
2360:
2361: rcRow.height = 0;
2362:
2363: if (rcRow.y > rcInside.height + /*rcRow.y*/rcInside.y)
2364: break;
2365: }
2366:
2367: vs.setVisibleAmount(itemsThisPage(g));
2368: vs.setMaximum(m_arrItems.size());
2369:
2370: vs.setValue(m_nTopRow);
2371: vs.setBlockIncrement(Math.max(cItemsThisPage, 1));
2372:
2373: if (m_bColumnLines && m_arrColumns.size() > 1)
2374: drawColumnLines(g);
2375: }
2376:
2377: /**
2378: * standard draw routine
2379: * @param g Graphics object
2380: */
2381: public void draw(Graphics g) {
2382:
2383: Rectangle bounds = getBounds();
2384:
2385: if (m_arrItems.size() == 0)
2386: return;
2387:
2388: if (m_nItemsThisPage == 0)
2389: updateScrollbar();
2390:
2391: Rectangle rectInside = getInsideRect();
2392:
2393: if (isHeaderCtrlEnabled()) {
2394: drawHeader(g);
2395: }
2396:
2397: // And finally, draw the contents of the list control
2398: if (m_nDraggingState == NONE)
2399: drawInvalidItems(g);
2400:
2401: if (vs != null && vs.isShowing() && hs != null
2402: && hs.isShowing()) {
2403: Rectangle rectClient, rectErase;
2404: rectInside = getInsideRect();
2405: rectClient = bounds;
2406: rectErase = new Rectangle();
2407:
2408: rectErase.x = rectClient.width - vs.getBounds().width;
2409: rectErase.width = rectClient.width - rectInside.width;
2410: rectErase.y = 0 + rectClient.height - hs.getBounds().height;
2411: rectErase.height = rectClient.height - rectInside.height;
2412: g.clearRect(rectErase.x, rectErase.y, rectErase.width,
2413: rectErase.height);
2414: }
2415:
2416: paintBorder(g, 0, 0, bounds.width, bounds.height, false);
2417:
2418: //drawFocusRect(g, 0, 0, bounds.width, bounds.height);
2419: }
2420:
2421: /**
2422: * draws the column lines
2423: * @param g Graphics object
2424: */
2425: public void drawColumnLines(Graphics g) {
2426: Rectangle bounds = getBounds();
2427:
2428: g.setColor(m_colGridLines);
2429: int xCoor = -m_ptViewportOrg.x;
2430: for (int i = 0; i < m_arrColumns.size(); i++) {
2431: xCoor = xCoor
2432: + ((Column) m_arrColumns.elementAt(i)).getWidth();
2433: if (m_nStyleGridLines == DOTTED)
2434: drawDottedLine(g, xCoor, m_cyHeader, xCoor, bounds.y
2435: + bounds.height);
2436: else
2437: g.drawLine(xCoor, m_cyHeader, xCoor, bounds.y
2438: + bounds.height);
2439: }
2440:
2441: }
2442:
2443: /**
2444: * draws the item lines (or the row lines)
2445: * @param g Graphics object
2446: * @param rcRow the rectangle covering the region to draw
2447: */
2448: public void drawItemLines(Graphics g, Rectangle rcRow) {
2449: Rectangle bounds = getBounds();
2450:
2451: g.setColor(m_colGridLines);
2452: if (m_nStyleGridLines == DOTTED)
2453: drawDottedLine(g, rcRow.x, rcRow.y + rcRow.height
2454: + m_nRowSpace / 2 - bounds.y/*+rcRow.height/4*/,
2455: rcRow.x + rcRow.width, rcRow.y + rcRow.height
2456: + m_nRowSpace / 2 - bounds.y/*+rcRow.height/4*/); //KLS took out height/4 and -2
2457:
2458: else
2459: g.drawLine(rcRow.x, rcRow.y + rcRow.height + m_nRowSpace
2460: / 2 - bounds.y/*+rcRow.height/4*/, rcRow.x
2461: + rcRow.width, rcRow.y + rcRow.height + m_nRowSpace
2462: / 2 - bounds.y/*+rcRow.height/4*/);//KLS took out height/4 and -2
2463: }
2464:
2465: private void drawHeader(Graphics g) {
2466: Column pCol;
2467: Rectangle rcHeader, rcClient;
2468: rcHeader = new Rectangle();
2469: Point szLog;
2470: int i;
2471: rcClient = getBounds();
2472: szLog = getLogicalSize();
2473:
2474: rcHeader.y = 0;
2475: rcHeader.height = m_cyHeader - 1;
2476: rcHeader.x = -m_ptViewportOrg.x;
2477: rcHeader.width = Math.max(szLog.x, rcClient.width + 1);
2478:
2479: g.setColor(getBackground());
2480: g.fillRect(rcHeader.x - 2, rcHeader.y, rcHeader.width,
2481: rcHeader.height);
2482: g.setColor(SystemColor.control);
2483: g.fill3DRect(rcHeader.x - 2, rcHeader.y, rcHeader.width,
2484: rcHeader.height, true);
2485: paintBorder(g, rcHeader.x + 2, rcHeader.y + 2,
2486: rcHeader.width - 2, rcHeader.height - 2, true);
2487:
2488: // Draw the column separators
2489: if (m_arrColumns.size() > 1) {
2490: int nColCount;
2491: nColCount = m_arrColumns.size();
2492: for (i = 0; i < nColCount; i++) {
2493: pCol = (Column) m_arrColumns.elementAt(i);
2494: rcHeader.width = pCol.m_nCX;
2495: g.drawLine(rcHeader.x + rcHeader.width, rcHeader.y,
2496: rcHeader.x + rcHeader.width, rcHeader.y
2497: + rcHeader.height);
2498: rcHeader.x = rcHeader.x + rcHeader.width;
2499: }
2500: }
2501:
2502: rcHeader.x = -m_ptViewportOrg.x;
2503:
2504: // Draw the column header text
2505: for (i = 0; i < m_arrColumns.size(); i++) {
2506: pCol = (Column) m_arrColumns.elementAt(i);
2507: rcHeader.width = pCol.m_nCX - 1;
2508:
2509: g.setFont(pCol.m_fonFont);
2510: String columnText = pCol.m_strText;
2511: FontMetrics fm = g.getFontMetrics(g.getFont());
2512: int nTotalWidth = fm.stringWidth(pCol.m_strText);
2513:
2514: String str = "";
2515: int nImgWidth = 0;
2516: if (nTotalWidth > pCol.m_nCX - m_nWidthGap) {
2517: int nDotWidth = fm.stringWidth(".");
2518: if (nImgWidth + m_nWidthGap + nDotWidth > pCol.m_nCX) {
2519: nTotalWidth = nImgWidth;
2520: str = " ";
2521: } else if (nImgWidth + m_nWidthGap + 2 * nDotWidth > pCol.m_nCX) {
2522: nTotalWidth = nImgWidth + m_nWidthGap + nDotWidth;
2523: str = ".";
2524: } else if (nImgWidth + m_nWidthGap + 3 * nDotWidth > pCol.m_nCX) {
2525: nTotalWidth = nImgWidth + m_nWidthGap + nDotWidth;
2526: str = "..";
2527: } else {
2528: int j = 0;
2529: for (j = 1; j < columnText.length(); j++) {
2530: nTotalWidth = nImgWidth
2531: + m_nWidthGap
2532: * 2
2533: + fm.stringWidth(columnText.substring(
2534: 0, j - 1)) + 3 * nDotWidth;
2535: if (nTotalWidth > pCol.m_nCX)
2536: break;
2537: }
2538: str = columnText.substring(0, j - 1) + "...";
2539: nTotalWidth = nImgWidth + m_nWidthGap
2540: + fm.stringWidth(str);
2541: }
2542: }
2543:
2544: if (fm.stringWidth(pCol.m_strText) > pCol.m_nCX
2545: - m_nWidthGap)
2546: columnText = str;
2547:
2548: int xPos = rcHeader.x + m_nWidthGap;
2549: int yPos = rcHeader.y + rcHeader.height - rcHeader.height
2550: / 4;
2551: int sLen = m_nWidthGap + fm.stringWidth(columnText);
2552:
2553: if (pCol.m_nFmt == FMT_CENTER) {
2554: if (sLen < pCol.m_nCX)
2555: xPos = pCol.m_nCX / 2 - (sLen - m_nWidthGap) / 2
2556: + xPos - m_nWidthGap;
2557: } else if (pCol.m_nFmt == FMT_RIGHT) {
2558: if (sLen < pCol.m_nCX)
2559: xPos = pCol.m_nCX - (sLen - m_nWidthGap) + xPos - 2
2560: * m_nWidthGap;
2561: }
2562:
2563: //System.out.println("Trying to drawing string : .... Bina ListBox");
2564: g.drawString(columnText, xPos, yPos);
2565: rcHeader.x = rcHeader.x + rcHeader.width + 1;
2566: }
2567: }
2568:
2569: private void paintBorder(Graphics g, int x, int y, int w, int h,
2570: boolean raised) {
2571:
2572: // paint the border.
2573:
2574: g.setColor(SystemColor.controlLtHighlight);
2575: if (raised) {
2576: g.drawLine(x, y, x + w, y);
2577: g.drawLine(x, y, x, y + h);
2578: } else {
2579: g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
2580: g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
2581: }
2582:
2583: g.setColor(SystemColor.controlHighlight);
2584: if (raised) {
2585: //g.drawLine(x, y, x+w-1, y);
2586: //g.drawLine(x, y, x, y+h-1);
2587: } else {
2588: g.drawLine(x + 1, y + h - 2, x + w - 2, y + h - 2);
2589: g.drawLine(x + w - 2, y + 1, x + w - 2, y + h - 2);
2590: }
2591:
2592: g.setColor(SystemColor.controlShadow);
2593: if (raised) {
2594: g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
2595: g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
2596: } else {
2597: g.drawLine(x, y, x + w - 1, y);
2598: g.drawLine(x, y, x, y + h - 1);
2599: }
2600:
2601: g.setColor(SystemColor.controlDkShadow);
2602: if (raised) {
2603: g.drawLine(x, y + h, x + w, y + h);
2604: g.drawLine(x + w, y, x + w, y + h);
2605: } else {
2606: g.drawLine(x + 1, y + 1, x + w - 2, y + 1);
2607: g.drawLine(x + 1, y + 1, x + 1, y + h - 2);
2608: }
2609: }
2610:
2611: /**
2612: * draws the focus rectangle for the dimensions passed in
2613: * @param g Graphics object
2614: * @param x start x position
2615: * @param y start y position
2616: * @param w width
2617: * @param h height
2618: */
2619: public void drawFocusRect(Graphics g, int x, int y, int w, int h) {
2620: //System.out.println("In drawFocuRect....");
2621: if (m_bHasFocus && getSelectedListItem() == null) {
2622: ListItem item = getItemAt(m_nTopRow);
2623: Rectangle r = item.getTextBounds();
2624:
2625: if (isColumnHeader()) {
2626: y += getColumnHeaderHeight();
2627: }
2628: drawDottedRect(g, x + 3, y + 3, w - 6, r.height);
2629: }
2630: }
2631:
2632: /**
2633: * getItem returns the item associated with the specified index.
2634: * @param index the item (row) index.
2635: * @return item as type Object
2636: */
2637: public Object getItem(int index) {
2638: return m_arrItems.elementAt(index);
2639: }
2640:
2641: /**
2642: * getSelectedIndex returns the currently selected index (row).
2643: * @return the current index as type int
2644: */
2645: public synchronized int getSelectedIndex() {
2646: int sel[] = getSelectedIndexes();
2647: return (selected.length == 1) ? selected[0] : -1;
2648: }
2649:
2650: /**
2651: * getSelectedIndexes returns the currently selected indexes.
2652: * @return selected index values as an int array (int [])
2653: */
2654: public synchronized int[] getSelectedIndexes() {
2655:
2656: return selected;
2657: }
2658:
2659: /**
2660: * Adds the specified item listener to recieve item events from
2661: * this list.
2662: * @param l the item listener
2663: */
2664: public void addItemListener(ItemListener l) {
2665: itemListener = AWTEventMulticaster.add(itemListener, l);
2666: }
2667:
2668: /**
2669: * Removes the specified item listener so it no longer receives
2670: * item events from this list.
2671: * @param l the item listener
2672: */
2673: public void removeItemListener(ItemListener l) {
2674: itemListener = AWTEventMulticaster.remove(itemListener, l);
2675: }
2676:
2677: /**
2678: * Adds the specified action listener to receive action events
2679: * from this list. Action events occur when a list item is
2680: * double-clicked or the top row has been changed.
2681: * @param l the action listener
2682: */
2683: public void addActionListener(ActionListener l) {
2684: actionListener = AWTEventMulticaster.add(actionListener, l);
2685: }
2686:
2687: /**
2688: * Removes the specified action listener so it no longer receives
2689: * action events from this list.
2690: * @param l the action listener
2691: */
2692: public void removeActionListener(ActionListener l) {
2693: actionListener = AWTEventMulticaster.remove(actionListener, l);
2694: }
2695:
2696: /**
2697: * Processes action events occurring on this component by
2698: * dispatching them to any registered ActionListener objects.
2699: * @param e the action event
2700: */
2701: protected void processActionEvent(ActionEvent e) {
2702: if (actionListener != null) {
2703: actionListener.actionPerformed(e);
2704: }
2705: }
2706:
2707: /**
2708: * Processes item events occurring on this list by
2709: * dispatching them to any registered ItemListener objects.
2710: * @param e the item event
2711: */
2712: protected void processItemEvent(ItemEvent e) {
2713: if (itemListener != null) {
2714: itemListener.itemStateChanged(e);
2715: }
2716: }
2717:
2718: protected boolean mouseMove(MouseEvent e, int x, int y) {
2719: int nCol = getColumnHit(x);
2720: int nColPos = getPosFromCol(nCol);
2721: int nNewCursorType;
2722:
2723: if ((y > 0 && y < m_cyHeader) && (Math.abs(x - nColPos) <= 3)
2724: && m_arrColumns.size() > 1) {
2725: m_nDraggingState = RESIZE;
2726: m_nDraggingCurrent = nCol;
2727: m_nDraggingBegin = nColPos
2728: - ((Column) m_arrColumns
2729: .elementAt(m_nDraggingCurrent)).m_nCX;//getColWidth(m_nDraggingCurrent);
2730: if (!m_bCaptured) {
2731: if (OSName.equals("Windows NT")
2732: || OSName.equals("Windows 95"))
2733: setCursor(Cursor
2734: .getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
2735: else
2736: setCursor(Cursor
2737: .getPredefinedCursor(Cursor.MOVE_CURSOR));
2738: }
2739: m_bCaptured = true;
2740: } else if ((y > 0 && y < m_cyHeader)
2741: && (Math.abs(nColPos
2742: + ((Column) m_arrColumns.elementAt(nCol)).m_nCX
2743: - x) <= 3) && m_arrColumns.size() > 1) {
2744: m_nDraggingState = RESIZE;
2745: m_nDraggingCurrent = nCol;
2746: m_nDraggingBegin = nColPos;
2747: if (!m_bCaptured) {
2748: if (OSName.equals("Windows NT")
2749: || OSName.equals("Windows 95"))
2750: setCursor(Cursor
2751: .getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
2752: else
2753: setCursor(Cursor
2754: .getPredefinedCursor(Cursor.MOVE_CURSOR));
2755: }
2756:
2757: m_bCaptured = true;
2758: } else {
2759: m_nDraggingState = NONE;
2760: if (m_bCaptured)
2761: setCursor(Cursor
2762: .getPredefinedCursor(Cursor.DEFAULT_CURSOR));
2763: m_bCaptured = false;
2764: onMoveOverItem(x, y);
2765: }
2766:
2767: return true;
2768: }
2769:
2770: protected void onMoveOverItem(int x, int y) {
2771: // used for rove mode, etc.
2772: }
2773:
2774: protected boolean mouseDrag(MouseEvent e, int x, int y) {
2775: m_bMouseDrag = true;
2776: m_bEditModeEnabled = false;
2777: if (m_nDraggingState == RESIZE && !(x - m_nDraggingBegin < -3)) {
2778: int nCol = getColumnHit(x);
2779: onMoveTracking(nCol, x);
2780: return true;
2781: } else {
2782: if (m_nDraggingState == RESIZE
2783: && (x - m_nDraggingBegin < -3))
2784: return true;
2785:
2786: if (m_bDragModeEnabled) {
2787: m_bEditModeEnabled = false;
2788: Graphics g = getGraphics();
2789: if (m_bDragDropDrawn) {
2790: printDragItem(g);
2791: } else
2792: m_bDragDropDrawn = true;
2793: m_nXMouse = x;
2794: m_nYMouse = y;
2795: printDragItem(g);
2796: g.dispose();
2797: }
2798:
2799: }
2800: return true;
2801: }
2802:
2803: public int getDropTargetItem() {
2804: return m_dropTargetItem;
2805: }
2806:
2807: public int getIndex(ListItem pItem) {
2808: return m_arrItems.indexOf(pItem);
2809: }
2810:
2811: public void moveItems(Object[] items, int targetIndex) {
2812: if (targetIndex == -1)
2813: return;
2814: for (int j = items.length - 1; j > -1; j--) {
2815: if (items[j] == m_arrItems.elementAt(targetIndex))
2816: return;
2817: }
2818:
2819: Vector premoveList = new Vector();
2820: for (int j = 0; j < selected.length; j++)
2821: premoveList.addElement(m_arrItems.elementAt(selected[j]));
2822:
2823: deselectAll(false);
2824:
2825: synchronized (m_arrItems) {
2826: for (int i = items.length - 1; i > -1; i--) {
2827: int nIndex = getIndex((ListItem) items[i]);
2828:
2829: if (nIndex > targetIndex) {
2830: nIndex++;
2831: }
2832: m_arrItems.insertElementAt(items[i], targetIndex);
2833: m_arrItems.removeElementAt(nIndex);
2834: targetIndex = getIndex((ListItem) items[i]);
2835: }
2836: } // synchronized(m_arrItems)
2837:
2838: for (int k = 0; k < premoveList.size(); k++)
2839: select(getIndex((ListItem) premoveList.elementAt(k)), false);
2840: update();
2841: }
2842:
2843: /**
2844: * printDragItem draws an image when user is performing the drag&drop operation.
2845: * overwrite this method to draw your prefered image.
2846: * @param g Graphics object
2847: */
2848: public void printDragItem(Graphics g) {
2849: // draw the drag image.
2850:
2851: g.setXORMode(getBackground());
2852: if (!m_bColumnHeader || m_nYMouse + 10 > m_cyHeader) {
2853: drawTargetHighLight(g);
2854: if (!m_bDrawDragImage)
2855: return;
2856:
2857: if (m_imgDragPic != null)
2858: g.drawImage(m_imgDragPic, m_nXMouse + 10,
2859: m_nYMouse + 10, this );
2860: else {
2861: g.setColor(Color.white);
2862: g.fillRect(m_nXMouse + 10, m_nYMouse + 10, 10, 10);
2863: g.setColor(Color.black);
2864: g.drawRect(m_nXMouse + 10, m_nYMouse + 10, 10, 10);
2865: }
2866:
2867: }
2868: }
2869:
2870: protected void drawTargetHighLight(Graphics g) {
2871:
2872: //System.out.println("In drawTargetHighlight");
2873: Rectangle bounds = getBounds();
2874:
2875: int index = getTarget(m_nXMouse, m_nYMouse);
2876:
2877: if (index == m_nOldTargetIndex)
2878: return;
2879: g.setColor(SystemColor.textHighlight);
2880:
2881: if (index >= 0 && !isSelected(index)) {
2882: g.setColor(Color.red);
2883: ListItem pItem = (ListItem) m_arrItems.elementAt(index);
2884: g.drawLine(0, pItem.getTextBounds().y - bounds.y, bounds.x
2885: + getInsideRect().width, pItem.getTextBounds().y
2886: - bounds.y);
2887: }
2888:
2889: if (m_nOldTargetIndex != -1 && !isSelected(m_nOldTargetIndex)) {
2890: g.setColor(Color.red);
2891: ListItem tempItem = (ListItem) m_arrItems
2892: .elementAt(m_nOldTargetIndex);
2893: g.drawLine(0, tempItem.getTextBounds().y - bounds.y,
2894: getInsideRect().width + bounds.x, tempItem
2895: .getTextBounds().y
2896: - bounds.y);
2897: }
2898: m_nOldTargetIndex = index;
2899: }
2900:
2901: /**
2902: * setDragDropImage sets the image to be displayed during drag&drop operation.
2903: * @param image the image to be displayed during drag&drop operation.
2904: */
2905: public void setDragDropImage(Image image) {
2906: m_imgDragPic = image;
2907: }
2908:
2909: protected boolean mouseExit(MouseEvent e, int x, int y) {
2910:
2911: setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
2912: return true;
2913: }
2914:
2915: protected void onMoveTracking(int nCol, int x) {
2916: Rectangle rcInside = getBounds();//getInsideRect();
2917:
2918: int nListWidth = rcInside.width;
2919: int nListHeight = rcInside.height;
2920:
2921: Graphics g = getGraphics();
2922: g.setColor(Color.red);
2923: g.setXORMode(getBackground());
2924: g.fillRect(m_rectDragging.x, m_rectDragging.y,
2925: m_rectDragging.width, m_rectDragging.height);
2926:
2927: m_rectDragging = new Rectangle(x, m_cyHeader, 1, nListHeight);
2928: g.fillRect(m_rectDragging.x, m_rectDragging.y,
2929: m_rectDragging.width, m_rectDragging.height);
2930:
2931: ((Column) m_arrColumns.elementAt(m_nDraggingCurrent)).m_nCX = Math
2932: .max(x - m_nDraggingBegin, 20);
2933: g = getGraphics();
2934: Rectangle m_rectClip = new Rectangle(m_nDraggingBegin, 0,
2935: nListWidth - m_nDraggingBegin, m_cyHeader);
2936: g.clipRect(m_rectClip.x, m_rectClip.y, m_rectClip.width,
2937: m_rectClip.height);
2938:
2939: update(g);
2940: }
2941:
2942: protected boolean mouseUp(MouseEvent e, int x, int y) {
2943: if (m_bDragModeEnabled) {
2944:
2945: //AAB m_bEditModeEnabled = false;
2946: m_bEditModeEnabled = false;
2947: Graphics g = getGraphics();
2948: if (m_bDragDropDrawn)
2949: printDragItem(g);
2950: m_bDragModeEnabled = false;
2951: m_bDragDropDrawn = false;
2952: m_dropTargetItem = getTarget(x, y);
2953: onDropAction();
2954: processActionEvent(new ActionEvent(this , DRAGDROP,
2955: commandDragDrop));
2956:
2957: }
2958:
2959: if (!m_bHasFocus)
2960: requestFocus();
2961:
2962: //check for end of tracking
2963: if (m_nDraggingState == RESIZE) {
2964: onEndTracking(m_nDraggingCurrent, x);
2965: m_bDragModeEnabled = false;
2966: m_bEditModeEnabled = false;
2967: m_bDragDropDrawn = false;
2968: m_bMouseDrag = false;
2969:
2970: return true;
2971: } else if (m_bEditModeEnabled) {
2972: editItem();
2973:
2974: m_bDragModeEnabled = false;
2975: m_bMouseDrag = false;
2976:
2977: }
2978:
2979: if (m_bSelectedItemChanged)
2980: processItemEvent(new ItemEvent(this ,
2981: ItemEvent.ITEM_STATE_CHANGED,
2982: getSelectedListItem(), ItemEvent.SELECTED));
2983:
2984: m_bDragModeEnabled = false;
2985: m_bEditModeEnabled = false;
2986: m_nOldTargetIndex = -1;
2987: m_bMouseDrag = false;
2988:
2989: return true;
2990: }
2991:
2992: protected int getTarget(int x, int y) {
2993: return getSelected(x, y);
2994: }
2995:
2996: protected void onDropAction() {
2997: //used for extra dropping actions
2998: }
2999:
3000: protected void editItem() {
3001: m_bEditModeEnabled = false;
3002: m_bDragModeEnabled = false;
3003: Rectangle bounds = getBounds();
3004:
3005: /*if (selected.length > 1)
3006: { int temp = selected[selected.length-1];
3007: selected = new int[0];
3008: select(temp);
3009: }*/
3010: m_itemCurrentEdit = getSelectedListItem();
3011: ListItem item = ((ListItem) m_arrItems
3012: .elementAt(selected[selected.length - 1]));
3013:
3014: m_nColumnEdit = 0;
3015: int totalWidth = 0;
3016: if (m_nXMouse < ((Column) m_arrColumns.elementAt(0)).getWidth()
3017: - m_ptViewportOrg.x) {
3018: m_textEditNode.setText(m_itemCurrentEdit.getText());
3019: } else {
3020: int i;
3021: totalWidth = ((Column) m_arrColumns.elementAt(0))
3022: .getWidth()
3023: - m_ptViewportOrg.x;
3024: for (i = 1; i < m_arrColumns.size(); i++) {
3025: totalWidth += ((Column) m_arrColumns.elementAt(i))
3026: .getWidth();
3027: if (m_nXMouse < totalWidth)
3028: break;
3029: }
3030: m_nColumnEdit = i;
3031: m_textEditNode.setText(m_itemCurrentEdit.getSubItem(i)
3032: .getText());
3033: totalWidth -= ((Column) m_arrColumns.elementAt(i))
3034: .getWidth();
3035: }
3036: m_textEditNode.setBorderStyle(Text.NORMAL);
3037: m_textEditNode.setTextHIndent(1);
3038: m_textEditNode.setTextVIndent(Text.STANDARD + 1);
3039: m_textEditNode.selectAll();
3040: m_textEditNode.setBorderColor(Color.black);
3041: Font font = m_itemCurrentEdit.getFont();
3042: if (font == null)
3043: font = defaultfont;
3044: m_textEditNode.setFont(font);
3045:
3046: if (m_nColumnEdit == 0)
3047: m_itemCurrentEdit.setText("");
3048: else
3049: m_itemCurrentEdit.getSubItem(m_nColumnEdit).setText("");
3050: deselectAll();
3051: m_textEditNode.selectAll();
3052: m_textEditNode.setVisible(true);
3053: m_textEditNode.requestFocus();
3054: int temp = item.getImageBounds().width;
3055: if (temp != 0)
3056: temp += m_nWidthGap;
3057:
3058: if (m_bOverlapEdit) {
3059: m_textEditNode.setFixedWidth(0);
3060: } else {
3061: int nWidth = 0;
3062: if (m_nColumnEdit == 0) {
3063: nWidth = ((Column) m_arrColumns
3064: .elementAt(m_nColumnEdit)).m_nCX
3065: - m_nWidthGap * 2 - item.getImageBounds().width;
3066: } else {
3067: nWidth = ((Column) m_arrColumns
3068: .elementAt(m_nColumnEdit)).m_nCX
3069: - m_nWidthGap * 2;
3070: }
3071: m_textEditNode.setFixedWidth(nWidth);
3072: }
3073:
3074: if (m_nColumnEdit == 0)
3075: m_textEditNode.setBounds(item.getTextBounds().x
3076: + m_nWidthGap - m_ptViewportOrg.x + temp, item
3077: .getTextBounds().y
3078: - bounds.y, item.getTextBounds().width, item
3079: .getTextBounds().height
3080: + m_nRowSpace + 1); //AAB item.getTextBounds().height/4);
3081: else
3082: m_textEditNode.setBounds(
3083: m_nWidthGap + totalWidth /*- m_ptViewportOrg.x*/,
3084: item.getTextBounds().y - bounds.y, item
3085: .getTextBounds().width, item
3086: .getTextBounds().height
3087: + m_nRowSpace + 1); //AAB item.getTextBounds().height/4);
3088:
3089: m_textEditNode.update();
3090: }
3091:
3092: public void actionPerformed(ActionEvent e) {
3093: if (e.getSource() == m_textEditNode
3094: && e.getActionCommand().equals(Text.endEditing)) {
3095: changeItemText();
3096: //reMeasureAllItems();
3097: //updateScrollbar();
3098: //update();
3099: }
3100: }
3101:
3102: protected boolean m_bHasFocus = false;
3103:
3104: protected void processFocusEvent(FocusEvent e) {
3105: switch (e.getID()) {
3106: case FocusEvent.FOCUS_GAINED:
3107: m_bHasFocus = true;
3108: update();
3109: break;
3110: case FocusEvent.FOCUS_LOST:
3111: m_bHasFocus = false;
3112: update();
3113: break;
3114: }
3115:
3116: super .processFocusEvent(e);
3117: }
3118:
3119: protected void onTopRowChanged(int nRow) {
3120: if (m_textEditNode != null && m_textEditNode.isShowing())
3121: changeItemText();
3122: if (m_nTopRow != nRow) {
3123: m_nTopRow = nRow;
3124: update();
3125:
3126: processActionEvent(new ActionEvent(this ,
3127: Event.ACTION_EVENT, commandTopRowChanged));
3128: }
3129: }
3130:
3131: protected void onLeftColChanged(int nCol) {
3132: if (m_textEditNode != null && m_textEditNode.isShowing())
3133: changeItemText();
3134: if (m_ptViewportOrg.x != nCol) {
3135: m_ptViewportOrg.x = nCol;
3136: update();
3137: processActionEvent(new ActionEvent(this ,
3138: Event.ACTION_EVENT, commandLeftColChanged));
3139: }
3140: }
3141:
3142: protected void changeItemText() {
3143:
3144: if (m_nColumnEdit == 0)
3145: m_itemCurrentEdit.setText(m_textEditNode.getText());
3146: else
3147: m_itemCurrentEdit.getSubItem(m_nColumnEdit).setText(
3148: m_textEditNode.getText());
3149: m_textEditNode.stop();
3150: m_textEditNode.setVisible(false);
3151: //measureItem(getIndex(m_itemCurrentEdit),getGraphics());
3152: //select(getIndex(m_itemCurrentEdit));
3153: reMeasureAllItems();
3154: update();
3155: //updateScrollbar();
3156: }
3157:
3158: /**
3159: * retrieves the currently selected ListItem (row)
3160: * @return currently selected ListItem, or null if none selected
3161: */
3162: public ListItem getSelectedListItem() {
3163: if (selected.length > 0
3164: && selected[selected.length - 1] < m_arrItems.size()) {
3165: return (((ListItem) m_arrItems
3166: .elementAt((selected[selected.length - 1]))));
3167: }
3168:
3169: return null;
3170: }
3171:
3172: /**
3173: * retrieves the text of the currently selected item
3174: * @return text of the currently selected item as type String
3175: */
3176: public String getSelectedItem() {
3177: if (selected.length > 0
3178: && selected[selected.length - 1] < m_arrItems.size()) {
3179: ListItem item = (((ListItem) m_arrItems
3180: .elementAt((selected[selected.length - 1]))));
3181: return item.getText();
3182: }
3183:
3184: return null;
3185: }
3186:
3187: protected void onEndTracking(int nCol, int x) {
3188: m_nDraggingState = NONE;
3189:
3190: setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
3191:
3192: ((Column) m_arrColumns.elementAt(nCol)).m_nCX = Math.max(x
3193: - m_nDraggingBegin, 20);
3194:
3195: if (getMaxTopRow() == 0) {
3196: m_nTopRow = 0;
3197: }
3198:
3199: if (getMaxLeftCol() == 0) {
3200: m_nLeftCol = 0;
3201: }
3202:
3203: reMeasureAllItems();
3204: update();
3205: }
3206:
3207: transient boolean m_bSelectedItemChanged = false;
3208:
3209: protected boolean mouseDown(MouseEvent e, int x, int y) {
3210:
3211: m_bSelectedItemChanged = false;
3212:
3213: if (m_bDragModeAllowed)
3214: m_bDragModeEnabled = true;
3215:
3216: m_bEditModeEnabled = false;
3217: m_nXMouse = x;
3218: m_nYMouse = y;
3219: if (m_nDraggingState == NONE)
3220: requestFocus();
3221:
3222: if (e.isShiftDown()) {
3223:
3224: m_bDragModeEnabled = false;
3225: m_bEditModeEnabled = false;
3226: selected = new int[0];
3227:
3228: int index = getSelected(x, y);
3229: if (!m_bMultipleSelections) {
3230: if (index != -1) {
3231: prev = index;
3232: select(index, true);
3233: m_bSelectedItemChanged = true;
3234: }
3235: return true;
3236: }
3237:
3238: if (index != -1) {
3239: int f = (index > prev) ? prev : index;
3240: int l = (index > prev) ? index : prev;
3241: if (f == -1)
3242: f = index;
3243: prev = index;
3244:
3245: for (int i = f; i <= l; i++) {
3246: select(i, false);
3247: }
3248: update();
3249: m_bSelectedItemChanged = true;
3250: }
3251:
3252: return true;
3253:
3254: } else if (e.isControlDown()) {
3255:
3256: m_bEditModeEnabled = false;
3257: m_bDragModeEnabled = false;
3258: int index = getSelected(x, y);
3259: if (!m_bMultipleSelections) {
3260: if (index != -1) {
3261: prev = index;
3262: select(index, true);
3263: m_bSelectedItemChanged = true;
3264: }
3265: return true;
3266: }
3267:
3268: // if the item is already selected, deselect it.
3269: if (isSelected(index)) {
3270: deselect(index);
3271: update();
3272: m_bSelectedItemChanged = true;
3273: m_bEditModeEnabled = false;
3274: return true;
3275: }
3276:
3277: // otherwise, select the item.
3278: if (index != -1) {
3279: prev = index;
3280: select(index, true);
3281: m_bSelectedItemChanged = true;
3282: }
3283: return true;
3284:
3285: } else { // no key modifiers
3286: m_bEditModeEnabled = false;
3287:
3288: int index = getSelected(x, y);
3289: boolean bSelected = isSelected(index);
3290: deselectAll(false);
3291:
3292: if (m_nDraggingState == NONE) {
3293: if (index == -1)
3294: m_bDragModeEnabled = false;
3295:
3296: if (index != -1) {
3297: if (bSelected) {
3298: select(index, true);
3299: if (!isRoot(index))
3300: if (m_bEditModeAllowed)
3301: m_bEditModeEnabled = true;
3302: m_nXMouse = x;
3303: m_nYMouse = y;
3304: Graphics g = getGraphics();
3305: m_bDragDropDrawn = false;
3306: g.dispose();
3307: if (m_bDragModeAllowed)
3308: m_bDragModeEnabled = true;
3309: if (e.getClickCount() == 2) {
3310: if (m_bEditModeAllowed)
3311: m_bEditModeEnabled = false;
3312: m_bDragModeEnabled = false;
3313: doubleClickEvent(index);
3314: processActionEvent(new ActionEvent(this ,
3315: Event.ACTION_EVENT,
3316: commandDoubleClicked));
3317:
3318: }
3319: if (e.getClickCount() != 2)
3320: m_bSelectedItemChanged = true;
3321: return true;
3322: }
3323:
3324: selected = new int[0];
3325: prev = index;
3326: select(index, true);
3327: if (e.getClickCount() != 2)
3328: m_bSelectedItemChanged = true;
3329:
3330: if (e.getClickCount() == 2) {
3331: doubleClickEvent(index);
3332:
3333: processActionEvent(new ActionEvent(this ,
3334: Event.ACTION_EVENT,
3335: commandDoubleClicked));
3336:
3337: }
3338: }
3339: }
3340: return true;
3341: }
3342: }
3343:
3344: protected boolean isRoot(int index) {
3345: return false;
3346: }
3347:
3348: protected void doubleClickEvent(int itemHit) {
3349: //used mainly in tree class...
3350: }
3351:
3352: protected void processKeyEvent(KeyEvent e) {
3353:
3354: super .processKeyEvent(e);
3355:
3356: int key = e.getKeyCode();
3357:
3358: if (e.getID() == Event.KEY_PRESS) {
3359: switch (key) {
3360: case KeyEvent.VK_DOWN:
3361: if (prev < m_arrItems.size() - 1) {
3362: if (m_bMultipleSelections && e.isShiftDown()) {
3363: } else {
3364: selected = new int[0];
3365: }
3366: select(++prev, false, false);
3367: scrollToView(prev, Event.DOWN);
3368: update();
3369: }
3370: break;
3371: case KeyEvent.VK_UP:
3372: if (prev > 0) {
3373: if (m_bMultipleSelections && e.isShiftDown()) {
3374: } else {
3375: selected = new int[0];
3376: }
3377: select(--prev, false, false);
3378: scrollToView(prev, Event.UP);
3379: update();
3380: }
3381: break;
3382: case KeyEvent.VK_LEFT:
3383: case KeyEvent.VK_HOME:
3384: selected = new int[0];
3385: prev = 0;
3386: select(prev, false, false);
3387: scrollToView(prev, Event.LEFT);
3388: hs.setValue(prev);
3389: onLeftColChanged(prev);
3390: update();
3391: break;
3392: case KeyEvent.VK_RIGHT:
3393: case KeyEvent.VK_END:
3394: selected = new int[0];
3395: prev = m_arrItems.size() - 1;
3396: select(prev, false, false);
3397: scrollToView(prev, Event.RIGHT);
3398: hs.setValue(prev);
3399: onLeftColChanged(prev);
3400: update();
3401: break;
3402: case KeyEvent.VK_PAGE_DOWN:
3403: prev = m_nTopRow + itemsThisPage(getGraphics()) - 1;
3404: if (isSelected(prev)) {
3405: m_nTopRow = prev;
3406: vs.setValue(prev);
3407: onTopRowChanged(prev);
3408: prev = m_nTopRow + itemsThisPage(getGraphics()) - 1;
3409: }
3410: selected = new int[0];
3411: prev = Math.min(prev, m_arrItems.size() - 1);
3412: select(prev, false, false);
3413:
3414: update();
3415: break;
3416: case KeyEvent.VK_PAGE_UP:
3417: if (isSelected(m_nTopRow)) {
3418: m_nTopRow = Math.max(m_nTopRow
3419: - itemsThisPage(getGraphics()), 0);
3420: vs.setValue(m_nTopRow);
3421: onTopRowChanged(m_nTopRow);
3422: }
3423:
3424: selected = new int[0];
3425: prev = m_nTopRow;
3426: select(prev, false, false);
3427: update();
3428: break;
3429: case KeyEvent.VK_DELETE:
3430: if (m_bAllowDelete && selected.length > 0) {
3431: //Iterate through to delete all selected entries
3432: int sel[] = getSelectedIndexes();
3433: for (int i = sel.length - 1; i >= 0; i--) {
3434: if (i != 0)
3435: deleteItem(sel[i], false);
3436: else
3437: deleteItem(sel[i], true);
3438: }
3439: }
3440: deselectAll();
3441:
3442: break;
3443: case KeyEvent.VK_ENTER:
3444: processItemEvent(new ItemEvent(this ,
3445: ItemEvent.ITEM_STATE_CHANGED,
3446: getSelectedListItem(), ItemEvent.SELECTED));
3447: break;
3448: default:
3449: break;
3450: }
3451: }
3452: }
3453:
3454: /**
3455: * Processes events on this listbox.
3456: * @param e the event
3457: */
3458: protected void processEvent(AWTEvent e) {
3459:
3460: switch (e.getID()) {
3461: case Event.MOUSE_DOWN:
3462: Point p = ((MouseEvent) e).getPoint();
3463: mouseDown((MouseEvent) e, p.x, p.y);
3464: break;
3465: case Event.MOUSE_MOVE:
3466: Point p2 = ((MouseEvent) e).getPoint();
3467: mouseMove((MouseEvent) e, p2.x, p2.y);
3468: break;
3469: case Event.MOUSE_DRAG:
3470: Point p3 = ((MouseEvent) e).getPoint();
3471: mouseDrag((MouseEvent) e, p3.x, p3.y);
3472: break;
3473: case Event.MOUSE_UP:
3474: Point p4 = ((MouseEvent) e).getPoint();
3475: mouseUp((MouseEvent) e, p4.x, p4.y);
3476: break;
3477: default:
3478: }
3479:
3480: super .processEvent(e);
3481: }
3482:
3483: /**
3484: * scrollToView scrolls the given row to the view.
3485: * @param nRow the index of the row to be scrolled.
3486: * @param nDirection the direction to scroll.
3487: */
3488: public void scrollToView(int nRow, int nDirection) {
3489:
3490: int nRowCount = m_arrItems.size();
3491:
3492: int nLastVisibleRow = getLastVisibleRow();
3493:
3494: Scrollbar scrV = getVScrollbar();
3495:
3496: if (nRow < m_nTopRow && nDirection == Event.UP) {
3497: int nValue = nRow;
3498: if (nValue < scrV.getMinimum())
3499: nValue = scrV.getMinimum();
3500:
3501: scrV.setValue(nValue);
3502: onTopRowChanged(nValue);
3503: } else if (nDirection == Event.UP)
3504: update();
3505:
3506: // the row is next to the last visible row.
3507: if (nRow > nLastVisibleRow && nDirection == Event.DOWN) {
3508: int nValue = nRow;
3509: int nItemsThisPage = itemsThisPage(getGraphics());
3510: while (nRow > getLastVisibleRow()) {
3511: nValue = nValue - itemsThisPage(getGraphics()) + 1;//*/+1;//scrV.getValue()+1;
3512:
3513: if (nValue >= scrV.getMaximum() - 1) {
3514: nValue = scrV.getMaximum() - 1;
3515: scrV.setValue(nValue);
3516: onTopRowChanged(nValue);
3517: break;
3518: }
3519: nItemsThisPage = itemsThisPage(getGraphics());
3520:
3521: scrV.setValue(nValue);
3522: m_nTopRow = nValue;
3523: nValue = nValue + nItemsThisPage;
3524: nLastVisibleRow = getLastVisibleRow();
3525:
3526: }
3527:
3528: onTopRowChanged(nValue - nItemsThisPage);
3529: //update();
3530: } else if (nDirection == Event.DOWN)
3531: update();
3532:
3533: if (nDirection == Event.LEFT) {
3534: int nValue = scrV.getMinimum();
3535: scrV.setValue(nValue);
3536: onTopRowChanged(nValue);
3537: }
3538:
3539: // the column is next to the last visible column.
3540: if (nDirection == Event.RIGHT) {
3541:
3542: int nValue = getMaxTopRow() + 3;
3543: if (nValue >= scrV.getMaximum() - 1)
3544: nValue = scrV.getMaximum() - 1;
3545: scrV.setValue(++nValue);
3546:
3547: onTopRowChanged(nValue);
3548: }
3549: }
3550:
3551: /**
3552: * scrollToView scrolls the given row to the view.
3553: * @param nRow the index of the row to be scrolled.
3554: */
3555: public void scrollToView(int nRow) {
3556:
3557: if (!getVScrollbar().isShowing())
3558: return;
3559:
3560: int nRowCount = m_arrItems.size();
3561:
3562: int nLastVisibleRow = getLastVisibleRow();
3563:
3564: Scrollbar scrV = getVScrollbar();
3565:
3566: if (nRow < m_nTopRow) {
3567: int nValue = scrV.getValue() - m_nTopRow + nRow + 2;
3568: if (nValue < scrV.getMinimum())
3569: nValue = scrV.getMinimum();
3570: scrV.setValue(nValue);
3571: onTopRowChanged(nValue);
3572: }
3573:
3574: // the row is next to the last visible row.
3575: else if (nRow > nLastVisibleRow - 2) {
3576: int nValue = scrV.getValue() + nRow - nLastVisibleRow + 1;
3577: if (nValue > scrV.getMaximum() - 1)
3578: nValue = scrV.getMaximum() - 1;
3579:
3580: scrV.setValue(nValue);
3581: onTopRowChanged(nValue);
3582: }
3583:
3584: if (nRow == 0) {
3585: scrV.setValue(0);
3586: onTopRowChanged(0);
3587: }
3588: }
3589:
3590: /**
3591: * getLastVisibleRow returns the index of the last visible row.
3592: * @param last visible row as type int
3593: */
3594: public int getLastVisibleRow() {
3595:
3596: if (itemsThisPage(getGraphics()) != 0) {
3597: return (m_nTopRow + itemsThisPage(getGraphics()) - 1);
3598: } else {
3599: return m_nTopRow;
3600: }
3601: }
3602:
3603: /**
3604: * retrieves the currently selected item
3605: * @return currently selected item as type ListItem
3606: */
3607: public ListItem getSelected() {
3608: return getItemAt(selected[selected.length - 1]);
3609: }
3610:
3611: protected int getSelected(int x1, int y1) {
3612:
3613: ListItem pItem = new ListItem();
3614: Column pCol = new Column();
3615:
3616: int xColLeft, xColRight;
3617:
3618: Rectangle rcItem = new Rectangle();
3619:
3620: Rectangle rcInside, rcClient;
3621: rcInside = new Rectangle();
3622: rcClient = new Rectangle();
3623: int nTopIndex;
3624: int nHitItem;
3625: int nHitCol;
3626: int iSubItem;
3627: int i;
3628:
3629: nHitItem = -1;
3630: nHitCol = -1;
3631:
3632: rcClient = getBounds();
3633: rcClient.x = 0;
3634: rcClient.y = 0;
3635: rcInside = new Rectangle();
3636:
3637: rcInside = getInsideRect();
3638: rcInside.x = 0;
3639: if (isHeaderCtrlEnabled())
3640: rcInside.y = (m_cyHeader);
3641: else
3642: rcInside.y = 0;
3643: nTopIndex = m_nTopRow;
3644:
3645: // So, which column was hit?
3646: xColLeft = -m_ptViewportOrg.x;
3647: xColRight = xColLeft;
3648:
3649: if (m_arrColumns.size() > 1) {
3650: for (i = 0; i < m_arrColumns.size(); i++) {
3651: pCol = (Column) m_arrColumns.elementAt(i);
3652: xColRight += pCol.m_nCX;
3653: if (x1 >= xColLeft && x1 < xColRight) {
3654: nHitCol = i;
3655: break;
3656: } else
3657: xColLeft = xColLeft;
3658: }
3659: } else {
3660: pCol = (Column) m_arrColumns.elementAt(0);
3661: nHitCol = 0;
3662: }
3663:
3664: // Did the user click on a column header?
3665: if (y1 <= rcInside.y)
3666:
3667: {
3668: if (m_nDraggingState == RESIZE) {
3669: int nCol = getColumnHit(x1);
3670: if (onStartTracking(nCol)) {
3671: Graphics g = getGraphics();
3672: g.setColor(Color.red);
3673: g.setXORMode(getBackground());
3674: m_rectDragging = new Rectangle(x1, m_cyHeader, 1,
3675: getInsideRect().height);
3676: g
3677: .fillRect(m_rectDragging.x,
3678: m_rectDragging.y,
3679: m_rectDragging.width,
3680: m_rectDragging.height);
3681: return -1;
3682: }
3683:
3684: } else
3685: onHitColumnHeader(getColumnHit(x1));
3686: Rectangle rcCol = new Rectangle();
3687:
3688: int nColCount;
3689:
3690: rcCol.y = rcClient.y;
3691: rcCol.x = -m_ptViewportOrg.x;
3692: rcCol.height = 0;
3693: rcCol.width = 0;
3694:
3695: nColCount = m_arrColumns.size();
3696:
3697: for (i = 0; i < nColCount; i++) {
3698: pCol = (Column) m_arrColumns.elementAt(i);
3699: rcCol.width += pCol.m_nCX;
3700: if (m_arrColumns.size() > 1) {
3701: nHitItem = i - 1;
3702:
3703: break;
3704: } else if (rcCol.contains(new Point(x1, y1))) {
3705: nHitItem = i - 1;
3706: break;
3707: } else {
3708:
3709: rcCol.x = rcCol.x + rcCol.width;
3710: }
3711: }
3712:
3713: } else // An item was definitely hit.. So which one?
3714: {
3715: rcItem.y = rcInside.y - ((1 / 2) * m_nRowSpace);
3716: rcItem.x = -m_ptViewportOrg.x;
3717: rcItem.width = rcInside.width;
3718: rcItem.width = getLogicalSize().x;
3719: if (m_arrColumns.size() == 1)
3720: // rcItem.width = ((Column)m_arrColumns.elementAt(0)).m_nCX;
3721: rcItem.width = getLogicalSize().x;
3722: rcItem.height = 0;
3723:
3724: for (i = nTopIndex; rcItem.y < rcInside.height + rcInside.y
3725: && i < m_arrItems.size(); i++) {
3726: pItem = (ListItem) m_arrItems.elementAt(i);
3727:
3728: if (pItem.m_nCY == LVXC_UNINITIALIZED) {
3729: pItem.m_nCY = measureItem(i, getGraphics());
3730: }
3731: rcItem.height = (pItem.m_nCY /*+ pItem.m_nCY/4 LWang */)
3732: + m_nRowSpace;
3733:
3734: if (rcItem.contains(new Point(x1, y1))) {
3735: nHitItem = i;
3736: iSubItem = pCol.m_iSubItem;
3737:
3738: if (iSubItem == 0) {
3739: Rectangle rcText, rcIcon;
3740: rcText = new Rectangle();
3741: rcIcon = new Rectangle();
3742:
3743: rcText.y = rcItem.y;
3744: rcText.height = rcItem.height + m_nRowSpace;
3745: rcText.x = xColLeft + pItem.m_rcText.x;
3746: rcText.width = pItem.m_rcText.width;
3747:
3748: rcIcon.y = rcItem.y + rcIcon.y;
3749: rcIcon.height = pItem.m_rcIcon.height;
3750: rcIcon.x = xColLeft + pItem.m_rcIcon.x;
3751: rcIcon.width = pItem.m_rcIcon.width;
3752:
3753: }
3754: break;
3755: } else
3756: rcItem.y += rcItem.height;
3757: }
3758: }
3759:
3760: return nHitItem;
3761:
3762: }
3763:
3764: protected boolean onStartTracking(int nCol) {
3765: return true;
3766: }
3767:
3768: protected void onHitColumnHeader(int nCol) {
3769: // used for sorting, etc
3770: }
3771:
3772: /**
3773: * isSelected returns true if the index is one of the current selected index.
3774: * @param index the index to be checked.
3775: * @return true if index is currently selected, otherwise false.
3776: */
3777: public synchronized boolean isSelected(int index) {
3778: int sel[] = getSelectedIndexes();
3779: for (int i = 0; i < sel.length; i++) {
3780: if (sel[i] == index) {
3781: return true;
3782: }
3783: }
3784: return false;
3785: }
3786:
3787: /**
3788: * select set the selected index.
3789: * @param index the index to be selected.
3790: * @param bUpdate if this is true the list will be repainted.
3791: */
3792: public synchronized void select(int index, boolean bUpdate) {
3793: select(index, bUpdate, false);
3794: }
3795:
3796: protected synchronized void select(int index, boolean bUpdate,
3797: boolean bScroll) {
3798: // check if the index is valid.
3799: if (index < 0 || index >= getItemCount())
3800: return;
3801:
3802: for (int i = 0; i < selected.length; i++) {
3803: if (selected[i] == index) {
3804: return;
3805: }
3806: }
3807: if (!m_bMultipleSelections) {
3808: selected = new int[1];
3809: selected[0] = index;
3810: prev = index;
3811: } else {
3812: int newsel[] = new int[selected.length + 1];
3813: System.arraycopy(selected, 0, newsel, 0, selected.length);
3814: newsel[selected.length] = index;
3815: selected = newsel;
3816: prev = index;
3817: }
3818:
3819: if (bScroll)
3820: scrollToView(index);
3821: if (bUpdate)
3822: update();
3823: }
3824:
3825: /**
3826: * select set the selected index.
3827: * @param index the index to be selected.
3828: */
3829: public synchronized void select(int index) {
3830: select(index, true, true);
3831: }
3832:
3833: /**
3834: * deselect reset the specified selected item.
3835: * @param index the index to be deselected.
3836: */
3837: public synchronized void deselect(int index) {
3838: for (int i = 0; i < selected.length; i++) {
3839: if (selected[i] == index) {
3840: int newsel[] = new int[selected.length - 1];
3841: System.arraycopy(selected, 0, newsel, 0, i);
3842: System.arraycopy(selected, i + 1, newsel, i,
3843: selected.length - (i + 1));
3844: selected = newsel;
3845: return;
3846: }
3847: }
3848:
3849: update();
3850: }
3851:
3852: public boolean isFocusTraversable() {
3853: return true;
3854: }
3855:
3856: /**
3857: * Visual Cafe Support Routine
3858: * Allows String[] interaction
3859: */
3860: public synchronized void setItems(String[] its) {
3861: for (int i = 0; i < its.length; i++)
3862: addItem(its[i]);
3863: }
3864:
3865: public String[] getItems() {
3866: int max = m_arrItems.size();
3867: String[] res = new String[max];
3868: for (int i = 0; i < max; i++)
3869: res[i] = (String) m_arrItems.elementAt(i);
3870: return res;
3871: }
3872: /**
3873: * End of VC Support
3874: */
3875:
3876: }
|