public void dispose() { /* * Unregister listeners. */ for (IAttributeEditor editor : this.editors.values()) { editor.removeAttributeListener(forwardListener); } super.dispose(); }
/** Adds validation overlay component to the control. */ private void addValidationOverlay( final AttributeDescriptor descriptor, final IAttributeEditor editor, final Object defaultValue, final Control label) { final ControlDecoration decoration = new ControlDecoration(label, SWT.LEFT | SWT.BOTTOM); decoration.hide(); final FieldDecoration requiredDecoration = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR); decoration.setImage(requiredDecoration.getImage()); decoration.setDescriptionText("Invalid value"); final IAttributeListener validationListener = new InvalidStateDecorationListener(decoration, descriptor, defaultValue); globalEventsProvider.addAttributeListener(validationListener); editor.addAttributeListener(validationListener); label.addDisposeListener( new DisposeListener() { public void widgetDisposed(DisposeEvent e) { globalEventsProvider.removeAttributeListener(validationListener); editor.removeAttributeListener(validationListener); decoration.dispose(); } }); }
/** Initialize and instantiate the delegate editor class. */ public AttributeEditorInfo init( BindableDescriptor bindable, AttributeDescriptor descriptor, IAttributeEventProvider eventProvider, Map<String, Object> defaultValues) { final boolean floatingPointType = descriptor.type.equals(Double.class) || descriptor.type.equals(Float.class); final boolean unbounded; final boolean hasNegativeValues; if (floatingPointType) { final DoubleRange r = NumberUtils.getDoubleRange(descriptor); hasNegativeValues = (r == null || r.min() < 0); unbounded = (r == null || NumberUtils.isUnbounded(r)); } else { final IntRange r = NumberUtils.getIntRange(descriptor); hasNegativeValues = (r == null || r.min() < 0); unbounded = (r == null || NumberUtils.isUnbounded(r)); } final IAttributeEditor delegate; if (unbounded) { /* * If the range is unbounded or contains negative values, use unbounded * numeric editor (simple text box). Such unconstrained public attributes * shouldn't be common anyway. */ if (floatingPointType) { delegate = new UnboundedDoubleEditor(); } else { if (!hasNegativeValues) { delegate = new IntegerRangeEditor(); } else { delegate = new UnboundedIntegerEditor(); } } } else if (hasNegativeValues) { /* * If the range covers negative values, or if the range is too big to fit in * the integer range, use unbounded double editor. TODO: Negative * scale/sliders are available in Eclipse 3.4M5: * https://bugs.eclipse.org/bugs/show_bug.cgi?id=91317 */ if (floatingPointType) { delegate = new UnboundedDoubleEditor(); } else { delegate = new UnboundedIntegerEditor(); } } else { /* * The range exists, is bounded and contains only non-negative values, use * slider/scale directly. */ if (floatingPointType) { delegate = new DoubleRangeEditor(); } else { delegate = new IntegerRangeEditor(); } } this.delegate = delegate; return delegate.init(bindable, descriptor, eventProvider, defaultValues); }
public void dispose() { delegate.dispose(); }
public String getAttributeKey() { return delegate.getAttributeKey(); }
public Object getValue() { return delegate.getValue(); }
public void setValue(Object currentValue) { delegate.setValue(currentValue); }
public void addAttributeListener(IAttributeListener listener) { delegate.addAttributeListener(listener); }
public void removeAttributeListener(IAttributeListener listener) { delegate.removeAttributeListener(listener); }
public void setFocus() { delegate.setFocus(); }
public void createEditor(Composite parent, int gridColumns) { delegate.createEditor(parent, gridColumns); }
/** Sets the <code>key</code> editor's current value to <code>value</code>. */ public void setAttribute(String key, Object value) { final IAttributeEditor editor = editors.get(key); if (editor != null) { editor.setValue(value); } }
/** Create internal GUI. */ private void createComponents(Map<String, Object> currentValues) { /* * Sort alphabetically by label. */ final Locale locale = Locale.getDefault(); final Map<String, String> labels = Maps.newHashMap(); for (Map.Entry<String, AttributeDescriptor> entry : attributeDescriptors.entrySet()) { labels.put(entry.getKey(), getLabel(entry.getValue()).toLowerCase(locale)); } final Collator collator = Collator.getInstance(locale); final List<String> sortedKeys = Lists.newArrayList(labels.keySet()); Collections.sort( sortedKeys, new Comparator<String>() { public int compare(String a, String b) { return collator.compare(labels.get(a), labels.get(b)); } }); /* * Create editors and inquire about their layout needs. */ editors = Maps.newHashMap(); final Map<String, AttributeEditorInfo> editorInfos = Maps.newHashMap(); int maxColumns = 1; for (String key : sortedKeys) { final AttributeDescriptor descriptor = attributeDescriptors.get(key); IAttributeEditor editor = null; try { editor = EditorFactory.getEditorFor(this.componentClazz, descriptor); final AttributeEditorInfo info = editor.init(bindable, descriptor, globalEventsProvider, currentValues); editorInfos.put(key, info); maxColumns = Math.max(maxColumns, info.columns); } catch (EditorNotFoundException ex) { Utils.logError( "No editor for attribute: " + descriptor.key + " (class: " + descriptor.type + ")", false); /* * Skip editor. */ editor = null; } editors.put(key, editor); } /* * Prepare the layout for this editor. */ final GridLayout layout = GUIFactory.zeroMarginGridLayout(); layout.makeColumnsEqualWidth = false; layout.numColumns = maxColumns; this.setLayout(layout); /* * Create visual components for editors. */ final GridDataFactory labelFactory = GridDataFactory.fillDefaults().span(maxColumns, 1); boolean firstEditor = true; for (String key : sortedKeys) { final AttributeDescriptor descriptor = attributeDescriptors.get(key); final IAttributeEditor editor = editors.get(key); final AttributeEditorInfo editorInfo = editorInfos.get(key); if (editor == null) { // Skip attributes without the editor. continue; } final Object defaultValue; if (currentValues != null && currentValues.get(key) != null) { defaultValue = currentValues.get(key); } else { defaultValue = attributeDescriptors.get(key).defaultValue; } // Add label to editors that do not have it. if (!editorInfo.displaysOwnLabel) { final Label label = new Label(this, SWT.LEAD); final GridData gd = labelFactory.create(); if (!firstEditor) { gd.verticalIndent = SPACE_BEFORE_LABEL; } label.setLayoutData(gd); label.setText(getLabel(descriptor) + (descriptor.requiredAttribute ? " (required)" : "")); /* * Add validation overlay. */ addValidationOverlay(descriptor, editor, defaultValue, label); AttributeInfoTooltip.attach(label, descriptor); } // Add the editor, if available. editor.createEditor(this, maxColumns); // Set the default value for the editor. editor.setValue(defaultValue); editors.put(editor.getAttributeKey(), editor); /* * Forward events from this editor to all our listeners. */ editor.addAttributeListener(forwardListener); firstEditor = false; } }