Archivos de la categoría ‘codigo’

Continuando con el tutorial sobre el formulario Producto, implementaremos la funcionalidad para exportar nuestra tabla a un archivo Microsoft Excel con extensión XLS.


Creamos un evento en nuestro boton btnExportar ey incluimos el siguiente codigo

private void btnExportarActionPerformed(java.awt.event.ActionEvent evt) {
//creamos un filtro de archivos para definir que archivos ver en el JFileChooser
javax.swing.filechooser.FileNameExtensionFilter filterXls = new javax.swing.filechooser.FileNameExtensionFilter("Documentos MS Excel 95/2003", "xls");

//instanciamos una ventana de seleccion de archivo
final JFileChooser fc = new JFileChooser();

//agregamos el filtro al filechooser
fc.setFileFilter(filterXls);

//capturamos la respuesta del usuario
int returnVal = fc.showSaveDialog(null);

//definimos el comportamiento de la ventana
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

if (returnVal == JFileChooser.APPROVE_OPTION) {

FileOutputStream fileOut = null;
File fileXLS = null;
try {
//Creamos un objeto archivo con la ruta seleccionada
fileXLS = fc.getSelectedFile();

//Validamos si en la ruta el archivo se ha especificado la extensión
String name = fileXLS.getName();
if (name.indexOf('.') == -1) {
//De no ser asi le agregamos
name += ".xls";
fileXLS = new File(fileXLS.getParentFile(), name);
}
fileOut = new FileOutputStream(fileXLS);
//Creamos la cabecera
final String[] headers = {"CODIGO", "DESCRIPCION", "PRECIO"};

//Creamos el libro Excel
Workbook wb = new HSSFWorkbook();
//Creamos una nueva Hoja
Sheet sheet = wb.createSheet("PRODUCTOS");

//Definimos el estilo de la cabecera
CellStyle headerStyle = wb.createCellStyle();
//Color de fondo
headerStyle.setFillBackgroundColor(IndexedColors.GREY_40_PERCENT.getIndex());
//Estilo de la fuente
Font hfont = wb.createFont();
hfont.setBoldweight(Font.BOLDWEIGHT_BOLD);
headerStyle.setFont(hfont);
//Alineacion Horizontal
headerStyle.setAlignment(CellStyle.ALIGN_CENTER);
// Creamos una fila, las filas empiezan en 0
Row titleRow = sheet.createRow((short) 0);
//Creamos una celda para nuestra fila
Cell hCell = titleRow.createCell((short) 0);
//Asignamos un valor a la celda
hCell.setCellValue("Lista de Productos");
//Vamos a unir nuestra celdas de la primera fila
sheet.addMergedRegion(new CellRangeAddress(
0, //first row (0-based)
0, //last row (0-based)
0, //first column (0-based)
headers.length-1 //last column (0-based)
));
//Asignamos el estilo que deseamos
hCell.setCellStyle(headerStyle);
//Creamos una nueva fila para las cabeceras
Row row = sheet.createRow((short) 1);
/**
Creamos nuestras celdas de acuerdo a nuestro array headers
Por cada cabecera creamos una celda y le asignamos el estilo.
*/
for (int i = 0; i < headers.length; i++) {
Cell cell = row.createCell(i);
cell.setCellValue(headers[i]);
cell.setCellStyle(headerStyle);
//Asigna automaticamente el tamaño
sheet.autoSizeColumn(i);
}
/**
Variable para saber en que fila estamos, se inicializa en 2 porque ya hemos creado 2 filas antes.
*/
int rowIndex=2;
//Recorremos los objetos Producto que tiene nuestra tabla
for (Producto p : productoTableModel.getData()) {
//Por cada objeto creamos una fila
Row newRow = sheet.createRow((short) rowIndex);
//Creamos una celda por cada campo de nuestro objeto
newRow.createCell(0).setCellValue(p.getCodigo());
newRow.createCell(1).setCellValue(p.getDescripcion());
newRow.createCell(2).setCellValue(p.getPrecio().toString());
/*
Aumentamos nuestra variable de manera que en la siguiente iteracion salta a otra fila
*/
rowIndex++;
}


for (int i = 0; i < headers.length; i++) {
sheet.autoSizeColumn(i);
}
// Escribimos el libro
wb.write(fileOut);
} catch (IOException ex) {
Logger.getLogger(FrmProductos.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
//Cerramos nuestro archivo
fileOut.close();
//abrimos el archivo generado con el programa correspondiente
if (System.getProperty("os.name").equals("Linux")) {
Runtime.getRuntime().exec("libreoffice " + fileXLS.getAbsolutePath());
} else {
Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + fileXLS.getAbsolutePath());
}

} catch (IOException ex) {
Logger.getLogger(FrmProductos.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}

El codigo es casi auto explicativo, si tienen dudas hacerlas en los comentarios que con gusto nos ayudamos. Viene de Tutorial : Implementar funcionalidad de Formulario Productos – Parte 7.2

Nuestro formulario realiza las siguientes acciones :
1. Crear un nuevo producto.
2. Listar productos.
3. Eliminar un producto.
4. Editar un producto.
5. Exportar a MS Excel
6. Exportar en formato de impresión.
 

Bueno vamos a ir trabajando de acuerdo a lo que necesitemos, ya les he dicho que este no es un manual de buenas prácticas, hay muchas mejores formas de hacer todo esto, pero quiero dejarlo lo más sencillo posible.

Crear un nuevo producto.

Sencillo, es instanciar un objeto de nuestra clase Producto y asignar los valores de sus propiedades con lo que ingresemos en nuestros JtextField, al presionar Aceptar, hará toda la “magia”.

Esto creará un método que escucha las acciones que se realizan sobre el botón.
Como recordarán ya existe una explicación sobre nuestra clase Controladora ProductoControl

Por lo que nuestro código se reduce a esto :

Producto producto=new Producto();
producto.setCodigo(txtCodigo.getText().trim());
producto.setDescripcion(txtDescripcion.getText().trim());
producto.setPrecio(new BigDecimal(txtPrecio.getText().trim()));
try {
ProductoControl.crear(producto);
} catch (SQLException ex) {
Logger.getLogger(FrmProductos.class.getName()).log(Level.SEVERE, null, ex);
}

y para comprobar usamos el Editor SQL de Netbeans

Listar productos

Como verán en el post sobre la clase ProductoControl no hemos definido un método listar, en este caso haremos la implementación, para que entienda como funciona un Jtable en Swing, explicaré que un Jtable es un componente que muestra información tabulada que es obtenida de un objeto TableModel el cual maneja los datos que se cargarán.
Por lo tanto, necesitamos nuestro método listar el cual proveerá a nuestro modelo de los datos, vamos al código :

public static ArrayList<Producto> listar() throws SQLException{
final String query="select * from Producto";
ArrayList lista=new ArrayList();
java.sql.ResultSet rs=H2Util.getInstance().getResultSet(query);
while(rs.next()){
Producto obj=new Producto();
obj.setId(rs.getInt("ID"));
obj.setDescripcion(rs.getString("DESCRIPCION"));
obj.setCodigo(rs.getString("CODIGO"));
obj.setPrecio(rs.getBigDecimal("PRECIO"));
lista.add(obj);
}
return lista;
}

Ahora crearemos nuestro TableModel, este lo haremos heredando de AbstractTableModel, creamos una clase en nuestro paquete producto, y le denominamos ProductoTableModel
Este es su código :

public class ProductoTableModel extends AbstractTableModel {
ArrayList<Producto> data;
private String labels[] = {"ID", "CODIGO", "DESCRIPCION", "PRECIO"};

public ProductoTableModel(ArrayList<producto> data) {
this.data = data;
}
public ArrayList<producto> getData() {
return data;
}
public void setData(ArrayList<producto> data) {
this.data = data;
}
@Override
public int getRowCount() {
return data.size();
}
@Override
public int getColumnCount() {
return labels.length;
}
@Override
public String getColumnName(int column) {
return labels[column];
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Producto producto = data.get(rowIndex);
Object value = null;
switch (columnIndex) {
case 0:
value = producto.getId();
break;
case 1:
value = producto.getCodigo();
break;
case 2:
value = producto.getDescripcion();
break;
case 3:
value = producto.getPrecio();
break;
}
return value;
}

public Producto getRow(int rowIndex){
return data.get(rowIndex);
}
}

Primero definamos un campo productoTableModel para interactuar con el modelo de datos,

private ProductoTableModel productoTableModel;  

Bueno entonces configuremos nuestra tabla.

private void configurarTabla() {
try {
//Instanciamos nuestro productoTableModel y le pasamos los datos
productoTableModel = new ProductoTableModel(ProductoControl.listar());
//asignamos el modelo a nuestra tabla tblProductos
tblProductos.setModel(productoTableModel);
//Y removemos la columna 0 que contiene el ID de nuestros registros
tblProductos.removeColumn(tblProductos.getColumnModel().getColumn(0));
} catch (SQLException ex) {
Logger.getLogger(FrmProductos.class.getName()).log(Level.SEVERE, null, ex);
}
}

Si les queda duda como se pasan los datos, recuerden que cuando definimos el constructor de ProductoTableModel le pusimos un parámetro mediante el cual asignamos los valores al campo data de nuestro TableModel.
Llamamos a nuestro nuevo método dentro del constructor del Jframe.

public FrmProductos() {
initComponents();
configurarTabla();
}

Siguiente vamos a crear otro método donde actualizaremos nuestro modelo, asi cada vez que se inserte o actualice un dato de nuestra tabla de Productos, se actualiza en la tabla.

private void cargarTabla() throws SQLException {
productoTableModel.setData(ProductoControl.listar());
productoTableModel.fireTableDataChanged();
}

Ahora enlacemos esto cada vez que damos click en el botón Aceptar.
Final mente agregaremos este método en nuestro evento aceptar de manera que el código queda asi:

private void btnAceptarActionPerformed(java.awt.event.ActionEvent evt) {                                           
Producto producto = new Producto();
producto.setCodigo(txtCodigo.getText().trim());
producto.setDescripcion(txtDescripcion.getText().trim());
producto.setPrecio(new BigDecimal(txtPrecio.getText().trim()));
try {
ProductoControl.crear(producto);
cargarTabla();
} catch (SQLException ex) {
Logger.getLogger(FrmProductos.class.getName()).log(Level.SEVERE, null, ex);
} finally {
limpiarCampos();
}
}

Si se preguntan que es limpiarCampos solo es un método que vuelve los JtextFields con valores en blanco.

private void limpiarCampos() {
txtCodigo.setText("");
txtDescripcion.setText("");
txtPrecio.setText("");
}

Corrremos nuestra aplicación y ….

Eliminar un producto.

Primero debemos capturar el registro seleccionado y de preferencia mostrarlo en nuestro Panel Producto, entonces agregamos un listener a nuestra tabla que escuche nuestro evento cuando presionamos con el mouse., dentro le decimos que asigne el registro obtenido a un objeto producto que lo vamos a definir como campo de nuestro formulario.

public class FrmProductos extends javax.swing.JInternalFrame {
private Producto producto;

Y en nuestro evento.

private void tblProductosMousePressed(java.awt.event.MouseEvent evt) {
if (tblProductos.getModel().getRowCount() > 0) {
producto = ((ProductoTableModel) tblProductos.getModel()).getRow(tblProductos.getSelectedRow());
txtCodigo.setText(producto.getCodigo());
txtDescripcion.setText(producto.getDescripcion());
txtPrecio.setText(producto.getPrecio().toString());
}
}

Asignamos un evento a nuestro boton Eliminar.

Y en el código generado ingresamos lo siguiente:

private void btnEliminarActionPerformed(java.awt.event.ActionEvent evt) {
if (producto != null) {
try {
ProductoControl.borrar(producto.getId());
cargarTabla();
} catch (SQLException ex) {
Logger.getLogger(FrmProductos.class.getName()).log(Level.SEVERE, null, ex);
}finally{
limpiarCampos();
}
}
}

Editar Producto

Ya sabemos seleccionar un producto de nuestra tabla, asi que solo hay que saber cuando estamos registrando uno nuevo y cuando es una modificación dado que utilizamos el mismo boton Aceptar para ambos casos.
En este caso yo estoy utilizando lo siguiente, defino una variable tipo String llamada action, y cada vez que selecciono un producto, le asigno el valor MODIFICAR, luego en nuestro codigo aceptar valido que accion tomar de acuerdo a esta variable, nuestro codigo de seleccionar fila y aceptar quedan asi :

private void tblProductosMousePressed(java.awt.event.MouseEvent evt) {                                          
if (tblProductos.getModel().getRowCount() > 0) {
producto = ((ProductoTableModel) tblProductos.getModel()).getRow(tblProductos.getSelectedRow());
txtCodigo.setText(producto.getCodigo());
txtDescripcion.setText(producto.getDescripcion());
txtPrecio.setText(producto.getPrecio().toString());
action = "MODIFICAR";
}
}

El evento del boton Aceptar

private void btnAceptarActionPerformed(java.awt.event.ActionEvent evt) {                                           
if (producto == null) {
producto = new Producto();
}
producto.setCodigo(txtCodigo.getText().trim());
producto.setDescripcion(txtDescripcion.getText().trim());
producto.setPrecio(new BigDecimal(txtPrecio.getText().trim()));
try {
if (action.equals("MODIFICAR")) {
ProductoControl.editar(producto);
} else {
ProductoControl.crear(producto);
}
cargarTabla();
} catch (SQLException ex) {
Logger.getLogger(FrmProductos.class.getName()).log(Level.SEVERE, null, ex);
} finally {
limpiarCampos();
}
}

Hacemos unos cambios en limpiarCampos y queda asi :

private void limpiarCampos() {
txtCodigo.setText("");
txtDescripcion.setText("");
txtPrecio.setText("");
producto=null;
action="";
}

Aqui se puede ver en accion

Viene de  Creacion de Aplicación Java J2SE Swing con Netbeans IDE 7

El exportar a Excel y la impresión las veremos en el siguiente post.

[ACTUALIZADO]
Tutorial : Java Swing Exportar a Excel con Apache POI y JFileChooser – Parte 7.2.1

JQuery y PHP combos enlazados

Publicado: marzo 29, 2012 en codigo, combos, jquery, php, tips, tutorial, web

Hace tiempo hice un tutorial Kumbiaphp combos enlazados con JQuery [PHP combobox JQuery] y en el explicaba como realizar estos combos enlazados, por aquel entonces no puse un Ejemplo visible, pero he aqui uno y mas abierto para cualquier tipo de framework, no he dejado mi querido KumbiaPHP, pero queria afianzar este tema, espero les sirva.

La tabla con los paises la pueden obtener en esta direccionTabla de Paises

El codigo es el siguiente :

<html>

<select id="combo_paises">
<option>..Cargando paises</option>
</select>

<select id="combo_ciudades">
<option>Elija primero un pais</option>
</select>

Javascript

$(function(){
    //Cargar paises   
    $("#combo_paises").load("listar_paises.php");

    $("#combo_paises").change(function(){
        var pais_id=$(this).val();
        if(pais_id!=0){
            $("#combo_ciudades").html("<option>Cargando</option>");       
            var url="listar_ciudades_por_pais.php?country=" + pais_id;
            $("#combo_ciudades").load(url);
        }
    });
});

PHP

//listar_paises.php
<?php include_once("conexion.php"); ?>
<option value="0">Seleccione un pais</option>
<?php
$result = mysql_query("select * from Country");
while ($pais = mysql_fetch_object($result)) :
?>
<option value='<?php echo $pais->Code ?>'><?php echo $pais->Name ?></option>
<?php endwhile; ?>

//listar_ciudades_por_pais.php
<?php include_once("conexion.php"); ?>
<?php
$contrycode=$_GET['country'];
$query="select * from City where CountryCode='$contrycode' ";
$result = mysql_query("select * from Country");
while ($ciudad = mysql_fetch_object($result)) :
?>
<option value='<?php echo $ciudad->Id ?>'><?php echo $ciudad->Name ?></option>
<?php endwhile; ?>

Bueno el código creo que es auto explicativo, pero si tienen dudas, dejen sus comentarios.

Ejemplo :
http://ejemplos.dairdev.com/combos_enlazados.php



En esta parta vamos a crear la interface para el manejo de los productos, podremos ver como hacemos uso de nuestras clases creadas previamente, y también como es posible hacer GUI’s de manera rápida utilizando Netbeans. Verán el uso de componentes como JInternalFrames, Jpanel, Jtable y la clase SwingWorker, asi como la creacion de un TableModel personalizado.
Primero vamos a crear un paquete dentro de UI al cual llamaremos modules y dentro productos, así tendremos las cosas un poco más ordenadas.

Pensemos como queremos nuestra interfaz, podemos hacerlo basado en cuanta información vamos a presentar y el tamaño donde se ejecutara la aplicación.
Nuestra premisas entonces podrían ser, es una aplicación Desktop por lo tanto su tamaño debe ser de 1024×768 a más (no creo que alguien use aun 800×600), nuestra tabla solo contiene 3 campos a mostrar, recuerden que el id del producto no debe ser visto por los usuarios.

Para crearla, click derecho en nuestro paquete y elegimos :

Y le ponemos de nombre FrmProductos

Ahora nuestro IDE debiera verse similar a esto :

 

Puede que varíe un poco dependiendo del S.O., lo importante es que en la parte derecha aparece la paleta de componentes, para insertarlos en nuestra ventana o marco solo hay que seleccionar y arrastrarlos.
Pueden apreciarlo en este video :

Primero le daremos un titulo al formulario, dentro de la ventana Propiedades ubicamos la propiedad Title o Titulo y escribimos Administración de Productos, asi también les agregamos los botones de Cerrar y Maximizar.

Nuestro formulario debe verse asi :

 

Para definir los nombres de nuestras columnas en la tabla, hacemos anticlick en la misma y vamos a la opcion Table Contents o Contenido de la Tabla, en la ventana vamos a la segunda pestaña, Columnas y en la tabla mostrada elegimos la primera fila, quitamos los checks de Editable y Resizable, por ultimo elimnamos la ultima fila, debemos tener una ventana como esta.

 

Los pasos se puede ver en el video a continuación:
Vamos a cambiar nuestro boton Aceptar por el texto Agregar asi como el nombre de la variable y además que tenga un nemonico que seria la letra A, además de un texto de ayuda para cuando el mouse esté encima de nuestro control.

Algunos se dirán y si quiero que mis botones tengan imágenes ?, he aquí los pasos :
Crearemos un paquete icons dentro de nuestro paquete ui.

Ok, ahora vamos a la carpeta nuestro proyecto y dentro de la carpeta src navegamos hasta la carpeta icons,una vez ahi pegamos los iconos que nos gustaría utilizar, en mi caso estoy usando los iconos Oxygen.

 

En nuestro IDE, ya aparecen nuestros icono agregados.
 
Bueno pongamos un icono en nuestros botones.
Seleccionamos el boton Agregar y picamos en la propiedad icon, presionamos el botón de explorar,

 

en la pantalla a continuación en Paquete o Package elegimos el paquete icons y luego el icono que deseamos en mi caso save.png

 Nuestro botón se verá así :
Agregamos una caja de búsqueda y los botones Imprimir y Exportar, nuestro formulario final se vea así.

 

Veamos como va quedando por completo nuestra aplicación.

Para despejar algunas dudas que podrían sucitarse al ver esta pantalla, el tema o como se le llama en Java, el LookAndFeel es automatico, viene en el JDK desde la version 1.6, se llama Nimbus, y Netbeans cuando genera el codigo, lo hace incluyendo este LookAndFeel.

Para integrar nuestro menus con los JinternalFrame siga este Tutorial

 

 Viene de 

Vamos a saltarnos la creación de las otras clases para no demorarnos, y vamos a crear nuestra interface y también el manejo de los Productos.
Aprovecharemos el uso de una interface MDI, que es una de las mas comunes para las aplicaciones.


Bueno, primero vamos a crear un paquete que denominaremos ui.

Luego agregaremos a nuestro Proyecto un formulario MDI

A este lo denominaremos MainWindow

Como verán se ha creado la ventana y podemos editarla de manera gráfica

Quiero que mi aplicación solo tenga los menús :
Sistema

    • Administrar Productos
    • Administrar Clientes
    • Reportes
    • Salir

Ventas

  • Registrar Venta
  • Listar Ventas

Ayuda

  • Manual
  • Acerca de

Cambiamos el nombre al menu File

Cambiamos el nombre de la variable al que hace referencia

De similar manera con el resto y obtenemos lo siguiente:

En el caso de eliminar un menuItem, solo seleccione y presione la tecla SUPR

Ahora debemos eliminar nuestra clase Minitienda.java o en su defecto comentar el void main de la misma, dado que nuestro clase MainWindow cuenta con su propio void main.

Todo ese código es autogenerado por el IDE.

Ahora debemos decirle a Netbeans que es MainWindow nuestra clase principal, para esto damos anticlick en nuestro proyecto y seleccionamos Propiedades, en la ventana a continuacion nos ubicamos en la Opción Run:

Donde dice Main Class, presionamos el botón Browse o Explorar y seleccionamos nuestra nueva clase Main.

Ejecutamos nuestra aplicación y tenemos.

Viene de :
Creacion de Aplicación Java J2SE Swing con Netbeans IDE 7

La clases controladoras nos permiten encapsular las funcionalidades e interactuar con nuestras clases dominio, independiente de la interface, gráfica, dado que estas son las que le entregan a las interfaces la data a mostrar.



Creamos un paquete denominado control y dentro especificamos nuestras clases controladoras, si gustan pueden usar alguna nomenclatura especial para identificarlas, para este ejemplo simplemente escogeremos la palabra Control como sufijo de nuestras clases.

Así tenemos por ejemplo para la administración de Productos, una clase ProductoControl, con métodos como crear(), editar() y borrar().
Pero antes vamos a hacer un pequeño cambio en nuestra aplicación para facilitarnos ciertas pruebas antes de pasar a hacer nuestra interface.
Primero si ha seguido el Tutorial, sabran que tenemos una BD Stand Alone y cuyo esquema es generado por nuestra aplicación, bueno debemos evitar que cada vez que se ejecute la aplicación se vuelva a generar y perdamos nuestros datos, para esto modificamos nuestro método crearDB así :

public void crearDB() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException {
//Revisamos si no ha sido creada previamiente la BD
File archivoDB = new File(DB_URL + ".h2.db");
if (!archivoDB.exists()) {
//ejecutamos el script de creacion de la BD
String createTables = leerSqlFile();
Class.forName(DRIVER).newInstance();
Connection con = DriverManager.getConnection("jdbc:h2:" + DB_URL, "sa", "sa");
java.sql.Statement stm = con.createStatement();
stm.execute(createTables);
stm.close();
con.close();
}
Logger.getLogger(H2Util.class.getName()).log(Level.INFO,"La BD ya fue creada previamiente");
}


El cambio es generar un objeto File llamado archivoDB, al momento de instanciarlo hemos definido la ruta que tiene y la extensión del archivo .h2.db, en caso no exista se procede a generar la base.
Para certificar que todo funciona, he realizado una escritura en un log utilizando la clase Logger, esto se mostrará en nuestra Output Window

También crearemos una clase Aplicacion, la cual nos va a permitir realizar operaciones sin incluirlas directamente en nuestro void main().. De manera que nuestro código quede asi :

public static void main(String[] args) {
Aplicacion app=new Aplicacion();
app.creardb();
app.pruebas();
}

Y nuestra clase Aplicacion tendrá el siguiente código :

public void creardb(){
try {
H2Util.getInstance().crearDB();
} catch (ClassNotFoundException ex) {
Logger.getLogger(Minitienda.class.getName()).log(Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
Logger.getLogger(Minitienda.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(Minitienda.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Minitienda.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(Minitienda.class.getName()).log(Level.SEVERE, null, ex);
}
}

public void pruebas(){
try {
//Crear un producto
Producto p=new Producto();
p.setCodigo("000123");
p.setDescripcion("Este es un producto");
p.setPrecio(new BigDecimal(15.36));

ProductoControl.crear(p);

//Asumismos para el test que como es nuestro primer producto el id=1
p.setPrecio(new BigDecimal(17.36));
ProductoControl.editar(p, 1);

//Crear un producto
Producto p2=new Producto();
p2.setCodigo("000123");
p2.setDescripcion("Este es un producto");
p2.setPrecio(new BigDecimal(15.36));

ProductoControl.crear(p2);

//asumimos que es el producto con id=2 el ultimo que hemos creado
ProductoControl.borrar(2);

} catch (SQLException ex) {
Logger.getLogger(Aplicacion.class.getName()).log(Level.SEVERE, null, ex);
}

}

Como verá ya hemos puesto el código para probar nuestra clase Controladora ProductoControl, cuyo código es el siguiente:

public class ProductoControl {

public static void crear(Producto producto) throws SQLException {
PreparedStatement psmt = H2Util.getInstance().getPreparedStatement(H2Util.getInstance().queryInsert(Producto.class));
psmt.setString(1, producto.getCodigo());
psmt.setString(2, producto.getDescripcion());
psmt.setBigDecimal(3, producto.getPrecio());
H2Util.getInstance().executePsmt(psmt);
}

public static void editar(Producto producto, int id) throws SQLException {
PreparedStatement psmt = H2Util.getInstance().getPreparedStatement(H2Util.getInstance().queryUpdate(Producto.class));
psmt.setString(1, producto.getCodigo());
psmt.setString(2, producto.getDescripcion());
psmt.setBigDecimal(3, producto.getPrecio());
psmt.setInt(3, id);
H2Util.getInstance().executePsmt(psmt);
}

public static void borrar(int id) throws SQLException {
String query = "delete from Producto where id=" + id;
H2Util.getInstance().executeQuery(query);
}
}


Vamos a explicar un poco el código empleado y tomaremos como ejemplo el método crear

Lo hemos definido como método estático para no tener que instanciar la clase ProductoControl, el único parámetro que se le envía es un objeto de la clase Producto, este método nos arroja una excepción tipo SQL, esto es si existe un error por ejemplo en la conexión o la consulta.

public static void crear(Producto producto) throws SQLException {

La api SQL de J2SE posee una clase PreparedStatement la cual nos permite ejecutar sentencias o consultas, y al mismo tiempo haciendo un cache de las mismas, asi como proveyendo de la facilidad de utilizar sentencias con parámetros, por ejemplo, como verán acá no se ve el código Sql, esto es porque lo he puesto en un método de la clase H2Util, sino el código debiera ser :
insert into Producto (codigo, descripcion, precio) values (?, ?, ?);
Los caracteres ? Son comodines que indican la posición de los parámetros.

PreparedStatement psmt = H2Util.getInstance().getPreparedStatement(H2Util.getInstance().queryInsert(Producto.class));

El valor de los parámetros se asigna mediante los métodos setXXX, donde las XXX es el tipo de variable que contiene el valor, asi si el parámetro es del tipo String entonces se utiliza setString, el primer valor es la posición o índice del parámetro y el siguiente el valor en si.

psmt.setString(1, producto.getCodigo());
psmt.setString(2, producto.getDescripcion());
psmt.setBigDecimal(3, producto.getPrecio());

Por último ejecutamos nuestra sentencia.

H2Util.getInstance().executePsmt(psmt);
}


Como habrán visto varias cosas se han encapsulado dentro de H2Util, aclaro esto dista de ser la mejor solución pero al menos da una idea de como facilitarnos el trabajo.
Así por ejemplo para no tener que estar haciendo manualmente todos nuestros querys como INSERT o UPDATE, he creado unos métodos que aprovechan el Api Reflection de Java, el cual nos permite conocer como está compuesta una clase en tiempo de ejecución, asi he agregado el siguiente código a nuestra clase H2Util

/**
*
* @param clase
* @return una cadena conteniendo el query INSERT INTO
*/
public String queryInsert(Class clase) {
StringBuilder query = new StringBuilder();
query.append("insert into ").append(clase.getSimpleName());

StringBuilder comodin = new StringBuilder();
StringBuilder fields = new StringBuilder();
for (Field f : clase.getDeclaredFields()) {
if (!f.getName().equals("id")) {
fields.append(f.getName()).append(",");
comodin.append("?,");
}
}
query.append(" (").append(fields.toString().substring(0, fields.length() - 1)).append(")");
query.append(" values (").append(comodin.toString().substring(0, comodin.toString().length() - 1)).append(")");

return query.toString();

}

/**
*
* @param clase
* @return una cadena conteniendo el query UPDATE
*/

public String queryUpdate(Class clase){
StringBuilder query = new StringBuilder();
query.append("update ").append(clase.getSimpleName()).append(" set ");

StringBuilder fields = new StringBuilder();
for (Field f : clase.getDeclaredFields()) {
if (!f.getName().equals("id")) {
fields.append(f.getName()).append("=?,");
}
}
query.append(fields.toString().substring(0, fields.length() - 1)).append(" where id=?");

Logger.getLogger(H2Util.class.getName()).log(Level.OFF, query.toString());

return query.toString();
}


Tener en cuenta que por eso las clases del dominio tienen su campos denominados de igual forma que lo son en sus respectivas tablas.

También habrán visto que utilizo otro método de ayuda para ejecutar el PreparedStatement, este es su código.

/**
* ejecuta un PreparedStatement previamente definido
*/
public void executePsmt(PreparedStatement psmt) throws SQLException {
psmt.executeUpdate();
//cerramos el psmt y su conexion
psmt.getConnection().close();
psmt.close();
}


Esto no quiere decir que necesariamente hay que estar haciendo esto con cada query que se nos ocurra ejemplo de ello es el método borrar

public static void borrar(int id) throws SQLException {
String query = "delete from Producto where id=" + id;
H2Util.getInstance().executeQuery(query);
}

Y bueno ahora comprobaremos que lo que he puesto aquí es correcto, ejecutamos nuestra aplicación y …


Utilizamos el QueryBrowser  descrito antes, aquí podrán ver el editor SQL que provee.

 Viene de :

Creacion de Aplicación Java J2SE Swing con Netbeans IDE 7

Nuestras clases dominio son aquellas que nos permiten interactuar con nuestras tablas como si fueran objetos.


Bueno es sencillo crearemos un paquete que denominaremos dominio.


Dentro de el pondremos nuestras Clases que son un reflejo de nuestras tablas.
Nuestras clases al final deben ser similares a esto.

import java.util.Date;

/**
*
* @author dinfantas
*/
public class Cliente {
private int id;
private String nombre;
private Date nacimiento;
private String documento;
private String tipocliente;

public Cliente() {
}

public String getDocumento() {
return documento;
}

public void setDocumento(String documento) {
this.documento = documento;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public Date getNacimiento() {
return nacimiento;
}

public void setNacimiento(Date nacimiento) {
this.nacimiento = nacimiento;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}

public String getTipocliente() {
return tipocliente;
}

public void setTipocliente(String tipocliente) {
this.tipocliente = tipocliente;
}

}

Dentro de nuestro paquete dominio, deben haber estas clases :

Viene de :

Creacion de Aplicación Java J2SE Swing con Netbeans IDE 7


Netbeans provee una estupenda herramienta para poder navegar por nuestras tablas, vistas y procedimientos almacendas, aparte de un editor de sql desde donde podemos lanzar nuestras consultas.

 


Bueno para comprobar que nuestra BD ha sido creada correctamente, vamos a la pestaña Services o Servicios y en el nodo Base de Datos vamos a crear una conexión a nuestra base de datos.

 

Primero debemos agregar nuestro driver.

Elegimos el archivo que tiene los drivers, en nuestro caso h2.jar y le damos un nombre, en este caso usaremos H2Database.

Se puede apreciar que fue agregado a la lista de Drivers

Una vez agregado el Driver, creamos nuestra conexión.

Seleccionamos nuestro Driver recientemente agregado.

Presionamos siguiente y en la siguiente ventana, escribimos los datos que utilizamos para crear nuestra base de datos, asi como su ubicación, esta ubicación es la que se pone en el URL, en nuestro caso es dentro de la carpeta de la aplicación, para corroborar que todo está bien presionamos el botón Test Connection

Presionamos el botón Finalizar y veremos que aparece dentro del árbol Databases

Abrimos los nodos y veremos como nuestras tablas han sido creadas.

Mas adelante veremos más usos posibles a dicho QueryBrowser.

Viene de
Creacion de Aplicación Java J2SE Swing con Netbeans IDE 7


Para crear nuestra base de datos con H2 SQL, vamos a hacerlo de la siguiente manera, crearemos un archivo creardb.sql, el cual contiene el script que crea la base de datos.

En base a nuestro modelo ER el código sería el siguiente :

create table cliente (
id int not null auto_increment,
nombre varchar(55) not null,
nacimiento date,
documento varchar(15),
tipocliente char(1),
primary key (id)
);

create index idxnombre on cliente(nombre);

create table producto(
id int not null auto_increment,
codigo varchar(15),
descripcion varchar(45),
precio decimal(7,2),
primary key (id)
);

create index idxcodigo on producto(codigo);

create table venta (
id int not null auto_increment,
fecha date not null,
documento varchar(15) not null,
tipodocumento char(2),
cliente_id int,
primary key (id),
foreign key (cliente_id) references cliente(id)
);

create table detalleventa (
id int not null auto_increment,
cantidad decimal(5,2) not null,
total decimal(10,2) not null,
venta_id bigint,
producto_id int,
primary key (id),
foreign key (venta_id) references venta(id),
foreign key (producto_id) references producto(id)
);


Este archivo lo guardaremos en una carpeta de nuestro proyecto a la que llamaremos querys, en la pestaña de Files o Archivos debiéramos ver algo asi.

Bien ahora simplemente le diremos a nuestro programa que cuando inicie revise si existe la base de datos de no ser asi, que la cree y ejecute el archivo creardb.sql.

/**
* lee nuestro archivo creardb.sql que se encuentra en /querys/creardb.sql
* @return String
* @throws java.io.IOException
*/
private static String leerSqlFile() throws java.io.IOException {
String filePath = String.format("%s/%s", System.getProperty("user.dir"), "querys/creardb.sql");
byte[] buffer = null;
//System.out.println(filePath);
File file = new File(filePath);

buffer = new byte[(int) file.length()];
BufferedInputStream f = null;
try {
f = new BufferedInputStream(new FileInputStream(filePath));
f.read(buffer);
} finally {
if (f != null) {
f.close();
}
}
return new String(buffer);
}

/**
* Leemos y ejecutamos nuestro archivo de creacion de Base de Datos
* @throws ClassNotFoundException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws IOException
* @throws SQLException
*/
public void crearDB() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException {
//ejecutamos el script de creacion de la BD
String createTables = leerSqlFile();
Class.forName(DRIVER).newInstance();
Connection con = DriverManager.getConnection("jdbc:h2:" + DB_URL + ";IFEXISTS=TRUE", "sa", "sa");
java.sql.Statement stm = con.createStatement();
stm.execute(createTables);
stm.close();
con.close();
}

Dentro de nuestro método main en nuestra clase Minitienda.java vamos a ejecutar nuestro script de creación a la base de datos.

public static void main(String[] args) {
try {
H2Util.getInstance().crearDB();
} catch (ClassNotFoundException ex) {
Logger.getLogger(Minitienda.class.getName()).log(Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
Logger.getLogger(Minitienda.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(Minitienda.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Minitienda.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(Minitienda.class.getName()).log(Level.SEVERE, null, ex);
}
}


Ejecutamos nuestra aplicación, presionamos la tecla F6.

En nuestra ventana Output o Salida podemos ver que la ejecución ha sido exitosa.

Para comprobar que se creo nuestra base de datos, vamos a ir a nuestra carpeta donde alojamos nuestro proyecto, si hemos seguido los pasos, Netbeans debe haber creado una carpeta con el nombre del proyecto en una carpeta que debe estar en HOME_DEL_USUARIO/NetbeansProjects.
En el caso de GNU/Linux, bueno todos uds saben donde está su Home, pero los amigos Windowseros, tal vez no, para ellos debiera estar en Documents and Settings/SUUSUARIO o en USERS/SUSUARIO.

 

H2Sql cuando crea una base de datos, genera un archivo con extension .h2.db, en Windows tal vez solo vean hasta .h2 porque asi funciona dicho S.O.

Viene de :

Creacion de Aplicación Java J2SE Swing con Netbeans IDE 7

Si ya sé que existe hibernate, toplink, eclipse-link y mas implementaciones de ORM’s, pero este no es un ORM es simplemente una clase para manejar nuestras consultas SQL sin complicarnos tanto.

Aparte me permite explicarles el Patron Singleton y aprovechar una funcionalidad de la librería H2 que es el pool de conexiones.

  1. Creamos nuestro paquete denominado util y dentro db, entonces tendremos algo asi (he cambiado el nombre del paquete raiz a blog.dairdev.minitienda previamiente, pero esto no influye demasiado)

     

  2. Dentro de db creamos nuestra clase denominada H2Util

Con esta clase manejaremos nuestras conexiones a la base de datos y la ejecución de los querys.
Vamos a utilizar el Patron Singleton, que este caso nos va a permitir tener una sola instancia de esta clase para todo el tiempo de vida de la aplicación.

Para eso implementamos el siguiente codigo :

public class H2Util {

//Implementamos el patron Singleton
static private H2Util INSTANCE = null;

// creador sincronizado para protegerse de posibles problemas multi-hilo
// otra prueba para evitar instanciación múltiple
private synchronized static void createInstance() {
if (INSTANCE == null) {
INSTANCE = new H2Util();
}
}

public static H2Util getInstance() {
if (INSTANCE == null) {
createInstance();
}
return INSTANCE;
}
}

Crearemos nuestro método para abrir conexiones.

private void conectar() {
try {
Class.forName(DRIVER).newInstance();
//si no existe el pool de conexiones crea uno
if (pool == null) {
pool = JdbcConnectionPool.create("jdbc:h2:" + DB_URL, "sa", "sa");
}
} catch (ClassNotFoundException ex) {
Logger.getLogger(H2Util.class.getName()).log(Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
Logger.getLogger(H2Util.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(H2Util.class.getName()).log(Level.SEVERE, null, ex);
}
}

/**
* Abre la coneccion si no ha sido creada previamente
* retorna un objecto connection
*/
public Connection getConnection() throws SQLException {
if (pool == null) {
conectar();
}
return pool.getConnection();
}

Bueno ahora implementaremos algunos métodos públicos que nos será útiles.

/**
* retorna un objeto PreparedStatement utilizando una nueva conexion
*/
public PreparedStatement getPreparedStatement(String query) throws SQLException {
return H2Util.getInstance().getConnection().prepareStatement(query);
}

/**
* retorna un objeto ResultSet basado en un PreparedStatement de acuerdo al query pasado
*/
public ResultSet getResultSet(String query) throws SQLException {
return H2Util.getInstance().getPreparedStatement(query).executeQuery();
}

/**
* ejecuta un query tipo INSERT, UPDATE o DELETE
*/
public void execute(String query) throws SQLException {
PreparedStatement psmt = H2Util.getInstance().getPreparedStatement(query.toString());
//Este metodo es que se debe llamar en caso de ejecutar INSERT, UPDATE o DELETE
psmt.executeUpdate();
//cerramos el psmt y su conexion
psmt.close();
psmt.getConnection().close();
}

Viene de :

Creacion de Aplicación Java J2SE Swing con Netbeans IDE 7