📄 tree.java
字号:
* * NOTE: This only happens on Windows XP. */ customDraw = false; items = null; if (imageList != null) { OS.SendMessage (handle, OS.TVM_SETIMAGELIST, OS.TVSIL_NORMAL, 0); display.releaseImageList (imageList); } else { int hOldList = OS.SendMessage (handle, OS.TVM_GETIMAGELIST, OS.TVSIL_NORMAL, 0); OS.SendMessage (handle, OS.TVM_SETIMAGELIST, OS.TVSIL_NORMAL, 0); if (hOldList != 0) OS.ImageList_Destroy (hOldList); } imageList = null; int hOldList = OS.SendMessage (handle, OS.TVM_GETIMAGELIST, OS.TVSIL_STATE, 0); OS.SendMessage (handle, OS.TVM_SETIMAGELIST, OS.TVSIL_STATE, 0); if (hOldList != 0) OS.ImageList_Destroy (hOldList); super.releaseWidget ();}/** * Removes all of the items from the receiver. * <p> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */public void removeAll () { checkWidget (); ignoreDeselect = ignoreSelect = true; boolean redraw = drawCount == 0 && OS.IsWindowVisible (handle); if (redraw) { OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0); /* * This code is intentionally commented. */// OS.SendMessage (handle, OS.WM_SETREDRAW, 0, 0); } int result = OS.SendMessage (handle, OS.TVM_DELETEITEM, 0, OS.TVI_ROOT); if (redraw) { OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); /* * This code is intentionally commented. */// OS.SendMessage (handle, OS.WM_SETREDRAW, 1, 0); OS.InvalidateRect (handle, null, true); } ignoreDeselect = ignoreSelect = false; if (result == 0) error (SWT.ERROR_ITEM_NOT_REMOVED); for (int i=0; i<items.length; i++) { TreeItem item = items [i]; if (item != null && !item.isDisposed ()) { item.releaseResources (); } } if (imageList != null) { OS.SendMessage (handle, OS.TVM_SETIMAGELIST, 0, 0); display.releaseImageList (imageList); } imageList = null; customDraw = false; items = new TreeItem [4]; hAnchor = 0;}/** * Removes the listener from the collection of listeners who will * be notified when the receiver's selection changes. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see SelectionListener * @see #addSelectionListener */public void removeSelectionListener (SelectionListener listener) { checkWidget (); if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); eventTable.unhook (SWT.Selection, listener); eventTable.unhook (SWT.DefaultSelection, listener); }/** * Removes the listener from the collection of listeners who will * be notified when items in the receiver are expanded or collapsed.. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see TreeListener * @see #addTreeListener */public void removeTreeListener(TreeListener listener) { checkWidget (); if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); if (eventTable == null) return; eventTable.unhook (SWT.Expand, listener); eventTable.unhook (SWT.Collapse, listener);}/** * Display a mark indicating the point at which an item will be inserted. * The drop insert item has a visual hint to show where a dragged item * will be inserted when dropped on the tree. * * @param item the insert item. Null will clear the insertion mark. * @param before true places the insert mark above 'item'. false places * the insert mark below 'item'. * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */public void setInsertMark (TreeItem item, boolean before) { checkWidget (); int hItem = 0; if (item != null) { if (item.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT); hItem = item.handle; } OS.SendMessage (handle, OS.TVM_SETINSERTMARK, (before) ? 0 : 1, hItem);}/** * Selects all of the items in the receiver. * <p> * If the receiver is single-select, do nothing. * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */public void selectAll () { checkWidget (); if ((style & SWT.SINGLE) != 0) return; TVITEM tvItem = new TVITEM (); tvItem.mask = OS.TVIF_STATE; tvItem.state = OS.TVIS_SELECTED; tvItem.stateMask = OS.TVIS_SELECTED; int oldProc = OS.GetWindowLong (handle, OS.GWL_WNDPROC); OS.SetWindowLong (handle, OS.GWL_WNDPROC, TreeProc); for (int i=0; i<items.length; i++) { TreeItem item = items [i]; if (item != null) { tvItem.hItem = item.handle; OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem); } } OS.SetWindowLong (handle, OS.GWL_WNDPROC, oldProc);}void setBackgroundPixel (int pixel) { if (background == pixel) return; background = pixel; /* * Bug in Windows. When TVM_GETBKCOLOR is used more * than once to set the background color of a tree, * the background color of the lines and the plus/minus * does not change to the new color. The fix is to set * the background color to the default before setting * the new color. */ int oldPixel = OS.SendMessage (handle, OS.TVM_GETBKCOLOR, 0, 0); if (oldPixel != -1) OS.SendMessage (handle, OS.TVM_SETBKCOLOR, 0, -1); OS.SendMessage (handle, OS.TVM_SETBKCOLOR, 0, pixel); if ((style & SWT.CHECK) != 0) setCheckboxImageList ();}void setBounds (int x, int y, int width, int height, int flags) { /* * Ensure that the selection is visible when the tree is resized * from a zero size to a size that can show the selection. */ boolean fixSelection = false; if ((flags & OS.SWP_NOSIZE) == 0 && (width != 0 || height != 0)) { if (OS.SendMessage (handle, OS.TVM_GETVISIBLECOUNT, 0, 0) == 0) { fixSelection = true; } } super.setBounds (x, y, width, height, flags); if (fixSelection) { int hItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); if (hItem != 0) showItem (hItem); }}void setCursor () { /* * Bug in Windows. Under certain circumstances, when WM_SETCURSOR * is sent using SendMessage(), Windows GP's in the window proc for * the tree. The fix is to avoid calling the tree window proc and * set the cursor for the tree outside of WM_SETCURSOR. * * NOTE: This code assumes that the default cursor for the tree * is IDC_ARROW. */ Cursor cursor = findCursor (); int hCursor = cursor == null ? OS.LoadCursor (0, OS.IDC_ARROW) : cursor.handle; OS.SetCursor (hCursor);}void setCheckboxImageList () { if ((style & SWT.CHECK) == 0) return; int count = 5; int height = OS.SendMessage (handle, OS.TVM_GETITEMHEIGHT, 0, 0), width = height; int hImageList = OS.ImageList_Create (width, height, OS.ILC_COLOR, count, count); int hDC = OS.GetDC (handle); if (!OS.IsWinCE && (OS.WIN32_MAJOR << 16 | OS.WIN32_MINOR) >= (4 << 16 | 10)) { OS.SetLayout (hDC, 0); } int memDC = OS.CreateCompatibleDC (hDC); int hBitmap = OS.CreateCompatibleBitmap (hDC, width * count, height); int hOldBitmap = OS.SelectObject (memDC, hBitmap); RECT rect = new RECT (); OS.SetRect (rect, 0, 0, width * count, height); int hBrush = OS.CreateSolidBrush (getBackgroundPixel ()); OS.FillRect (memDC, rect, hBrush); OS.DeleteObject (hBrush); int oldFont = OS.SelectObject (hDC, defaultFont ()); TEXTMETRIC tm = OS.IsUnicode ? (TEXTMETRIC) new TEXTMETRICW () : new TEXTMETRICA (); OS.GetTextMetrics (hDC, tm); OS.SelectObject (hDC, oldFont); int itemWidth = Math.min (tm.tmHeight, width); int itemHeight = Math.min (tm.tmHeight, height); int left = (width - itemWidth) / 2, top = (height - itemHeight) / 2 + 1; OS.SetRect (rect, left + width, top, left + width + itemWidth, top + itemHeight); OS.DrawFrameControl (memDC, rect, OS.DFC_BUTTON, OS.DFCS_BUTTONCHECK | OS.DFCS_FLAT); rect.left += width; rect.right += width; OS.DrawFrameControl (memDC, rect, OS.DFC_BUTTON, OS.DFCS_BUTTONCHECK | OS.DFCS_CHECKED | OS.DFCS_FLAT); rect.left += width; rect.right += width; OS.DrawFrameControl (memDC, rect, OS.DFC_BUTTON, OS.DFCS_BUTTONCHECK | OS.DFCS_INACTIVE | OS.DFCS_FLAT); rect.left += width; rect.right += width; OS.DrawFrameControl (memDC, rect, OS.DFC_BUTTON, OS.DFCS_BUTTONCHECK | OS.DFCS_CHECKED | OS.DFCS_INACTIVE | OS.DFCS_FLAT); OS.SelectObject (memDC, hOldBitmap); OS.DeleteDC (memDC); OS.ReleaseDC (handle, hDC); OS.ImageList_AddMasked (hImageList, hBitmap, 0); OS.DeleteObject (hBitmap); int hOldList = OS.SendMessage (handle, OS.TVM_GETIMAGELIST, OS.TVSIL_STATE, 0); OS.SendMessage (handle, OS.TVM_SETIMAGELIST, OS.TVSIL_STATE, hImageList); if (hOldList != 0) OS.ImageList_Destroy (hOldList);}void setForegroundPixel (int pixel) { if (foreground == pixel) return; foreground = pixel; OS.SendMessage (handle, OS.TVM_SETTEXTCOLOR, 0, pixel);}public void setRedraw (boolean redraw) { checkWidget (); /* * Bug in Windows. For some reason, when WM_SETREDRAW * is used to turn redraw on for a tree and the tree * contains no items, the last item in the tree does * not redraw properly. If the tree has only one item, * that item is not drawn. If another window is dragged * on top of the item, parts of the item are redrawn * and erased at random. The fix is to ensure that this * case doesn't happen by inserting and deleting an item * when redraw is turned on and there are no items in * the tree. */ int hItem = 0; if (redraw && drawCount == 1) { int count = OS.SendMessage (handle, OS.TVM_GETCOUNT, 0, 0); if (count == 0) { TVINSERTSTRUCT tvInsert = new TVINSERTSTRUCT (); tvInsert.hInsertAfter = OS.TVI_FIRST; hItem = OS.SendMessage (handle, OS.TVM_INSERTITEM, 0, tvInsert); } } super.setRedraw (redraw); if (hItem != 0) { OS.SendMessage (handle, OS.TVM_DELETEITEM, 0, hItem); }}/** * Sets the receiver's selection to be the given array of items. * The current selection is cleared before the new items are selected. * <p> * Items that are not in the receiver are ignored. * If the receiver is single-select and multiple items are specified, * then all items are ignored. * * @param items the array of items * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the array of items is null</li> * <li>ERROR_INVALID_ARGUMENT - if one of the items has been disposed</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see Tree#deselectAll() */public void setSelection (TreeItem [] items) { checkWidget (); if (items == null) error (SWT.ERROR_NULL_ARGUMENT); int length = items.length; if (length == 0 || ((style & SWT.SINGLE) != 0 && length > 1)) { deselectAll(); return; } /* Select/deselect the first item */ TreeItem item = items [0]; if (item != null) { if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); int hOldItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); int hNewItem = hAnchor = item.handle; /* * Bug in Windows. When TVM_SELECTITEM is used to select and * scroll an item to be visible and the client area of the tree * is smaller that the size of one item, TVM_SELECTITEM makes * the next item in the tree visible by making it the top item * instead of making the desired item visible. The fix is to * detect the case when the client area is too small and make * the desired visible item be the top item in the tree. * * Note that TVM_SELECTITEM when called with TVGN_FIRSTVISIBLE * also requires the work around for scrolling. */ boolean fixScroll = checkScroll (hNewItem); if (fixScroll) { OS.SendMessage (handle, OS.WM_SETREDRAW, 1, 0); OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0); } ignoreSelect = true; OS.SendMessage (handle, OS.TVM_SELECTITEM, OS.TVGN_CARET, hNewItem); ignoreSelect = false; if (OS.SendMessage (handle, OS.TVM_GETVISIBLECOUNT, 0, 0) == 0) { OS.SendMessage (handle, OS.TVM_SELECTITEM, OS.TVGN_FIRSTVISIBLE, hNewItem); } if (fixScroll) { OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); OS.SendMessage (handle, OS.WM_SETREDRAW, 0, 0); } /* * Feature in Windows. When the old and new focused item * are the same, Windows does not check to make sure that * the item is actually selected, not just focused. The * fix is to force the item to draw selected by setting * the state mask, and to ensure that it is visible. */ if (hOldItem == hNewItem) { TVITEM tvItem = new TVITEM (); tvItem.mask = OS.TVIF_STATE; tvItem.state = OS.TVIS_SELECTED; tvItem.stateMask = OS.TVIS_SELECTED; tvItem.hItem = hNewItem; OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem); showItem (hNewItem); } } if ((style & SWT.SINGLE) != 0) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -