miércoles, 27 de noviembre de 2019

Eventos de mouse en java swing

Esta entrada es mas que nada para dar a conocer de manera separada el listener del mouse, ya que es algo que promete dar mucho de que hablar mas adelante...

Para hacer uso de estos metodos primero que nada es necesaro implementar la interface de actionListener y mouseListener, esto nos dara acceso a capturar los distintos eventos que componen al mouse.

MouseClicked: el cual se ejecuta al soltar el boton del mouse, esto se puede interpretar en un mouseUp por desir un ejemplo.

MousePressed: es cuando se presiona el boton del mouse, se puede interpretar como un mouseDown,

MouseReleased: ocurre cuando se suelta un boton del mouse

MouseEntered: este evento ocurre cuando el mouse entra al objeto sobre el que se esta agregando el evento.

MouseExited: Este evento se ejecuta cuando el mouse sale del objeto al que se agrego el evento.

A parte de estos métodos, existe otra interfaz que cuenta con otros eventos propios del mouse, dicha interfaz te permite capturar otros tipos de eventos durante el manejo del mouse, esta libreria se llama.

MouseMotionListener,al agregar dicha libreria te pide agregar los metodos MouseDragged, MouseMoved.

MouseDragged: Se dispara cuando el mouse esta siendo presionado y en movimiento.

MouseMoved: se dispara cuando el mouse se encuentra sobre un componente.

La implementación es la siguiente.


tabla.addMouseListener( new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {}
            @Override
            public void mousePressed(MouseEvent e) {}
            @Override
            public void mouseReleased(MouseEvent e) {}
            @Override
            public void mouseEntered(MouseEvent e) {}
            @Override
            public void mouseExited(MouseEvent e) {}
        });
        tabla.addMouseMotionListener( new MouseMotionListener() {
            @Override
            public void mouseDragged(MouseEvent e) {}
            @Override
            public void mouseMoved(MouseEvent e) {}
        });


Con esto damos fin  esta entrada.

No olvides dejar tu comentario en caso de que esto te sea de utilidad, o no, aun así agradeceria tu comentario al respecto.

viernes, 22 de noviembre de 2019

Agregar columnas a JTable

Siguiendo con el proyecto de creacion de Jtable en java viene el momento de agregar una columna a nuestra JTable.

A diferencia de como agregar un registro a nuestra JTable, para agregar una columna es mas sencillo que lo anterior, se necesita de un JOptionPane en el ejemplo que estoy usando. y punto.


Ahora trabajaremos con el total de los renglones, esto nos dará como resultado un arreglo del tipo Object que sera el data de la nueva columna, quedando de la siguiente manera.



 
    public void addCols(){
        String n = (String) JOptionPane.showInputDialog(
                null, 
                "Nombre de la columna", 
                "New Column", 
                JOptionPane.QUESTION_MESSAGE, 
                null, 
                null, 
                "Columna Nueva"
        );
        if( n==null ){
            return;
        }else if( ( n.length() == 0 ) || ( n.trim().length() == 0 ) ){
            return;
        }else if( n.trim() != null ){
            Object[] newColumn = new Object[tabla.getRowCount()];
            dtm.addColumn( n, newColumn );
        }
    }
    
Como lo mencione anteriormente, en el ejemplo que les estoy mostrando pido el nombre de la columna mediante un JOptionPane, pasandole los parametros que se requieren para mostrar esta ventana.



Al final solo se agrega la nueva columna al DefaultTableModel. le agregamos unas validaciones tales como. valor no nulo o que la longitud del valor sea mayor a 0, dejando como resultado la asignación del nombre a la nueva columna.


Sin mas es todo por hoy, Déjame tu comentario para saber en que mejorar.

jueves, 21 de noviembre de 2019

Agregar renglones a JTable

Continuando con el proyecto de creación de una tabla en java ahora corresponde al tema de agregar un nuevo elemento a la tabla ya existente, para ello vamos a crear ya sea un JButton o bien un JMenu como lo hice.

Lo importante es agregar el elemento a la tabla, vamos a ello.


Del proyecto anterior colocamos de manera global tanto la tabla como el DefaultTableModel esto con la finalizdad de poder acceder a ellos desde otros metodos, quedando de la siguiente manera.



public class CreacionTabla extends JFrame implements ActionListener{
    DefaultTableModel dtm;
    JTable tabla;
}

De esta forma podremos acceder a ellos desde cualquier parte del documento. Seguido de ello creamos el método addRows, el cual nos ayudara a agregar un nuevo elemento en la tabla, para que esto funcione necesitamos conocer el total de columnas que tiene la tabla con el método getColumnCount(), que nos da como resultado el total de columnas en la tabla.

De esta forma creamos un ciclo que recorra el total de columnas construyendo un arreglo de tipo Object para finalmente agregar celo a la tabla. el metodo addRows quedara de la siguiente manera.


    private void addRows(){
        Object[] newRow = new Object[ tabla.getColumnCount() ];
        for( int i = 0; i < tabla.getColumnCount(); i ++ ){
            newRow[ i ] = "";
        }
        dtm.addRow(newRow);
    }


Es así como queda agregado un nuevo elemento a la tabla, para poder editar el nuevo elemento es necesario dar click en la celda que se quiere editar. posteriormente agregaremos los métodos necesarios para poder insertar el elemento con su contenido.




Sin mas por el momento me despido, espero sus comentarios, no olvides seguirme para poder ser de los primeros en leer mis siguientes publicaciones... 



Creacion de JTabla en java

En lo personal las tablas nos ayudan a manejar mas información que solo un simple System.out o cualquier otra forma. Es por ello que hoy les traigo la manera en como trabajar con una JTable desde ceros.

En este capitulo les mostrare como se monta una tabla, su creacion en espera de datos. Posteriormente iremos mejorando el proyecto hasta llegar a conectarla con una base de datos y modificando la informacion de la misma, viendose reflejado en la base.


Por ahora comensemos con los siguientes requisitos. Para comensar necesitamos.

1 DefaultTableModel.
2 JTable.
3 JScrollPane.
4 JFrame.


Ahora para comenzar construiremos el frame que contendra la tabla en un principio, en nuestro constructor le decimos.


public constructor(){
     JFrame frame = new JFrame();
     frame.setTitle( "Hola Tabla" );
     //se construye la tabla y se agrega al frame
     construyeTabla(frame);
     frame.setSize( 500, 300 );
     frame.setDefaultCloseOperation(EXIT_ON_CLOE);
     frame.setVisible( true );
}

public void construyeTabla( JFrame frame ){
     Object[][] data = { {"sitio","inovania.blogspot.com"},
                            {"autor","Oscar Martagon Valera"}};
        String[] colNames= {"Dato","Descripcion"};
        DefaultTableModel dtm = new DefaultTableModel( data, colNames );
        JTable tabla = new JTable ( dtm );
     
        tabla.setPreferredScrollableViewportSize(new Dimension( 250, 250 ) );
        JScrollPane scrollPane = new JScrollPane(tabla);
        frame.add(scrollPane,BorderLayout.CENTER);
}

Quedando así de esta manera simple y sencilla como hacer una tabla en java.



Sin mas por el momento los dejo. No olvides dejar tu comentario, sígueme  para poder ser de los primeros en leer mis próximas entradas.

Hasta la proxima.

miércoles, 16 de octubre de 2019

Cargar CSV en JavaScript

Cargar y leer un archivo csv en JavaScript sin necesidad de php, java u otro más.

Así es, tal y como lo leen, hoy les traigo un código que espero les ayude tanto como a mi me a ayudado hasta este momento, con un poco de lógica, que les dejara como resultado el contenido del archivo en un array.

Y como siempre lo digo... vamos al punto.

<div id="drop_file_zone" ondragover="return false" ondrop="upload_file(event)">
 <div id="drag_upload_file">
  <div id="datos">
   <h2>
    Drag and drop file here or click for selected file
   </h2>
  </div>
  <input id="selectfile" type="file" />
 </div>
</div>
<div id="dvCSV"></div>
dando como resultado lo siguiente


A esto demos le un poco de estilo.


#drop_file_zone{
 border: solid 1px;
 cursor: pointer;
 }
#drop_file_zone #drag_upload_file{
 height: 3em;
 padding: 1em;
 }
#drop_file_zone:hover{
 border-style: dashed;
 border-radius: 5px;
 border-color: blue;
 }
#drop_file_zone input[type=file]{
 display: none;
 }

Esto quedara así


Ahora lo mas esperado. Así es, el codigo.

Comencemos con las acciones del drop y el evento click a nuestra área de archivo.

---

$( '#drag_upload_file' ).click(function(){
 document.getElementById('selectfile').click();
 document.getElementById('selectfile').onchange = function () {
  uploadCsv( document.getElementById('selectfile').files[0], function(data){
   createTable( data );
  });
 };
});
function upload_file( e ){
 e.preventDefault();
 uploadCsv( e.dataTransfer.files[0], function(data){
  createTable( data );
 } );
}
function uploadCsv( fileUpload, callback ){}
function createTable( datos ){}
---

Con esto, decimos que cuando den click o bien cuando dejen un archivo en nuestra área esta invocará la función uploadCsv, la cual recibe como primer parametro el archivo del file upload mientras que en su segundo parametro deja una funcion de retorno.

Ahora bien el codigo de la funcion uploadCsv es el siguiente.


---

function uploadCsv(fileUpload, callBack) {
 var rtn = {};
 var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.csv)$/;
 if (regex.test(fileUpload.name.toLowerCase())) {
  rtn.name = fileUpload.name;
  rtn.data = [];
  rtn.size = fileUpload.size;
  rtn.encabezado = [];
  if (typeof (FileReader) != "undefined") {
   var reader = new FileReader();
   reader.onload = function (e) {
    var x = 0;
    var rows = e.target.result.split("\n");
    for (var i = 0; i < rows.length; i++) {
     var cells = rows[ i ].split( "," );
     var obj = {};
     var have = 0;
     for( var j = 0; j < cells.length; j ++ ){
      if( cells[ j ].length == 0 )break;
      have = 1;
      if( i == 0 ){
       obj[ 'field_' + j ] = ( cells[ j ].trim() ).toUpperCase();
      }else{
       var field =  rtn.encabezado[0]['field_' + j ] ;
       obj[ field ] = cells[ j ];
      }
     }
     if( i == 0 ){
      rtn.encabezado.push( obj );
     }else{
      if( have == 1 )
       rtn.data.push( obj );
     }
     x++;
    }
    rtn.total = x ;
    callBack( rtn );
   }
   reader.readAsText(fileUpload);//.files[0]);
  } else {
   callBack( "Este navegador no soporta html5" );
  }
 } else {
  callBack( "El archivo no es csv");
 }
}
---

Ahora solo falta el mostrar el contenido de nuestro archivo, y para ello nos creamos la funcion createTable con lo siguiente,


---

function createTable(datos) {
 var table = document.createElement("table");
 var rows = datos.data;
 var cells = Object.keys( datos.encabezado[ 0 ] );
 for (var i = 0; i < rows.length; i++) {
  var row = table.insertRow(-1);
  for (var j = 0; j < cells.length; j++) {
   var cell = row.insertCell(-1);
   cell.innerHTML = datos.data[i][ datos.encabezado[ 0 ][ cells[ j ] ] ];
  }
 }
 var head = table.createTHead( -1 );
 var row = head.insertRow( -1 );
 for( var j = 0; j < cells.length; j ++ ){
  var th = document.createElement( 'TH' );
  th.innerHTML = datos.encabezado[ 0 ][ cells[ j ] ];
  row.appendChild( th );
 }
 var caption = table.createCaption();
 caption.innerHTML = "
" + datos.name + "";

 var dvCSV = document.getElementById("dvCSV");
 dvCSV.append( table );
}
---

Y así de simple es como queda esto. no sin antes darle un mejor estilo a nuestra tabla creada a partir del contenido del archivo csv.


----

table{
 width: 100%;
 border: 1px;
 border-collapse: collapse;
}
table caption {
 border: solid 1px;
 font-size: larger;
 padding: 0.5em;
}
table thead tr th {
 padding: 0.75em;
 border: solid 1px;
 border-top: none;
 font-size: larger;
}
table tr td {
 border: solid 1px;
 padding: 0.5em;
 font-size: small;
}
----
dejando al final un resultado como el siguiente.


Espero les sirva de apoyo para su desarrollo, sin mas.. me despido por el momento, espero sus comentarios.

jueves, 3 de octubre de 2019

Pricipios con NodeJs

Así es, tal y como sus ojos lo leen, esta vez les traigo una entrada referente a la librería node.js.

Para comenzar instalaremos el paquete, para ello es lo siguiente.

https://nodejs.org/es/download/

Dependiendo del caso que lo requiera Windows, Linux o Mac.

Una vez instalado, comprobamos la librería abriendo la terminal o linea de comando, con la orden.

C:\>_ node --version

Para continuar es necesario seguir estos pasos.

1.- Crear un directorio
2.- En el directorio nuevo, crear el init con node.
3.- Descargar los módulos necesarios para la aplicación requerida.

Con todo esto aclarado aremos nuestro primer "Hola mundo" desde node.js, Manos a la obra.

En xampp/htdocs: creamos la carpeta holamundo, desde cmd nos posicionamos en la carpeta holamundo e indicamos.


El resultado debería ser el siguiente.


Esto nos deja un archivo package.json el cual ira cargando los módulos que se instalen.

Dentro de hola mundo, creamos un archivo js llamado index.js, el cual contendrá el siguiente código...


var http = require( "http" );
http.createServer( function( req, res ){
res.writeHead( 200, {
'Content-Type':'text/plain'
});
res.end( 'hola Mundo\n' );
}).listen( 8420 );
console.log( 'servidor en url http://localhost:8420' );


Al final, damos el comando.

nos colocamos en nuestro navegador en el puerto indicado y listo, tenemos nuestro hola mundo echo en node js



No olvides dejarme tu comentario.

Si puedo ayudarte en algo escribeme.

Asta la próxima.

jueves, 27 de junio de 2019

PLSQL REGEXP_SUBSTR

"El lenguaje de base siempre es demasiado cuadrado" es lo que siempre eh dicho, no por ello puedo decir que lo encuentro aburrido ya que sin este lenguaje nadamas no podriamos obtener información de manera precisa respaldada y bueno, todo lo bueno que nos dejan las bases de datos.

Ahora solo les hablare de una función que es de mucha ayuda en otros lenguajes, tales como java, javascript, php, entre otros. Se trata nada mas y nada menos que de la funcion REGEXP_SUBSTR
la cual nos permite hacer un substring a la cadena que pasamos como parametro, dejando en un arreglo ( columna ) el resultado esperado.


Sin mas por el momento, vamos al grano...


Suponiendo que tenemos una  cadena como la siguiente.


"En|inovania.blogspot.com|siempre|encuentro|respuestas|a|mis|dudas"

