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

miércoles, 3 de febrero de 2010

Cargando un BMP byte a byte con JAVA

Prefacio
Este post está dedicado a entender como cargar un archivo BMP con java pero bueno a que viene eso, si ya hay librerías y APIs o métodos de la librería swing que hacen este trabajo sucio. Pues bueno me interese en saber como haría para cargar esta imagen byte a byte de un fichero almacenado, para después cargar una imagen en un LCD de un celular (eso es para después), bueno la lógica es la misma creo en los diferentes lenguajes.

LinkGrafia
http://es.wikipedia.org/wiki/BMP
http://carlosagreda.googlepages.com/bmp.html
http://elblogdelfrasco.blogspot.com/2008/06/java-nivel-de-bits.html

Que se necesita
1. Netbeans 5.5 o mayor.

Empezamos

Bueno los primeros 54 bytes de todo archivo BMP son de la metadata (Información del Fichero) dicha información la encontrar en los 2 link que os pongo a disposición.
Bueno a mi me sirvieron los Bytes que conforman el alto y ancho de la imagen.

A Continuación les pongo el fragmento de código que permite leer los 54 bytes para sacara el ancho alto y tamaño de la imagen.




Es hora de explicar esto:

(datos[i] & 0xff)



Bueno eso es nada más que una operación lógica a nivel de bits por ejemplo si en binario seria:


1 Byte 2 Byte 3 Byte 4 Byte Hexadecimal Decimal
00000000 00000000 00000000 01111110 0x7E 126
Aplico el operador &
11111111 11111111 11111111 11111111 0xFF 255
Resultado
00000000 00000000 00000000 01111110 0X7E 126


Como se observa no pasa nada e incluso es un poco innecesario pero al momento de leer los bytes del fichero el método read inserta en el vector valores negativos por lo cual se la aplica la máscara para que devuelva el valor real del número.

Segundo ahora a que viene el símbolo <<
((long)(datos[2] & 0xff))<<bite

Bueno esto es una operación de desplazamiento que lo que hará es que el resultado anterior moverlo 0, 8, 16 y 24 posiciones si quisiera mover 8 bits a la izquierda seria así:

byte1=00000000.00000000.0000000.11100111
byte2=00000000.00000000.1111101.00000000
byte3=00000000.00000010.0000000.00000000
byte4=10111101.00000000.0000000.00000000
byte1 | byte2 | byte3 | byte4
Resultado
byte=10111101.00000010.1111101.11100111 = 5E817DE7 = 1585544679 Bytes


bueno lo del (long) esta demás pero no es nada más que un casting de tipos de datos ahora así como unimos los bytes. lo haremos usando el operador | de operación lógica de bits. Resumiendo


Uffff larga explicación... solo para el inicio bueno todo esto se pude resumir practicando y usando un ciclo for.

Bueno una vez sacado los datos de la meta data nos queda nada más que hacer 2 for para recorrer las filas y columnas, leer los bytes que nos quedan de 3 en 3 ya que ese el estándar RGB el primer byte es el ROJO(R), el segundo el VERDE(G) y el Tercero el AZUL(B) quedando así (255,255,255) y por ultimo sobrescribir el método paint de un formulario swing para graficar el pixel basta con poner:
g2d.drawRect(x,y,1,1)
Le pones de 1 de ancho por 1 de alto hay el pixel el código es el siguiente:



La variable resto son bytes sobrantes que debe calcularse en el bmp y leer estos bytes restantes para que no se descuadre a imagen.

Nota: el for de las filas empieza al revés por que se almacenan de abajo hacia arriba.

Descarga el Proyecto

Con Nuevo Blog ...

Esmpezando el 2010 y migro de blog mas que todo lo hize por usar el svn de google y estaba arto de tanto spam en mi cuenta de gmail.... voy a recuperar mis post anteriores antes que los borren definitivamente