⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 contentproposaladapter.java

📁 jfa2ce 源码帮助开发人员更好的理解运用
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************* * Copyright (c) 2005, 2006 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: *     IBM Corporation - initial API and implementation *******************************************************************************/package org.eclipse.jface.fieldassist;import java.util.ArrayList;import org.eclipse.core.runtime.ListenerList;import org.eclipse.jface.bindings.keys.KeyStroke;import org.eclipse.jface.dialogs.PopupDialog;import org.eclipse.jface.util.Assert;import org.eclipse.jface.viewers.ILabelProvider;import org.eclipse.swt.SWT;import org.eclipse.swt.events.DisposeEvent;import org.eclipse.swt.events.DisposeListener;import org.eclipse.swt.events.FocusAdapter;import org.eclipse.swt.events.FocusEvent;import org.eclipse.swt.events.SelectionEvent;import org.eclipse.swt.events.SelectionListener;import org.eclipse.swt.graphics.Image;import org.eclipse.swt.graphics.Point;import org.eclipse.swt.graphics.Rectangle;import org.eclipse.swt.layout.GridData;import org.eclipse.swt.widgets.Composite;import org.eclipse.swt.widgets.Control;import org.eclipse.swt.widgets.Event;import org.eclipse.swt.widgets.Listener;import org.eclipse.swt.widgets.ScrollBar;import org.eclipse.swt.widgets.Shell;import org.eclipse.swt.widgets.Table;import org.eclipse.swt.widgets.TableItem;import org.eclipse.swt.widgets.Text;/** * ContentProposalAdapter can be used to attach content proposal behavior to a * control. This behavior includes obtaining proposals, opening a popup dialog, * managing the content of the control relative to the selections in the popup, * and optionally opening up a secondary popup to further describe proposals. * <p> * A number of configurable options are provided to determine how the control * content is altered when a proposal is chosen, how the content proposal popup * is activated, and whether any filtering should be done on the proposals as * the user types characters. * <p> * This class is not intended to be subclassed. *  * @since 3.2 */public class ContentProposalAdapter {	/*	 * The lightweight popup used to show content proposals for a text field. If	 * additional information exists for a proposal, then selecting that	 * proposal will result in the information being displayed in a secondary	 * popup.	 */	class ContentProposalPopup extends PopupDialog {		/*		 * The listener we install on the popup and related controls to		 * determine when to close the popup. Some events (move, resize, close,		 * deactivate) trigger closure as soon as they are received, simply		 * because one of the registered listeners received them. Other events		 * depend on additional circumstances.		 */		private final class PopupCloserListener implements Listener {			private boolean scrollbarClicked = false;			public void handleEvent(final Event e) {				// If focus is leaving an important widget or the field's				// shell is deactivating				if (e.type == SWT.FocusOut) {					scrollbarClicked = false;					/*					 * Ignore this event if it's only happening because focus is					 * moving between the popup shells, their controls, or a					 * scrollbar. Do this in an async since the focus is not					 * actually switched when this event is received.					 */					e.display.asyncExec(new Runnable() {						public void run() {							if (isValid()) {								if (scrollbarClicked										|| hasFocus()										|| (infoPopup != null && infoPopup												.hasFocus())) {									return;								}								// Workaround a problem on X and Mac, whereby at								// this point, the focus control is not known.								// This can happen, for example, when resizing								// the popup shell on the Mac.								// Check the active shell.								Shell activeShell = e.display.getActiveShell();								if (activeShell == getShell()										|| (infoPopup != null && infoPopup												.getShell() == activeShell)) {									return;								}								/*								 * System.out.println(e);								 * System.out.println(e.display.getFocusControl());								 * System.out.println(e.display.getActiveShell());								 */								close();							}						}					});					return;				}				// Scroll bar has been clicked. Remember this for focus event				// processing.				if (e.type == SWT.Selection) {					scrollbarClicked = true;					return;				}				// For all other events, merely getting them dictates closure.				close();			}			// Install the listeners for events that need to be monitored for			// popup closure.			void installListeners() {				// Listeners on this popup's table and scroll bar				proposalTable.addListener(SWT.FocusOut, this);				ScrollBar scrollbar = proposalTable.getVerticalBar();				if (scrollbar != null) {					scrollbar.addListener(SWT.Selection, this);				}				// Listeners on this popup's shell				getShell().addListener(SWT.Deactivate, this);				getShell().addListener(SWT.Close, this);				// Listeners on the target control				control.addListener(SWT.MouseDoubleClick, this);				control.addListener(SWT.MouseDown, this);				control.addListener(SWT.Dispose, this);				control.addListener(SWT.FocusOut, this);				// Listeners on the target control's shell				Shell controlShell = control.getShell();				controlShell.addListener(SWT.Move, this);				controlShell.addListener(SWT.Resize, this);			}			// Remove installed listeners			void removeListeners() {				if (isValid()) {					proposalTable.removeListener(SWT.FocusOut, this);					ScrollBar scrollbar = proposalTable.getVerticalBar();					if (scrollbar != null) {						scrollbar.removeListener(SWT.Selection, this);					}					getShell().removeListener(SWT.Deactivate, this);					getShell().removeListener(SWT.Close, this);				}				if (control != null && !control.isDisposed()) {					control.removeListener(SWT.MouseDoubleClick, this);					control.removeListener(SWT.MouseDown, this);					control.removeListener(SWT.Dispose, this);					control.removeListener(SWT.FocusOut, this);					Shell controlShell = control.getShell();					controlShell.removeListener(SWT.Move, this);					controlShell.removeListener(SWT.Resize, this);				}			}		}		/*		 * The listener we will install on the target control.		 */		private final class TargetControlListener implements Listener {			// Key events from the control			public void handleEvent(Event e) {				if (!isValid()) {					return;				}				char key = e.character;				// Traverse events are handled depending on whether the				// event has a character.				if (e.type == SWT.Traverse) {					// If the traverse event contains a legitimate character,					// then we must set doit false so that the widget will					// receive the key event. We return immediately so that					// the character is handled only in the key event.					// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=132101					if (key != 0) {						e.doit = false;						return;					}					// Traversal does not contain a character. Set doit true					// to indicate TRAVERSE_NONE will occur and that no key					// event will be triggered. We will check for navigation 					// keys below.					e.detail = SWT.TRAVERSE_NONE;					e.doit = true;				} else {					// Default is to only propagate when configured that way.					// Some keys will always set doit to false anyway.					e.doit = propagateKeys;				}				// No character. Check for navigation keys. 				if (key == 0) {					int newSelection = proposalTable.getSelectionIndex();					int visibleRows = (proposalTable.getSize().y / proposalTable							.getItemHeight()) - 1;					switch (e.keyCode) {					case SWT.ARROW_UP:						newSelection -= 1;						if (newSelection < 0) {							newSelection = proposalTable.getItemCount() - 1;						}						// Not typical - usually we get this as a Traverse and						// therefore it never propagates.  Added for consistency.						if (e.type == SWT.KeyDown) {							// don't propagate to control							e.doit = false;								}						break;					case SWT.ARROW_DOWN:						newSelection += 1;						if (newSelection > proposalTable.getItemCount() - 1) {							newSelection = 0;						}						// Not typical - usually we get this as a Traverse and						// therefore it never propagates.  Added for consistency.						if (e.type == SWT.KeyDown) {							// don't propagate to control							e.doit = false;								}						break;					case SWT.PAGE_DOWN:						newSelection += visibleRows;						if (newSelection >= proposalTable.getItemCount()) {							newSelection = proposalTable.getItemCount() - 1;						}						if (e.type == SWT.KeyDown) {							// don't propagate to control							e.doit = false;								}						break;					case SWT.PAGE_UP:						newSelection -= visibleRows;						if (newSelection < 0) {							newSelection = 0;						}						if (e.type == SWT.KeyDown) {							// don't propagate to control							e.doit = false;								}						break;					case SWT.HOME:						newSelection = 0;						if (e.type == SWT.KeyDown) {							// don't propagate to control							e.doit = false;								}						break;					case SWT.END:						newSelection = proposalTable.getItemCount() - 1;						if (e.type == SWT.KeyDown) {							// don't propagate to control							e.doit = false;								}						break;											// If received as a Traverse, these should propagate 				    // to the control as keydown.  If received as a keydown,				    // proposals should be recomputed since the cursor				    // position has changed.					case SWT.ARROW_LEFT:					case SWT.ARROW_RIGHT:						if (e.type == SWT.Traverse) {							e.doit = false;						} else {							e.doit = true;							String contents = getControlContentAdapter().getControlContents(									getControl());							// If there are no contents, changes in cursor position 							// have no effect.  Note also that we do not affect the filter							// text on ARROW_LEFT as we would with BS.							if (contents.length() > 0) {								asyncRecomputeProposals(filterText);							}						}						break;					// Any unknown keycodes will cause the popup to close.					// Modifier keys are explicitly checked and ignored because					// they are not complete yet (no character).					default:						if (e.keyCode != SWT.CAPS_LOCK && e.keyCode != SWT.MOD1								&& e.keyCode != SWT.MOD2								&& e.keyCode != SWT.MOD3								&& e.keyCode != SWT.MOD4) {							close();						}						return;					}					// If any of these navigation events caused a new selection,					// then handle that now and return.					if (newSelection >= 0) {						selectProposal(newSelection);					}					return;				}				// key != 0				// Check for special keys involved in cancelling, accepting, or				// filtering the proposals.				switch (key) {				case SWT.ESC:					e.doit = false;					close();					break;				case SWT.LF:				case SWT.CR:					e.doit = false;					Object p = getSelectedProposal();					if (p != null) {						acceptCurrentProposal();					}					close();					break;				case SWT.TAB:					e.doit = false;					getShell().setFocus();					return;				case SWT.BS:					// Backspace should back out of any stored filter text					if (filterStyle != FILTER_NONE) {						// We have no filter to back out of, so do nothing						if (filterText.length() == 0) {							return;						}						// There is filter to back out of						filterText = filterText.substring(0, filterText								.length() - 1);						asyncRecomputeProposals(filterText);						return;					}					// There is no filtering provided by us, but some 					// clients provide their own filtering based on content.					// Recompute the proposals if the cursor position					// will change (is not at 0).  					int pos = getControlContentAdapter().getCursorPosition(getControl());					// We rely on the fact that the contents and pos do not yet					// reflect the result of the BS.  If the contents were already empty, then BS should not cause					// a recompute.					if (pos > 0) {						asyncRecomputeProposals(filterText);					}					break;				default:					// If the key is a defined unicode character, and not one of					// the special cases processed above, update the filter text					// and filter the proposals.					if (Character.isDefined(key)) {						if (filterStyle == FILTER_CUMULATIVE) {							filterText = filterText + String.valueOf(key);						} else if (filterStyle == FILTER_CHARACTER) {							filterText = String.valueOf(key);						}						// Recompute proposals after processing this event.						asyncRecomputeProposals(filterText);					}					break;				}			}		}		/*		 * Internal class used to implement the secondary popup.		 */		private class InfoPopupDialog extends PopupDialog {			/*			 * The text control that displays the text.			 */			private Text text;			/*			 * The String shown in the popup.			 */			private String contents = EMPTY;			/*			 * Construct an info-popup with the specified parent.			 */			InfoPopupDialog(Shell parent) {				super(parent, PopupDialog.HOVER_SHELLSTYLE, false, false,						false, false, null, null);			}			/*			 * Create a text control for showing the info about a proposal.			 */			protected Control createDialogArea(Composite parent) {				text = new Text(parent, SWT.MULTI | SWT.READ_ONLY | SWT.WRAP						| SWT.NO_FOCUS);				// Use the compact margins employed by PopupDialog.				GridData gd = new GridData(GridData.BEGINNING						| GridData.FILL_BOTH);				gd.horizontalIndent = PopupDialog.POPUP_HORIZONTALSPACING;				gd.verticalIndent = PopupDialog.POPUP_VERTICALSPACING;				text.setLayoutData(gd);				text.setText(contents);				// since SWT.NO_FOCUS is only a hint...				text.addFocusListener(new FocusAdapter() {					public void focusGained(FocusEvent event) {						ContentProposalPopup.this.close();					}				});				return text;			}			/*			 * Adjust the bounds so that we appear adjacent to our parent shell			 */			protected void adjustBounds() {				Rectangle parentBounds = getParentShell().getBounds();				Rectangle proposedBounds;				// Try placing the info popup to the right				Rectangle rightProposedBounds = new Rectangle(parentBounds.x						+ parentBounds.width						+ PopupDialog.POPUP_HORIZONTALSPACING, parentBounds.y						+ PopupDialog.POPUP_VERTICALSPACING,						parentBounds.width, parentBounds.height);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -