jueves, 3 de junio de 2010

Netbeans Plataform LookUp + Visual Library + Property Sheet

Hola, este es un pequeño tutorial de como usar el netbenas plataform con su famosa libreria visual y el lookup (dificil de entender en un principio), bueno basicamente tratare de explicar el objetivo del proyecto:

Objetivo: Crear un Aplicacion Siute basada en Netbeans Plataform que tenga un entorno grafico ,que haga uso de LookUp API para la comunicacion entre componentes y la ventana de propiedades para visulizar las propiedades del Nodo.

Ok Empezemos.

Primero lo basico Crear un nuevo proyecto -> NetBeans Module -> NetBeans Platform Application

Ok le damos un nombre por ejemplo "Graph"

Creamos un modulo. para ello abrimos el arbol del proyecto en modulos -> click derecho y damos nuevo Modulo el nombre por ejemplo "Editor"

Ahora damos click derecho sobre el modulo propiedades -> Lebrerias
y agregamos las siguinetes dependencias qeu qeude de esta forma:





Abrimos el nodo de codigo y creamos 1 top componet dando click derecho nuevo Otro->ModuleDeveloped-> WindowComponent->WindowPosition en Editor y habilitamos el chek que dice open on aplication start

Le damos un nombre y le ponemos ejemplo "Visual Editor".

Agregamos en el formulario un BorderLayout y un ScrollPane que les quede de la siguiente forma:






Vamos al codigo fuente y escribimos lo siguiente en el constructor:


public VisualEditorTopComponent() {
initComponents();
setName(NbBundle.getMessage(VisualEditorTopComponent.class,"CTL_VisualEditorTopComponent"));
setToolTipText(NbBundle.getMessage(VisualEditorTopComponent.class,"HINT_VisualEditorTopComponent"));
//        setIcon(ImageUtilities.loadImage(ICON_PATH, true));
ScenaGrafica sg = new ScenaGrafica();
scrollpanel.setViewportView(sg.createView());
add(sg.createSatelliteView(), BorderLayout.WEST);
associateLookup(sg.getLookup());
}
              

Creamos una clase en el paquete que se llame ScenaGrafica.java y le ponemos el siguiente codigo:


/**
*
* @author ulmum
*/
public class ScenaGrafica extends GraphScene {

private Lookup lookup;
private InstanceContent content = new InstanceContent();
private LayerWidget capa_base = null;
private static int x = 10;
private static int y = 10;

public ScenaGrafica() {
capa_base = new LayerWidget(this);
addChild(capa_base);
addNode("Hola");
addNode("Luis");
addNode("Ulloa");
//Crea una bolsa abstracta
lookup = new AbstractLookup(content);
//getActions().addAction(ActionFactory.createSelectAction(new MySelectProvider()));

}

//Sobrescribe para que me de la bolsa que necesito
@Override
public Lookup getLookup() {
return lookup;
}

@Override
protected Widget attachNodeWidget(String node) {
LabelWidget widget = new LabelWidget(this, node);
widget.setPreferredLocation(new Point(x *= 2, y *= 2));
//crear movimiento al widget
widget.getActions().addAction(ActionFactory.createMoveAction());
//Click sobre el widget evento del raton
widget.getActions().addAction(new WidgetAction.Adapter() {

@Override
public State mouseClicked(Widget widget, WidgetMouseEvent event) {
if (event.getButton()!=1) {
   return State.REJECTED;
}
LabelWidget nodo = (LabelWidget) widget;
//Obtener el TopComponet
VisualEditorTopComponent tc = VisualEditorTopComponent.getDefault();
//Object obj= findObject(arg0);
//Crear el Nodo
miNodo nd = new miNodo(nodo);
//Ponerlo como activo en el topcomponent para que escuche la ventana de propiedades

tc.setActivatedNodes(new Node[]{nd});
//tc.set
//Mete a la bolsa el objeto y se modifica cuando se selecciona el objeto
content.set(Collections.singleton(nodo), null);
return State.CONSUMED;
}
});
//Crear la accion de seleccion cuando de click derecho del mouse
//widget.getActions().addAction(ActionFactory.createSelectAction(new SeleccionProveedor(), true));

//Agregar el widget a la capa base
//Dar el Borde
widget.setBorder(BorderFactory.createRoundedBorder(10, 5, Color.yellow, Color.blue));
capa_base.addChild(widget);

return widget;
}

@Override
protected Widget attachEdgeWidget(Object edge) {
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
protected void attachEdgeSourceAnchor(Object edge, String oldSourceNode, String sourceNode) {
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
protected void attachEdgeTargetAnchor(Object edge, String oldTargetNode, String targetNode) {
throw new UnsupportedOperationException("Not supported yet.");
}

private class SeleccionProveedor implements SelectProvider {

public boolean isAimingAllowed(Widget arg0, Point arg1, boolean arg2) {
return true;
}

public boolean isSelectionAllowed(Widget arg0, Point arg1, boolean arg2) {
return true;
}

/**
* Se ejecuta cuando se selecciona el widget
* @param arg0
* @param arg1
* @param arg2
*/
public void select(Widget arg0, Point arg1, boolean arg2) {

//Cast del widget a labelwidget
LabelWidget nodo = (LabelWidget) arg0;

VisualEditorTopComponent tc = VisualEditorTopComponent.getDefault();
//Object obj= findObject(arg0);

miNodo nd = new miNodo(nodo);
tc.setActivatedNodes(new Node[]{nd});
//tc.set
//Mete a la bolsa el objeto y se modifica cuando se selecciona el objeto
content.set(Collections.singleton(nodo), null);
}
}
}
          

Ahora creamos un topcomponet que va escuchar cuando cuando seleccionamos un nodo para ello crean un topcomponent y agregan un jlabel e impementan al topcomponete el LookupListener les debe quedar algo asi resumiendo:
public final class VisorTopComponent extends TopComponent implements LookupListener
          

Ahora escribimos el codigo del metodo componentOpened que se ejecuta cuando el componente abre y ponemos lo siguiente:
@SuppressWarnings("unchecked")
public void componentOpened() {
//tpl criterio de busqueda del Lookup en este caso como meti en la bolsa un LabelWidget busco por LabelWidget.class
Lookup.Template tpl = new Lookup.Template(LabelWidget.class);
//Buscar el bolsa global el criterio
result = Utilities.actionsGlobalContext().lookup(tpl);
//Registrar el evento que escucha cuando un objeto se mete a la bolsa o se saca se le asigna este mismo componete
result.addLookupListener(this);
}
          

Ha como nueva propiedad de la clase deben crear el result de la siguiente manera:

private Result result;
          


Ok ahora debemos escribir cuando el componente se cierra el metodo componentClosed


public void componentClosed() {
result.removeLookupListener(this);
result = null;
}
          


He implentamos el metodo que sobrescribe la intefaz LookUpListener

public void resultChanged(LookupEvent ev) {
//System.out.println(ev);
Lookup.Result r = (Lookup.Result) ev.getSource();
Collection c = r.allInstances();
//System.out.println("Tamanio de la coleccion " + c.size());
if (!c.isEmpty()) {
 LabelWidget o = (LabelWidget) c.iterator().next();
 jLabel1.setText(o.getLabel());
} else {
 jLabel1.setText("[no selection]");
 //Vaciar la ventana de propiedades del compenente Visual
 //VisualEditorTopComponent tc = VisualEditorTopComponent.getDefault();
 //Object obj= findObject(arg0);
 //tc.setActivatedNodes(new Node[]{Node.EMPTY});

}

}
          


Y la parte final creamos un clase miNodo.java que extiende la clase AbstractNode esto es para que mustre en la ventana de propiedades el objeto seleccionado ponemos el siguiente codigo

/**
*
* @author ulmum
* Mi Nodo es para usar la sheet properties
*/
public class miNodo extends AbstractNode {

public miNodo(LabelWidget widget) {
super(Children.LEAF,Lookups.singleton(widget));
setDisplayName("Propiedades del Nodo " + widget.getLabel());
}

public miNodo() {
super(Children.LEAF);
setDisplayName("Root");
}

@Override
protected Sheet createSheet() {
Sheet sheet = Sheet.createDefault();
Sheet.Set set = Sheet.createPropertiesSet();
LabelWidget obj = getLookup().lookup(LabelWidget.class);
try {
  Property label = new PropertySupport.Reflection(obj, String.class, "getLabel", null);
  label.setName("Nombre Etiqueta");
  set.put(label);
} catch (NoSuchMethodException ex) {
  ErrorManager.getDefault();
}

sheet.put(set);
return sheet;

}
}

          

Una vez hecho todo esto corremos y probamos si tienen alguna duda favor enviar sus comentarios adjunto el proyecto en zip para ser descargado
aqui