En este caso la cadena esta separada por el caracter [ | ] el cual sera nuestro separador ( antes de continuar aclaro estar trabajando con PLSQL Developer, pero la funcion es la misma en otros id's ), comenzando con un bloque anonimo creamos nuestras variables.

--declaracion de un bloque anonimo
declare 
  --declaracion de variables
   TYPE t_separador IS TABLE OF TABLA.COLUMNA%type;--SE PASA EL TIPO DE DATO QUE SEA LO QUE SEPARAREMOS
   vt_dato t_separador;
   is_cadena_str VARCHAR2( 100 );
begin
  --asignacion de valor a variable
  is_cadena_str:= 'En|inovania.blogspot.com|siempre|encuentro|respuestas|a|mis|dudas';
  --impresion de contenido de variable
  dbms_output.put_line('is_cadena_str: ' ||  is_cadena_str );
  --fin del bloque anonimo
end;

Aquí, lo que da como resultado este bloque anónimo es una muestra el valor de la variable con el texto que anteriormente dijimos.

A continuación se se parsea la cadena guardandola en la variable vt_dato.

select valor
    bulk collect into vt_dato
    from (
        select regexp_substr(is_cadena_str,'[^|]+', 1, level) as valor from dual
        connect by regexp_substr(is_cadena_str, '[^|]+', 1, level) is not null
    );

Los campos de la función en el orden que los va pidiendo:
1.- is_cadena_str : cadena que queremos parsear,
2.- '[^|]+' : expresion que nos ayuda a separar la cadena por el caracter |
3.- 1 : El numero de consecutivos a seguir dependiendo cada separador, si se pone 2 deja a un lado la primera posicion del resultado es decir de ser 8 los valores resultado de esta cadena solo seran 7.
4.- level: undefined. required : true.


Ya para finalizar recorremos el resultado en un for loop mostrando nuestra cadena dentro del arreglo, colection, tabla.

  for a in vt_dato.first .. vt_dato.last loop
      dbms_output.put_line( 'valor de vt_dato( ' || a || ' ): ' || vt_dato( a ) || '' );
    end loop;

Dejando como salida.

is_cadena_str: En|inovania.blogspot.com|siempre|encuentro|respuestas|a|mis|dudas
valor de vt_dato( 1 ): En
valor de vt_dato( 2 ): inovania.blogspot.com
valor de vt_dato( 3 ): siempre
valor de vt_dato( 4 ): encuentro
valor de vt_dato( 5 ): respuestas
valor de vt_dato( 6 ): a
valor de vt_dato( 7 ): mis
valor de vt_dato( 8 ): dudas


No olvides dejarme tus comentarios. si hay algo que se me paso, escribe y daré respuesta.


Hasta la proxima.

miércoles, 12 de junio de 2019

Funciones personalizadas en EXCEL

Recientemente me encuentro con un problema que me esta dando vueltas en la cabeza, resulta que buque una función en especifico en excel, la cual trata lo siguiente.

Tengo dos series


Se requiere evaluar si cada uno  de los valores en la serie 2 existe en la serie 1

Dejando de esta manera es como resulta mas fácil identificar que valores están repetidos para ello es necesario entrar al modo edición de módulos de Excel.

En el menú Insertar--> Modulo


Function busqueda_en_rango(valor As Integer, rango As Range) As Integer
    Dim count As Integer
    count = 0
    For Each celda In rango.Cells
        If celda.Value = valor Then
            count = count + 1
        End If
    Next celda
    If count = 0 Then
        busqueda_en_rango= 0
    Else
        busqueda_en_rango= 1
    End If
End Function

Y es así como pasamos la función en la celda que queremos comparar

dejando como resultado el valor 1 en caso de existir y 0 en caso de no existir en la serie

Espero sus comentarios, sus opiniones cuentan. nos vemos a la proxima.

viernes, 31 de mayo de 2019

Uso de JDBC

La conexión a base de datos desde java es un punto indispensable de nuestras aplicaciones, para ello tenemos la librería JDBC  ( Java Database Connectivity ) la cual no permite genera una conexión segura a la base de datos, hablando de Oracle como db.

Por otro lado tenemos el enlace a MySQL desde java. Pero... eso lo vemos después.

Los métodos que estarán presentes en nuestros objetos serán, conectar y desconectar, pero antes de ello es necesario agregar la librería a nuestro pom en caso de tenerlo, la dependencia es la siguiente.


        <dependency>
           <groupId>com.oracle</groupId>
           <artifactId>ojdbc6</artifactId>
           <version>11.2.0.3</version>
       </dependency>
    


De lo contrario si tu proyecto no cuenta con un archivo pom.xml, la segunda opción es agregar un jar al proyecto, para ello lo puedes descargar de aquí.

Una vez que ya se tiene el driver, lo siguiente es crear los métodos anteriormente mencionados, para ello creamos una clase.


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author decodemy.blogspot.com
 */
public class JDBCConnection {

    /**
     * Establece la coneccion a una base de datos Oracle mediante JDBC
     *
     * @param user Usuario de db
     * @param pass Password de db
     * @param stringConnection Cadena de conexion para crear enlace
     * @throws java.sql.SQLException Throws exception SQL
     * @throws java.lang.ClassNotFoundException Throws Class Not fownd
     * @return connection
     */
    public Connection conectar(
        String user, 
        String pass, 
        String stringConnection
    ) throws SQLException, ClassNotFoundException {
        
        Connection con = null;
        Class.forName("oracle.jdbc.OracleDriver");
        con = DriverManager.getConnection(stringConnection, user, pass);
        if (con == null) {
            throw new SQLException("Connection is null");
        }
        return con;
    }
    
    /**
     * metodo creado para cerrar la conexion
     * @param con conexion a cerrar
     * @return true or false
     */
    public boolean desconectar( Connection con ){
        try {
            con.close();
            if( con == null )
                return true;
            else
                return false;
        } catch (SQLException ex) {
            Logger.getLogger(JDBCConnection.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }
}



Esta clase permite conectar y desconectar una instancia a base de datos, su implementación la dejamos de la siguiente manera.

Creamos una clase que herede la clase anterior, con " extends JDBCConnection  ", para después agregar nuestra cadena de conexión.

Nota: la cadena de conexión contiene el balanceo para poder diferenciar entre los nodos donde se encuentra nuestra base. Quedando de la siguiente manera

String stringDeConeccion = "jdbc:oracle:thin:@ ( DESCRIPTION = ( ADDRESS = ( PROTOCOL = TCP )( HOST = IP_DEL_SERVIDOR_DB ) ( PORT = PUERTO_DEL_SERVIDOR_DB ) ) ( CONNECT_DATA = ( SERVICE_NAME=sie ) ) )";

con ello tenemos una cadena de coneccion a la cual podemos agregar mas address para ir haciendo a su vez un balanceo entre los nodos.

El método de consulta queda así.

    public Consulta() {
        Connection con;
        PreparedStatement stmt = null;
        StringBuilder query = new StringBuilder();
        try {
            con = conectar("usuario", "password", sdc);
            query.append("SELECT COUNT(*) AS TOTAL FROM EMPLEADOS");
            stmt = con.prepareStatement(query.toString());
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                System.out.println(rs.getInt("TOTAL"));
            }
            desconectar(con);
        } catch (ClassNotFoundException | SQLException err) {
            System.err.println("Error en consulta " + err.getMessage());
        }
    }

De esta manera el metodo conectar y desconectar que creamos en la clase JDBCConnection quedan heredados en nuestra clase dao.

Mas adelante les mostrare como hacer diferentes llamados a base desde java, invocando funciones, strore procedure, querys sencillos como se tiene ahorita, entre otras cosas.


No olvides dejar tu comentario al respecto, de esa manera conoceré tu opinión.

Nos vemos pronto.

martes, 28 de mayo de 2019

MMORPG --> Part 2 - Cliente

Ya con un tiempo de espera por fin aquí daremos seguimiento al mmorpg, espero les sea de ayuda.

Por ahora veremos un login sencillo con no mas que un user, password y su respectivo aceptar entre otras cosas mas.

La opción final quedará de la siguiente manera.


Cual será la función, bueno.
 1.- El usuario inicia su aplicación.
 2.- El cliente se conecta con el servidor
 3.- El servidor crea un thread para el cliente nuevo
 4.- El cliente ingresa su usuario y contraseña
 5.- La aplicación del cliente cifra la contraseña
 6.- El usuario envía la petición al servidor
 7.- El servidor valida el usuario y contraseña del cliente, re
torna true o false [ 1, 0 ]
 8.- Si el usuario no fue logeado correctamente corrige usuario o contraseña según sea el caso
 9.- Muestra mensaje de satisfacción Bienvenido.

Sera necesaria la siguiente estructura



De esta manera se queda la estructura del proyecto del lado del cliente por el momento se seguiran agregando más módulos con formeavance el mismo.

El código de cada uno de ello queda de la siguente manera.
                        import com.inovania.cliente.main.Principal;
                        import java.io.DataInputStream;
                        import java.io.DataOutputStream;
                        import java.io.IOException;
                        import java.net.Socket;

                        public class Connections{
                            private final String IP_SERVER = "localhost";
                            public DataInputStream entrada_1 = null;
                            public DataInputStream entrada_2 = null;
                            DataOutputStream salida = null;
                            
                            Socket socket_1 = null;
                            Socket socket_2 = null;
                            String nombreCliente = "";
                            
                            Principal app;
                            
                            public Connections( Principal app ){
                                this.app = app;
                            }
                            
                            public void conexion(){
                                try{
                                    socket_1 = new Socket( IP_SERVER, 5555 );
                                    socket_2 = new Socket( IP_SERVER, 4445 );
                                    entrada_1 = new DataInputStream( socket_1.getInputStream() );
                                    entrada_2 = new DataInputStream( socket_2.getInputStream() );
                                    salida = new DataOutputStream( socket_1.getOutputStream() );
                                    app.init();
                                }catch( IOException ioe ){
                                    System.err.println( "error en la conexion:[ " + ioe.getMessage() + " ]" );
                                }
                            }
                            public void flujo( int opcion,String msg ){
                                try{
                                    salida.writeInt( opcion );
                                    salida.writeUTF(msg);
                                }catch( IOException e ){
                                    System.err.println(e.getMessage());
                                }
                            }
                            public void login( String usr ){
                                try {
                                    salida.writeInt( -1000 );
                                    salida.writeUTF(usr);
                                    if( entrada_1.readInt() == 0 ){
                                        app.messageDialog("eNoLogin");
                                    }else{
                                        app.messageDialog("isLogin");
                                    }
                                } catch (IOException ex) {
                                    System.err.println( ex.getMessage() );
                                }
                            }
                        }
                    
      
                        import com.inovania.cliente.utils.TypeMsg;
                        import java.util.ArrayList;
                        import java.util.List;
                        import static javax.swing.JOptionPane.ERROR_MESSAGE;
                        import static javax.swing.JOptionPane.INFORMATION_MESSAGE;

                        public class Mensajes {
                            public List getMensajes(){
                                List rtn = new ArrayList<>();
                                TypeMsg elem;
                                
                                elem = new TypeMsg("Falta el usuario", ERROR_MESSAGE, "eLoginUser","Usuario");
                                rtn.add(elem);
                                
                                elem = new TypeMsg("Falta el Password", ERROR_MESSAGE, "eLoginPass","Password");
                                rtn.add(elem);
                                
                                elem = new TypeMsg( "Felicidades", INFORMATION_MESSAGE, "isLogin", "Exito" );
                                rtn.add( elem );
                                
                                elem = new TypeMsg( "Usuario o contraseña incorrecta", ERROR_MESSAGE, "eNoLogin", "Credenciales invalid" );
                                rtn.add( elem );
                                
                                return rtn;
                            }
                        }
                    
                        import com.inovania.cliente.controller.Connections;
                        import com.inovania.cliente.controller.Mensajes;
                        import com.inovania.cliente.utils.TypeMsg;
                        import com.inovania.cliente.mmorpg.autenticacion.Autorized;
                        import java.awt.Cursor;
                        import java.awt.Desktop;
                        import java.awt.event.ActionEvent;
                        import java.awt.event.ActionListener;
                        import java.awt.event.KeyAdapter;
                        import java.awt.event.KeyEvent;
                        import java.awt.event.MouseEvent;
                        import java.awt.event.MouseListener;
                        import java.io.IOException;
                        import java.net.URI;
                        import java.net.URISyntaxException;
                        import java.util.List;
                        import javax.swing.JButton;
                        import javax.swing.JFrame;
                        import javax.swing.JLabel;
                        import javax.swing.JOptionPane;
                        import javax.swing.JPasswordField;
                        import javax.swing.JTextField;
                        public class Principal extends JFrame implements ActionListener, MouseListener{
                            JTextField txtUsr;
                            JLabel lblUsr; 
                            JLabel lblPss; 
                            JLabel lblNotLogin;
                            JPasswordField txtPss;
                            JButton btnAceptar;
                            Autorized auth;
                            Connections con;
                            
                            public Principal(){
                                auth = new Autorized();
                                con = new Connections(this);
                                con.conexion();
                            }
                            public static void main(String[] args) {
                                Principal app = new Principal();
                            }
                            public void init() {
                                this.setTitle( "Inovania Game");
                                this.setLayout(null);
                                this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                                this.setSize(330, 150);
                                this.setLocationRelativeTo(null);
                                
                                lblUsr = new JLabel( "Usuario: " );
                                lblUsr.setBounds( 5,5,50,25);
                                this.add(lblUsr);
                                
                                txtUsr = new JTextField();
                                txtUsr.setBounds( 65,5,140,25 );
                                txtUsr.addKeyListener(new KeyAdapter(){
                                    @Override
                                    public void keyTyped( KeyEvent e ){
                                        if( e.getKeyChar() == '&' ){
                                            e.consume();
                                        }
                                    }
                                });
                                this.add( txtUsr );
                                
                                lblUsr = new JLabel( "Password: " );
                                lblUsr.setBounds( 5,30,50,25);
                                this.add(lblUsr);
                                
                                txtPss = new JPasswordField();
                                txtPss.setBounds( 65, 30, 140, 25 );
                                txtPss.addKeyListener(new KeyAdapter(){
                                    @Override
                                    public void keyTyped( KeyEvent e ){
                                        if( txtPss.getText().trim().length() >= 8 ){
                                            e.consume();
                                        }
                                    }
                                });
                                this.add( txtPss );
                                
                                lblNotLogin = new JLabel( "Create Account");
                                lblNotLogin.addMouseListener(this);
                                lblNotLogin.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
                                lblNotLogin.setName("notLogin");
                                lblNotLogin.setBounds( 5,55,100,25);
                                
                                this.add( lblNotLogin );
                                
                                
                                btnAceptar = new JButton("Aceptar");
                                btnAceptar.setBounds( 210, 5, 95, 50 );
                                btnAceptar.setActionCommand("login");
                                btnAceptar.addActionListener(this);
                                this.add( btnAceptar );
                                
                                txtUsr.setNextFocusableComponent(txtPss);
                                txtPss.setNextFocusableComponent(btnAceptar);
                                btnAceptar.setNextFocusableComponent(txtUsr);
                                
                                this.setVisible(true);
                            }

                            @Override
                            public void actionPerformed(ActionEvent e) {
                                if( e.getActionCommand().equals( "login" ) ){
                                    String usuario = txtUsr.getText();
                                    String passwor = txtPss.getText().trim();
                                    if( usuario.equals("")){
                                        messageDialog("eLoginUser");
                                        return;
                                    }
                                    if( passwor.equals("") ){
                                        messageDialog("eLoginPass");
                                        return;
                                    }
                                    String password = auth.encriptaPassword(passwor);
                                    con.login(usuario + "&" + password);
                                }    
                            }
                            
                            @Override
                            public void mouseClicked(MouseEvent e) {
                                if( e.getSource() == lblNotLogin ){
                                    try{
                                        if( Desktop.isDesktopSupported() ){
                                            Desktop dt = Desktop.getDesktop();
                                            if( dt.isSupported( Desktop.Action.BROWSE ) ){
                                                dt.browse( new URI( "www.inovania.blogspot.com" ) );
                                            }
                                        }
                                    }catch( IOException | URISyntaxException x ){
                                        System.err.println( x.getMessage() );
                                    }
                                }
                            }

                            @Override public void mousePressed(MouseEvent e) {}
                            @Override public void mouseReleased(MouseEvent e) {}
                            @Override public void mouseEntered(MouseEvent e) {}
                            @Override public void mouseExited(MouseEvent e) {}
                            
                            public void messageDialog(Object... msg){
                                Mensajes m = new Mensajes();
                                List mts = m.getMensajes();
                                boolean msgShow = false;
                                for( TypeMsg tm : mts ){
                                    if( tm.getClave().equals( msg[ 0 ] ) ){
                                        JOptionPane.showMessageDialog(
                                                null,
                                                tm.getMsg(),
                                                tm.getTitle(),
                                                tm.getTipo()
                                        );
                                        msgShow = true;
                                        break;
                                    }
                                }
                                if( !msgShow ){
                                    JOptionPane.showMessageDialog(
                                            null,
                                            msg[ 0 ].toString(),//mensaje
                                            (msg.length>1)?msg[ 1 ].toString():"",//titulo
                                            (msg.length>2)?Integer.parseInt( msg[ 2 ].toString() ):JOptionPane.INFORMATION_MESSAGE//tipo
                                    );
                                }
                            }
                        }
                    
                        public class TypeMsg{
                            private String msg;
                            private int tipo;
                            private String clave;
                            private String title;
                            
                            public TypeMsg(String msg, int tipo, String clave, String title) {
                                this.msg = msg;
                                this.tipo = tipo;
                                this.clave = clave;
                                this.title = title;
                            }

                            /**
                             * @return the msg
                             */
                            public String getMsg() {
                                return msg;
                            }

                            /**
                             * @return the tipo
                             */
                            public int getTipo() {
                                return tipo;
                            }

                            /**
                             * @return the clave
                             */
                            public String getClave() {
                                return clave;
                            }
                            /**
                             * @return the title
                             */
                            public String getTitle(){
                                return title;
                            }
                        }
                    

Sin mas por el momento es todo por hoy espero sus comentarios al respecto. No olvides comentar, suscribirte y seguirme para poder continuar con este proyecto hasta el final.


Nos leemos pronto.

lunes, 27 de mayo de 2019

Open Browse width java

Recientemente me vi en la necesidad de agregar un hipervinculo desde un JFrame mediante un JLabel, tras buscar y buscar una solucion me encuentro con la siguiente caracteristica de java.


Desktop:

El cual aparte de poder abrir un un archivo en su programa predeterminado puede mandarnos en este caso a una ruta en especifico de búsqueda en mi caso en chrome.

El código es el siguiente


   try{
      if( Desktop.isDesktopSupported() ){
         Desktop dt = Desktop.getDesktop();
         if( dt.isSupported(Desktop.Action.BROWSE)){
            dt.browse( new URI( "www.google.com" ));
         }
      }
   }catch( IOException | URISyntaxException x ){
      System.err.println( x.getMessage() );
   }


De esta manera al agregar este código en el evento mouseClicked al JLabel, nos abrirá en la direxion espesificada.


Otras opciones de Descktop.


Open file

El código queda de la siguiente manera.


    try{
        if( Desktop.isDesktopSupported() ){
            File file = new File( "archivo.txt");
            Desktop dt = Desktop.getDesktop();
            dt.open( file );
        }
    }catch( IOException ){
        System.err.println( x.getMessage() );
    }

Por el momento es todo.


Espero sus comentarios, nos vemos pronto.

jueves, 23 de mayo de 2019

Transferir archivos de servidor a servidor en java

Buenos días a todos. Les traigo esta información que recientemente me acaba de llegar a las manos, resulta que me encuentro tratando de pasar archivos vía ftp de un servidor a otro utilizando java...

Pasa que después de tanto buscar y buscar me tope con esta manera de pasar archivos, cabe mencionar que es muy rápida la transferencia, muy fácil de utilizar y sobre todo de entender, sin mas, aquí esta.


Creando la clase TransfiereArchivo, las variables necesarias son: 

user: usuario para la conexion
host: host del server
pass: password para conectarse
port: el puerto por el cual se conectara por default casi siempre es el 22


import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.UserInfo;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * @Param rutaFinal... ruta donde se quedara el archivo en el servidor.
 * @Param rutaFile... ruta del archivo que se va a mover.
 */
public boolean putFile(String rutaFinal, String rutaFile){
        boolean rtn = false;
        try{
            JSch jsch = new JSch();
            Session session = jsch.getSession(user, host, port);
            UserInfo ui = new SUserInfo(pass, null);
            session.setUserInfo(ui);
            session.setPassword(pass);
            session.connect();
            ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp");
            sftp.connect();
            File file = new File( rutaFile );
            sftp.cd( rutaFinal );
            sftp.put(new FileInputStream( file ), file.getName() );
            file.delete(); //opcional
            sftp.exit();
            sftp.disconnect();
            session.disconnect();
            rtn = true;
        }catch(JSchException | FileNotFoundException | SftpException jse){
            System.out.println(jse.getMessage());
        }
        return rtn;
    }



JSch: refiriéndose a JavaShellChannel crea la instancia para la conexión.

Session: en este caso al igual que un jdbc se genera una session con lo necesario para estar activos.

UserInfo: es una instancia de un POJO el cual contiene lo siguiente:

---
public class SUserInfo implements com.jcraft.jsch.UserInfo{
    
    private String password;
    private String passPhrase;

    public SUserInfo(String password, String passPhrase) {
        this.password = password;
        this.passPhrase = passPhrase;
    }

    @Override
    public String getPassphrase() {
        return passPhrase;
    }
 
    @Override
    public String getPassword() {
        return password;
    }
 
    @Override
    public boolean promptPassphrase(String arg0) {
        return true;
    }
 
    @Override
    public boolean promptPassword(String arg0) {
        return false;
    }
 
    @Override
    public boolean promptYesNo(String arg0) {
        return true;
    }
 
    @Override
    public void showMessage(String arg0) {
        System.out.println("SUserInfo.showMessage()");
    }
}
---
Una vez con esto podemos iniciar la conexión.

Abrimos el canal con la instancia:

ChannelSftp canal = (ChanelSftp) session.openchanel("");

canal.connect();

Inicializamos el archivo mediante un File, (nota: los comandos en ChannelSftp son muy similares a los de la linea de comandos de windows ) nos ubicamos en la carpeta donde quedara el archivo mediante el codigo
sftp.cd( rutafinal );
Y al final escribimos el archivo pasando el File, en conjunto con el nombre del archivo ( este ultimo es un String, para finalizar es necesario cerrar y desconectar el canal al igual que la sesión


De esta forma es como agregamos el archivo que queremos en el servidor.

Por el momento es todo, nos vemos en la próxima entrega para ver como extraer un archivo desde el servidor y depositario en una ruta en especifico.

ForEach en javaScript

Buen día a todos.

Así como en javaScript existe el ForEach en java su similar no se llama ForEach o Each como normalente se llamaría, en java se invoca igual que un for normal solo que la declaración de las variables cambia esto se ve reflejado de la siguiente manera,


ForEach:


String[] semana = { "lun","mar","mie","jue","vie","sab","dom" };

for( String sem: semana ){
   System.out.println( sem );
}

Suponiendo que tenemos una clase con los siguientes datos:

class Datos{
   String nombre;
   int edad;
   String ciudad;
}

Con sus respectivos set's y get's, ahora hemos creado una lista del tipo Datos la cual contiene n... cantidad de registros y lo que quieres es recorrerla, el ciclo queda de esta manera.


List listita; // ya la tienes seteada con su respectiva información.

for( Datos dato: listita ){
   System.out.println( dato.getNombre() + " " + dato.getEdad() + " " + dato.getCiudad() );
}


En cuanto al uso de un foreach recomiendo mas solo cuando se trata de recorrer un conjunto de datos ya sea un array o bien una lista, el punto aquí es que si solo se requiere recorrer.

Por otro lado tal vez te preguntas como es que le haces para salir de un ciclo como esto, bueno el código para finalizar es con un break; quedando así


for( String sem: semana ){
   if( sem.equals( "mie" ) ){
      break;
   }
}

Por hoy es todo. Espero les aya servido de algo, si es así, deja tu comentario, si algo se me paso, de igual manera deja tu comentario. si tienes alguna duda espero poder ayudarte.


saludos y hasta la proxima;

miércoles, 22 de mayo de 2019

ssh server-cliente

Buen día a todos, les quiero compartir algo que me acaba de pasar hace un momento.

Resulta que se trata de la configuración de un ssh ( Secury Shell ó shell seguro ) en linux, recientemente tuve que configurarlo, es por ello que les comparto esta experiencia...

La configuración es mas sencillo de lo que parece.

Para instalarlo es el siguiente comando.

En Ubuntu:

sudo apt-get install openssh-server


En Fedora:

yum install openssh-server


Una vez instalado es necesario iniciar el servicio, el comando es el siguiente.


En Ubuntu:

sudo /etc/init.d/ssh start


En Fedora:

systemctl start sshd


De esta manera queda activo el servicio ssh para poder acceder al equipo desde un servicio remoto como puede ser putty o bien desde otra maquina con linux.

Los comando ahora para acceder son.

ssh -p 22 usuario@ip


Accediendo con la contraseña del equipo remoto y listo, tienes acceso ssh al equipo o servidor.



Bueno eso es todo por hoy,

No olvides dejar tu comentario y te espero a la proxima.

martes, 21 de mayo de 2019

MMORPG --> Modificaciones a Principal, ThreadServidor

Con el avance hasta ahora solo tenemos una vista estática, hace falta hacer unos cambios que permitan estar a la espera en cada momento de cualquier cosa que manden los usuarios, para ello creamos un método llamado runServer al igual que un método llamado log que recibirá un parámetro tipo varargs  no es espanten, después explico de que trata.

Por ahora solo modificaremos las clases Principal y ThreadServidor dejando el código de la siguiente manera.

Agregando el método log a la clase Principal.

    public void log(Object... msg){
        for( Object sg: msg){
            txtMostrar.append( sg.toString() );
            txtMostrar.append( "\t" );
        }
        txtMostrar.append("\n");
    }


Este método servirá para mostrar en la ventana del servidor los mensajes del thread o de cualquier otro lado que queramos mostrar solo con la linea Servidor.log( "mensaje",valorVariable,"mensaje");

Por otro lado tenemos el método runServer a la clase Principal, quedando de la siguiente manera.



    public void runServer(){
        ServerSocket serv1;
        ServerSocket serv2;
        try{
            serv1 = new ServerSocket( 5555 );
            serv2 = new ServerSocket( 4445 );
            log( "se espseran clientes" );
            while( isRunning ){
                Socket socket1;
                Socket socket2;
                try{
                    log( "Esperando usuarios");
                    socket1 = serv1.accept();
                    socket2 = serv2.accept();
                }catch(IOException e ){
                    log( "Error en while:",e.getMessage());
                    continue;
                }
                ThreadServidor usr = new ThreadServidor( socket1, socket2, this );
                usr.start();
            }
        } catch (IOException ex) {
            log( "Error en runServer" , ex.getMessage() );
        }
    }


De esta manera se abren los sockets en los puertos 5555 y 4445 en mi caso son los puertos que tengo habilitados, ( no entro en detalle con lo de puertos ya que redes todavía no es mi campo ).

En el lado de ThreadServidor reemplazamos los System.out.println por un servidor.log() por ejemplo en el construcotr de ThreadServidor

antes: System.out.println("Added customer waithing for login: " + sClient_1 + " " + sClient_2 );
despues: servidor.log("Added customer waithing for login: ",sClient_1,sClient_2 );



Sin mas por el momento es todo por hoy.

Te pido respondas estas preguntas en la sección de comentarios
¿Que tal te a parecido el blog hasta ahora?
¿Te ah servido la información ?
¿Esto es nuevo para ti?
¿Tienes algún tema que requieras ayuda?

Esto me ayudará a conocerte mas y saber de que temas hablar mas adelante.
Suscribete y nos leemos mas tarde.

lunes, 20 de mayo de 2019

MMORPG -- > main

Siguiendo con el proceso de lo anterior, del lado del servidor, se me hizo cordial el hacer una vista mas amigable para la lectura del estado de los usuarios,

Hasta este momento solo se agregan unos cambios a la clase ThreadServidor y se agrega una clase llamada Principal, que, Como su nombre lo indica, sera esta nuestra clase principal...

Tambien por otro lado se cambio el nombre del paquete [ de: com.inovania.cliente.mmorpg, a: com.inovania.server.mmorpg ] ya que dichos archivos son parte del server y no del cliente.

El código de la clase principal queda de la siguiente manera:

import com.inovania.server.mmorpg_proyect.hilo.ThreadServidor;
import com.inovania.server.mmorpg_proyect.pojo.Usuario;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.ListSelectionEvent;

public class Principal extends JFrame{
    JTextArea txtMostrar;
    JTextArea txtMensajeServer;
    
    public JList lstUsuarios;
    public static void main(String[] args) {
        Principal app = new Principal();
    }
    private void init(){
        this.setSize(625,555);
        this.setTitle("Cliente Servidor MMORPG");
        this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        this.setLayout( null );
        
        txtMostrar = new JTextArea();
        JScrollPane jsp1 = new JScrollPane( txtMostrar );
        jsp1.setBounds( 5,5, 400, 400 );
        this.add( jsp1 );
        
        txtMensajeServer = new JTextArea();
        JScrollPane jsp2 = new JScrollPane( txtMensajeServer );
        jsp2.setBounds( 5, 410, 600, 100 );
        this.add( jsp2 );
        
        lstUsuarios = new JList( new ThreadServidor().getUsuarios() );
        lstUsuarios.setBounds( 410, 5,192,400 );
        lstUsuarios.addListSelectionListener( ( ListSelectionEvent e ) -> {
            if( e.getValueIsAdjusting() ){
                Usuario usr = ( Usuario ) ( (JList) e.getSource() )
                        .getSelectedValue();
                System.out.println("usuario seleccionado " + 
                        usr.getUserName() + " " + usr.getIp_Client() );
            }
        });
        this.add( lstUsuarios );
        
        this.setVisible( true );
        
    }
    public Principal(){
        init();
    }

Tambien en este punto hemos modificado el código de ThreadServidor agregando un método mas, el siguiente.

    /**
     * cargara los usuarios conectados y los mostrara en la lista en la 
     * pantalla del servidor
     * @return
     */
    public DefaultListModel getUsuarios() {
        DefaultListModel rtn = new DefaultListModel<>();
        Usuario usr = new Usuario();
        usr.setUserName("usuarioNuevo");
        usr.setIp_Client("192.0.0.2");
        usr.setNickName("El primero");
        usr.setPassword("encriptada");
        rtn.addElement( usr );
        return rtn;
    }



Sin mas por ahora quedamos hasta ---->. <--- este punto.

No olvides Dejar tu comentario y seguirme para poder continuar con este proyecto juntos.


Multi Masive Online Rol Player Game ( MMORPG )

Así como lo leen.

Se trata de un pequeño proyecto que da inicio a un mmorpg, con la finalidad de que esto sea solo un pequeño paso para algo mas grande mas adelante...

Comenzaremos con la conexión de dos computadoras e iniciar el juego, posteriormente agregaremos a mas usuarios hasta llegar hacer un pequeño torneo con eliminación y un ganador por posición.

Este proyecto se conectará por medio de sockets en java ( obviamente ), comenzando con un thread que se encargara de crear un gestionar a los usuarios. Este Thread comienza por crear un nuevo hilo cada vez que se conecta un usuario, a su vez actualiza la lista de usuarios, la cual incluye. UserName, IP_Client, NickName, Password.  ( lo se, lo se, están en ingles las variables,  ( ¬.¬ ) es por que suenan mejor ), de esta manera tenemos ya dos archivos que crear, Usuario ( POJO, por sus siglas en ingles Plain Old Java Object ) y por otro lado el threadServer que será quien gestione.

De esta manera queda Usuario.java

public class Usuario {
    private String userName;
    private String ip_Client;
    private String nickName;
    private String password;

    @Override
    public String toString() {
        return "userName: " + userName;
    }

    /**
     * @return the userName
     */
    public String getUserName() {
        return userName;
    }

    /**
     * @param userName the userName to set
     */
    public void setUserName(String userName) {
        this.userName = userName;
    }

    /**
     * @return the ip_Client
     */
    public String getIp_Client() {
        return ip_Client;
    }

    /**
     * @param ip_Client the ip_Client to set
     */
    public void setIp_Client(String ip_Client) {
        this.ip_Client = ip_Client;
    }

    /**
     * @return the nickName
     */
    public String getNickName() {
        return nickName;
    }

    /**
     * @param nickName the nickName to set
     */
    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    /**
     * @return the password
     */
    public String getPassword() {
        return password;
    }

    /**
     * @param password the password to set
     */
    public void setPassword(String password) {
        this.password = password;
    }
    
}


Por otro lado el ThreadServidor.java quedara de la siguiente manera

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class ThreadServidor extends Thread {
    Socket sClient_1 = null;
    Socket sClient_2 = null;
    DataInputStream entrada = null;
    public DataOutputStream salida_1 = null;
    public DataOutputStream salida_2 = null;
    
    List clientesActivos = new ArrayList<>();
    
    /**
     * Constructor de la clase, se inicializan los sockets y se construyen 
     * los hilos cliente por cliente
     * @param sClient_1
     * @param sClient_2
     */
    public ThreadServidor( Socket sClient_1, Socket sClient_2 ){
        this.sClient_1 = sClient_1;
        this.sClient_2 = sClient_2;
        clientesActivos.add( this );
        System.out.println("Added customer waithing for login: " + 
                sClient_1 + "\t" +
                sClient_2 );
    }
    /**
     * Metodo run de la clase Thread.
     */
    @Override
    public void run(){
        System.out.println(".:: Esperando actividad ::.");
        try{
            entrada = new DataInputStream( sClient_1.getInputStream() );
            salida_1 = new DataOutputStream( sClient_1.getOutputStream() );
            salida_2 = new DataOutputStream( sClient_2.getOutputStream() );
            System.out.println( entrada.readUTF() );
            
        }catch( IOException ex ){
            System.out.println("Connection exit: " + ex.getMessage() );
            this.stop();
        }
        /*
         * en esta parte, se gestiona la interaccion del usuario con el servidor
         */
    }
}



Por el momento estas clases estarán cambiando con forme avance el proyecto.

No olvides dejar tus comentarios, seguirme en este blog para estar al tanto de como sigue este proyecto y muchos mas.

Nos vemos en la proxima entrada...

martes, 14 de mayo de 2019

Conteo 3 - 2 - 1 go

Buen ( día, tarde, noche ) a todos. primero que nada gracias por seguir aquí con migo,

Esta vez les mostrare lo ultimo hasta el momento... un conteo regresivo de 3, 2, 1 para el comienzo de cualquier programa... cabe mencionar que carece de diseño. eso se los dejo a su criterio.

Comencemos.

public class Principal extends JFrame implements Runnable{

   String v = "3";
   public Principal(){ init(); }

   publi final void init(){
      this.setTitle( "" ); //opcional
      this.setVisible( true );
      this.setSize( 400, 400 );
      this.setLocationRelativeTo( null );
      this.setundecorate( true ); //la magia del no borders
      run();
   }

   @Override
   public void run(){
      while( true ){
         try{
            Thread.sleep( 1000 );
            if( Integer.parseInt( v ) > 1 ){
               removeAll();
               repaint();
               v = "" + ( Integer.parseInt( v ) - 1 );
            }else{
               System.exit( 0 );//en vez de finalizar el sistema se agrega aqui el llamado o la invocacion de la siguiente aplicacion
            }
         }catch( InterruptedException e ){
            System.err.println( e.getMessage() );
         }
      }
   }
   
   @Override
   public void  paint( Graphics g ){
      Graphics2D g2 = ( Graphics2D ) g;

      g2.setColor( Color.GRAY );
      g2.fillRowndRect( 0, 0, 100, 105, 5, 5 );

      g2.setColor( Color.WHITE );
      g2.setFont( new Font( "Arial Black", 1, 120 );
      g2.drawString( v, 10, 100 );
   }

   public static void main( String[] args ){
      Principal app = new Principal();
   }

}


Explicación:

En el método init() se agrego la linea this.setUndecorated( true ); esta linea es la encargada de quitar los margenes y botones de maximizar, minimizar y cerrar, es por ello que dicha linea del código hace la magia del programa.

Por otro lado el programa solo se encarga de crear un thread deteniéndolo cada segundo al momento se reduce la cantidad a mostrar, limpiando y repintando la nueva cantidad.


Sin mas por el momento es así como queda este código es algo rápido y fácil de agregar, no te olvides de dejar tus comentarios en la parte de abajo y continuar con ello mas adelante.

Tan bien puedes dejar tu solicitud de cualquier cosa en java, php, javascript que desees te ayude a buscar la solución.

Sígueme para ser el primero en tener mi próxima publicación.


lunes, 13 de mayo de 2019

Pasar un array de java a Nested

Buenos días, tardes, noches.

Este día les traigo la creacion de un nuevo desarrollo el cual se trata de el paso de informacion de java a Oracle, usando del lado de Oracle lo que se conoce como Nested Table del cual encuentran mas informacion aquí.

Dejando a un lado la estructura de la tabla en Oracle, nos vamos directo al código en el lado de Java.


He creado la siguiente estructura, una clase Pojo, una clase Dao y por ultimo una clase Library, empezando por el Pojo tenemos lo siguiente.

public class ObjetoPojo{

    // creamos la clase que servira de estructura para los valores que se envian y reciben

    // con su respectivo constructor

    private int clave = 0;

    private String valor = "N/A";

    public ObjetoPOJO(int clave, String valor){

        this.clave = clave;

        this.valor = valor;

    }

    public int getClave() {

        return clave;

    }



    public void setClave(int clave) {

        this.clave = clave;

    }



    public String getValor() {

        return valor;

    }



    public void setValor(String valor) {

        this.valor = valor;

    }

 

}

pasando a la clase Dao quedaria de la siguiente manera

 
public class conexionDao {
    // el metodo pasaNestedPrueba: cuenta con un parametro del tipo lista< ObjetoPOJO>

    public ListpasaNestedPrueba(List item) {
        /*
        * se crea una varible para el retorno
         */
        List adds = new ArrayList<>();
        try {
            /*
             * se crean los descriptores para la estructura y el arreglo que llevara la informacion a la tabla en base de datos y al final se prepara la llamada al procedimiento almacenado
             */ 
            conecta();
            StructDescriptor desc2 = StructDescriptor.createDescriptor("TABLA_STRUCT", conexion);
            ArrayDescriptor des = ArrayDescriptor.createDescriptor("TABLA_DATA", conexion);
            CallableStatement st = conexion.prepareCall("call schema.package.procedure( ? , ? )");

            /*
             * se necesita de un arreglo de objetos, en este caso lo creamos a la longitud de la lista que recibimos, al igual que el arreglo que posteriormente se pasara a la base
             */ 
            Object[] itemAtributes = new Object[item.size()];
            STRUCT itemObject = null;
            STRUCT[] idsArray = new STRUCT[item.size()];

            /*
             * recorremos la lista que pasa como parametro y llenamos instantáneamente el arreglo de tipo Objeto , para asignarlo a la estructura y agregarlo al arreglo final.
             */
            for (int i = 0; i < item.size(); i++) {
                itemAtributes = new Object[]{
                    item.get(i).getClave(),
                    item.get(i).getValor()
                };
                itemObject = new STRUCT(desc2, conexion, itemAtributes);
                idsArray[i] = itemObject;
            }

            /*
             * creamos un ARRAY del tipo oracle.sql.ARRAY pasandole el arreglo de objetos estructurados
             */
            ARRAY array_to_pass = new ARRAY(des, conexion, idsArray);

            /*
             * seteamos los parametros de la llamada
             */
            st.setArray(1, array_to_pass);
            st.registerOutParameter(2, OracleTypes.CURSOR);
            st.executeQuery();
            /*
             *     despues de haber ejecutado el comando en oracle recorremos el set de resultados y asignamos los valores otenidos en la variable retorno
             */
            ResultSet rs = (ResultSet) st.getObject(2);

            while (rs.next()) {
                ObjetoPOJO _consulta = new ObjetoPOJO();

                _consulta.setClave(rs.getInt("clave"));
                _consulta.setValor(rs.getString("valor"));

                adds.add(_consulta);
            }
            desconecta();

        } catch (SQLException e) {
            System.err.println("Exception in Method DAO: " + e);
        } finally {
            desconecta();
        }
        return adds;
    }
}


ahora vamos a la clase library

 
public class ConexionNestedLibrary {

    /*
     * este metodo asigna los valores a una lista que sera enviada al Dao
     * para su guardado en la base,
     * llenando 100 elementos y posteriormente recibidos 
     */
    public void estableseMatriz() {
        List lista = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            ObjetoPOJO _item = new ObjetoPOJO(i + 1, "Dato: " + i + " : con valor " + (i + 1));
            lista.add(_item);
        }
        ConexionNestedDAO cnd = new ConexionNestedDAO();

        List recibido = cnd.pasaNestedPrueba(lista);
        for (int i = 0; i < recibido.size(); i++) {
            System.out.println("Clavedel producto: " + recibido.get(i).getClave()
                    + " con valor: " + recibido.get(i).getValor());
        }
    }
}



Una vez finalizado el ejercicio no me queda mas que esperar sus comentarios, sean buenos o malos, aquí los espero... hasta pronto y buen día.


domingo, 12 de mayo de 2019

Creacion de alarma en java parte 3

Continuando con lo anterior...

La clase setAlarma se encargara de la construcción de una ventana en la se pueda seleccionar la hora, minuto y segundo de un respectivo dropdown.

Sin mas el codigo esta aquí.


---
import com.alarma.Principal;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;

public final class SetAlarma extends JFrame implements ActionListener {

    private JComboBox hora;
    private JComboBox minutos;
    private JComboBox segundos;
    Principal p;
    
    public SetAlarma(Principal p) {
        this.p = p;
        elements();
    }

    public void elements() {
        this.setTitle("Seteo de alarma");
        this.setSize(300, 100);
        this.setLayout(null);
        this.setResizable(false);
        this.setLocationRelativeTo(null);

        hora = new JComboBox();
        minutos = new JComboBox();
        segundos = new JComboBox();
        for (int i = 0; i < 24; i++) {
            if (i < 10) {
                hora.addItem("0" + i);
            } else {
                hora.addItem(i + "");
            }
        }
        for (int i = 0; i < 60; i++) {
            if (i < 10) {
                minutos.addItem("0" + i);
                segundos.addItem("0" + i);
            } else {
                minutos.addItem(i + "");
                segundos.addItem(i + "");
            }
        }
        hora.addActionListener(this);
        hora.setActionCommand("hora");
        minutos.addActionListener(this);
        minutos.setActionCommand("minuto");
        segundos.addActionListener(this);
        segundos.setActionCommand("segundo");
        if( p._hora>-1 ){
            String h = "";
            if( p._hora < 10 ){h = "0"+p._hora;}else{ h = p._hora + "";}
            hora.setSelectedItem(h);
        }
        if( p._minuto>-1 ){
            String m = "";
            if( p._minuto < 10 ){m = "0"+p._minuto;}else{ m = p._minuto + "";}
            minutos.setSelectedItem(m);
        }
        if( p._segundo>-1 ){
            String s = "";
            if( p._segundo < 10 ){s= "0"+p._segundo;}else{ s= p._segundo + "";}
            segundos.setSelectedItem(s);
        }
        hora.setBounds(5, 5, 50, 25);
        minutos.setBounds(60, 5, 50, 25);
        segundos.setBounds(115, 5, 50, 25);
        this.add(hora);
        this.add(minutos);
        this.add(segundos);

        this.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if( "hora".equals(e.getActionCommand() ) ){
            p._hora = Integer.parseInt( hora.getSelectedItem().toString() );
        }
        if( "minuto".equals(e.getActionCommand() ) ){
            p._minuto = Integer.parseInt( minutos.getSelectedItem().toString() );
        }
        if( "segundo".equals(e.getActionCommand() ) ){
            p._segundo = Integer.parseInt( segundos.getSelectedItem().toString() );
        }
    }

}

---

vallamos a la explicación

vamonos directo a la accion...
En la construccion de el cada uno de los elementos en esta ventana. creamos un ciclo para llenar dichos espacios, por ejemplo.  para la hora. creamos el ciclo que va de 0 a 23, para generar un horario extendido de 24 horas considerando las 12:00 pm como las 00:00 pm. con esto hay que espesificar que todo valor menor a 10 es necesario agregar un 0 al comienzo de la cadena. Por otro lado construimos otro ciclo, el cual ira del 0 al 59, para crear tanto los minutos como los segundos., de igual manera  los primeros numeros menores a 10 se les agrega un 0 al comienzo de la cadena.


Seguido de esto es necesrio validar si se tiene seteada una hora en particular para asi inicializar los componentes con un valor en espesifico.

Para finalizar se agregan los action listener a cada uno de estos componentes.

En el ActionEvent los distinguimos por el actionCommand que se agrego a cada uno... así al seleccionar un valor se setea el valor a cada correspondiente variable.

De esta manera quedan seteadas las variables correspondientes.


No te olvides de dejar tu comentario.

Si eres usuario de blogger. No te olvides de seguirme y asi poder finalizar esta aplicacion.

jueves, 9 de mayo de 2019

Creacion de alarma en Java Parte 2

En continuidad con lo anterior, veremos la creación de las operaciones en la cual aremos el seteo de las horas, minutos y segundos  junto con la fecha...

En este código lo que are sera en primera instancia el get de la hora del sistema para setear el label de la vista.

El código queda así.
---
public class Operations implements Runnable{
 Principal p;

 public Operations( Principal p ){
  this.p = p;
 }

 public void getHora(){
  run();
 }

 @Override
 public void run(){
   Calendar calen = Calendar.getInstance();
        long lastTime = System.nanoTime();
        double unprocessed = 0;
        double nsPerTick = 1000000000.0/60;
        int frames = 0;
        int ticks = 0;
        long lastTimer1 = System.currentTimeMillis();
        while( true ){
            long now = System.nanoTime();
            unprocessed += ( now - lastTime) / nsPerTick;
            lastTime = now;
            boolean shouldRender = true;
            while( unprocessed >= 1 ){
                ticks ++;
                unprocessed -= 1;
                shouldRender = true;
            }
            try{
                Thread.sleep( 2 );
            }catch( InterruptedException e ){
                System.err.println( e.getMessage() );
            }
            if( shouldRender ){
                frames ++;
                calen = Calendar.getInstance();
                p.lblReloj.setText( fechaActual(calen) );
    /*+ ":" +  calen.get(Calendar.MILLISECOND)*/
            }
            if( System.currentTimeMillis() - lastTimer1 > 1000 ){
                System.out.println( "Frames & ticks [ " + frames + "," + ticks + "]");
                lastTimer1 += 1000;
                frames = 0;
                ticks = 0;
            }
        }
 }
    public String fechaActual(Calendar calen ){
        String dia =  calen.get( Calendar.DAY_OF_MONTH ) +""; dia = ( Integer.parseInt( dia ) < 10 )? "0" + dia: dia;
        String mes =  calen.get( Calendar.MONTH ) +""; mes = ( Integer.parseInt( mes ) < 10 )? "0" + mes: mes;
        int hora_ = calen.get(Calendar.HOUR_OF_DAY );
        int minuto_ = calen.get( Calendar.MINUTE );
        int segundo_ = calen.get( Calendar.SECOND );
        String fecha = dias(calen.get( Calendar.DAY_OF_WEEK) ) + " " + 
            dia + " de " + 
            mesAn( Integer.parseInt( mes ) ) + " del " + 
            calen.get( Calendar.YEAR ) + " " +
            hora_ + ":" + minuto_+":" + segundo_ ;

        if( p.chkActive.isSelected() ){
            if( p._hora > -1 && p._minuto > -1 && p._segundo > -1 ){
                if ((hora_ == p._hora) && (minuto_ == p._minuto) && (segundo_ == p._segundo)) {
                    if (!p.estaSonando) {
                        new SoundClipTest();
                    }
                    p.estaSonando = true;
                }
            }
        }
        return fecha;
    }
    public String dias(int dia ){
        String[] semana = { "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo" };
        return semana[ dia ];
    }
    public String mesAn( int mes ){
        String[] mesAnio = { "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre" };
        return mesAnio[ mes ];
    }
    class SoundClipTest extends JFrame implements ActionListener{
        JButton btnPause = new JButton("Pause");
        public SoundClipTest() {
                this.setTitle("Test Sound Clip");
                this.setSize(300, 200);
                this.setVisible(true);
                this.setLayout(null);
                
                btnPause.setBounds(5,5,100,25);
                btnPause.setActionCommand("pause");
                btnPause.addActionListener(this);
                this.add(btnPause);
                play();
        }
        public void play(){
            reproduce();
        }
        AudioClip s;
        public void reproduce(){
            
            try {
                File f = new File("a1.wav");
                if (f.exists()) {
                    System.out.println("validando que el archivo exista");
                }
                URL url = f.toURL();
                s = Applet.newAudioClip(url);
                s.play();
            } catch (MalformedURLException ex) {
                Logger.getLogger(Operations.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if( "pause".equals(e.getActionCommand())){
                s.stop();
                btnPause.setActionCommand( "play");
                btnPause.setText("Play");
            }
            if( "play".equals(e.getActionCommand())){
                s.play();
                btnPause.setActionCommand( "pause");
                btnPause.setText("Pause");
            }
            
        }
    }

}
---
Explicaciones...
Principal p;

 public Operations( Principal p ){
  this.p = p;
 }
Es necesario hacer una instancia de la clase principal, para poder acceder a sus
propiedaddes y sus elementos.
 public void getHora(){
  run();
 }

El método getHora() inicia el thread que estará seteando la hora cada segundo.


 @Override
 public void run(){
   Calendar calen = Calendar.getInstance();
        long lastTime = System.nanoTime();
        double unprocessed = 0;
        double nsPerTick = 1000000000.0/60;
        int frames = 0;
        int ticks = 0;
        long lastTimer1 = System.currentTimeMillis();
        while( true ){
            long now = System.nanoTime();
            unprocessed += ( now - lastTime) / nsPerTick;
            lastTime = now;
            boolean shouldRender = true;
            while( unprocessed >= 1 ){
                ticks ++;
                unprocessed -= 1;
                shouldRender = true;
            }
            try{
                Thread.sleep( 2 );
            }catch( InterruptedException e ){
                System.err.println( e.getMessage() );
            }
            if( shouldRender ){
                frames ++;
                calen = Calendar.getInstance();
                p.lblReloj.setText( fechaActual(calen) );
    /*+ ":" +  calen.get(Calendar.MILLISECOND)*/
            }
            if( System.currentTimeMillis() - lastTimer1 > 1000 ){
                System.out.println( "Frames & ticks [ " + frames + "," + ticks + "]");
                lastTimer1 += 1000;
                frames = 0;
                ticks = 0;
            }
        }
 }

El método run() se encarga de construir el thread y reproducirlo cada determinado tiempo...
para ello se ocupa el nanotiempo del sistema mostrando frames y ticks cada segundo.


Nota: Este método lo tengo agregado en un proyecto diferente ( un juego ) es por ello
que tiene las variables de frames y ticks.



    public String fechaActual(Calendar calen ){
        String dia =  calen.get( Calendar.DAY_OF_MONTH ) +""; dia = ( Integer.parseInt( dia ) < 10 )? "0" + dia: dia;
        String mes =  calen.get( Calendar.MONTH ) +""; mes = ( Integer.parseInt( mes ) < 10 )? "0" + mes: mes;
        int hora_ = calen.get(Calendar.HOUR_OF_DAY );
        int minuto_ = calen.get( Calendar.MINUTE );
        int segundo_ = calen.get( Calendar.SECOND );
        String fecha = dias(calen.get( Calendar.DAY_OF_WEEK) ) + " " + 
            dia + " de " + 
            mesAn( Integer.parseInt( mes ) ) + " del " + 
            calen.get( Calendar.YEAR ) + " " +
            hora_ + ":" + minuto_+":" + segundo_ ;

        if( p.chkActive.isSelected() ){
            if( p._hora > -1 && p._minuto > -1 && p._segundo > -1 ){
                if( ( hora_ == p._hora ) && (minuto_ == p._minuto) && (segundo_ == p._segundo) ){
                    System.out.println( "esta sonando" );
                    p.estaSonando = !true;
                }
            }
        }
        return fecha;
    }
El metodo fechaActual( calendar calen ) se encarga de extraer lo necesario para crear
el string que se mostrara en el label del reloj.

Nota: Por el momento es un string seteado manualmente mas adelante lo que are sera agregar un date Format



    public String dias(int dia ){
        String[] semana = { "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo" };
        return semana[ dia ];
    }
    public String mesAn( int mes ){
        String[] mesAnio = { "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre" };
        return mesAnio[ mes ];
    }

Por ultimo los metodos dias y mesAn se encargan de cambiar el dia y el mes de un entero a un string con su respectiva descripción...



Con esto finalizamos la clase Operations...

No te olvides de dejar tu comentario y seguirme para que de esta manera puedas recibir mis próximas publicaciones.


Hasta la próxima.