本文主要是介绍gef实现属性页,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1.如果要实现在属性视图中编辑被选择的对象,则至少必须满足以下两个条件:
- 被选择的对象必须实现或者能够适配成IPropertySource接口对象。
- 被选择的对象必须能够被实现了ISelectionProvider接口的选择提供者提供属性视图
2.Eclipse中内置了一些实现了IPropertyDescriptor接口的类
- PropertyDescriptor 可以实现不可编辑的属性
- ColorPropertyDescriptor 会弹出颜色选择对话框
- ComboBoxPropertyDescriptor 可以通过下拉框选择需要的属性
- TextPropertyDescriptor 实现可编辑的属性
- StandardComboBoxPropertyDescriptor
3.实现属性栏打开自定义的对话框
可以参考在属性页中打开对话框 ,写得已经很详细了。
4.实现属性的显示顺序
在PropertySheetPage显示的属性中, 如果需要自定义属性显示的上下顺序, 就需要给PropertySheetPage添加一个PropertySheetSorter, 从而决定属性显示的上下顺序.
4.1 在Editor中加入如下代码:
1. ...................
2. if (type.equals(IPropertySheetPage.class)) {
3. return new PropertySheetPage() {
4. public void createControl(Composite parent) {
5. // super.createControl(parent);
6. PropertySheetSorter sorter = new PropertySheetSorter() {
7. public int compare(IPropertySheetEntry entryA,
8. IPropertySheetEntry entryB) {
9. return getCollator().compare(
10. entryA.getDescription(),
11. entryB.getDescription());
12. }
13. };
14. this.setSorter(sorter);
15. super.createControl(parent);
16. }
17. };
18. }
19. return super.getAdapter(type);
20. }
...................
if (type.equals(IPropertySheetPage.class)) {
return new PropertySheetPage() {
public void createControl(Composite parent) {
// super.createControl(parent);
PropertySheetSorter sorter = new PropertySheetSorter() {
public int compare(IPropertySheetEntry entryA,
IPropertySheetEntry entryB) {
return getCollator().compare(
entryA.getDescription(),
entryB.getDescription());
}
};
this.setSorter(sorter);
super.createControl(parent);
}
};
}
return super.getAdapter(type);
}
4.2 在处理属性视图的类中加入以下代码
Java代码
1. public IPropertyDescriptor[] getPropertyDescriptors() {
2. ArrayList<IPropertyDescriptor> properties = new ArrayList<IPropertyDescriptor>();
3. TextPropertyDescriptor name=new TextPropertyDescriptor(Node.PROPERTY_RENAME, "Name");
4. name.setDescription("01");//设置这个是为了排序
5. properties.add(name);//增加任务名
6. if (node instanceof TaskModel) {
7. TextPropertyDescriptor des=new TextPropertyDescriptor(TaskModel.PROPERTY_DESCRIPTION,
8. "Description");
9. des.setDescription("02");
10. properties.add(des);//增加任务描述
11. ...........................
public IPropertyDescriptor[] getPropertyDescriptors() {
ArrayList<IPropertyDescriptor> properties = new ArrayList<IPropertyDescriptor>();
TextPropertyDescriptor name=new TextPropertyDescriptor(Node.PROPERTY_RENAME, "Name");
name.setDescription("01");//设置这个是为了排序
properties.add(name);//增加任务名
if (node instanceof TaskModel) {
TextPropertyDescriptor des=new TextPropertyDescriptor(TaskModel.PROPERTY_DESCRIPTION,
"Description");
des.setDescription("02");
properties.add(des);//增加任务描述
实例2------------------------
要添加视图,首先我们首先要添加所要依赖的Jar包,org.eclipse.ui.views Jar包,修改AbstractModel模型,实现IpropertySource接口,在HelloModel中实现最上层父类的方法
@Override
public IPropertyDescriptor[] getPropertyDescriptors() {
IPropertyDescriptor []desc = new IPropertyDescriptor[]{new TextPropertyDescriptor(P_TEXT,"属性")};
return desc;
}
我们这里只提供一个属性。通过ID,我们获取要的数值
@Override
public Object getPropertyValue(Object id) {
if(id.equals(P_TEXT)){
return text;
}
return null;
}
@Override
public boolean isPropertySet(Object id) {
if(id.equals(P_TEXT)){
return true;
}
return false;
}
@Override
public void setPropertyValue(Object id, Object value) {
if(id.equals(P_TEXT)){
setText((String)value);
}
super.setPropertyValue(id, value);
}
}
2.在HelloEditPart中,在PropertyChange(PropertyChangeEvent evnt)中刷新视图
@Override
public void propertyChange(PropertyChangeEvent event) {
super.propertyChange(event);
if(event.getPropertyName().equals(HelloModel.P_CONSTRAINT)){
refreshVisuals();
}else if(event.getPropertyName().equals(HelloModel.P_TEXT)){
Label label = (Label) getFigure();
label.setText((String)event.getNewValue());
}
}
3.在Perspective中设置属性视图可以显示
public class Perspective implements IPerspectiveFactory {
public void createInitialLayout(IPageLayout layout) {
final String properties ="org.eclipse.ui.views.PropertySheet";
final String editArea = layout.getEditorArea();
IFolderLayout leftLayout = layout.createFolder("LeftTop", IPageLayout.BOTTOM, 0.28f, editArea);
leftLayout.addView(properties);
layout.setEditorAreaVisible(true);
}
}
1. 直接编辑文本
派生出DirectEditManager的子类CustomDirectEditManager,
public class CustomDirectEditManager extends DirectEditManager {
private HelloModel helloModel;
public CustomDirectEditManager(GraphicalEditPart source, Class editorType,
CellEditorLocator locator) {
super(source, editorType, locator);
this.helloModel=(HelloModel) source.getModel();
}
@Override
protected void initCellEditor() {
getCellEditor().setValue(this.helloModel.getText());
Text txt = (Text)getCellEditor().getControl();
txt.selectAll();
}
}然后我们从CellEditLocator里面派生出CustomCellEditLocator类,public class CustomCellEditorLocator implements CellEditorLocator {
private IFigure figure;
public CustomCellEditorLocator(IFigure fg){
figure = fg;
}
@Override
public void relocate(CellEditor cellEditor) {
Text txt = (Text) cellEditor.getControl();
Rectangle rect = figure.getBounds().getCopy();
figure.translateToAbsolute(rect);
txt.setBounds(rect.x, rect.y, rect.width, rect.height);
}
}
在HeloEditPart中重载
@Override
public void propertyChange(PropertyChangeEvent event) {
super.propertyChange(event);
if(event.getPropertyName().equals(HelloModel.P_CONSTRAINT)){
refreshVisuals();
}else if(event.getPropertyName().equals(HelloModel.P_TEXT)){
Label label = (Label) getFigure();
label.setText((String)event.getNewValue());
}
}
运行效果图
要想能够对里面的编辑起到作用,我们需要创建策略和命令
创建Command命令
public class DirectEditCommmand extends Command {
private String oldValue,newValue;
private HelloModel helloModel;
@Override
public void execute() {
super.execute();
oldValue = helloModel.getText();
helloModel.setText(newValue);
}
@Override
public void undo() {
super.undo();
helloModel.setText(oldValue);
}
public void setHelloModel(HelloModel helloModel) {
this.helloModel = helloModel;
}
public void setOldValue(String oldValue) {
this.oldValue = oldValue;
}
public void setNewValue(String newValue) {
this.newValue = newValue;
}
}
创建策略CustomDirectEditPolicy
public class CustomDirectEditPolicy extends DirectEditPolicy {
@Override
protected Command getDirectEditCommand(DirectEditRequest req) {
DirectEditCommmand command = new DirectEditCommmand();
command.setHelloModel((HelloModel)getHost().getModel());
command.setNewValue((String)req.getCellEditor().getValue());
return command;
}
@Override
protected void showCurrentEditValue(DirectEditRequest arg0) {
}
}
创建对应的CustomDirectEditPolicy策略后,我们需要将该策略安装到HelloEditPart中 @Override
protected void createEditPolicies() {
installEditPolicy(EditPolicy.COMPONENT_ROLE , new CustomComponentEditPolicy());
installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new CustomDirectEditPolicy());
}
1. 键盘直接操作文本
@Override
protected void configureGraphicalViewer() {
super.configureGraphicalViewer();
viewer = getGraphicalViewer();
viewer.setEditPartFactory(new PartFactory());
//创建键盘句柄
KeyHandler keyHandler = new KeyHandler();
//按Del时候执行Del操作
keyHandler.put(KeyStroke.getPressed(SWT.DEL, 127,0), getActionRegistry().getAction(GEFActionConstants.DELETE));
keyHandler.put(KeyStroke.getPressed(SWT.F2, 0), getActionRegistry().getAction(GEFActionConstants.DIRECT_EDIT));
// getGraphicalViewer().setKeyHandler(keyHandler);
getGraphicalViewer().setKeyHandler(new GraphicalViewerKeyHandler(getGraphicalViewer()).setParent(keyHandler));
}
在createActions()中注册DirectEditAction
@Override
protected void createActions() {
super.createActions();
IAction action = new UndoRetargetAction();
action.setId(ActionFactory.UNDO.getId());
getActionRegistry().registerAction(action);
getSelectionActions().add(action.getId());
action = new RedoRetargetAction();
action.setId(ActionFactory.REDO.getId());
getActionRegistry().registerAction(action);
getSelectionActions().add(action.getId());
action = new DirectEditAction(this);
getActionRegistry().registerAction(action);
getSelectionActions().add(action.getId());
}
连接Connection
1. 首先创建连接模型及其控制器AbstractConnectionModel 和LineConnectionEditPart,然后把模型和控制器连接起来。在PartFactory中添加,修改节点模型,使HelloModel变成连接的Node节点,因为HelloModel既是起始节点,又是终止节点。
//connection
public static final String P_Source_Connection = "P_Source_Connection";
public static final String P_Target_Connection ="P_Target_Connection";
private List sourceConnection = new ArrayList();
private List targetConnection = new ArrayList();
public void addSourceConnection(Object conx){
sourceConnection.add(conx);
firePropertyChange(P_Source_Connection, null, null);
}
public void addTargetConnection(Object conx){
targetConnection.add(conx);
firePropertyChange(P_Target_Connection, null, null);
}
public List getModelSourceConnections(){
return sourceConnection;
}
public List getModelTargetConnections(){
return targetConnection;
}
public void removeSourceConnections(Object conx){
sourceConnection.remove(conx);
firePropertyChange(P_Source_Connection, null, null);
}
public void removeTargetConnections(Object conx){
targetConnection.remove(conx);
firePropertyChange(P_Target_Connection, null, null);
}
要把HelloModel模型当做节点来看待,就需要在HelloEditPart中实现NodeEditPart
@Override
public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart arg0) {
return new ChopboxAnchor(getFigure());
}
@Override
public ConnectionAnchor getSourceConnectionAnchor(Request arg0) {
return new ChopboxAnchor(getFigure());
}
在HelloEditPart中调用所有的SourceConnection和TargetConnection节点的方法
@Override
public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart arg0) {
return new ChopboxAnchor(getFigure());
}
@Override
public ConnectionAnchor getTargetConnectionAnchor(Request arg0) {
return new ChopboxAnchor(getFigure());
}
然后在工具箱中添加工具栏
PaletteDrawer drawer1 = new PaletteDrawer("连接");
ConnectionCreationToolEntry conncreateEntry = new ConnectionCreationToolEntry("简单连接", "创建最简单的连接", new SimpleFactory(LineConnectionModel.class), Activator.getImageDescriptor("icons/ch_callers(3).gif"), Activator.getImageDescriptor("icons/ch_callers(3).gif"));
drawer1.add(conncreateEntry);
root.add(drawer1);
2.修改连接模型public abstract class AbstractConnectionModel {
private HelloModel source,target;
public void attachSource(){
if(!source.getModelSourceConnections().contains(this)){
source.addSourceConnection(this);
}
}
public void attachTarget(){
if(!target.getModelTargetConnections().contains(this)){
target.addTargetConnection(this);
}
}
public void detachSource(){
source.removeSourceConnections(this);
}
public void detachTarget(){
target.removeTargetConnections(this);
}
public void setSource(HelloModel source) {
this.source = source;
}
public void setTarget(HelloModel target) {
this.target = target;
}
public HelloModel getSource() {
return source;
}
public HelloModel getTarget() {
return target;
}
}
实例三---------------------
当使用Eclipse的多页签Editor时,如果按照单个Editor的Property页和Outline的设计,会出现两个Editor使用同一个CommandStack和多页签的Outline不能切换的问题,经过试验以两个页签为例使用下面的解决方案:建立在于MultPageEditorPart级别的IPropertySheetPage和IContentOutlinePage然后通过获取MultiPageEditorPart的pageChange(int index)方法来动态的设置相应的Property和Outline。具体是先步骤:
1.建立MultiPageEditorPart的子类FormEditor,主要实现CreatePages方法,在这个方法里边具体是的实现相应两个子Editor的初始化工作,并且使用阿addPage(Editor,EditorInput)方法把它们加入到MultiPageEditorPart中
2.实现相应的getAdapter(Class)方法,当传入的Class是IPropertySheetPage和IContentOutlinePage的时候,初始化相应的MultiPageEditorPart级别的PropertySheetPage和ContentOutlinePage,这两个类的实现代码如下:
- import java.util.Map;
- import org.eclipse.jface.viewers.ISelection;
- import org.eclipse.swt.SWT;
- import org.eclipse.swt.widgets.Composite;
- import org.eclipse.swt.widgets.Control;
- import org.eclipse.ui.IActionBars;
- import org.eclipse.ui.IWorkbenchPart;
- import org.eclipse.ui.SubActionBars;
- import org.eclipse.ui.part.PageBook;
- import org.eclipse.ui.views.properties.IPropertySheetPage;
- import org.eclipse.ui.views.properties.PropertySheetPage;
- /**
- * @author kang.ao
- *
- *
- */
- public class FormPropertySheetPage extends PropertySheetPage implements IPropertySheetPage {
- private PageBook pagebook;
- private Map recMap = new HashMap();
- private PropertySheetPage defaultPage;
- private IActionBars actionBars;
- private IPropertySheetPage currentPage;
- private boolean disposed = false;
- class PageRec {
- IPropertySheetPage page;
- SubActionBars bars;
- void setBarsActive(boolean active) {
- if (active)
- bars.activate();
- else
- bars.deactivate();
- }
- }
- public FormPropertySheetPage() {
- defaultPage = new PropertySheetPage();
- }
- public void createControl(Composite parent) {
- pagebook = new PageBook(parent, SWT.NULL);
- defaultPage.createControl(pagebook);
- if (currentPage != null)
- setPageActive(currentPage);
- }
- private PageRec createPageRec(IPropertySheetPage page) {
- if (actionBars == null)
- return null;
- PageRec rec = new PageRec();
- rec.page = page;
- rec.bars = new SubActionBars(actionBars);
- getPageControl(page);
- page.setActionBars(rec.bars);
- recMap.put(page, rec);
- return rec;
- }
- public void dispose() {
- updateActionBars();
- if (pagebook != null && !pagebook.isDisposed())
- pagebook.dispose();
- pagebook = null;
- disposed = true;
- super.dispose();
- }
- public boolean isDisposed() {
- return disposed;
- }
- public Control getControl() {
- return pagebook;
- }
- private Control getPageControl(IPropertySheetPage page) {
- Control control = page.getControl();
- if (control == null || control.isDisposed()) {
- // first time
- page.createControl(pagebook);
- control = page.getControl();
- }
- return control;
- }
- public void selectionChanged(IWorkbenchPart part, ISelection sel) {
- if (currentPage != null)
- currentPage.selectionChanged(part, sel);
- }
- public void setActionBars(IActionBars bars) {
- this.actionBars = bars;
- createPageRec(defaultPage);
- if (currentPage != null) {
- PageRec rec = createPageRec(currentPage);
- setPageActive(rec);
- updateActionBars();
- }
- }
- public void setDefaultPageActive() {
- setPageActive(defaultPage);
- }
- public void setFocus() {
- if (currentPage != null)
- currentPage.setFocus();
- }
- private void setPageActive(PageRec pageRec) {
- IPropertySheetPage page = pageRec.page;
- Control control = getPageControl(page);
- pagebook.showPage(control);
- pageRec.setBarsActive(true);
- }
- public void setPageActive(IPropertySheetPage page) {
- IPropertySheetPage oldPage = currentPage;
- this.currentPage = page;
- if (pagebook == null) {
- return;
- }
- if (oldPage != null) {
- PageRec oldRec = (PageRec) recMap.get(oldPage);
- if (oldRec != null) {
- oldRec.setBarsActive(false);
- }
- }
- PageRec rec = (PageRec) recMap.get(page);
- if (rec == null) {
- rec = createPageRec(page);
- }
- if (rec != null) {
- setPageActive(rec);
- updateActionBars();
- }
- }
- private void updateActionBars() {
- actionBars.updateActionBars();
- }
- }
OutlinePage:
在MultiPageEditorPart的 protected void pageChange(int newPageIndex);方法中进行更新当前的激活Editor的PropertySheetPage和OutlinePage,方法如下:
更新PropertySheet:
具体的子Editor中的获得PropertySheet和OutlinePage的方法可以参照Gef例子中的编写,在子Editor中初始化Outline的时候由于同一使用MultiPageEditorPart中的OutlinePage的Action,所以在子Editor的OutlinePage中不能去设定Action按钮,具体的参照FormContentOutline的Action的初始化,这点是与gef例子中给的不同的!
这篇关于gef实现属性页的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!