Aprende Java Aprende Php Aprende C++ Aprende HTML 5 Aprende JavaScript Aprende JSON Aprende MySQL Aprende SQLServer Aprende Visual Basic 6 Aprende PostgreSQL Aprende SQLite Aprende Redis Aprende Kotlin Aprende XML Aprende Linux VSC Aprende Wordpress Aprende Laravel Aprende VueJS Aprende JQuery Aprende Bootstrap Aprende Netbeans Aprende Android
Sigueme en Facebook Sigueme en Twitter Sigueme en Instagram Sigueme en Youtube Sigueme en TikTok Sigueme en Whatsapp
Home / Proyectos / Crea patrón de desbloqueo para tus app java

Crea patrón de desbloqueo para tus app java

Por jc mouse martes, marzo 8, 2016

El patrón de desbloqueo es una medida de seguridad que tienen algunos teléfonos inteligentes para evitar el acceso al dispositivo por parte de personas extrañas, este patrón consiste por lo general en una matriz 3×3 de círculos o puntos los cuales se unen con el dedo para formar el «patrón de desbloqueo«, si el patrón es correcto, se tiene acceso al dispositivo móvil, caso contrario este continuara boqueado.

Pues bien, esta manera de evitar el acceso de personas no autorizadas a un dispositivo móvil puede extrapolarse a una aplicación de escritorio e incluso porque no, a una aplicación web.

Herramientas

  • Netbeans 8.x
  • java 8

Tiempo: 20 minutos

Nivel: Intermedio – Avanzado

Paso 1. Análisis y diseño

Este sistema de bloqueo esta formado por un panel con una matriz 3×3  de figuras circulares que permiten dibujar el patrón de desbloqueo.

matrix

Cada uno de estas figuras tiene asignado un valor que debe ser único, en nuestro ejemplo valores del 1 al 9, son estos valores los que forman el patrón de desbloqueo. Cuando el usuario arrastra el dedo entre cada uno de estas figuras, internamente se va formando un código, es decir, en la imagen de abajo podemos advertir que según el movimiento que se le de al sistema, se forma un código «125895«, el código de desbloqueo del ejemplo de este post.

android bolivia

Cada elemento de la matriz es un objeto de 80×80 pixeles el cual esta conformado por un circulo externo y un circulo más pequeño en su centro, las medidas y coordenadas de cada objeto se pueden ver a continuación

circulo de confianza

Paso 2. El Proyecto

Crea un nuevo proyecto java con nombre «Unlock Pattern«, agrega la siguiente estructura:

unlock netbeans

El proyecto contiene 2 paquetes :

  • demo: Aquí colocarías tu programa principal que seria visible una vez se complete el patrón de desbloqueo.
  • unlockpattern: Como su nombre indica este paquete contendrá las clases del sistema de bloqueo

El paquete unlockpattern esta formado por las siguientes clases:

  • FigurePattern: Es la figura circular que forma la matriz 3×3
  • UnlockJFrame: El JFrame principal donde se muestra todo el sistema
  • UnlockPanel: Un JPanel donde pintar las figuras circulares e implementar los eventos del ratón para pintar el patrón de desbloqueo.

Adicionalmente hacemos uso de una imagen, no es necesaria ya que podíamos pintar su contenido directamente con java2d pero a veces la flojera nos gana 🙂 la imagen que utilizaremos esta en formato PNG de 290×93 pixeles, la imagen es la siguiente:

access denied

Paso 3. FigurePattern

Como dijimos más arriba esta clase nos pintara un par de figuras circulares a modo de botón en nuestro sistema de desbloqueo, las medidas de esta figura se indican en el paso 1, el código de la clase es:

package net.jc_mouse.unlockpattern;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
/**
 * @web https://www.jc-mouse.net/
 * @author Mouse
 */
public class FigurePattern {
    //identificador/valor de objeto (NO debe repetirse)
    private int key;
    //coordenadas
    private int x               =   0;
    private int y               =   0;  
    //bandera 
    private boolean selected    =   false;
    //area sensible a eventos del raton
    private Rectangle area      =   new Rectangle();
    
    /**Constructor de clase */
    public FigurePattern(){}
    
    /**
     * Constructor de clase
     * @param k clave de celda
     * @param x coordenada X de objeto
     * @param y coordenada Y de objeto
     */
    public FigurePattern(int k, int x, int y){
        this.key = k;
        this.x = x;
        this.y = y;
        //area interna del circulo
        area.setBounds(x+10, y+10 , 60, 60);
    }
    
    public void draw(Graphics2D g2){
        //fondo
        g2.setColor( new Color(0,0,0) );
        g2.fill( new Ellipse2D.Double(x+10, y+10 , 60, 60 ) );
        //borde exterior
        g2.setStroke(new BasicStroke( 4 ));        
        g2.setColor( (selected)?new Color(0,204,0):new Color(153,153,153) );        
        g2.draw( new Ellipse2D.Double(x+10, y+10 , 60, 60 ) );                
        //circulo interno
        g2.setColor( new Color(255,255,255) );
        g2.fill( new Ellipse2D.Double(x+30, y+30 , 20, 20 ) );        
    }

    public int getKey() {
        return key;
    }

    public void setKey(int key) {
        this.key = key;
    }
    
    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    public Rectangle getArea() {
        return area;
    }

    public void setArea(Rectangle area) {
        this.area = area;
    }
    
    /**
     * retorna el punto medio de la figura
     * @return Point
     */
    public Point getCenterPoint(){
        Point p = new Point( x+40, y+40);
        return p;
    }
    
    /**
     * Metodo statico que determina su un punto se encuentra dentro un area rectangular
     * @param r rectangle
     * @param p point
     * @return boolean
     */
    public static boolean insideArea(Rectangle r,Point p) {            
        return r.contains(p);            
    }
    
}//end:FigurePattern

Paso 4.  UnlockPanel

Esta clase que desciende de un JPanel sera donde se pinte la matriz con las 9 figuras circulares, así mismo implementa métodos para que el usuario pueda arrastrando el cursor del mouse dibujar el patrón de desbloqueo .

El método checkUnlockPattern()  se encarga de verificar si el patrón introducido por el usuario es correcto,de ser cierto, abrirá un nuevo JFrame (tu aplicación) que en nuestro ejemplo se encuentra en el paquete «demo» y se llama «AppDemoJFrame«, caso contrario, de ser un patrón incorrecto, muestra un mensaje de error «Access denied».

package net.jc_mouse.unlockpattern;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import net.jc_mouse.demo.AppDemoJFrame;
/**
 * @web https://www.jc-mouse.net/
 * @author Mouse
 */
public class UnlockPanel extends JPanel implements MouseListener,MouseMotionListener {
        
    private JFrame parent;
    private String myKey="125895";//patron de desbloqueo
    //array para las 9 figuras que forman la matriz
    private ArrayList<FigurePattern> figurePatternArr = new ArrayList();
    //array para las figuras que conforman el patron desbloqueo
    private ArrayList<FigurePattern> pattern= new ArrayList();
    //String para guardar el patron generado por el usuario
    private String password = "";
    //para mostrar imagen de "acceso denegado"
    private final Image image = new ImageIcon(getClass().getResource("/net/jc_mouse/unlockpattern/access_denied.png")).getImage();
    private boolean showError=false;
    
    /**
     * Constructor de clas
     * @param parent JFrame que contiene el JPanel
     */
    public UnlockPanel(JFrame parent){                
        this.parent = parent;
        //se agregan 9 circulos al contenedor
        figurePatternArr.add(new FigurePattern(1,0,0));
        figurePatternArr.add(new FigurePattern(2,80,0));
        figurePatternArr.add(new FigurePattern(3,160,0));
        
        figurePatternArr.add(new FigurePattern(4,0,80));
        figurePatternArr.add(new FigurePattern(5,80,80));
        figurePatternArr.add(new FigurePattern(6,160,80));
        
        figurePatternArr.add(new FigurePattern(7,0,160));
        figurePatternArr.add(new FigurePattern(8,80,160));
        figurePatternArr.add(new FigurePattern(9,160,160));
        
        //Eventos del raton        
        UnlockPanel.this.addMouseListener( UnlockPanel.this );        
        UnlockPanel.this.addMouseMotionListener( UnlockPanel.this);        
    }
    
   @Override
    public void paintComponent(Graphics g){    
        Graphics2D g2 =(Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);            
        g2.setColor( new Color(0,0,0) );
        g2.fill(new Rectangle2D.Double(0,0,getWidth(),getHeight()));  
        
        //dibuja las lineas del patron de desbloqueo entre los circulos
        Point point = null;
        for(FigurePattern figurePattern: pattern){
            g2.setStroke( new BasicStroke( 20 ) );
            g2.setColor( new Color(204,204,204) );
            if(point!=null)
                g2.drawLine(point.x, point.y, figurePattern.getCenterPoint().x, figurePattern.getCenterPoint().y);  
             point = figurePattern.getCenterPoint();            
        }
        
        //dibuja los circulos para los patrones de desbloqueo       
        if(figurePatternArr!=null)
            figurePatternArr.stream().forEach((b) -> {
                b.draw(g2);
        });  
        
        //muestra error 
        if(showError){
            g2.drawImage(image, (getWidth()-220)/2, (getHeight()-93)/2, 220, 93, null);         
        }        
    }

    @Override
    public void mouseClicked(MouseEvent e) {}

    @Override
    public void mousePressed(MouseEvent e) {}

    @Override
    public void mouseReleased(MouseEvent e) {      
        checkUnlockPattern();
    }

    @Override
    public void mouseEntered(MouseEvent e) {}

    @Override
    public void mouseExited(MouseEvent e) {}

    @Override
    public void mouseDragged(MouseEvent e) {
        //cuando se arrastra el cursor del mouse
        figurePatternArr.stream().filter((p) -> ( 
            FigurePattern.insideArea(p.getArea(),e.getPoint()) )).forEach((p) -> {
            if(this.pattern.isEmpty()){//Si esta vacio se añade objeto
                pattern.add(p);//añade a array
                p.setSelected(true);//cambia color
                password +=p.getKey();//concatena valor de figura
            }else{//Si ya existen objetos en el array
                //se comprueba que objeto nuevo no se repita con el ultimo añadido
                if(pattern.get(pattern.size()-1).getKey() != p.getKey()){
                    pattern.add(p);//añade a array
                    p.setSelected(true);//cambia color
                    password +=p.getKey(); //concatena valor de figura
                }
            }
        });
        repaint();
    }

    @Override
    public void mouseMoved(MouseEvent e) { showError=false; repaint();}
    
    /**
     * metodo para comprobar que patron de desbloqueo es correcto
     * de ser asi -> abre nuevo formulario
     * caso contrario -> muestra mensaje de error
     */
    public void checkUnlockPattern(){
        if(password.equals(myKey)){//si patron de desbloqueo es correcto
            parent.setVisible(false);//se oculta 
            //se muestra aplicacion cliente
            AppDemoJFrame app = new AppDemoJFrame();
            app.setVisible(true);
        }else{            
            showError=true;
        }
        pattern.clear();//limpia movimientos antiguos
        password="";//resetea password
        //reinicia valor para objetos
        figurePatternArr.stream().forEach((b) -> {
            b.setSelected(false);
        });
        repaint();
    }
    
}//end

Paso 5. UnlockJFrame

Para terminar el tutorial, el panel creado en el paso 4, debemos añadirlo a un JFrame para poder ejecutarlo, la clase queda de la siguiente forma:

package net.jc_mouse.unlockpattern;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
/**
 * @web https://www.jc-mouse.net/
 * @author Mouse
 */
public class UnlockJFrame extends JFrame {

    private UnlockPanel unlockPanel;

    /**Constructor de clase*/
    public UnlockJFrame(){
        initComponents();
        UnlockJFrame.this.setLocationRelativeTo(null);
    }
    
    private void initComponents() {        
        setTitle("Unlock Pattern");
        setResizable(false);
        setSize(new Dimension(246,280));
        setPreferredSize(new Dimension(246,280));
        unlockPanel = new UnlockPanel(this);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);        
        getContentPane().add(unlockPanel);
        pack();
    }
    
    public static void main(String args[]){
        EventQueue.invokeLater(() -> {
            new UnlockJFrame().setVisible(true);
        });
    }
    
}

Ejecutamos y probamos, no olvides el patrón de desbloqueo es «125895»

desbloqueo android

Código fuente: <<enlace pobre>>

enjoy!!!

Tags

Artículos similares

Crear PopupMenu (Ventana Emergente)

En este tutorial crearemos una aplicación android que nos permitirá abrir un PopupMenu de donde podremos seleccionar una[...]

SwingWorker con base de datos

Cuando se realizan aplicaciones en java con base de datos y se llega a un punto donde es necesario realizar una consulta[...]

Cascadia Code: la nueva fuente OpenSource de Microsoft

Microsoft acaba de lanzar Cascadia Code una fuente monoespaciada enfocada en proporcionar una mejor experiencia en conso[...]

Conexión a múltiples bases de datos en Laravel

En este tutorial conoceremos una forma de conectar una aplicación en Laravel con tres bases de datos diferentes, 2 en My[...]

Ejercicio resuelto: Personalizar JTable

PROBLEMA: Se tiene un JTable con 19 columnas y 50 registros, se desea personalizar el JTable de la siguiente manera:[...]

Introducción a la internacionalización de aplicaciones

La internacionalización permite a las aplicaciones adaptarse a los diferentes idiomas y regiones sin necesidad de cambio[...]