📄 decoratedfield.java
字号:
// Since sizes may have changed or there could be a new position // defined, we need to update layout data on the control. updateControlAttachments(i, decDatas[i]); } /* * A decoration at the specified index has been added. Update the control's * attachments if it has not previously been attached on that side or if it * was attached to a decoration with a lesser width. */ private void updateControlAttachments(int index, FieldDecorationData decData) { FormData formData = (FormData) control.getLayoutData(); int newWidth = widthOf(decData.decoration.getImage()); // opposing represents the location of the decoration above or below // the one in question. int opposing; switch (index) { case LEFT_TOP: case LEFT_BOTTOM: if (index == LEFT_TOP) { opposing = LEFT_BOTTOM; } else { opposing = LEFT_TOP; } if (decDatas[opposing] == null) { // No decorator on the opposing side. // Attach the control to this decorator formData.left = new FormAttachment(decData.label); } else if (decDatas[opposing].data.width < newWidth) { // Decorator on opposing side is the smaller one. Attach // control to the new one. formData.left = new FormAttachment(decData.label); // Center align the smaller one relative to the larger one. decDatas[opposing].data.left.alignment = SWT.CENTER; decDatas[opposing].data.left.control = decData.label; } else { // The new decorator is the smaller one. Keep the // control attached to the opposing one. formData = null; // Horizontally center the smaller one relative to the larger one. decData.data.left.alignment = SWT.CENTER; decData.data.left.control = decDatas[opposing].label; } break; /* * The only real difference in right side cases is that we are attaching * the right side of the control to the wider decoration rather than the * left side of the control. Other concerns (horizontally aligning the * smaller decoration relative to the larger one) are the same. */ case RIGHT_TOP: case RIGHT_BOTTOM: if (index == RIGHT_TOP) { opposing = RIGHT_BOTTOM; } else { opposing = RIGHT_TOP; } if (decDatas[opposing] == null) { // No decorator on the opposing side. // Attach the control to this decorator. formData.right = new FormAttachment(decData.label); } else if (decDatas[opposing].data.width < newWidth) { // Decorator on opposing side is the smaller one. Attach // control to the new one. formData.right = new FormAttachment(decData.label); // Center align the smaller one to the larger one. // Note that this could be done using the left or right // attachment, we use the right since it is already // created for all right-side decorations. decDatas[opposing].data.right.alignment = SWT.CENTER; decDatas[opposing].data.right.control = decData.label; } else { // The new decorator is the smaller one. Keep the // control attached to the opposing one. formData = null; // Horizontally center align the smaller one to the // larger one. decData.data.right.alignment = SWT.CENTER; decData.data.right.control = decDatas[opposing].label; } break; default: return; } if (formData != null) { // Form data was updated. control.setLayoutData(formData); form.layout(); } } /** * Get the control that is decorated by the receiver. * * @return the Control decorated by the receiver, or <code>null</code> if * none has been created yet. */ public Control getControl() { return control; } /** * Get the control that represents the decorated field. This composite * should be used to lay out the field within its parent. * * @return the Control that should be layed out in the field's parent's * layout. This is typically not the control itself, since * additional controls are used to represent the decorations. */ public Control getLayoutControl() { return form; } /** * Create the parent composite and a form layout that will be used to manage * decorations. */ private Composite createForm(Composite parent) { Composite composite = new Composite(parent, SWT.NO_FOCUS); // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=126553 composite.setBackgroundMode(SWT.INHERIT_DEFAULT); composite.setLayout(new FormLayout()); return composite; } /** * Add any listeners needed on the target control. */ private void addControlListeners() { control.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent event) { if (hover != null) { hover.dispose(); } } }); control.addFocusListener(new FocusListener() { public void focusGained(FocusEvent event) { controlFocusGained(); } public void focusLost(FocusEvent event) { controlFocusLost(); } }); } /* * Return the index in the array of decoration datas that represents the * specified SWT position. * * @param position The SWT constant indicating the position of the * decoration relative to the field's control. The position should include * style bits describing both the vertical and horizontal orientation. * <code>SWT.LEFT</code> and <code>SWT.RIGHT</code> describe the * horizontal placement of the decoration relative to the field, and the * constants <code>SWT.TOP</code> and <code>SWT.BOTTOM</code> describe * the vertical alignment of the decoration relative to the field. * Decorations always appear on either horizontal side of the field, never * above or below it. For example, a decoration appearing on the left side * of the field, at the top, is specified as SWT.LEFT | SWT.TOP. * * @return index the index in the array of decorations that represents the * specified SWT position. If the position is not an expected position, the * index representing the top left position will be returned. * */ private int indexForPosition(int position) { switch (position) { case SWT.LEFT | SWT.BOTTOM: return LEFT_BOTTOM; case SWT.RIGHT | SWT.TOP: return RIGHT_TOP; case SWT.RIGHT | SWT.BOTTOM: return RIGHT_BOTTOM; default: return LEFT_TOP; } } /* * Create a form data that will place the decoration at the specified * position. * * @param index the index in the decDatas describing the position of the * decoration. * * @param image the image shown in the decoration. * */ private FormData createFormDataForIndex(int index, Image image) { Assert.isTrue(index >= 0 && index < DECORATION_SLOTS, "Index out of range"); //$NON-NLS-1$ FormData data = new FormData(); switch (index) { case LEFT_TOP: data.left = new FormAttachment(0, 0); data.top = new FormAttachment(0, 0); break; case LEFT_BOTTOM: data.left = new FormAttachment(0, 0); data.bottom = new FormAttachment(100, 0); break; case RIGHT_TOP: data.right = new FormAttachment(100, 0); data.top = new FormAttachment(0, 0); break; case RIGHT_BOTTOM: data.right = new FormAttachment(100, 0); data.bottom = new FormAttachment(100, 0); break; } data.width = widthOf(image); data.height = SWT.DEFAULT; return data; } /** * Show the specified text using the same hover dialog as is used to show * decorator descriptions. Normally, a decoration's description text will be * shown in an info hover over the field's control whenever the mouse hovers * over the decoration. This method can be used to show a decoration's * description text at other times (such as when the control receives * focus), or to show other text associated with the field. * * <p> * If there is currently a hover visible, the hover's text will be replaced * with the specified text. * * @param text * the text to be shown in the info hover, or <code>null</code> * if no text should be shown. */ public void showHoverText(String text) { showHoverText(text, control); } /** * Hide any hover popups that are currently showing on the control. * Normally, a decoration's description text will be shown in an info hover * over the field's control as long as the mouse hovers over the decoration, * and will be hidden when the mouse exits the control. This method can be * used to hide a hover that was shown using <code>showHoverText</code>, * or to programatically hide the current decoration hover. * * <p> * This message has no effect if there is no current hover. * */ public void hideHover() { if (hover != null) { hover.setVisible(false); } } /* * The target control gained focus. Any decorations that should show only * when they have the focus should be shown here. */ private void controlFocusGained() { for (int i = 0; i < DECORATION_SLOTS; i++) { if (decDatas[i] != null && decDatas[i].showOnFocus) { setVisible(decDatas[i], true); } } } /* * The target control lost focus. Any decorations that should show only when * they have the focus should be hidden here. */ private void controlFocusLost() { for (int i = 0; i < DECORATION_SLOTS; i++) { if (decDatas[i] != null && decDatas[i].showOnFocus) { setVisible(decDatas[i], false); } } } /** * Show the specified decoration. This message has no effect if the * decoration is already showing, or was not already added to the field * using <code>addFieldDecoration</code>. * * @param decoration * the decoration to be shown. */ public void showDecoration(FieldDecoration decoration) { FieldDecorationData data = getDecorationData(decoration); if (data == null) { return; } // record the fact that client would like it to be visible data.visible = true; // even if it is supposed to be shown, if the field does not have focus, // do not show it (yet) if (!data.showOnFocus || control.isFocusControl()) { setVisible(data, true); } } /** * Hide the specified decoration. This message has no effect if the * decoration is already hidden, or was not already added to the field using * <code>addFieldDecoration</code>. * * @param decoration * the decoration to be hidden. */ public void hideDecoration(FieldDecoration decoration) { FieldDecorationData data = getDecorationData(decoration); if (data == null) { return; } // Store the desired visibility in the decData. We remember the // client's instructions so that changes in visibility caused by // field focus changes won't violate the client's visibility setting. data.visible = false; setVisible(data, false); } /** * Update the specified decoration. This message should be used if the image * or description in the decoration have changed. This message has no * immediate effect if the decoration is not visible, and no effect at all * if the decoration was not previously added to the field. * * @param decoration * the decoration to be hidden. */ public void updateDecoration(FieldDecoration decoration) { FieldDecorationData data = getDecorationData(decoration); if (data == null) { return; } if (data.label != null) { data.label.setImage(decoration.getImage()); // If the decoration is being shown, and a hover is active, // update the hover text to display the new description. if (data.label.getVisible() == true && hover != null) { showHoverText(decoration.getDescription(), data.label); } } } /* * Set the visibility of the specified decoration data. This method does not * change the visibility value stored in the decData, but instead consults * it to determine how the visibility should be changed. This method is * called any time visibility of a decoration might change, whether by * client API or focus changes. */ private void setVisible(FieldDecorationData decData, boolean visible) { // Check the decData visibility flag, since it contains the client's // instructions for visibility. if (visible && decData.visible) { decData.label.setVisible(true); } else { decData.label.setVisible(false); } } /* * Get the FieldDecorationData that corresponds to the given decoration. */ private FieldDecorationData getDecorationData(FieldDecoration dec) { for (int i = 0; i < DECORATION_SLOTS; i++) { if (decDatas[i] != null && dec == decDatas[i].decoration && decDatas[i].label != null && !decDatas[i].label.isDisposed()) { return decDatas[i]; } } return null; } /* * Show the specified text in the hover, positioning the hover near the * specified control. */ private void showHoverText(String text, Control hoverNear) { if (text == null) { hideHover(); return; } if (hover == null) { hover = new Hover(hoverNear.getShell()); } hover.setText(text, hoverNear, control); hover.setVisible(true); } /** * Set a boolean that indicates whether the receiver should use the * decoration registry's maximum decoration width when allocating space for * decorations. The default value is <code>true</code>. Using the maximum * decoration width is useful so that decorated fields on the same dialog * that have different decoration widths will all align. This also allows * client dialogs to align non-decorated fields with decorated fields by * consulting the maximum decoration width. * </p> * <p> * Clients may wish to set this value to <code>false</code> in cases where * space usage is more important than alignment of fields. This value must * be set before the decorations are added in order to ensure proper * alignment. * </p> * * @param useMaximumWidth * <code>true</code> if the maximum decoration width should be * used as the size for all decorations, <code>false</code> if * only the decoration size should be used. * * @see FieldDecorationRegistry#getMaximumDecorationWidth() */ public void setUseMaximumDecorationWidth(boolean useMaximumWidth) { useMaxDecorationWidth = useMaximumWidth; } /* * Return the width appropriate for the specified decoration image. */ private int widthOf(Image image) { if (image == null) { return 0; } return useMaxDecorationWidth ? FieldDecorationRegistry.getDefault() .getMaximumDecorationWidth() : image.getBounds().width; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -