Mostrando las entradas con la etiqueta java. Mostrar todas las entradas
Mostrando las entradas con la etiqueta java. Mostrar todas las entradas

lunes, 27 de junio de 2011

Custom Contact Manager Android

Quiero un listado de contactos en 2 columnas, hecho de la manera más simple posible. 
En principio solo mostraremos los nombres de los contactos, luego imagenes, abrir dialer, etc.
 Main.java
package b.android;

import java.util.ArrayList;

import java.util.HashMap;

import android.app.Activity;

import android.database.Cursor;

import android.net.Uri;

import android.os.Bundle;

import android.provider.ContactsContract;

import android.widget.GridView;

import android.widget.SimpleCursorAdapter;

public class Main extends Activity {

static final ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();

String[] projection = new String[] { ContactsContract.Data.DISPLAY_NAME,

ContactsContract.Data._ID };

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.main);

populateContactList();

}

private void populateContactList() {

// Build adapter with contact entries

Cursor cursor = getContacts();

SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,

R.layout.contact, cursor, projection,

new int[] { R.id.contactName });

GridView gridview = (GridView) findViewById(R.id.gridview);

gridview.setAdapter(adapter);

}

private Cursor getContacts() {

// Run query

Uri uri = ContactsContract.Contacts.CONTENT_URI;

String sortOrder = ContactsContract.Data.DISPLAY_NAME

+ " COLLATE LOCALIZED ASC";

return managedQuery(uri, projection, null, null, sortOrder);

}

}
Contacto Individual
 contact.xml 
 <?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent" android:layout_height="wrap_content"

android:orientation="horizontal">

<TextView android:id="@+id/contactName" android:textSize="12sp"

android:textStyle="bold" android:layout_width="fill_parent"

android:layout_height="fill_parent" />

</LinearLayout>
Listado
 main.xml  
<?xml version="1.0" encoding="utf-8"?>

<GridView xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/gridview"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:numColumns="auto_fit"

android:verticalSpacing="10dp"

android:horizontalSpacing="10dp"

android:columnWidth="130dp"

android:stretchMode="columnWidth"

android:gravity="center"

/>
Seteamos el Main, y los permisos de lectura a contactos
 AndroidManifest.xml  

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="b.android"

android:versionCode="1"

android:versionName="1.0">

<application android:icon="@drawable/icon" android:label="@string/app_name">

<activity android:name=".Main"

android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>



<uses-permission android:name="android.permission.GET_ACCOUNTS" />

<uses-permission android:name="android.permission.READ_CONTACTS" />

<uses-permission android:name="android.permission.WRITE_CONTACTS" />

</manifest>


jueves, 19 de noviembre de 2009

Test paginas con wicket messages

En el anterior post puse algo sobre la Internacionalización en wicket, ahora que pasa si tenemos los archivos.properties en otro lado que no sea la pagina

por ejemplo

home.java
home.html
home.properties

application.java
application.properties


las claves-valor q tengamos en application.properties cuando corramos los tests, no van a andar (no las va a encontrar )

esto se debe a que corriendo, wicket busca

panel_locale -> panel -> form_locale -> form -> page_locale -> page -> appication_locale -> application


pero WicketTester no, solo busca las primeras

lo q podemos hacer es en el setUp del test, especificarle que lo use, x.properties




import org.apache.wicket.spring.injection.annot.SpringComponentInjector;
import org.apache.wicket.spring.test.ApplicationContextMock;
import org.apache.wicket.util.tester.WicketTester;
import org.apache.wicket.resource.loader.ClassStringResourceLoader;

public class testHome extends TestCase {


@Override
public void setUp() {
appctx = new ApplicationContextMock();
testerApplication = new WicketTester();
testerApplication.getApplication().addComponentInstantiationListener(
new SpringComponentInjector(testerApplication.getApplication(),
appctx));
testerApplication.getApplication().getResourceSettings().addStringResourceLoader(new ClassStringResourceLoader(Application.class));
}
}





miércoles, 18 de noviembre de 2009

Internacionalización en wicket (aplicaciones multi idioma )

Obvio, no se usa mas poner los textos hace mil años =D, incluso, aunque la aplicacion este pensada para un solo idioma.
Por ? y facil, correcciones ortograficas, estandarizacion de palabras (no queda bien que un boton diga guardar, otro diga save, y otro aplicar )

Solucion magica gracias a java y wicket

archivos.properties

Simple, es un archivo de texto (o varios ) que tienen clave-valor para los textos (o configuraciones)



# comentarios
clave=valor

#clasico ejemplo hola mundo
message=Hola mundo !




ahora donde y como ponemos estos archivos ?

wicket busca primero en un archivo.properties con el mismo nombre que la pagina
por ej: home.html y home.java , va a buscar el home.properties, si no lo encuentra, va a buscar el de la clase super de este (WebPage.properties ) si no puede, su padre y asi hasta
llegar al object.java

si no encuentra la clave hasta ahi, busca por los componentes (por ejemplo panelMenu.properties , panelFooter.properties, etc ) o por la aplicacion.

Con esto, podemos tener uno con el nombre de la aplicacion, y sobreescribir si queremos algo particular, en uno

entonces


Application.properties



#clasico ejemplo hola mundo
message=Hola mundo !




home.properties



#clasico ejemplo hola mundo
message=Hola mundo sobreescrito


como se usa ?




<wicket:message key="message">esto se pisa si encuentra una clave (si no, no )</wicket:message>





en vez de poner el texto en el html


si lo queremos en un componente html por ejemplo un input



<input type="submit" value="Hello world"/>
lo reemplazamos por
<input type="submit" value="texto por defecto" wicket:message="value:helloworld"/>


y si quicieramos poner mas de una propiedad



<input type="submit" value="texto por defecto" wicket:message="value:helloworld,title:hellotitle"/>




como darle varios idiomas

se pone un archivo por cada idioma

(idioma por defecto)
application.properties
(ingles)
application.properties
(españo)
application.properties
(español argentina)
application.properties


codigos en http://msdn.microsoft.com/en-us/library/ms533052(VS.85).aspx

"si, m$ hace cosas buenas =P"



tambien podemos usar esto para configuraciones,

desde codigo java podemos levantarlo con wicket

new StringResourceModel(key, this,null)





MyPanel.properties:
bla=Un texto loco

MyPanel.html:
<span wicket:id="summary">Text that will be replaced.</span>

MyPanel.java:

Summary summary = ...;
add(new Label("summary", new StringResourceModel("bla", this, null)));





tambien se puede inducir cual locale usar

Locale.getDefault() y Locale.setDefault(Locale))




Referencias


http://cwiki.apache.org/WICKET/everything-about-wicket-internationalization.html
http://www.chuidiang.com/java/ResourceBundle/internacionalizacion.php
http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/model/StringResourceModel.html
listado locales
http://msdn.microsoft.com/en-us/library/ms533052(VS.85).aspx















Powered by ScribeFire.

martes, 17 de noviembre de 2009

Testear todos los paneles wicket

Bueno primero que nada, no es mi idea, solo lo traduzco y adapte a mi codigo.

Original : http://stuq.nl/weblog/2009-11-01/automatically-test-your-wicket-panel-html-markup


La idea es de testear todos los componentes Panel (se puede hacer para mas cosas) por reflection, gracias a spring.
Intente dejarlo lindo con labdaj pero no me salio =( , quedaba inentendible, Cuando tenga mas practica con eso, probamos

Con esto, si en un panel no cerramos un tag (ej <div bla </div> ) el unit test fallaria donde lo encuentre, lo mismo con los errores comunes de cambiar un wicket:id o algo asi

bueno, dependencias solo junit y spring






package base2dev.web.panel;

import java.lang.reflect.Constructor;
import java.util.Set;
import org.apache.wicket.markup.html.panel.Panel;
import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AssignableTypeFilter;
import base2dev.web.common.test.TestCase;

public class PanelsTest extends TestCase {

@Test
public void testAllWicketPanels() throws Exception {

//cosas de spring
ClassPathScanningCandidateComponentProvider provider =
new ClassPathScanningCandidateComponentProvider(true);

//seteo como filtro las cosas del tipo Panel
provider.addIncludeFilter(new AssignableTypeFilter(Panel.class));

//path donde buscar
Set<BeanDefinition> components = provider
.findCandidateComponents("base2dev/web/common/controls");


//esto podria ser mas lindo con labdaj
// llamamos a testear el panel, por cada componente, nada muy loco
for (BeanDefinition component : components) {
Class clazz = Class.forName(component.getBeanClassName());
if (hasDefaultConstructor(clazz)) {
testWicketPanel(clazz);
}
}
}

public void testWicketPanel(Class clazz) {
getTesterApplication().startPanel(clazz);
getTesterApplication().assertNoErrorMessage();
getTesterApplication().assertNoInfoMessage();
}

public boolean hasDefaultConstructor(Class clazz) {
for (Constructor constructor : clazz.getConstructors()) {
if (constructor.getParameterTypes().length == 1
&& constructor.getParameterTypes()[0].getSimpleName()
.equals("String")) {
return true;
}
}

return false;
}
}
-----------------------------------------------





Powered by ScribeFire.

lunes, 16 de noviembre de 2009

wicket test paginas con parametros

por ejemplo si tenemos







public class AlbumPage extends WebPage{
private final Album album;

public AlbumPage(Album album) {
this.album = album;
}
}







el test seria






//creado asi por fluent (http://en.wikipedia.org/wiki/Fluent_interface#Java )
final Album mockAlbum = new Album().setArtist( new Artist().setName("Pepe Argento")).setName("el disco de pp");

public void testRenderThePage() {
//con una clase anonima, estamos sobreescribiendo el metodo getTestPage(), para porder invocar a la pagina con el constructor
//(otra bondad de las clases anonimas =D )
getTesterApplication().startPage(new ITestPageSource() {
private static final long serialVersionUID = 1L;
public Page getTestPage() {
return new AlbumPage(mockAlbum);
}
});

getTesterApplication().assertRenderedPage(AlbumPage.class);








el error que da si queremos usar startPage(MiPagina.class )

org.apache.wicket.WicketRuntimeException: Unable to create page from class base2dev.web.pages.musics.AlbumPage.
Class does neither have a constructor with PageParameter nor a default constructor
at org.apache.wicket.session.DefaultPageFactory.newPage(DefaultPageFactory.java:68)
at org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.newPage(BookmarkablePageRequestTarget.java:299)
at org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.getPage(BookmarkablePageRequestTarget.java:321)
at org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.processEvents(BookmarkablePageRequestTarget.java:234)
at org.apache.wicket.request.AbstractRequestCycleProcessor.processEvents(AbstractRequestCycleProcessor.java:92)
at org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1250)
...





Powered by ScribeFire.



Testear paginas Wicket JUnit EasyMock

bueno vamos a testear una webPage de Wicket


asumo el uso de maven, asi que si no esta, a poner las librerias a manopla =D

dependencias en el pom







<!-- .......TEST (JUNIT).............-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
</dependency>

<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>2.5.2</version>
</dependency>

<dependency>
<groupId>easymock</groupId>
<artifactId>easymockclassextension</artifactId>
<version>2.2</version>
</dependency>




codigo


//uso de import static es para no escribir los tipos
// Ejemplo "EasyMock.expect( ...."
// con import static va solo "expect(.."
//mas en http://java.sun.com/j2se/1.5.0/docs/guide/language/static-import.html
import static org.easymock.EasyMock.*;

import java.util.ArrayList;

public class ArtistPageTest extends TestCase {

private WicketTester testerApplication;
private ApplicationContextMock appctx;

@Override
public void setUp() {
appctx = new ApplicationContextMock();

testerApplication = new WicketTester();
testerApplication.getApplication().addComponentInstantiationListener(
new SpringComponentInjector(testerApplication.getApplication(),
appctx));

//esto es un listado de artistas con un getAll (algo asi como un dao)
Bag<Artist> artists = createMock(Bag.class );


ArrayList<Artist> unaLista = new ArrayList<Artist>();

//esto es fluent new Algo().SetProp("bla") en vez de void los metodos son del tipo de la clase, y pongo return this
//http://code.google.com/p/base2dev/source/browse/src/trunk/base2dev/core/src/main/java/musics/model/Artist.java
unaLista.add(new Artist().setName("Pepe Argento").setDescription("pepe fue un grande"));


//seteamos con easyMock que espera cuando llama a algun metodo
expect(artists.getAll()).andReturn(mockList);
replay(artists);

// lo agregamos al manejador de instancias
getAppContext().putBean("artists", artists);

}

public WicketTester getTesterApplication() {
return testerApplication;
}

public ApplicationContextMock getAppContext() {
return appctx;
}




@Test
public void testRenderThePage() {

getTesterApplication().startPage(Artists.class);
getTesterApplication().assertRenderedPage(Artists.class);

}




todo el codigo esta en

http://code.google.com/p/base2dev/source/browse/src/trunk/#trunk/base2dev






Powered by ScribeFire.

sábado, 7 de noviembre de 2009

jetty deja lockeados los archivos al correr

bueno, no se si lo vieron, pero si quiero editar por ejemplo un css con jetty corriendo, no me deja, ya que quedan lockeados los archivos, ya que por defecto, cachea los archivos y los lee de memoria.

para cambiar eso descomprimimos el .jar de jetty (el mio es

.m2/repository/org/mortbay/jetty/jetty/6.1.4/jetty-6.1.4.jar )

vamos hasta la carpeta

/org/mortbay/jetty/webapp

y editamos

webdefault.xml

buscamos "useFileMappedBuffer"



useFileMappedBuffer
false





y lo ponemos en false

y deberiamos ser felices



referencia

http://docs.codehaus.org/display/JETTY/Files+locked+on+Windows

viernes, 6 de noviembre de 2009

Dialect class not found

BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: Dialect class not found: org.hibernate.dialect.HSQLDialect

Algo que en principio no deberia pasar, googleando veo que a varios les paso, pero no vi la solucion.

Empece a cambiar de todas las formas posibles mis pom´s files (maven) y nada,

Bueno, el error viene dado por la configuracion del session factory en spring




<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<value>
hibernate.hbm2ddl.auto=create
hibernate.dialect=org.hibernate.dialect.HSQLDialect" " <--- ahi habia un espacio en blanco
hibernate.show_sql=true
</value>
</property>


el parser se ve que se mambea y no corta asi que quitando los espacios en blanco, todo funciona bien

jueves, 31 de julio de 2008

Threads-Hilos En Java y C#

Multi hilos o Multi threads

Tanto java como .Net proveen soporte para multihilos.

Ambos corren con un hilo principal (ejecutado por el main) y desde aqui en adelante se pueden crear hilos hijos, workers, y aqui el el programa se vuelve multithread.

Los procesos separados (workers) corren en distintos pedazos de memoria (del stack)
y son dos instancias distintas.

Se puede compartir datos entre ellos por ejemplo con variables estaticas, pero hay que tener mucho cuidado porque la modificacion de uno puede afectar al desempeño del otro.
Esto se llama concurrencia, y para que esto no afecte, se puede loquear la modificacion/lectura de la variable.

Vamos con un ejemplo.

clase CajeroAutomatico{

Cuenta unaCuentaBancaria;
funcion ExtraerDinero(Double cantidad){

if (unaCuentaBancaria.dineroDisponible > cantidad ){


unaCuentaBancaria.dineroDisponible = unaCuentaBancaria.dineroDisponible -cantidad;


}
}
}





El procesamiento de los hilos (manejando los tiempos de procesador que le otorga el sistema operativo a cada hilo) puede dedicarle el tiempo que crea necesario a cada hilo, y frenarlo cuando tambien lo quiera. Esto no lo podemos controlar nosotros porque depende de todo lo que esta corriendo en la pc en ese momento.


Suponiendo que vieje Pepe Argento al cajero, y decide sacar $900 de su cuenta que tiene $ 1000.
entra al método ExtraerDinero , entra al if, y el sistema operativo descide frenar por un momento la ejecución de este programa antes de sacar dinero, para darle un rato de procesador a otro programa.

Sabrina Rojas (mujer de el :) ) descide ir y sacar $500 de dinero de la misma cuenta, y el SO le otorga un rato de procesador a ella (a su programa)

Pero a diferencia del otro, no lo frena dentro del if, sino que sigue y extrae

ahora el SO , vuelve a darle tiempo al proceso frenado anteriormente (frenado justo antes de sacar) y quiere extraer.

Que paso aca?
la cuenta tenia $ 1000.
Sabrina saco $500 (qdan $500)
pepe quiere sacar $900 , Esto reventaria en algun lado , ya que faltan $400.


El problema fue la concurrencia sobre la variable "dineroDisponible" .

para ello toda la ejecucion del método, o mas concreto, del if , debería estar loqueada.

algo asi como


lock {
if (...){...}

}



Con esto, El SO sabe que NO debe frenar el proceso dentro del lock ( o sea en el if)

de esta manera, Sabrina no podria entrar a la condición del if, ya que cuando salga del if de pepe quedaran $100.



ejemplo c#

class ThreadTest {

static void Main() {

Thread t = new Thread (WriteY);

t.Start(); // Run WriteY on the new thread

while (true) Console.Write ("x"); // Write 'x' forever

}



static void WriteY() {

while (true) Console.Write ("y"); // Write 'y' forever

}

}


sacado de http://www.albahari.com/threading/index.html#_Introduction

ahi veriamos como le asigna ("aleatoriamente") tiempo a cada uno de los procesos.

la salida seria algo asi


yyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxyyyyyyyyy
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxyyyyy
xxxxxxxxxxxxxx



(un rato a cada uno)

Java:

 

En Java para la creacion de hilos, se hereda de la clase Thread Java aplica aqui el patrón Template.

La clase Thread es abstracta e implementa la interfaz Runeable, que tiene el metodo run();

Nos provee métodos para:

start() : Este metodo ejecutara el metodo run() implementado por nosotros (aqui esta el patrón template)

isAlive() : True si el hilo esta corriendo

sleep(N) : Duerme al hilo N milisegundos

interrupt() : Pide al hilo que se interrumpa (InterrumpedException si estaba en sleep)

isInterrupted() : True si esta interrumpido

priority : Prioridad del hilo (No conviene abusar de esto a menos que se sepa bien lo que se hace)

yield() : El hilo deja su ejecucion para darle lugar al siguiente. la proxima vez que le toque se ejecutara

join() : El hilo actual se queda esperando hasta que el hilo que llamo al join termine su ejecucion y nuestra clase hija,

 

 

 

 

Sacado de Algoritmos 3 (Fontela FIUBA)

 

 

Dibujo1

 

Para crear un hilo:

class HiloConcreto extends Thread {
    public void run() {
        ... código del hilo ...
    }
        ...
    }
        ...
    HiloConcreto unHilo = new HiloConcreto();
    unHilo.start(); // start llama a run de manera polimorfa

 

 

DotNet C#

 

A diferencia de Java, c# aplica el patrón  Command, donde se le pasa “Un puntero a función” del método a ejecutar.

Usamos el namespace

using System.Threading;

y en main por ejemplo

 

Thread unHiloWorker = new Thread(new ThreadStart(metodoAEjecutar));

unHiloWorker.Start();

 

 

Donde Start() ejecutara el metodo que le hayamos pasado (aqui el patron command)

martes, 1 de julio de 2008

Nuestro propio Archetype Maven (Arquetipo=Template)

Bueno, básicamente un archetype es un Template (molde) de Maven, una herramienta que explicare con mas detalle en otro post.

Para Crear un template propio, un molde que genere todo lo que queramos apara hacer el típico
"New Project" , y que sea como queramos , hacemos lo siguiente (Todo esto teniendo Maven2 ya instalado)

creamos una carpeta raíz donde nos guste .

$ cd carpeta



"D" es para indicar parámetro
"groupId" DgroupId=nombre de la empresa, grupo , etc.
"artifactId" DartifactId=nombre del archetype (nombre del template).
"archetypeArtifactId" DarchetypeArtifactId= nombre del template en el que nos basamos




$ mvn archetype:create -DgroupId=mberrueta -DartifactId=proyecto-basico -DarchetypeArtifactId=maven-archetype-archetype


esto nos va a crear una estructura de directorios que también estará en la explicación de maven. =)

en src estan los fuentes del template (archetype en adelante)
desp de compilar estara la carpeta target
main/resources tenemos:
archetype-resources (aca van los templates)
META-INF (aca va el listado de archivos a utilizar)

nos va a crear como debe ser el pom (xml de configuración de maven) , un "hola mundo" y un test de "hola mundo"

hay un bug que para arreglarlo se debe reemplazar en los "holas mundos " (App.java y AppTest.java el :

package $"el groupId que pusimos"; --->por---&gt; package $package;

luego en el pom.xml


$"el groupId que pusimos"
$"el artifactId que pusimos"
$1.0-SNAPSHOT

por

$groupId
$artifactId
$version


Luego, Editamos/Agregamos los .java que queramos , o el POM y cuando creemos una aplicación con nuestro archetype utilizara este template.
Para Agregar hay que editar el archivo
META-INF\maven\archetype.xml

y agregarle el source que queramos por ej:


src/main/java/App2.java

luego


$ mvn install


Con esto lo tenemos instalado en nuestro repositorio local, y ya podemos usarlo.

Ahora, para usarlo sin las comillas (")

mvn archetype:create
-DarchetypeGroupId="el groupId que pusimos al template"
-DarchetypeArtifactId="el artifactId que pusimos al template"
-DarchetypeVersion=1.0-SNAPSHOT
-DgroupId="group id de este proyecto"
-DartifactId="artifact id de este proyecto"

ej:


$mvn archetype:create
-DarchetypeGroupId=mberrueta
-DarchetypeArtifactId=proyecto-basico
-DarchetypeVersion=1.0-SNAPSHOT
-DgroupId=mberrueta
-DartifactId=progama-nuevo