我正在开发一个eclipse插件,我在其中创建自己的自定义属性。我有一个扩展AbstractTextPropertyEditor
的类,并覆盖了这个类的paint方法。
我想通过写入值手动编辑属性表中的属性。我为此扩展了AbstractPropertyTextEditor类的窗口构建器。
package com.verifone.ide.eclipse.edt.editors.layout.properties;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.wb.internal.core.model.property.Property;
import org.eclipse.wb.internal.core.model.property.editor.AbstractTextPropertyEditor;
import org.eclipse.wb.internal.core.model.property.editor.presentation.ButtonPropertyEditorPresentation;
import org.eclipse.wb.internal.core.model.property.editor.presentation.PropertyEditorPresentation;
import org.eclipse.wb.internal.core.model.property.table.PropertyTable;
import org.eclipse.wb.internal.core.utils.ui.DrawUtils;
import tk.eclipse.plugin.htmleditor.HTMLPlugin;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.resources.ResourceType;
import com.google.common.collect.Maps;
import com.verifone.ide.eclipse.edt.editors.SimpleGraphicalEditor;
public class HTMLPropertyEditor extends AbstractTextPropertyEditor {
// public static final HTMLPropertyEditor INSTANCE = new
// HTMLPropertyEditor();
private PropertyTable mPropertyTable;
public HTMLPropertyEditor(PropertyTable propertyTable) {
mPropertyTable = propertyTable;
}
private static final int SAMPLE_SIZE = 10;
private static final int SAMPLE_MARGIN = 3;
private final PropertyEditorPresentation mPresentation = new ButtonPropertyEditorPresentation() {
@Override
protected void onClick(PropertyTable propertyTable, Property property)
throws Exception {
openDialog(propertyTable, property);
}
};
private void openDialog(PropertyTable propertyTable, Property property)
throws Exception {
// HTMLProperty htmlProperty = (HTMLProperty) property;
// IAttributeInfo attributeInfo = htmlProperty.getDescriptor()
// .getAttributeInfo();
//
// if (isIdProperty(property)) {
// Object value = htmlProperty.getValue();
// if (value != null && !value.toString().isEmpty()) {
// SimpleGraphicalEditor editor = htmlProperty
// .getGraphicalEditor();
// if (editor != null) {
// LayoutCanvas canvas = editor.getCanvasControl();
// SelectionManager manager = canvas.getSelectionManager();
//
// NodeProxy primary = canvas.getNodeFactory().create(
// htmlProperty.getNode());
// if (primary != null) {
// RenameResult result = manager.performRename(primary,
// null);
// if (result.isCanceled()) {
// return;
// } else if (!result.isUnavailable()) {
// String name = result.getName();
// String id = NEW_ID_PREFIX
// + BaseViewRule.stripIdPrefix(name);
// htmlProperty.setValue(id);
// return;
// }
// }
// }
// }
//
// // When editing the id attribute, don't offer a resource chooser:
// // usually
// // you want to enter a *new* id here
// // attributeInfo = null;
// }
//
// boolean referenceAllowed = false;
// if (attributeInfo != null) {
// EnumSet<Format> formats = attributeInfo.getFormats();
// ResourceType type = null;
// List<ResourceType> types = null;
// if (formats.contains(Format.FLAG)) {
// String[] flagValues = attributeInfo.getFlagValues();
// if (flagValues != null) {
// FlagXmlPropertyDialog dialog = new FlagXmlPropertyDialog(
// propertyTable.getShell(), "Select Flag Values",
// false /* radio */, flagValues, htmlProperty);
//
// dialog.open();
// return;
// }
// } else if (formats.contains(Format.ENUM)) {
// String[] enumValues = attributeInfo.getEnumValues();
// if (enumValues != null) {
// FlagXmlPropertyDialog dialog = new FlagXmlPropertyDialog(
// propertyTable.getShell(), "Select Enum Value",
// true /* radio */, enumValues, htmlProperty);
// dialog.open();
// return;
// }
// } else {
// for (Format format : formats) {
// ResourceType t = format.getResourceType();
// if (t != null) {
// if (type != null) {
// if (types == null) {
// types = new ArrayList<ResourceType>();
// types.add(type);
// }
// types.add(t);
// }
// type = t;
// } else if (format == Format.REFERENCE) {
// referenceAllowed = true;
// }
// }
// }
// if (types != null || referenceAllowed) {
// // Multiple resource types (such as string *and* boolean):
// // just use a reference chooser
// SimpleGraphicalEditor graphicalEditor = htmlProperty
// .getGraphicalEditor();
// if (graphicalEditor != null) {
// LayoutEditorDelegate delegate = graphicalEditor
// .getEditorDelegate();
// IProject project = delegate.getParentEditor().getProject();
// if (project != null) {
// // get the resource repository for this project and the
// // system
// resources.ResourceRepository projectRepository = ResourceManager
// .getInstance().getProjectResources(project);
// Shell shell = AdtPlugin.getShell();
// ReferenceChooserDialog dlg = new ReferenceChooserDialog(
// project, projectRepository, shell);
// dlg.setPreviewHelper(new ResourcePreviewHelper(dlg,
// graphicalEditor));
//
// String currentValue = (String) property.getValue();
// dlg.setCurrentResource(currentValue);
//
// if (dlg.open() == Window.OK) {
// String resource = dlg.getCurrentResource();
// if (resource != null) {
// // Returns null for cancel, "" for clear and
// // otherwise a new value
// if (resource.length() > 0) {
// property.setValue(resource);
// } else {
// property.setValue(null);
// }
// }
// }
//
// return;
// }
// }
// } else if (type != null) {
// // Single resource type: use a resource chooser
// SimpleGraphicalEditor graphicalEditor = htmlProperty
// .getGraphicalEditor();
// if (graphicalEditor != null) {
// String currentValue = (String) property.getValue();
// // TODO: Add validator factory?
// String resource = ResourceChooser
// .chooseResource(graphicalEditor, type,
// currentValue, null /* validator */);
// // Returns null for cancel, "" for clear and otherwise a new
// // value
// if (resource != null) {
// if (resource.length() > 0) {
// property.setValue(resource);
// } else {
// property.setValue(null);
// }
// }
// }
//
// return;
// }
// }
//
// // Fallback: Just use a plain string editor
// StringXmlPropertyDialog dialog = new StringXmlPropertyDialog(
// propertyTable.getShell(), property);
// dialog.open();
// if (dialog.open() == Window.OK) {
// TODO: Do I need to activate?
// }
}
public PropertyEditorPresentation getPresentation() {
return mPresentation;
};
//
// @Override
// public boolean activate(PropertyTable propertyTable, Property property,
// Point location) throws Exception {
// boolean isActive = super.activate(propertyTable, property, location);
// Utils.getInstance().printMsg("isActivate: " + isActive);
// return isActive;
// }
@Override
public String getText(Property property) throws Exception {
Object value = property.getValue();
if (value instanceof String) {
return (String) value;
}
return null;
}
@Override
protected String getEditorText(Property property) throws Exception {
return getText(property);
}
@Override
public void paint(Property property, GC gc, int x, int y, int width,
int height) throws Exception {
String text = getText(property);
if (text != null) {
ResourceValue resValue = null;
String resolvedText = null;
// TODO: Use the constants for @, ?, @android: etc
if (text.startsWith("@") || text.startsWith("?")) { //$NON-NLS-1$ //$NON-NLS-2$
// // Yes, try to resolve it in order to show better info
HTMLProperty htmlProperty = (HTMLProperty) property;
SimpleGraphicalEditor graphicalEditor = htmlProperty
.getGraphicalEditor();
if (graphicalEditor != null) {
// ResourceResolver resolver =
// graphicalEditor.getResourceResolver();
// boolean isFramework = text.startsWith(ANDROID_PREFIX)
// || text.startsWith(ANDROID_THEME_PREFIX);
// boolean isFramework = true;
// resValue = resolver.findResValue(text, isFramework);
// while (resValue != null && resValue.getValue() != null) {
// String value = resValue.getValue();
// if (value.startsWith(PREFIX_RESOURCE_REF)
// || value.startsWith(PREFIX_THEME_REF)) {
// // TODO: do I have to strip off the @ too?
// isFramework = isFramework
// || value.startsWith(ANDROID_PREFIX)
// || value.startsWith(ANDROID_THEME_PREFIX);
// ResourceValue v = resolver.findResValue(text,
// isFramework);
// if (v != null && !value.equals(v.getValue())) {
// resValue = v;
// } else {
// break;
// }
// } else {
// break;
// }
// }
}
} else if (text.startsWith("#") && text.matches("#\\p{XDigit}+")) { //$NON-NLS-1$
resValue = new ResourceValue(ResourceType.COLOR,
property.getName(), text, false);
}
if (resValue != null && resValue.getValue() != null) {
// String value = resValue.getValue();
// // Decide whether it's a color, an image, a nine patch etc
// // and decide how to render it
// if (value.startsWith("#") || value.endsWith(DOT_XML) //$NON-NLS-1$
// && value.contains("res/color")) { //$NON-NLS-1$ // TBD: File.separator?
// HTMLProperty htmlProperty = (HTMLProperty) property;
// SimpleGraphicalEditor graphicalEditor = htmlProperty
// .getGraphicalEditor();
// if (graphicalEditor != null) {
// ResourceResolver resolver = graphicalEditor
// .getResourceResolver();
// RGB rgb = ResourceHelper.resolveColor(resolver,
// resValue);
// if (rgb != null) {
// Color color = new Color(gc.getDevice(), rgb);
// // draw color sample
// Color oldBackground = gc.getBackground();
// Color oldForeground = gc.getForeground();
// try {
// int width_c = SAMPLE_SIZE;
// int height_c = SAMPLE_SIZE;
// int x_c = x;
// int y_c = y + (height - height_c) / 2;
// // update rest bounds
// int delta = SAMPLE_SIZE + SAMPLE_MARGIN;
// x += delta;
// width -= delta;
// // fill
// gc.setBackground(color);
// gc.fillRectangle(x_c, y_c, width_c, height_c);
// // draw line
// gc.setForeground(IColorConstants.gray);
// gc.drawRectangle(x_c, y_c, width_c, height_c);
// } finally {
// gc.setBackground(oldBackground);
// gc.setForeground(oldForeground);
// }
// color.dispose();
// }
// }
// } else {
// Image swtImage = null;
// if (value.endsWith(DOT_XML)
// && value.contains("res/drawable")) { // TBD:
// // Filesep?
// Map<String, Image> cache = getImageCache(property);
// swtImage = cache.get(value);
// if (swtImage == null) {
// HTMLProperty htmlProperty = (HTMLProperty) property;
// SimpleGraphicalEditor graphicalEditor = htmlProperty
// .getGraphicalEditor();
// RenderService service = RenderService
// .create(graphicalEditor);
// service.setOverrideRenderSize(SAMPLE_SIZE,
// SAMPLE_SIZE);
// BufferedImage drawable = service
// .renderDrawable(resValue);
// if (drawable != null) {
// swtImage = SwtUtils.convertToSwt(
// gc.getDevice(), drawable,
// true /* transferAlpha */, -1);
// cache.put(value, swtImage);
// }
// }
// } else if (value.endsWith(DOT_PNG)) {
// // TODO: 9-patch handling?
// // if (text.endsWith(DOT_9PNG)) {
// // // 9-patch image: How do we paint this?
// // URL url = new File(text).toURI().toURL();
// // NinePatch ninepatch = NinePatch.load(url, false /* ??
// // */);
// // BufferedImage image = ninepatch.getImage();
// // }
// Map<String, Image> cache = getImageCache(property);
// swtImage = cache.get(value);
// if (swtImage == null) {
// File file = new File(value);
// if (file.exists()) {
// try {
// BufferedImage awtImage = ImageIO.read(file);
// if (awtImage != null
// && awtImage.getWidth() > 0
// && awtImage.getHeight() > 0) {
// awtImage = ImageUtils.cropBlank(
// awtImage, null);
// if (awtImage != null) {
// // Scale image
// int imageWidth = awtImage
// .getWidth();
// int imageHeight = awtImage
// .getHeight();
// int maxWidth = 3 * height;
//
// if (imageWidth > maxWidth
// || imageHeight > height) {
// double scale = height
// / (double) imageHeight;
// int scaledWidth = (int) (imageWidth * scale);
// if (scaledWidth > maxWidth) {
// scale = maxWidth
// / (double) imageWidth;
// }
// awtImage = ImageUtils.scale(
// awtImage, scale, scale);
// }
// swtImage = SwtUtils
// .convertToSwt(
// gc.getDevice(),
// awtImage,
// true /* transferAlpha */,
// -1);
// }
// }
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// cache.put(value, swtImage);
// }
//
// } else if (value != null) {
// // It's a normal string: if different from the text,
// // paint
// // it in parentheses, e.g.
// // @string/foo: Foo Bar (probably cropped)
// if (!value.equals(text) && !value.equals("@null")) { //$NON-NLS-1$
// resolvedText = value;
// }
// }
//
// if (swtImage != null) {
// // Make a square the size of the height
// ImageData imageData = swtImage.getImageData();
// int imageWidth = imageData.width;
// int imageHeight = imageData.height;
// if (imageWidth > 0 && imageHeight > 0) {
// gc.drawImage(swtImage, x, y + (height - imageHeight) / 2);
// int delta = imageWidth + SAMPLE_MARGIN;
// x += delta;
// width -= delta;
// }
// }
// }
}
DrawUtils.drawStringCV(gc, text, x, y, width, height);
if (resolvedText != null && resolvedText.length() > 0) {
Point size = gc.stringExtent(text);
x += size.x;
width -= size.x;
x += SAMPLE_MARGIN;
width -= SAMPLE_MARGIN;
if (width > 0) {
Color oldForeground = gc.getForeground();
try {
gc.setForeground(PropertyTable.COLOR_PROPERTY_FG_DEFAULT);
DrawUtils.drawStringCV(gc, '(' + resolvedText + ')', x,
y, width, height);
} finally {
gc.setForeground(oldForeground);
}
}
}
}
}
int i = 0;
private static boolean isIdProperty(Property property) {
// HTMLProperty xmlProperty = (HTMLProperty) property;
// return
// xmlProperty.getDescriptor().getHTMLLocalName().equals(ATTR_ID);
return false;
}
@Override
protected boolean setEditorText(Property property, String text)
throws Exception {
Object oldValue = property.getValue();
String old = oldValue != null ? oldValue.toString() : null;
property.setValue(text);
return true;
}
/** Qualified name for the per-project persistent property include-map */
private final static QualifiedName CACHE_NAME = new QualifiedName(
HTMLPlugin.PLUGIN_ID, "property-images");//$NON-NLS-1$
private static Map<String, Image> getImageCache(Property property) {
HTMLProperty htmlProperty = (HTMLProperty) property;
SimpleGraphicalEditor graphicalEditor = htmlProperty
.getGraphicalEditor();
IProject project = graphicalEditor.getProject();
try {
Map<String, Image> cache = (Map<String, Image>) project
.getSessionProperty(CACHE_NAME);
if (cache == null) {
cache = Maps.newHashMap();
project.setSessionProperty(CACHE_NAME, cache);
}
return cache;
} catch (CoreException e) {
e.printStackTrace();
return Maps.newHashMap();
}
}
}
显示属性的值,但是,我无法编辑此表的属性。
有人可以帮我解决这个问题吗?
答案 0 :(得分:0)
这是错误的做法。 paint()
是一种渲染方法,不能更改窗口小部件树 - 否则,整个窗口小部件树的绘制将以奇怪的方式打破。最有可能的是,您在某个时间点会得到ConcurrentModificationException
。
正确的解决方案是创建org.eclipse.ui.part.EditorPart
并在createPartControl()
内创建文本编辑器小部件,并将其附加到父小部件。这将确保在必要时呈现编辑器,正确处理事件以及大量其他事情。