<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4528125628115572726</id><updated>2025-12-07T21:45:39.289-05:00</updated><category term="Java"/><category term="El Javatar"/><category term="Java Swing"/><category term="Paradigmas de Programación"/><category term="SwingUtils"/><category term="Tutorial Java"/><category term="Algoritmos"/><category term="Cpp"/><category term="Diagramas de Flujo"/><category term="C"/><category term="C-Sharp"/><category term="Core Java"/><category term="Python"/><category term="Design Patterns"/><category term="Java Collections"/><category term="Patrones de Diseño"/><category term="Pseudocodigo"/><category term="UML"/><category term="Firebird"/><category term="POO"/><category term="Programación Orientada a Objetos"/><category term="API Java"/><category term="Aplicaciones Moviles"/><category term="ArrayList"/><category term="Curso de Java Basico"/><category term="JavaScript"/><category term="Nodejs"/><title type='text'>El Javatar</title><subtitle type='html'>Blog dedicado a la Programación en Java, C, PHP, Phyton, HTML, SQL y Mucho Más</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.eljavatar.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default?start-index=26&amp;max-results=25'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>84</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-9041648612638168922</id><published>2018-04-24T19:08:00.001-05:00</published><updated>2020-06-12T12:38:19.551-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java Swing"/><category scheme="http://www.blogger.com/atom/ns#" term="SwingUtils"/><title type='text'>SwingUtils - Crear JTable Paginado o Lazy y con Filtros (Java Swing)</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
En este tutorial, aprenderemos cómo crear de forma rápida un JTable que tenga paginación dinámica, que también permita carga dinámica (lazy), y que además acepte filtros por columna; para esto haremos uso de la &lt;b&gt;librería SwingUtils&lt;/b&gt; que posee un componente llamado &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;PaginatedTable&lt;/span&gt;, el cual extiende de la clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;javax.swing.JPanel&lt;/span&gt; y que internamente hace uso de un &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;javax.swing.JTable&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2xe0rV_wBfdtcRAmHL7QiNOjsGXpaIxZpF81xbX2OT5Ior6XNMYqqDDWLECmJt2JsPeuU2vW3jGTKJt07GEoaWQvGZL8GJB6rBDe_qyqIA_Gz0ksebWP4-9KWnu3sg5t2OiUksFt02NWD/s1600/SwingUtils+-+Crear+JTable+Paginado+o+Lazy+y+con+Filtros+%2528Java+Swing%2529.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;SwingUtils - Crear JTable Paginado o Lazy y con Filtros (Java Swing)&quot; border=&quot;0&quot; data-original-height=&quot;1000&quot; data-original-width=&quot;1600&quot; height=&quot;250&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2xe0rV_wBfdtcRAmHL7QiNOjsGXpaIxZpF81xbX2OT5Ior6XNMYqqDDWLECmJt2JsPeuU2vW3jGTKJt07GEoaWQvGZL8GJB6rBDe_qyqIA_Gz0ksebWP4-9KWnu3sg5t2OiUksFt02NWD/s400/SwingUtils+-+Crear+JTable+Paginado+o+Lazy+y+con+Filtros+%2528Java+Swing%2529.png&quot; title=&quot;SwingUtils - Crear JTable Paginado o Lazy y con Filtros (Java Swing)&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Nativamente, el &lt;b&gt;API de Java Swing&lt;/b&gt; no nos permite agregarle de forma rápida un paginador a un &lt;i&gt;JTable&lt;/i&gt;, así que si queremos tener esta funcionalidad, deberíamos programarla nosotros mismos. Una forma &quot;sencilla&quot; de hacerlo es implementando un &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;TableRowSorter&lt;/span&gt;; sin embargo el problema radica cuando queremos aplicar un filtro, por ejemplo de búsqueda a nuestra tabla, ya que sería un poco complejo el actualizar nuestro paginador.&lt;br /&gt;
&lt;br /&gt;
Por eso, en la librería &lt;i&gt;&lt;u&gt;&lt;b&gt;SwingUtils&lt;/b&gt;&lt;/u&gt;&lt;/i&gt; he creado un componente llamado &lt;b&gt;PaginatedTable&lt;/b&gt; el cual está diseñado para trabajar con dos tipos de tablas paginadas. Veamos cuáles son y en qué escenarios usaríamos cada una de ellas:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;- Tablas paginadas con carga completa:&lt;/b&gt; Son aquellas que usaríamos cuando sabemos que el volumen de datos de nuestra tabla no es muy grande y podríamos cargarlos todos sin afectar de manera radical a la memoria. Con este tipo de carga, obtenemos toda la lista de datos desde el principio, y los resultados de filtros y paginación se devuelven desde esa lista inicial.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;- Tablas paginadas con carga dinámica o lazy (perezosa):&lt;/b&gt; Son aquellas que usaríamos cuando sabemos que el volumen de datos de nuestra tabla puede llegar a ser muy grande y que cargarlos todos podría causar problemas en la memoria. Con este tipo de carga, vamos obteniendo dinámicamente los datos, es decir, que sólo tenemos en memoria los datos según la paginación y filtros que tengamos aplicados en el momento.&lt;br /&gt;
&lt;br /&gt;
Ahora que sabemos en qué escenarios podemos usar el componente de paginación de tablas de SwingUtils, veamos cómo podríamos usarlo para cada uno de ellos.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Crear una Tabla Paginada o Lazy y con Filtros en Java Swing usando PaginatedTable&lt;/b&gt;&lt;/h3&gt;
Lo primero que debemos hacer es importar la librería SwingUtils a nuestro proyecto. Puedes ver las instrucciones en el siguiente enlace:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;!-- anuncios --&gt;
==&amp;gt; &lt;b&gt;&lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Libreria-de-Utilidades-para-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;SwingUtils - Librería de Utilidades para Java Swing&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Debido a la facilidad de cambiar de implementación entre tablas paginadas con carga completa y tablas paginadas con carga dinámica, el proceso que se aplica para cada uno es el mismo. La diferencia principal está en la forma en cómo obtenemos los datos para cada uno de los casos.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Así que empezamos creando la clase que usaremos como modelo de datos (bean) para nuestro ejemplo:&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;public class Persona {

    private String codigo;
    private String nombres;
    private String apellidos;
    private String direccion;
    private String telefono;
    
    public Persona() {
        // Constructor vacío por defecto
    }
    
    public Persona(String codigo, String nombres, String apellidos, String direccion, String telefono) {
        this.codigo = codigo;
        this.nombres = nombres;
        this.apellidos = apellidos;
        this.direccion = direccion;
        this.telefono = telefono;
    }
    
    public String getCodigo() {
        return codigo;
    }
    
    public void setCodigo(String codigo) {
        this.codigo = codigo;
    }
    
    public String getNombres() {
        return nombres;
    }
    
    public void setNombres(String nombres) {
        this.nombres = nombres;
    }
    
    public String getApellidos() {
        return apellidos;
    }
    
    public void setApellidos(String apellidos) {
        this.apellidos = apellidos;
    }
    
    public String getDireccion() {
        return direccion;
    }
    
    public void setDireccion(String direccion) {
        this.direccion = direccion;
    }
    
    public String getTelefono() {
        return telefono;
    }
    
    public void setTelefono(String telefono) {
        this.telefono = telefono;
    }

}
&lt;/pre&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
A continuación, creamos la clase que usaremos como TableModel de nuestro JTable, el cual extiende de la clase TableModelGeneric de la librería &lt;b&gt;SwingUtils&lt;/b&gt; tal como lo vimos en el tutorial sobre &lt;a href=&quot;http://www.eljavatar.com/2017/10/SwingUtils-Crear-JTable-con-Modelo-de-Datos-Generico-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;cómo crear un JTable con un Modelo de Datos Genérico en Java Swing&lt;/a&gt;:&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;import com.eljavatar.swingutils.core.modelcomponents.FilterMatchModeEnum;
import com.eljavatar.swingutils.core.modelcomponents.ObjectFilter;
import com.eljavatar.swingutils.core.modelcomponents.TableModelGeneric;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class TableModelGestionPersonas extends TableModelGeneric&amp;lt;Persona&amp;gt; {

    public TableModelGestionPersonas() {
        this(new ArrayList&amp;lt;&amp;gt;());
    }
    
    public TableModelGestionPersonas(List&amp;lt;Persona&amp;gt; listDatos) {
        super(
                new Class[]{String.class, String.class, String.class, String.class, String.class},
                new String[]{&quot;Código&quot;, &quot;Nombres&quot;, &quot;Apellidos&quot;, &quot;Dirección&quot;, &quot;Teléfono&quot;},
                Arrays.asList(new ObjectFilter(&quot;Código&quot;, &quot;codigo&quot;, FilterMatchModeEnum.EXACT), new ObjectFilter(&quot;Nombres&quot;, &quot;nombres&quot;, FilterMatchModeEnum.CONTAINS), new ObjectFilter(&quot;Apellidos&quot;, &quot;apellidos&quot;, FilterMatchModeEnum.CONTAINS)),
                listDatos
        );
    }
    
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        switch (columnIndex) {
            case 0:
                return getListElements().get(rowIndex).getCodigo();
            case 1:
                return getListElements().get(rowIndex).getNombres();
            case 2:
                return getListElements().get(rowIndex).getApellidos();
            case 3:
                return getListElements().get(rowIndex).getDireccion();
            case 4:
                return getListElements().get(rowIndex).getTelefono();
            default:
                return null;
        }
    }

}
&lt;/pre&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
El código de la vista sería el siguiente:&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java; ; highlight: [25, 26, 28]&quot;&gt;import com.eljavatar.swingutils.core.annotations.PaginatedTableView;
import com.eljavatar.swingutils.core.componentsutils.JTableUtils;
import com.eljavatar.swingutils.core.componentsutils.SwingComponentsUtils;
import com.eljavatar.swingutils.core.modelcomponents.LazyDataProvider;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import javax.swing.JOptionPane;

public class PersonasView extends javax.swing.JFrame {

    private final PersonasController personasController;
    
    public PersonasView() {
        initComponents();
        this.personasController = new PersonasController(this);
        setModeloTablaPersonas();
        this.personasController.listarPersonas();
    }
    
    private void setModeloTablaPersonas() {
        SwingComponentsUtils.setFontAllComponents(paginatedTablePersonas.getDataTable(), new Font(&quot;Arial&quot;, Font.PLAIN, 12));
        paginatedTablePersonas.getDataTable().setSize(600, 300);
        JTableUtils.setProperties(paginatedTablePersonas.getDataTable(), new Font(&quot;Arial&quot;, Font.BOLD, 13), new TableModelGestionPersonas(), new int[]{16, 18, 18, 34, 14});
        
        PaginationDataProvider&amp;lt;Persona&amp;gt; dataProvider = this.personasController.createDataProvider();
        //LazyDataProvider&amp;lt;Persona&amp;gt; dataProvider = this.personasController.createLazyDataProvider();
        
        paginatedTablePersonas.decorateAndSet(dataProvider, new int[]{5, 10, 20, 50, 75, 100}, 10, true, new Font(&quot;Arial&quot;, Font.PLAIN, 12));
        
        paginatedTablePersonas.getDataTable().addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(java.awt.event.MouseEvent e) {
                int fila = paginatedTablePersonas.getDataTable().rowAtPoint(e.getPoint());
                if (fila &amp;gt; -1) {
                    if (e.getClickCount() == 2) {
                        seleccionarElement(fila);
                    }
                }
            }
        });
    }
    
    private void seleccionarElement(int fila) {
        if (fila &amp;gt;= 0) {
            Persona persona = paginatedTablePersonas.getTableModelGeneric().getListElements().get(fila);
            personasController.setPersona(persona);
            personasController.mostrarPersona();
        } else {
            JOptionPane.showMessageDialog(this, &quot;Debe hacer clic en una fila para poder seleccionar un Elemento&quot;, &quot;Mensaje de Error&quot;, JOptionPane.ERROR_MESSAGE);
        }
    }
    
    private void initComponents() {
        // Código generado por NetBeans
    }
    
    @PaginatedTableView(name = &quot;listaPersonas&quot;)
    private com.eljavatar.swingutils.core.components.PaginatedTable&amp;lt;Persona&amp;gt; paginatedTablePersonas;
    
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
En este código he de recalcar 3 líneas. Las &lt;b&gt;líneas 25 y 26&lt;/b&gt; crean la implementación para cada uno de los tipos de tablas paginadas que expliqué al inicio de este tutorial. Basta sólo con comentar uno y descomentar el otro para cambiar de implementación.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
En la &lt;b&gt;línea 28&lt;/b&gt; es donde creamos la paginación con el proveedor que hemos escogido y las otras propiedades que requerimos. Los parámetros que pasamos son los siguientes: El proveedor de datos, un array con los tamaños de página que le daremos al usuario para escoger, el tamaño de página inicial que verá el usuario, una variable que indica si mostraremos un filtro global, y finalmente la fuente de los componentes del paginador.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Ahora veamos el código del controlador:&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java; highlight: [44, 48]&quot;&gt;import com.eljavatar.swingutils.core.annotations.PropertyController;
import com.eljavatar.swingutils.core.beansupdate.AbstractObserverController;
import com.eljavatar.swingutils.core.beansupdate.ObjectUpdate;
import com.eljavatar.swingutils.core.beansupdate.TipoUpdateEnum;
import com.eljavatar.swingutils.core.modelcomponents.LazyDataProvider;
import com.eljavatar.swingutils.core.modelcomponents.PaginationDataProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.swing.JOptionPane;

public class PersonasController extends AbstractObserverController&amp;lt;PersonasController, PersonasView&amp;gt; {

    private final PersonasView personasView;
    private final PersonasDao personasDao;
    private Persona persona;
    
    @PropertyController
    private List&amp;lt;Persona&amp;gt; listaPersonas;

    public PersonasController(PersonasView personasView) {
        this.personasView = personasView;
        this.personasDao = new PersonasDao();
        this.listaPersonas = new ArrayList&amp;lt;&amp;gt;();
        
        super.setListeners(PersonasController.this, this.personasView);
    }
    
    public void mostrarPersona() {
        String mensaje = &quot;Código: &quot; + persona.getCodigo() + &quot;\n&quot;
                + &quot;Nombres: &quot; + persona.getNombres()+ &quot;\n&quot;
                + &quot;Apellidos: &quot; + persona.getApellidos()+ &quot;\n&quot;
                + &quot;Dirección: &quot; + persona.getDireccion()+ &quot;\n&quot;
                + &quot;Teléfono: &quot; + persona.getTelefono();
        JOptionPane.showMessageDialog(personasView, mensaje);
    }
    
    public void listarPersonas() {
        this.listaPersonas = personasDao.generarDatos();
        super.changeData(new ObjectUpdate(TipoUpdateEnum.VIEW, Arrays.asList(&quot;listaPersonas&quot;)));
    }
    
    public PaginationDataProvider&amp;lt;Persona&amp;gt; createDataProvider() {
        return new PaginationDataProvider(listaPersonas);
    }
    
    public LazyDataProvider&amp;lt;Persona&amp;gt; createLazyDataProvider() {
        return new LazyDataProvider&amp;lt;Persona&amp;gt;() {
            @Override
            public List&amp;lt;Persona&amp;gt; getRows(int first, int last, Map&amp;lt;String, Object&amp;gt; filters) {
                Object[] response = getPersonasDao().getResultado(first, last, filters);
                this.setListData((List&amp;lt;Persona&amp;gt;) response[0]);
                this.setRowCount((int) response[1]);
                return getListData();
            }
        };
    }

    public List&amp;lt;Persona&amp;gt; getListaPersonas() {
        return listaPersonas;
    }

    public void setListaPersonas(List&amp;lt;Persona&amp;gt; listaPersonas) {
        this.listaPersonas = listaPersonas;
    }

    public PersonasDao getPersonasDao() {
        return personasDao;
    }

    public Persona getPersona() {
        return persona;
    }

    public void setPersona(Persona persona) {
        this.persona = persona;
    }
    
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
En este código podemos resaltar 2 métodos. En la &lt;b&gt;línea 44&lt;/b&gt; vemos el método que crea el proveedor de datos para tablas paginadas con carga completa; y en la &lt;b&gt;línea 48&lt;/b&gt; vemos el método que crea el proveedor de datos para tablas paginadas con carga dinámica.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
A continuación vemos nuestra clase DAO, la cual simula la capa de servicios de datos, desde donde obtenemos los datos en métodos que usamos desde nuestro controlador para cada uno de los casos:&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PersonasDao {

    private static List&amp;lt;Persona&amp;gt; listaDatos;

    static {
        listaDatos = new ArrayList&amp;lt;&amp;gt;();
        listaDatos.add(new Persona(&quot;US-NZEPSJ&quot;, &quot;Armando&quot;, &quot;Costa&quot;, &quot;684 West Branch Rd. &quot;, &quot;35857229&quot;));
        listaDatos.add(new Persona(&quot;US-PXCZSJ&quot;, &quot;Emmy&quot;, &quot;Spence&quot;, &quot;Maineville, OH 45039&quot;, &quot;85462552&quot;));
        listaDatos.add(new Persona(&quot;US-AHFPZZ&quot;, &quot;Edith&quot;, &quot;Higgins&quot;, &quot;55 Saxton St. &quot;, &quot;52524848&quot;));
        listaDatos.add(new Persona(&quot;US-KRSEBV&quot;, &quot;Isabelle&quot;, &quot;Bonilla&quot;, &quot;Joliet, IL 60435&quot;, &quot;97957632&quot;));
        listaDatos.add(new Persona(&quot;US-BTJUXD&quot;, &quot;Elizabeth&quot;, &quot;Haley&quot;, &quot;74 Depot Street &quot;, &quot;92693956&quot;));
        listaDatos.add(new Persona(&quot;US-RKHERS&quot;, &quot;Giuliana&quot;, &quot;Crawford&quot;, &quot;Mobile, AL 36605&quot;, &quot;34229289&quot;));
        listaDatos.add(new Persona(&quot;US-LTYKWV&quot;, &quot;Marilyn&quot;, &quot;Osborne&quot;, &quot;69 Bedford St. &quot;, &quot;74277594&quot;));
        listaDatos.add(new Persona(&quot;US-PHXGVM&quot;, &quot;Justin&quot;, &quot;Rogers&quot;, &quot;Macon, GA 31204&quot;, &quot;85363778&quot;));
        listaDatos.add(new Persona(&quot;US-XJVRXW&quot;, &quot;Joselyn&quot;, &quot;Curtis&quot;, &quot;55 Princess St. &quot;, &quot;82264893&quot;));
        listaDatos.add(new Persona(&quot;US-YRMVQP&quot;, &quot;Dillon&quot;, &quot;Savage&quot;, &quot;Reynoldsburg, OH 43068&quot;, &quot;49627366&quot;));
        // Generamos una lista de 200 o más datos
    }

    public List&amp;lt;Persona&amp;gt; generarDatos() {
        return listaDatos.subList(0, 50);
    }

    public Object[] getResultado(int first, int last, Map&amp;lt;String, Object&amp;gt; filters) {
        List&amp;lt;Persona&amp;gt; listaFiltrada = null;
        int rowCount;

        if (filters.containsKey(&quot;codigo&quot;) &amp;amp;&amp;amp; !filters.get(&quot;codigo&quot;).toString().isEmpty()) {
            listaFiltrada = listaDatos.stream().filter(persona -&amp;gt; persona.getCodigo().matches(&quot;(?i)(.*)&quot; + filters.get(&quot;codigo&quot;).toString().trim() + &quot;(.*)&quot;)).collect(Collectors.toList());
        }

        if (filters.containsKey(&quot;nombres&quot;) &amp;amp;&amp;amp; !filters.get(&quot;nombres&quot;).toString().isEmpty()) {
            listaFiltrada = listaDatos.stream().filter(persona -&amp;gt; persona.getNombres().matches(&quot;(?i)(.*)&quot; + filters.get(&quot;nombres&quot;).toString().trim() + &quot;(.*)&quot;)).collect(Collectors.toList());
        }

        if (filters.containsKey(&quot;apellidos&quot;) &amp;amp;&amp;amp; !filters.get(&quot;apellidos&quot;).toString().isEmpty()) {
            listaFiltrada = listaDatos.stream().filter(persona -&amp;gt; persona.getApellidos().matches(&quot;(?i)(.*)&quot; + filters.get(&quot;apellidos&quot;).toString().trim() + &quot;(.*)&quot;)).collect(Collectors.toList());
        }

        if (listaFiltrada == null) {
            if (last &amp;gt; listaDatos.size()) {
                last = listaDatos.size();
            }
            rowCount = listaDatos.size();
            listaFiltrada = listaDatos.subList(first, last);
        } else {
            if (last &amp;gt; listaFiltrada.size()) {
                last = listaFiltrada.size();
            }
            rowCount = listaFiltrada.size();
            listaFiltrada = listaFiltrada.subList(first, last);
        }
        
        return new Object[]{listaFiltrada, rowCount};
    }

}
&lt;/pre&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Finalmente sólo nos resta ejecutar la clase PersonaView para ver el resultado, el cual es el siguiente:&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9BSE3sukEFpO3W7GZyyEnyGjcRDUnt2bg7XA0caudgWZZr1XMfb6d3-Il5rfpzGm3eyBG0rTJRczZ_u3OlUx7DsMbVW5DCxh8Ku468fU23yURuBtvLtVnxHoowUAqVo_lLZoaBOEiVbru/s1600/JTable+Paginado+o+Lazy+y+con+Filtros.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;JTable Paginado o Lazy y con Filtros - SwingUtils&quot; border=&quot;0&quot; data-original-height=&quot;331&quot; data-original-width=&quot;602&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9BSE3sukEFpO3W7GZyyEnyGjcRDUnt2bg7XA0caudgWZZr1XMfb6d3-Il5rfpzGm3eyBG0rTJRczZ_u3OlUx7DsMbVW5DCxh8Ku468fU23yURuBtvLtVnxHoowUAqVo_lLZoaBOEiVbru/s1600/JTable+Paginado+o+Lazy+y+con+Filtros.png&quot; title=&quot;JTable Paginado o Lazy y con Filtros - SwingUtils&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Como podemos apreciar, crear &lt;i&gt;JTable paginados en Java Swing&lt;/i&gt; es muy sencillo haciendo uso de la &lt;b&gt;librería SwingUtils&lt;/b&gt;. Por otro lado, si tienes dudas sobre cómo usar éste componente, puedes escribirlas en la caja de comentarios.&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/9041648612638168922/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2018/04/SwingUtils-Crear-JTable-Paginado-o-Lazy-y-con-Filtros-Java-Swing.html#comment-form' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/9041648612638168922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/9041648612638168922'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2018/04/SwingUtils-Crear-JTable-Paginado-o-Lazy-y-con-Filtros-Java-Swing.html' title='SwingUtils - Crear JTable Paginado o Lazy y con Filtros (Java Swing)'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2xe0rV_wBfdtcRAmHL7QiNOjsGXpaIxZpF81xbX2OT5Ior6XNMYqqDDWLECmJt2JsPeuU2vW3jGTKJt07GEoaWQvGZL8GJB6rBDe_qyqIA_Gz0ksebWP4-9KWnu3sg5t2OiUksFt02NWD/s72-c/SwingUtils+-+Crear+JTable+Paginado+o+Lazy+y+con+Filtros+%2528Java+Swing%2529.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-5571629885378036349</id><published>2018-04-09T15:23:00.000-05:00</published><updated>2018-04-09T15:23:34.760-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Algoritmos"/><title type='text'>Algoritmo para Calcular primeros n términos de la sucesión de Fibonacci</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
La serie o &lt;b&gt;sucesión de Fibonacci&lt;/b&gt;, es una sucesión infinita de números naturales que empieza con los términos 0 y 1, sucedidos consecutivamente por &lt;i&gt;n&lt;/i&gt; términos, donde cada uno es la suma de los dos anteriores. Así pues, los primeros 15 términos de la serie de Fibonacci serían:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre&gt;0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377...
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Esta sucesión fue descrita en Europa por el matemático italiano Leonardo de Pisa alrededor del siglo XIII, quien también era conocido como Fibonacci. Esta sucesión tiene aplicaciones en diversos campos de la computación, las matemáticas y más increíble aún, se correlaciona con la estructura biológica de muchos seres vivos en la naturaleza.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTcYz9Z0CtficxHX6MqV7SUoIGwGu6sAZ1yBb6LAwqi1Y627xKlOOaqRneCj2yEURnBG_0Wtj7mdzzirnEc_0enXZHEP4zaHEJQ79t42z6oa1s2LlWc5Hafkh4WqOn6K8Y7kX3aEH4PC8Y/s1600/Algoritmo+para+Calcular+primeros+n+t%25C3%25A9rminos+de+la+sucesi%25C3%25B3n+de+Fibonacci.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Algoritmo para Calcular primeros n términos de la sucesión de Fibonacci&quot; border=&quot;0&quot; data-original-height=&quot;185&quot; data-original-width=&quot;300&quot; height=&quot;246&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTcYz9Z0CtficxHX6MqV7SUoIGwGu6sAZ1yBb6LAwqi1Y627xKlOOaqRneCj2yEURnBG_0Wtj7mdzzirnEc_0enXZHEP4zaHEJQ79t42z6oa1s2LlWc5Hafkh4WqOn6K8Y7kX3aEH4PC8Y/s400/Algoritmo+para+Calcular+primeros+n+t%25C3%25A9rminos+de+la+sucesi%25C3%25B3n+de+Fibonacci.jpg&quot; title=&quot;Algoritmo para Calcular primeros n términos de la sucesión de Fibonacci&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Existen varias formas de &lt;u&gt;hallar el término &lt;i&gt;n&lt;/i&gt; de la sucesión de Fibonacci&lt;/u&gt;, y a partir de una de estas formas podemos obtener cada uno los anteriores términos de la serie. Así que veamos 2 de estas formas para hallar un término &lt;i&gt;n&lt;/i&gt; de la sucesión de Fibonacci.&lt;br /&gt;
&lt;br /&gt;
Primero que nada veamos la definición matemática de la &lt;i&gt;&lt;b&gt;sucesión de Fibonacci&lt;/b&gt;&lt;/i&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVcOB2kuT2BBFsfq-tO9J-K4pA_KHpYtzev_ZSbik1DMLIcCNbSvuixYEoCy4JNZfB2ZrPyQPKG5v8GNtVWG5VYmYzD8Dv2WHURQ-iZ_KKZ5ksRKKAD8SZ-KOe_vNJ4fElE1KM1Ve7yt3E/s1600/Algoritmo+para+Calcular+primeros+n+t%25C3%25A9rminos+de+la+serie+de+Fibonacci+-+Formula.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Algoritmo para Calcular primeros n términos de la serie de Fibonacci - Formula&quot; border=&quot;0&quot; data-original-height=&quot;35&quot; data-original-width=&quot;149&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVcOB2kuT2BBFsfq-tO9J-K4pA_KHpYtzev_ZSbik1DMLIcCNbSvuixYEoCy4JNZfB2ZrPyQPKG5v8GNtVWG5VYmYzD8Dv2WHURQ-iZ_KKZ5ksRKKAD8SZ-KOe_vNJ4fElE1KM1Ve7yt3E/s1600/Algoritmo+para+Calcular+primeros+n+t%25C3%25A9rminos+de+la+serie+de+Fibonacci+-+Formula.png&quot; title=&quot;Algoritmo para Calcular primeros n términos de la serie de Fibonacci - Formula&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
partiendo de dos primeros valores predeterminados que son:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQfOkRyVylFNCg7CPaVF-p8BYZ5YYnxkor-Kd6YZUw58ChwYp1YCDAPltL_uTcw1FUw5LZA9gd9HseI7o1-3TDdNnG9IMvHZgng-kQip6ZspvVB0gA0d6y6BbmsW__one52PKeV1HKUHqq/s1600/Algoritmo+para+Calcular+primeros+n+t%25C3%25A9rminos+de+la+serie+de+Fibonacci+-+Valores+predeterminados.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Algoritmo para Calcular primeros n términos de la serie de Fibonacci - Valores predeterminados&quot; border=&quot;0&quot; data-original-height=&quot;70&quot; data-original-width=&quot;72&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQfOkRyVylFNCg7CPaVF-p8BYZ5YYnxkor-Kd6YZUw58ChwYp1YCDAPltL_uTcw1FUw5LZA9gd9HseI7o1-3TDdNnG9IMvHZgng-kQip6ZspvVB0gA0d6y6BbmsW__one52PKeV1HKUHqq/s1600/Algoritmo+para+Calcular+primeros+n+t%25C3%25A9rminos+de+la+serie+de+Fibonacci+-+Valores+predeterminados.png&quot; title=&quot;Algoritmo para Calcular primeros n términos de la serie de Fibonacci - Valores predeterminados&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Así pues, para hallar el sexto término de la &lt;u&gt;sucesión de Fibonacci&lt;/u&gt; se calcularía así:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfpzHbth83DoUNAaV34xe6OESV5kL7x-ZH1ixEnkQY3QRWIj4GtWvx3qviFAwoEaGdyzANZ2_9z24WUYp_cDK-1WOcjnindQ5sdQPcVDFc6vx2yTtSZPEPGrXl_UuqRKbIail-zGh3Aoh5/s1600/Algoritmo+para+Calcular+primeros+n+t%25C3%25A9rminos+de+la+serie+de+Fibonacci+-+Ejemplo+01.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Algoritmo para Calcular primeros n términos de la serie de Fibonacci - Ejemplo 01&quot; border=&quot;0&quot; data-original-height=&quot;187&quot; data-original-width=&quot;228&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfpzHbth83DoUNAaV34xe6OESV5kL7x-ZH1ixEnkQY3QRWIj4GtWvx3qviFAwoEaGdyzANZ2_9z24WUYp_cDK-1WOcjnindQ5sdQPcVDFc6vx2yTtSZPEPGrXl_UuqRKbIail-zGh3Aoh5/s1600/Algoritmo+para+Calcular+primeros+n+t%25C3%25A9rminos+de+la+serie+de+Fibonacci+-+Ejemplo+01.png&quot; title=&quot;Algoritmo para Calcular primeros n términos de la serie de Fibonacci - Ejemplo 01&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Ahora despejamos y reemplazamos cada término:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvO5-k0P-AtaVsBdT9RrOyaPHioJxKU1Vsc5dZDBmgdlJXUp1tPWYx5kCJBZmcojgPov-dvRUQF-q7NwVMS8h7FdjM6y2ltsVmopqtL02vjQ4EsqceQJn5peeXsqnSvE7FWFzILJYGit1-/s1600/Algoritmo+para+Calcular+primeros+n+t%25C3%25A9rminos+de+la+serie+de+Fibonacci+-+Ejemplo+02.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Algoritmo para Calcular primeros n términos de la serie de Fibonacci - Ejemplo 02&quot; border=&quot;0&quot; data-original-height=&quot;184&quot; data-original-width=&quot;215&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvO5-k0P-AtaVsBdT9RrOyaPHioJxKU1Vsc5dZDBmgdlJXUp1tPWYx5kCJBZmcojgPov-dvRUQF-q7NwVMS8h7FdjM6y2ltsVmopqtL02vjQ4EsqceQJn5peeXsqnSvE7FWFzILJYGit1-/s1600/Algoritmo+para+Calcular+primeros+n+t%25C3%25A9rminos+de+la+serie+de+Fibonacci+-+Ejemplo+02.png&quot; title=&quot;Algoritmo para Calcular primeros n términos de la serie de Fibonacci - Ejemplo 02&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Como pudimos ver en el ejemplo, la &lt;i&gt;sucesión de Fibonacci&lt;/i&gt; empieza a calcularse como tal a partir del término 2, ya que los primeros valores &lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;f&lt;sub&gt;0&lt;/sub&gt;&lt;/span&gt; y &lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;f&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt; están predeterminados.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Algoritmo recursivo para calcular el término &lt;i&gt;n&lt;/i&gt; de la sucesión de Fibonacci&lt;/b&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;!-- anuncios --&gt;
Tomamos como valor de entrada la variable &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;n&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;1)&lt;/b&gt; Si &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;n&lt;/span&gt; es menor que 2, retornamos el valor de &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;n&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
En el ejemplo vimos que cada término en la serie, es la suma consecutiva de los dos anteriores términos hasta llegar al segundo término. Así pues, el paso 2 sería obtener el valor de dicha suma:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;2)&lt;/b&gt; Retornamos la suma &lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;f&lt;sub&gt;n-2&lt;/sub&gt; + f&lt;sub&gt;n-1&lt;/sub&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
En donde cada suma es el resultado de hacer el mismo proceso desde el paso 1. Esto lo conocemos como una forma recursiva. En la siguiente gráfica podemos apreciar de forma detallada este proceso:&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU_ro6HHhioojwf0_C5WZAGdVvkBaKlSYsL2dvkIAEUJrlGUgZM-oY16MvYIKWYcfxt_iFJjEAGYq0ksRcw4es5ejd2WVEexJHNOK4-2RvRd-0YPxaE9oKx17LHE6nUnzw1c6GduCV6ehR/s1600/Grafica+recursiva+para+hallar+el+termino+n+de+la+serie+de+Fibonacci.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Grafica recursiva para hallar el termino n de la serie de Fibonacci&quot; border=&quot;0&quot; data-original-height=&quot;392&quot; data-original-width=&quot;577&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU_ro6HHhioojwf0_C5WZAGdVvkBaKlSYsL2dvkIAEUJrlGUgZM-oY16MvYIKWYcfxt_iFJjEAGYq0ksRcw4es5ejd2WVEexJHNOK4-2RvRd-0YPxaE9oKx17LHE6nUnzw1c6GduCV6ehR/s1600/Grafica+recursiva+para+hallar+el+termino+n+de+la+serie+de+Fibonacci.png&quot; title=&quot;Grafica recursiva para hallar el termino n de la serie de Fibonacci&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Complejidad de la forma recursiva&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
A pesar de que la forma recursiva para &lt;b&gt;calcular el término &lt;i&gt;n&lt;/i&gt; de ls sucesión de Fibonacci&lt;/b&gt; requiere de pocos pasos, el costo computacional es elevado, ya que es un algoritmo de orden exponencial, es decir de &lt;b&gt;O&lt;sup&gt;&lt;i&gt;n&lt;/i&gt;&lt;/sup&gt;&lt;/b&gt;. En el siguiente artículo podemos apreciar una explicación más detallada de la complejidad de los algoritmos: &lt;a href=&quot;http://www.lcc.uma.es/~av/Libro/CAP1.pdf&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;La complejidad de los algoritmos&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;¿Y a qué se debe este nivel de complejidad?&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Como podemos apreciar en la imagen, se debe a la repetición de las operaciones, la cual va creciendo exponencialmente según el término que se desea hallar. Así pues, &lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;f&lt;sub&gt;6&lt;/sub&gt;&lt;/span&gt; se llama una vez, &lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;f&lt;sub&gt;5&lt;/sub&gt;&lt;/span&gt; se llama una vez, &lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;f&lt;sub&gt;4&lt;/sub&gt;&lt;/span&gt; 2 veces, &lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;f&lt;sub&gt;3&lt;/sub&gt;&lt;/span&gt; 3 veces, &lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;f&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt; 5 veces, &lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;f&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt; 8 veces y &lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;f&lt;sub&gt;0&lt;/sub&gt;&lt;/span&gt; 5 veces. Así pues, entre mayor sea el término a hallar, más rápido crecerán la cantidad de operaciones.&lt;/div&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Algoritmo iterativo para calcular el término &lt;i&gt;n&lt;/i&gt; de la sucesión de Fibonacci&lt;/b&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Tomamos como valor de entrada la variable&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;n&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;1)&lt;/b&gt; Declaramos tres variables de tipo entero: &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;a&lt;/span&gt;, &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;b&lt;/span&gt; y &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;c&lt;/span&gt;. Inicializamos &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;a&lt;/span&gt; con el valor 0, y &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;b&lt;/span&gt; con el valor 1.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;2)&lt;/b&gt; Iniciamos un ciclo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;for&lt;/span&gt;, el cual inicia en 0 y finaliza cuando la variable de control sea menor que &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;n&lt;/span&gt;. Dentro del ciclo realizamos las siguientes acciones:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; A la variable &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;c&lt;/span&gt;, le asignamos el total de la suma de &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;a + b&lt;/span&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; A la variable &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;a&lt;/span&gt; le asignamos el valor de &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;b&lt;/span&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; A la variable &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;b&lt;/span&gt; le asignamos el valor de &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;c&lt;/span&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;3)&lt;/b&gt; Al finalizar el ciclo, retornamos la variable a, la cual ha de tener el valor de &lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;f&lt;sub&gt;n&lt;/sub&gt;&lt;/span&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Complejidad de la forma iterativa&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Como podemos apreciar, la forma iterativa realiza &lt;i&gt;n&lt;/i&gt; repeticiones donde &lt;i&gt;n&lt;/i&gt; es el término a hallar, y en cada repetición se realizan las respectivas sumas y asignaciones de variables; por lo tanto, decimos que la forma iterativa tiene una complejidad de&amp;nbsp;&lt;b&gt;O(&lt;i&gt;n&lt;/i&gt;)&lt;/b&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Existen muchas otras formas de calcular el &lt;b&gt;término &lt;i&gt;n&lt;/i&gt; de la sucesión de Fibonacci&lt;/b&gt;, sin embargo, estas dos son las que estaré representando en diversos lenguajes de programación en próximas entradas.&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/5571629885378036349/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2018/04/Algoritmo-para-Calcular-primeros-n-terminos-de-la-sucesion-de-Fibonacci.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/5571629885378036349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/5571629885378036349'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2018/04/Algoritmo-para-Calcular-primeros-n-terminos-de-la-sucesion-de-Fibonacci.html' title='Algoritmo para Calcular primeros n términos de la sucesión de Fibonacci'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTcYz9Z0CtficxHX6MqV7SUoIGwGu6sAZ1yBb6LAwqi1Y627xKlOOaqRneCj2yEURnBG_0Wtj7mdzzirnEc_0enXZHEP4zaHEJQ79t42z6oa1s2LlWc5Hafkh4WqOn6K8Y7kX3aEH4PC8Y/s72-c/Algoritmo+para+Calcular+primeros+n+t%25C3%25A9rminos+de+la+sucesi%25C3%25B3n+de+Fibonacci.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-6658502451042884009</id><published>2018-01-12T13:58:00.001-05:00</published><updated>2018-01-12T14:05:34.801-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="API Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Core Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java Collections"/><title type='text'>¿Cómo Sincronizar un ArrayList en Java?</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnjmebFQty87__W7GmpEuURxeqpOsDsnvCY8QojEzbwMMFsKwfqbUnYp_jpSmUK_2erGbf87h4LiHBUfzrZbzpjvCvhxU-2an_e3SMv6yHx-d0YfjBIeVx5cD0TV9sVWPO9T-oL4FH0Kfb/s1600/C%25C3%25B3mo+Sincronizar+un+ArrayList+en+Java+1.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img alt=&quot;Cómo Sincronizar un ArrayList en Java&quot; border=&quot;0&quot; data-original-height=&quot;264&quot; data-original-width=&quot;256&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnjmebFQty87__W7GmpEuURxeqpOsDsnvCY8QojEzbwMMFsKwfqbUnYp_jpSmUK_2erGbf87h4LiHBUfzrZbzpjvCvhxU-2an_e3SMv6yHx-d0YfjBIeVx5cD0TV9sVWPO9T-oL4FH0Kfb/s1600/C%25C3%25B3mo+Sincronizar+un+ArrayList+en+Java+1.png&quot; title=&quot;Cómo Sincronizar un ArrayList en Java&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
ArrayList es una Colección muy útil en Java, e incluso es una de la más usadas, aunque no es una colección sincronizada. ¿Qué significa esto? Significa que no se puede compartir una instancia de un ArrayList entre varios hilos (&lt;a href=&quot;http://www.eljavatar.com/2017/10/como-implementar-un-thread-hilo-en-java.html&quot; target=&quot;_blank&quot;&gt;threads&lt;/a&gt;) no sólo para operaciones de lectura, sino tampoco para agregar o actualizar elementos.&lt;br /&gt;
&lt;br /&gt;
Entonces, ¿C&lt;i&gt;ómo podemos sincronizar un ArrayList en Java&lt;/i&gt;? Eso es lo que trataremos de explicar y con ejemplos en este tutorial, pero primero veamos la razón del por qué los ArrayList no están sincronizados por defecto en el API de Java. Los multi-procesos o multi-threading son una de las principales fortalezas de Java, e incluso casi todos los programas desarrollados en Java tienen más de un hilo; entonces ¿&lt;u&gt;por qué Java no nos facilita de forma nativa el uso de ArrayList para dicho entorno&lt;/u&gt;?&lt;br /&gt;
&lt;br /&gt;
La respuesta está en el rendimiento; hay un costo de rendimiento asociado con la sincronización y hacer que un &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ArrayList&lt;/span&gt; esté sincronizado haría que fuese más lento. Por lo tanto, los ArrayList quedaron nativamente en el &lt;i&gt;API de Java&lt;/i&gt; como colecciones no sincronizadas para mantenerlos rápidos; sin embargo, el &lt;u&gt;API de Java&lt;/u&gt; también nos proporciona formas fáciles de sincronizar un ArrayList en caso de que lo necesitemos, y esto es lo que vamos a aprender en este tutorial.&lt;br /&gt;
&lt;br /&gt;
La clase Collections del &lt;b&gt;API de Java&lt;/b&gt; tiene varios métodos para crear List, Set y Map sincronizados, y para este tutorial utilizaremos el método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Collections.synchronizedList()&lt;/span&gt; para sincronizar un ArrayList. Este método acepta una lista que puede ser cualquier implementación de la interface List, como por ejemplo, ArrayList y LinkedList, y lo que nos devuelve es una lista sincronizada &lt;b&gt;thread-safe&lt;/b&gt; (segura para subprocesos) respaldada por la lista especificada.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;Lista Sincronizada e Iteración en Java&lt;/b&gt;&lt;/h3&gt;
&lt;!-- anuncios --&gt;

&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Uno de los principales desafíos a los que nos enfrentamos cuando queremos compartir un ArrayList entre múltiples hilos es el lidiar con situaciones en las que un hilo intenta acceder a un elemento que otro hilo ha eliminado. Si se utilizan métodos como &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;get(index)&lt;/span&gt; o &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;remove(index)&lt;/span&gt; para obtener o eliminar elementos, también es posible que otro hilo también esté intentando eliminar dichos elementos, aunque de forma no fiable, a menos de que se realice una verificación manual de la lista antes de usar los métodos &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;get(index)&lt;/span&gt; y &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;remove(index)&lt;/span&gt;, lo cual significa que no se puede llamar a estos métodos de forma fiable sin antes verificar el tamaño de la lista, para lo cual también debe proporcionarse una sincronización adicional entre la llamada de los métodos &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;size()&lt;/span&gt; y &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;remove(int index)&lt;/span&gt;.
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;es&quot;&gt;Para garantizar 
el acceso en serie, es fundamental que todo el acceso a la lista de 
respaldo se realice a través de la lista devuelta y es imperativo que el
 usuario realice una sincronización manual en la lista devuelta al iterar sobre 
ella como se muestra en el siguiente código de ejemplo:&lt;/span&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;List list = Collections.synchronizedList(new ArrayList());

...
synchronized(list) {
    Iterator itr = list.iterator(); // El iterador debe estar en un bloque sincronizado
    while (itr.hasNext()) {
        Object obj = itr.next();
    }
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;Como se sugiere en la documentación de Java, no seguir este consejo puede dar como resultado un comportamiento no determinista, es decir, que no podemos saber de antemano cuál será el resultado cuando llamemos a los métodos &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;get(index)&lt;/span&gt; y &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;remove(index)&lt;/span&gt;.&lt;/span&gt; &lt;span class=&quot;&quot;&gt;Además, la lista será serializable si la ArrayList proporcionado es serializable.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h3&gt;
&lt;span class=&quot;&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;&lt;b&gt;Código para Sincronizar un ArrayList en Java&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;span class=&quot;&quot;&gt;A continuación veremos un ejemplo completo para &lt;b&gt;&lt;i&gt;&lt;u&gt;sincronizar un ArrayList en Java&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;. Lo que haremos será crear una lista de String y añadiremos algunos elementos en ella&lt;/span&gt;. Luego,&amp;nbsp; pasaremos dicha lista al método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Collections.synchronizedList()&lt;/span&gt;, el cual nos devolverá una versión &lt;b&gt;thread-safe&lt;/b&gt; (segura para subprocesos) de la lista.&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;span class=&quot;&quot;&gt;Con esto, ya podríamos compartir esta lista de forma segura entre varios threads, pero debemos tener cuidado al recuperar o eliminar elementos del &lt;u&gt;ArrayList&lt;/u&gt;.&lt;/span&gt;&amp;nbsp;Así que para tener acceso seguro, debemos de usar un Iterator de forma sincronizada para obtener y eliminar elementos de la lista, tal como lo veremos en este ejemplo:&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;


/**
 * How to synchronize ArrayList in Java
 * 
 * @author Andrés Mauricio (http://www.eljavatar.com)
 */

public class ArrayListSincronizadoDemo {

    public static void main(String args[]) {
       
       // Creamos una lista, la cual no está sincronizada
       List&amp;lt;String&amp;gt; marcasCelulares = new ArrayList&amp;lt;String&amp;gt;();
       
       marcasCelulares.add(&quot;SAMSUNG&quot;);
       marcasCelulares.add(&quot;IPHONE&quot;);
       marcasCelulares.add(&quot;HUAWEI&quot;);
       marcasCelulares.add(&quot;MOTOROLA&quot;);
       marcasCelulares.add(&quot;HTC&quot;);
       
       // Sincronizamos la lista
       marcasCelulares = Collections.synchronizedList(marcasCelulares);
       
       // Mientras iteramos sobre la lista sincronizada, se debe
       // sincronizar el iterador y las operaciones para evitar
       // comportamientos no deterministas
       
       synchronized(marcasCelulares) {
           Iterator&amp;lt;String&amp;gt; itr = marcasCelulares.iterator();
           
           while (itr.hasNext()) {
               System.out.println(itr.next());
           }
       }
       
    }

}
&lt;/pre&gt;
&lt;br /&gt;
Salida de nuestro programa:&lt;br /&gt;
&lt;pre&gt;SAMSUNG
IPHONE
HUAWEI
MOTOROLA
HTC
&lt;/pre&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;Como hemos visto, es muy fácil &lt;b&gt;&lt;i&gt;sincronizar un ArrayList en Java&lt;/i&gt;&lt;/b&gt; gracias al método 
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Collections.synchronizedList()&lt;/span&gt;, sin embargo, debemos ser un poco cuidadosos al recuperar y eliminar objetos de la Lista.&lt;/span&gt; &lt;span class=&quot;&quot;&gt;Por cierto, existen otras dos opciones para conseguir una lista de elementos sincronizada, las cuales son Vector y &lt;a href=&quot;http://www.eljavatar.com/2017/11/que-es-un-copyonwritearraylist-en-java.html&quot; target=&quot;_blank&quot;&gt;CopyOnWriteArrayList&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizTFaIiEd2JQfjIzgUXaRD4vjoXCNO9qsAGfBizMwXgGxcYoQU_uQqIvlifDt9QO55ERj9jemhcyjuaCJ5hQoScDTQkvhaEa5rueoqgpmL573NcLH3K3Tb7gUYNYS2KkTihmFtsdGqa9hT/s1600/C%25C3%25B3mo+Sincronizar+un+ArrayList+en+Java+2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Cómo Sincronizar un ArrayList en Java&quot; border=&quot;0&quot; data-original-height=&quot;250&quot; data-original-width=&quot;448&quot; height=&quot;222&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizTFaIiEd2JQfjIzgUXaRD4vjoXCNO9qsAGfBizMwXgGxcYoQU_uQqIvlifDt9QO55ERj9jemhcyjuaCJ5hQoScDTQkvhaEa5rueoqgpmL573NcLH3K3Tb7gUYNYS2KkTihmFtsdGqa9hT/s400/C%25C3%25B3mo+Sincronizar+un+ArrayList+en+Java+2.png&quot; title=&quot;Cómo Sincronizar un ArrayList en Java&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;span class=&quot;&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;&lt;span class=&quot;&quot;&gt;Vector es una 
clase muy antigua, pero fue adaptada para implementar la interface &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;List&lt;/span&gt; a partir de Java 1.4 y, lo que es más importante, está sincronizada, por lo
 cual no es necesario sincronizarla de nuevo.&lt;/span&gt; &lt;span class=&quot;&quot;&gt;Por 
cierto, debes tener en cuenta que al usar la clase Vector, asegúrate de usarlo mediante la interface &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;List&lt;/span&gt; y no mediante el uso de métodos heredados; de lo contrario, en caso de que desees cambiar de implementación después, no podrás hacerlo.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span class=&quot;&quot;&gt;Por otro lado, 
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;CopyOnWriteArrayList&lt;/span&gt; es parte de las clases de colecciones concurrentes de Java y es mucho más escalable que Vector y ArrayList.&lt;/span&gt;&amp;nbsp;Si una lista va a ser usada principalmente para leer registros,&lt;span class=&quot;&quot;&gt;&amp;nbsp;y sólo de vez en cuando va ser usada para realizar en ella operaciones de escritura, esta podría ser la elección más idónea.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;&quot; lang=&quot;es&quot;&gt;
&lt;/span&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/6658502451042884009/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2018/01/como-sincronizar-un-arraylist-en-java.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/6658502451042884009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/6658502451042884009'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2018/01/como-sincronizar-un-arraylist-en-java.html' title='¿Cómo Sincronizar un ArrayList en Java?'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnjmebFQty87__W7GmpEuURxeqpOsDsnvCY8QojEzbwMMFsKwfqbUnYp_jpSmUK_2erGbf87h4LiHBUfzrZbzpjvCvhxU-2an_e3SMv6yHx-d0YfjBIeVx5cD0TV9sVWPO9T-oL4FH0Kfb/s72-c/C%25C3%25B3mo+Sincronizar+un+ArrayList+en+Java+1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-198480716552356359</id><published>2017-11-27T17:13:00.002-05:00</published><updated>2017-11-27T17:13:50.097-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Core Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java Collections"/><title type='text'>¿Qué es un CopyOnWriteArrayList en Java?</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI-ORaPJstojwfzajwEuiPP4PKRXu_T_YzxPqEPItni-aJRSXFiPyGh3uC_2k5_f9yz81XMoCJvTuL5nH71HMI7b3f9QjSa81m80NMQDw9CHSbo_F0xeTjdFwHLl0W4fz-JvEPXH8qTfyH/s1600/Qu%25C3%25A9+es+un+CopyOnWriteArrayList+en+Java.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Qué es un CopyOnWriteArrayList en Java&quot; border=&quot;0&quot; data-original-height=&quot;361&quot; data-original-width=&quot;688&quot; height=&quot;209&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI-ORaPJstojwfzajwEuiPP4PKRXu_T_YzxPqEPItni-aJRSXFiPyGh3uC_2k5_f9yz81XMoCJvTuL5nH71HMI7b3f9QjSa81m80NMQDw9CHSbo_F0xeTjdFwHLl0W4fz-JvEPXH8qTfyH/s400/Qu%25C3%25A9+es+un+CopyOnWriteArrayList+en+Java.jpg&quot; title=&quot;Qué es un CopyOnWriteArrayList en Java&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;es&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;CopyOnWriteArrayList&lt;/span&gt; es 
una clase para trabajar colecciones concurrentes presentada en el &lt;b&gt;API de concurrencia de Java&lt;/b&gt; a partir de la versión 5 junto con la otra muy popular clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ConcurrentHashMap&lt;/span&gt;. &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;CopyOnWriteArrayList&lt;/span&gt;
 implementa la interface &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;List&lt;/span&gt;, tal como lo hacen las clases ArrayList, Vector y LinkedList, con la diferencia de que&amp;nbsp;&lt;/span&gt;CopyOnWriteArrayList es una colección&amp;nbsp;&lt;b&gt;thread-safety&lt;/b&gt; y logra la seguridad de 
subprocesos de una manera ligeramente diferente que la clase Vector u otra clase 
de colecciones &lt;b&gt;thread-safe&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Como su nombre lo indica, &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;CopyOnWriteArrayList&lt;/span&gt; crea una copia del ArrayList subyacente con cada operación de escritura, por ejemplo,&amp;nbsp;agregar, eliminar o cuando se modifican valores. Es por esta razón que CopyOnWriteArrayList solo es adecuado cuando trabajemos con una lista que se lea con frecuencia pero se modifique raramente&lt;span class=&quot;&quot;&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;&quot;&gt;&lt;span class=&quot;&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;!-- anuncios --&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;span class=&quot;&quot;&gt;&lt;span class=&quot;&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;Normalmente,&amp;nbsp; &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;CopyOnWriteArrayList&lt;/span&gt; puede llegar a ser ineficiente porque implica &lt;b&gt;costosas copias del Array&lt;/b&gt; con cada operación de escritura, pero es muy eficiente si lo que necesitamos es una lista donde las iteraciones superan las mutaciones, es decir, cuando las operaciones de escritura se dan con poca frecuencia.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
El iterador de 
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;CopyOnWriteArrayList&lt;/span&gt; es &lt;b&gt;fail-safe&lt;/b&gt; (a prueba de fallas) y no lanza excepciones de tipo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ConcurrentModificationException&lt;/span&gt;, incluso si la lista se modifica una vez que comienza la iteración, ya que el Iterador actúa sobre una copia separada del &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ArrayList&lt;/span&gt;. &lt;span class=&quot;&quot;&gt;En
 consecuencia, todas las actualizaciones realizadas fuera de un &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;CopyOnWriteArrayList&lt;/span&gt; no están disponibles para su Iterator, es decir, que no podremos ver los cambios que realice otro hilo sobre la colección de datos.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Así pues, en este tutorial
 de &lt;b&gt;Java Collections&lt;/b&gt; no sólo veremos qué es un CopyOnWriteArrayList, también expondré la diferencia entre ArrayList y CopyOnWriteArrayList y un ejemplo sencillo de un programa Java con el que aprenderemos cómo usar un &lt;b&gt;&lt;i&gt;&lt;u&gt;CopyOnWriteArrayList en Java&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;h3 style=&quot;text-align: justify;&quot;&gt;
&lt;span class=&quot;&quot;&gt;&lt;span class=&quot;&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;&lt;b&gt;Diferencia entre CopyOnWriteArrayList y ArrayList en Java&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Ya hemos visto lo que es un &lt;i&gt;CopyOnWriteArrayList en Java&lt;/i&gt; y cómo éste logra la seguridad del thread al crear una copia separada de la colección para 
cada operación de escritura.&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Ahora veamos algunas 
diferencias entre ArrayList y &lt;b&gt;CopyOnWriteArrayList en Java&lt;/b&gt;, las cuales son ambas implementaciones de la interface &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;List&lt;/span&gt;:&lt;/div&gt;
&lt;/div&gt;
&lt;span class=&quot;&quot;&gt;
&lt;/span&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;1)&lt;/b&gt; La principal 
diferencia entre &lt;b&gt;CopyOnWriteArrayList y ArrayList en Java&lt;/b&gt; es que 
CopyOnWriteArrayList es una colección segura para subprocesos (thread-safe), mientras 
que ArrayList no es seguro para subprocesos y no puede ser usado en un entorno de múltiples hilos.&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;2)&lt;/b&gt; La segunda 
diferencia entre ArrayList y CopyOnWriteArrayList es que el Iterador de un&amp;nbsp; ArrayList es fail-fast y lanzará una excepción de tipo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ConcurrentModificationException&lt;/span&gt; una vez 
que detecta cualquier modificación en la Lista mientras está iterando; por el contrario, el Iterador de un CopyOnWriteArrayList es fail-safe y no lanza excepciones de tipo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ConcurrentModificationException&lt;/span&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;3)&lt;/b&gt; La tercera 
diferencia entre &lt;i&gt;CopyOnWriteArrayList y ArrayList&lt;/i&gt; es que el iterador del primero no soporta la operación para eliminar elementos, mientras que el iterador 
del segundo si soporta el método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;remove()&lt;/span&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;h3 style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;&lt;span class=&quot;&quot;&gt;&lt;span class=&quot;&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;&lt;span class=&quot;&quot;&gt;Ejemplo de CopyOnWriteArrayList en Java&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;brush: java&quot;&gt;import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 *
 * Programa para demostrar como usar CopyOnWriteArrayList en Java,
 * y como usar el Iterador de CopyOnWriteArrayList
 *
 * @author Andrés M. Barragán (eljavatar)
 */
public class EjemploCopyOnWriteArrayList {

    public static void main(String args[]) {
     
        CopyOnWriteArrayList&amp;lt;String&amp;gt; listThreadSafe = new CopyOnWriteArrayList&amp;lt;&amp;gt;();
        listThreadSafe.add(&quot;Asia&quot;);
        listThreadSafe.add(&quot;Africa&quot;);
        listThreadSafe.add(&quot;America&quot;);
        listThreadSafe.add(&quot;Europa&quot;);
        listThreadSafe.add(&quot;Oceania&quot;);
     
        // Las operaciones add y remove no están soportadas por el Iterador de CopyOnWriteArrayList
        Iterator&amp;lt;String&amp;gt; failSafeIterator = listThreadSafe.iterator();
        while (failSafeIterator.hasNext()) {
            System.out.printf(&quot;Lectura del CopyOnWriteArrayList : %s %n&quot;, failSafeIterator.next());
            failSafeIterator.remove(); // Esta línea lanzará una excepción. (Comentar para ejecutar completo)
        }
    }
}
&lt;/pre&gt;
&lt;br /&gt;
La salida de este código (comentando la línea donde se usa el método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;remove(&lt;/span&gt;)) sería la siguiente:&lt;br /&gt;
&lt;br /&gt;


&lt;pre class=&quot;brush: java&quot;&gt;Lectura del CopyOnWriteArrayList : Asia 
Lectura del CopyOnWriteArrayList : Africa 
Lectura del CopyOnWriteArrayList : America 
Lectura del CopyOnWriteArrayList : Europa 
Lectura del CopyOnWriteArrayList : Oceania 
&lt;/pre&gt;
&lt;br /&gt;
Si lo ejecutamos sin comentar la línea donde se usa el método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;remove()&lt;/span&gt;, el resultado será el siguiente:&lt;br /&gt;
&lt;br /&gt;


&lt;pre class=&quot;brush: java&quot;&gt;Lectura del CopyOnWriteArrayList : Asia 

Exception in thread &quot;main&quot; java.lang.UnsupportedOperationException
 at java.util.concurrent.CopyOnWriteArrayList$COWIterator.remove(CopyOnWriteArrayList.java:1176)
 at EjemploCopyOnWriteArrayList.main(EjemploCopyOnWriteArrayList.java:26)
Command exited with non-zero status 1
&lt;/pre&gt;
&lt;span class=&quot;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;&quot;&gt;Esto
 es todo acerca de lo que es un &lt;b&gt;&lt;i&gt;&lt;u&gt;CopyOnWriteArrayList en Java&lt;/u&gt;&lt;/i&gt;&lt;/b&gt; y su diferencia respecto a un ArrayList.&lt;/span&gt; &lt;span class=&quot;&quot;&gt;En resumen, podemos concluir que deberíamos usar &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;CopyOnWriteArrayList&lt;/span&gt; si nuestro objetivo es principalmente iterar sobre la lista sin modificarla.&lt;/span&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/198480716552356359/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2017/11/que-es-un-copyonwritearraylist-en-java.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/198480716552356359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/198480716552356359'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2017/11/que-es-un-copyonwritearraylist-en-java.html' title='¿Qué es un CopyOnWriteArrayList en Java?'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI-ORaPJstojwfzajwEuiPP4PKRXu_T_YzxPqEPItni-aJRSXFiPyGh3uC_2k5_f9yz81XMoCJvTuL5nH71HMI7b3f9QjSa81m80NMQDw9CHSbo_F0xeTjdFwHLl0W4fz-JvEPXH8qTfyH/s72-c/Qu%25C3%25A9+es+un+CopyOnWriteArrayList+en+Java.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-5421441210465123925</id><published>2017-11-16T15:51:00.000-05:00</published><updated>2017-11-16T15:51:47.755-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java Swing"/><category scheme="http://www.blogger.com/atom/ns#" term="SwingUtils"/><title type='text'>SwingUtils - Sincronizar datos de un JTable con el Controlador (Java Swing)</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
En un artículo anterior estuve explicando &lt;a href=&quot;http://www.eljavatar.com/2017/10/SwingUtils-Crear-JTable-con-Modelo-de-Datos-Generico-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;cómo crear un JTable en Java usando un Modelo de Datos genérico&lt;/a&gt; que nos provee la librería &lt;b&gt;&lt;i&gt;&lt;u&gt;SwingUtils&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;. Ahora veremos &lt;i&gt;cómo sincronizar los datos de un JTable&lt;/i&gt; con un objeto de nuestro modelo de datos declarado en el controlador.&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Como estuvimos viendo, un &lt;u&gt;JTable&lt;/u&gt; nos permite trabajar con tipos de datos genéricos y dicho dato genérico es heredado por su modelo de datos, lo cual quiere decir que podemos trabajar incluso con tipos de datos de clases creadas por nosotros mismos.&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Lo primero que debemos hacer es descargarnos la librería &lt;b&gt;&lt;i&gt;SwingUtils&lt;/i&gt;&lt;/b&gt;. Para hacerlo puedes revisar las instrucciones en el siguiente artículo:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
==&amp;gt; &lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Libreria-de-Utilidades-para-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;SwingUtils - Librería de Utilidades para Java Swing&lt;/a&gt;&lt;/div&gt;
&lt;!-- anuncios --&gt;

&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;h3&gt;
&lt;b&gt;Anotaciones para usar en el Controlador&lt;/b&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Las anotaciones que podemos usar en el Controlador según sean nuestras necesidades son las siguientes:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; ModelBean&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; PropertyController&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Para saber como usar estas anotaciones puedes revisar esta misma sección de &quot;&lt;b&gt;Anotaciones para usar en el Controlador&lt;/b&gt;&quot; en el siguiente artículo:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
==&amp;gt; &lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Sincronizar-datos-de-un-JTextField-con-el-Controlador-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;SwingUtils - Sincronizar datos de un JTextField con el Controlador (Java Swing)&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
El modelo de datos que usaremos para nuestro &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JTable&lt;/span&gt; será el siguiente:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: java&quot;&gt;public class Pais {
    
    private Integer id;
    private String codigo;
    private String nombre;
 
    public Pais(Integer id, String codigo, String nombre) {
        this.id = id;
        this.codigo = codigo;
        this.nombre = nombre;
    }
 
    public Pais() {
    }
 
    public Integer getId() {
        return id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    public String getCodigo() {
        return codigo;
    }
 
    public void setCodigo(String codigo) {
        this.codigo = codigo;
    }
 
    public String getNombre() {
        return nombre;
    }
 
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
 
    @Override
    public int hashCode() {
        int hash = 7;
        hash = 13 * hash + Objects.hashCode(this.id);
        hash = 13 * hash + Objects.hashCode(this.codigo);
        return hash;
    }
 
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Pais other = (Pais) obj;
        if (!Objects.equals(this.codigo, other.codigo)) {
            return false;
        }
        if (!Objects.equals(this.id, other.id)) {
            return false;
        }
        return true;
    }
     
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
El modelo de datos que usaremos para sincronizarlo con la vista será el siguiente:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;public class MiModelo {
 
    private List&amp;lt;Pais&amp;gt; listaPaises;;
 
    public List&amp;lt;Pais&amp;gt; getListaPaises() {
        return listaPaises;
    }

    public void setListaPaises(List&amp;lt;Pais&amp;gt; listaPaises) {
        this.listaPaises = listaPaises;
    }
     
}
&lt;/pre&gt;
&lt;br /&gt;
Recuerda que los Getter y Setter de los atributos son requeridos para asignar y obtener el valor de los atributos.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;Anotaciones para usar en un JTable de Java Swing&lt;/b&gt;&lt;/h3&gt;
La librería &lt;i&gt;SwingUtils&lt;/i&gt; en su actual versión, permite asignar la siguiente anotación a un componente &lt;u&gt;Java Swing&lt;/u&gt; de tipo &lt;b&gt;JTable&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&lt;/b&gt; TableView&lt;br /&gt;
&lt;br /&gt;
Como ya he mencionado, el tipo de dato del &lt;b&gt;API de Java&lt;/b&gt; a usar en el modelo de datos puede ser de cualquier tipo, ya que los &lt;i&gt;JTable&lt;/i&gt; nos permiten trabajar con tipos de datos genéricos. Así pues, la forma de usar esta anotación sería la siguiente:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;@TableView(name = &quot;miModelo1.pais&quot;)
private javax.swing.JTable&lt;pais&gt; jTable1;
&lt;/pais&gt;&lt;/pre&gt;
&lt;br /&gt;
Declaramos nuestro controlador en la vista e inyectamos la dependencia de ésta para poder sincronizarlos. Además setearemos el modelo de datos para nuestro &lt;b&gt;JTable&lt;/b&gt;, para lo cual haremos uso de la clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JTableUtils&lt;/span&gt; de la librería &lt;i&gt;&lt;b&gt;SwingUtils&lt;/b&gt;&lt;/i&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;public class MiVista extends javax.swing.JFrame {
   
    private final MiControlador miControlador;
       
    public MiVista() {
        initComponents();
        
        this.miControlador = new MiControlador(this);
        
        JTableUtils.setProperties(jTable1, new Font(&quot;Arial&quot;, Font.BOLD, 13), new MiModeloTabla());
        jTable1.setSize(350, 250);
        JTableUtils.setAnchoColumnas(jTable1, jTable1.getWidth() - 1, 3, new int[]{20, 30, 50});
    }
    
    private void initComponents() {
        // Código generado por NetBeans
    }
}
&lt;/pre&gt;
&lt;br /&gt;
La clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;MiModeloTabla&lt;/span&gt; es el mismo modelo de datos que usamos en el artículo sobre &lt;a href=&quot;http://www.eljavatar.com/2017/10/SwingUtils-Crear-JTable-con-Modelo-de-Datos-Generico-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;cómo crear un JTable con un modelo de datos genérico&lt;/a&gt;, con la diferencia de que en este caso, lo inicializaremos con una lista vacía.&lt;br /&gt;
&lt;br /&gt;
Tal cual como lo vimos en el artículo sobre &lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Sincronizar-datos-de-un-JTextField-con-el-Controlador-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;Cómo sincronizar un JTextField con el controlador&lt;/a&gt;, los datos los podríamos obtener y setear de nuestro &lt;b&gt;JTable&lt;/b&gt; en la vista de forma sencilla, sin embargo, para este ejemplo lo que queremos es mostrar dos listas diferentes mediante dos botones, así que los métodos que nos permitirán realizar esto serían ligeramente distintos:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;// Método para obtener lista de países de Sudamérica
public List&amp;lt;Pais&amp;gt; getListPaisesSudamerica() {
    List&amp;lt;Pais&amp;gt; listaPaises = new ArrayList&amp;lt;&amp;gt;();
    listaPaises.add(new Pais(1, &quot;CO&quot;, &quot;Colombia&quot;));
    listaPaises.add(new Pais(2, &quot;AR&quot;, &quot;Argentina&quot;));
    listaPaises.add(new Pais(3, &quot;VE&quot;, &quot;Venezuela&quot;));
    listaPaises.add(new Pais(4, &quot;EC&quot;, &quot;Ecuador&quot;));
    listaPaises.add(new Pais(5, &quot;PE&quot;, &quot;Perú&quot;));
    listaPaises.add(new Pais(6, &quot;BO&quot;, &quot;Bolivia&quot;));
    listaPaises.add(new Pais(7, &quot;PA&quot;, &quot;Paraguay&quot;));
    listaPaises.add(new Pais(8, &quot;UR&quot;, &quot;Uruguay&quot;));
    listaPaises.add(new Pais(9, &quot;CH&quot;, &quot;Chile&quot;));
    listaPaises.add(new Pais(10, &quot;UR&quot;, &quot;Brasil&quot;));
    return listaPaises;
}

// Método para obtener lista de países de Europa
public List&amp;lt;Pais&amp;gt; getListPaisesEuropa() {
    List&amp;lt;Pais&amp;gt; listaPaises = new ArrayList&amp;lt;&amp;gt;();
    listaPaises.add(new Pais(1, &quot;ES&quot;, &quot;España&quot;));
    listaPaises.add(new Pais(2, &quot;FR&quot;, &quot;Francia&quot;));
    listaPaises.add(new Pais(3, &quot;GE&quot;, &quot;Alemania&quot;));
    listaPaises.add(new Pais(4, &quot;EN&quot;, &quot;Inglaterra&quot;));
    listaPaises.add(new Pais(5, &quot;HO&quot;, &quot;Holanda&quot;));
    listaPaises.add(new Pais(6, &quot;SU&quot;, &quot;Suecia&quot;));
    listaPaises.add(new Pais(7, &quot;NO&quot;, &quot;Noruega&quot;));
    listaPaises.add(new Pais(8, &quot;BE&quot;, &quot;Bélgica&quot;));
    return listaPaises;
}

// Método para mostrar en la tabla la lista de países de Sudamérica
public void verPaisesSudamerica() {
    miModelo1.setListaPaises(getListPaisesSudamerica());
    super.changeData(TipoUpdateEnum.VIEW);
}

// Método para mostrar en la tabla la lista de países de Europa
public void verPaisesEuropa() {
    miModelo1.setListaPaises(getListPaisesEuropa());
    super.changeData(TipoUpdateEnum.VIEW);
}

// Método para limpiar los datos
public void limpiar() {
    miModelo1 = new MiModelo();
    miModelo1.setListaPaises(new ArrayList&amp;lt;&amp;gt;());
    super.changeData(TipoUpdateEnum.VIEW);
}
&lt;/pre&gt;
&lt;br /&gt;
Puedes revisar &lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Sincronizar-datos-de-un-JTextField-con-el-Controlador-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;este artículo&lt;/a&gt; para comprender a fondo cómo funciona éste método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;super.changeData(), &lt;/span&gt;que como tal es el que realiza la actualización automática de los datos de la vista al modelo de datos en el controlador y viceversa. Como podemos apreciar también en el código, para limpiar o vaciar una tabla, es necesario setearle una lista vacía a la lista que tengamos en nuestro modelo de datos, o de lo contrario obtendremos una excepción de tipo&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;java.lang.NullPointerException&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwG9WnCy498fbmjvKghwouLi3KV-G2bVqlxxtX4Qb-m_lt6zNMKsup_bdl7rjgx0mArk_O3ZxvIKH0D81Nvs4LXevL3enALX-OqHrBEujjIpE-3tvDku1rjvOt7EPJgHaRTVTXqQMBzNRD/s1600/SwingUtils+-+Sincronizar+datos+de+un+JTable+con+el+Controlador+%2528Java+Swing%2529.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;SwingUtils - Sincronizar datos de un JTable con el Controlador (Java Swing)&quot; border=&quot;0&quot; data-original-height=&quot;270&quot; data-original-width=&quot;368&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwG9WnCy498fbmjvKghwouLi3KV-G2bVqlxxtX4Qb-m_lt6zNMKsup_bdl7rjgx0mArk_O3ZxvIKH0D81Nvs4LXevL3enALX-OqHrBEujjIpE-3tvDku1rjvOt7EPJgHaRTVTXqQMBzNRD/s1600/SwingUtils+-+Sincronizar+datos+de+un+JTable+con+el+Controlador+%2528Java+Swing%2529.png&quot; title=&quot;SwingUtils - Sincronizar datos de un JTable con el Controlador (Java Swing)&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Como podemos apreciar, usando la librería &lt;b&gt;&lt;i&gt;&lt;u&gt;SwingUtils&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;,&amp;nbsp; es muy rápido sincronizar fácilmente datos de un &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JTable&lt;/span&gt; con el Controlador para que la información de nuestra vista se actualice rápidamente en el modelo de datos y viceversa.&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/5421441210465123925/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2017/11/SwingUtils-Sincronizar-datos-de-un-JTable-con-el-Controlador-Java-Swing.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/5421441210465123925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/5421441210465123925'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2017/11/SwingUtils-Sincronizar-datos-de-un-JTable-con-el-Controlador-Java-Swing.html' title='SwingUtils - Sincronizar datos de un JTable con el Controlador (Java Swing)'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwG9WnCy498fbmjvKghwouLi3KV-G2bVqlxxtX4Qb-m_lt6zNMKsup_bdl7rjgx0mArk_O3ZxvIKH0D81Nvs4LXevL3enALX-OqHrBEujjIpE-3tvDku1rjvOt7EPJgHaRTVTXqQMBzNRD/s72-c/SwingUtils+-+Sincronizar+datos+de+un+JTable+con+el+Controlador+%2528Java+Swing%2529.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-5022343575534844486</id><published>2017-11-03T10:50:00.001-05:00</published><updated>2017-11-03T10:50:26.753-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ArrayList"/><category scheme="http://www.blogger.com/atom/ns#" term="Core Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java Collections"/><title type='text'>Diferencias entre ArrayList sincronizado y CopyOnWriteArrayList en Java</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgamGdpqEBp-6ytBMDmjUpZBLaYC1CeXo4xaC0hjqrTIp1F707AhHZGvVWFszfX6jPPgN8RdmDSVdoG8KmvfN3pNy3Or1cjLH77JgengR1YYYMlaaDpJr0GtcOeXOk2ITKymTT0H6Z31QxR/s1600/Java+Collections+Tutorial.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img alt=&quot;Diferencias entre ArrayList sincronizado y CopyOnWriteArrayList en Java&quot; border=&quot;0&quot; data-original-height=&quot;280&quot; data-original-width=&quot;392&quot; height=&quot;228&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgamGdpqEBp-6ytBMDmjUpZBLaYC1CeXo4xaC0hjqrTIp1F707AhHZGvVWFszfX6jPPgN8RdmDSVdoG8KmvfN3pNy3Or1cjLH77JgengR1YYYMlaaDpJr0GtcOeXOk2ITKymTT0H6Z31QxR/s320/Java+Collections+Tutorial.png&quot; title=&quot;Diferencias entre ArrayList sincronizado y CopyOnWriteArrayList en Java&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;Aunque tanto los &lt;b&gt;ArrayList sincronizados&lt;/b&gt; como &lt;b&gt;CopyOnWriteArrayList&lt;/b&gt; nos proporcionan 
seguridad cuando trabajamos con &lt;a href=&quot;http://www.eljavatar.com/2017/10/como-implementar-un-thread-hilo-en-java.html&quot; target=&quot;_blank&quot;&gt;threads&lt;/a&gt; (subprocesos), y pueden ser usados cuando necesitemos que una lista se comparta entre varios threads, existe una sutil diferencia entre estas dos implementaciones: un ArrayList sincronizado, como su nombre lo indica, es una colección sincronizada mientras que un &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;CopyOnWriteArrayList&lt;/span&gt; es una colección concurrente.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;¿Qué significa esto?&lt;/span&gt; &lt;span class=&quot;&quot;&gt;Significa
 que &lt;u&gt;CopyOnWriteArrayList&lt;/u&gt; está diseñado teniendo en cuenta escenarios de concurrencia y es más escalable que un &lt;u&gt;ArrayList sincronizado&lt;/u&gt;, siempre y cuando la lista 
se use principalmente para operaciones de lectura. Un&lt;/span&gt;&lt;span class=&quot;&quot;&gt;&amp;nbsp;&lt;b&gt;&lt;i&gt;ArrayList en Java&lt;/i&gt;&lt;/b&gt; no es sincronizado por defecto, por lo que no puede usarse directamente 
en un entorno de subprocesos (&lt;a href=&quot;http://www.eljavatar.com/2017/10/como-implementar-un-thread-hilo-en-java.html&quot; target=&quot;_blank&quot;&gt;threads&lt;/a&gt;) múltiples, donde la lista se accede y se 
modifica mediante varios subprocesos.&lt;/span&gt; &lt;span class=&quot;&quot;&gt;Para usar un ArrayList en dicho entorno, primero debemos obtener una lista 
sincronizada llamando a &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Collections.synchronizedList()&lt;/span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;!-- anuncios --&gt;

&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;span class=&quot;&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;&lt;span class=&quot;&quot;&gt;Esta lista sincronizada logra
 seguridad en el thread al bloquear toda la colección, lo que significa 
que si un hilo está leyendo de una lista y al mismo tiempo otro también intenta leer de la misma, estos irán uno por uno, es decir, que múltiples hilos pueden 
leer desde un mismo objeto sin&lt;/span&gt; &lt;span class=&quot;&quot;&gt;ningún problema.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;CopyOnWriteArrayList&lt;/b&gt;
 aprovecha también esta funcionalidad y proporciona lecturas sin bloqueos, lo 
cual significa un rendimiento mucho mejor si hay más hilos tratando de realizar operaciones de lectura y 
muy pocos o incluso ninguno realizando operaciones de escritura.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
En 
resumen, la principal diferencia entre un &lt;i&gt;&lt;u&gt;ArrayList sincronizado y 
CopyOnWriteArrayList en Java &lt;/u&gt;&lt;/i&gt;proviene del hecho de cómo logran seguridad en sus operaciones entre hilos y qué tan escalables son.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;h3 style=&quot;text-align: justify;&quot;&gt;
&lt;span class=&quot;&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;&lt;span class=&quot;&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;&lt;b&gt;List Sincronizado vs CopyOnWriteArrayList&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;span class=&quot;&quot;&gt;En primer lugar, debemos de saber que Java hace uso del &lt;b&gt;framework Collection&lt;/b&gt;, lo que nos evita usar muchas variantes de 
clases cunado tengamos que trabajar con listas de datos; así pues, el framework Collection nos proporciona wrappers mediante la clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;java.util.Collections&lt;/span&gt;; por ejemplo, si necesitamos un ArrayList de solo lectura, podemos obtenerlo 
llamando a &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Collections.unmodifiableList()&lt;/span&gt;, y de forma similar,&lt;/span&gt; &lt;span class=&quot;&quot;&gt;si necesitamos una lista sincronizada, podemos obtenerla llamando a &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Collections.synchronizedList()&lt;/span&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Por lo general, estas implementaciones venían funcionado bien, pero con el tiempo, las aplicaciones Java se han vuelto más 
sofisticadas y cuando estas clases se exponen en entornos altamente concurrentes, se convierten en un cuello de botella. &lt;span class=&quot;&quot;&gt;Una
 vez que los ingenieros detrás de Java se dieron cuenta de este hecho, vieron que necesitaban de colecciones que fuesen más escalables y pudiesen ofrecer mejor rendimiento cuando se utilizaran en un entorno de múltiples subprocesos (threads), y así es como a partir de &lt;i&gt;Java 5&lt;/i&gt; se incorporó un nuevo conjunto de clases para el manejo de colecciones denominado &lt;b&gt;Concurrent 
Collections&lt;/b&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Esta
 librería incluye alternativas concurrentes de las colecciones más 
populares, como por ejemplo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ConcurrentHashMap&lt;/span&gt; para &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;HashMap&lt;/span&gt; y &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;CopyOnWriteArrayList&lt;/span&gt; 
para &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ArrayList&lt;/span&gt;. Estas implementaciones e&lt;span class=&quot;&quot;&gt;stán diseñadas específicamente 
para escenarios de alta concurrencia y es por eso que logran la seguridad del thread de 
una forma más sofisticada que simplemente bloquear toda la colección.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Recapitulemos entonces algunas de las &lt;b&gt;&lt;i&gt;diferencias claves entre un ArrayList sincronizado y CopyOnWriteArrayList en Java&lt;/i&gt;&lt;/b&gt;:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;1)&lt;/b&gt; La primer diferencia entre un &lt;b&gt;ArrayList sincronizado&lt;/b&gt; y &lt;b&gt;CopyOnWriteArrayList&lt;/b&gt; proviene del hecho de cómo logran la seguridad del thread. Una lista sincronizada bloquea toda la colección para proporcionar sincronización y seguridad en los threads, mientras que CopyOnWriteArrayList no bloquea la colección y cuando un thread escribe en la lista, simplemente reemplaza la lista copiando sus elementos. De esta manera, proporciona acceso simultáneo a la lista para varios threads sin bloqueos y, dado que las operaciones de lectura son seguras cuando se ejecutan en distintos threads, quiere decir que no hay dos threads que puedan estar escribiendo en la misma lista de datos al tiempo.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;2)&lt;/b&gt; La segunda diferencia proviene del hecho de cómo se comportan sus iteradores. El iterador devuelto desde un ArrayList sincronizado es un &lt;b&gt;fail-fast iterator&lt;/b&gt; (Iterador que puede fallar rápido), mientras que el iterador devuelto por CopyOnWriteArrayList es un &lt;b&gt;fail-safe iterator&lt;/b&gt; (Iterador a prueba de fallos), es decir, no lanzará &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ConcurrentModifcationException&lt;/span&gt; incluso en escenarios donde la lista se modifique mientras un thread esté iterando sobre ella.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;3)&lt;/b&gt; En tercer lugar, y no menos importante, una de las principales diferencias entre CopyOnWriteArrayList y ArrayList es el rendimiento, especialmente si necesitamos que la lista se utilice principalmente con fines de solo lectura. Es probable que CopyOnWriteArrayList supere al ArrayList sincronizado si este es el caso, pero si la lista está expuesta a operaciones de lectura y escritura, es probable que el ArrayList sincronizado presente un mejor rendimiento.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Otra cosa muy importante que se debe tener en cuenta es el tamaño que tiene el ArrayList, o incluso el que pueda llegar a alcanzar, ya que debemos analizar según la necesidad que tengamos, si su gran costo de copiado (después de una operación de lectura) es lo suficientemente alto como para compensar el costo de bloqueo, pero si el ArrayList es pequeño, podría usarse CopyOnWriteArrayList sin preocuparse por este tipo de inconvenientes.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;es&quot;&gt;&lt;span class=&quot;&quot;&gt;Estas son entonces las &lt;b&gt;&lt;i&gt;&lt;u&gt;diferencias entre un ArrayList sincronizado y CopyOnWriteArrayList en Java&lt;/u&gt;&lt;/i&gt;&lt;/b&gt; que debes tener en cuenta y que te permitirán saber en qué escenario es mejor usar uno u otro&lt;/span&gt;&lt;span class=&quot;&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;&quot;&gt;Básicamente,
 CopyOnWriteArrayList es una mejor opción si se accede principalmente a 
una lista para leer datos, pero si las operaciones de escritura son considerablemente altas, 
la mejor opción es usar un ArrayList sincronizado porque el costo de copiar la 
lista con cada operación sería mayor que la ganancia de sacrificar el bloqueo de la lista.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Otro aspecto que nos permitirá saber rápidamente qué opción escoger, es ver si necesitamos que el iterador detecte modificaciones concurrentes cuando se está recorriendo la lista o si se desea modificar la colección a través del iterador; en estos casos la opción idónea es un ArrayList Sincronizado.&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/5022343575534844486/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2017/11/Diferencias-entre-ArrayList-sincronizado-y-CopyOnWriteArrayList-en-Java.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/5022343575534844486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/5022343575534844486'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2017/11/Diferencias-entre-ArrayList-sincronizado-y-CopyOnWriteArrayList-en-Java.html' title='Diferencias entre ArrayList sincronizado y CopyOnWriteArrayList en Java'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgamGdpqEBp-6ytBMDmjUpZBLaYC1CeXo4xaC0hjqrTIp1F707AhHZGvVWFszfX6jPPgN8RdmDSVdoG8KmvfN3pNy3Or1cjLH77JgengR1YYYMlaaDpJr0GtcOeXOk2ITKymTT0H6Z31QxR/s72-c/Java+Collections+Tutorial.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-4335084701239684484</id><published>2017-10-24T11:47:00.002-05:00</published><updated>2017-10-26T09:47:58.161-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Core Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><title type='text'>Cómo implementar un Thread (Hilo) en Java</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE6b8HtvDM6tS-t6QEL9sTDYCVFoxtzQvgAN6-I3nNIM1IpO2u_CggnA80iunfmt8-hJPYNogpnS5k9PW2-PZFUAmyxtSqZuujI8j_nxNwnODBueGupqM1a2Gu-rxzyQVJXq5QhVughqKM/s1600/C%25C3%25B3mo+implementar+un+Thread+%2528Hilo%2529+en+Java+2.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img alt=&quot;Cómo implementar un Thread (Hilo) en Java&quot; border=&quot;0&quot; data-original-height=&quot;451&quot; data-original-width=&quot;500&quot; height=&quot;180&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE6b8HtvDM6tS-t6QEL9sTDYCVFoxtzQvgAN6-I3nNIM1IpO2u_CggnA80iunfmt8-hJPYNogpnS5k9PW2-PZFUAmyxtSqZuujI8j_nxNwnODBueGupqM1a2Gu-rxzyQVJXq5QhVughqKM/s200/C%25C3%25B3mo+implementar+un+Thread+%2528Hilo%2529+en+Java+2.jpg&quot; title=&quot;Cómo implementar un Thread (Hilo) en Java&quot; width=&quot;200&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
Considero que los &lt;i&gt;Thread&lt;/i&gt; es una de las características más importantes de Java, ya que contribuyó a que éste se convirtiera en un lenguaje de programación mucho más popular, pues una de las habilidades que se busca un programador es su comprensión sobre programación multi-hilos, y su capacidad para escribir aplicaciones que realicen sub-procesos múltiples.&lt;br /&gt;
&lt;br /&gt;
El principal problema con la programación de aplicaciones que puedan ejecutar varios sub-procesos al mismo tiempo, está relacionado con inconvenientes relacionados con&amp;nbsp;&lt;a href=&quot;https://es.wikipedia.org/wiki/Concurrencia_(inform%C3%A1tica)&quot; target=&quot;_blank&quot;&gt;concurrencia&lt;/a&gt;, &lt;a href=&quot;https://es.wikipedia.org/wiki/Bloqueo_mutuo&quot; target=&quot;_blank&quot;&gt;deadlock&lt;/a&gt;, &lt;a href=&quot;https://es.wikipedia.org/wiki/Condici%C3%B3n_de_carrera&quot; target=&quot;_blank&quot;&gt;race condition&lt;/a&gt;, entre otros, lo cual lleva a que implementar multi-hilos en algunas aplicaciones Java requiera de cierto esfuerzo.&lt;br /&gt;
&lt;br /&gt;
En este tutorial veremos algunas formas de implementar un&amp;nbsp;&lt;b&gt;Thread (hilo) en Java&lt;/b&gt;, lo cual le permitirá crear e inicializar hilos ya sea implementando la interface &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html&quot; target=&quot;_blank&quot;&gt;Runnable&lt;/a&gt; o extendiendo de la clase &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html&quot; target=&quot;_blank&quot;&gt;Thread&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Cómo crear un Thread en Java&lt;/b&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;!-- anuncios --&gt;
Existen dos formas de implementar hilos en Java:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;1)&lt;/b&gt; Extendiendo de la clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;java.lang.Thread&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;2)&lt;/b&gt; Implementando la interface &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;java.lang.Runnable&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Antes de entrar en detalles sobre cómo implementar una opción o la otra, sería pertinente saber cuando debemos usar un&amp;nbsp;&lt;u&gt;Thread en Java&lt;/u&gt;. Un hilo o thread en Java lo usaremos en caso de que queramos que una funcionalidad (parte del código) de nuestro programa se ejecute en paralelo al proceso principal, así pues, dicho código lo colocaríamos dentro del método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;run()&lt;/span&gt; de la clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Thread&lt;/span&gt; o la interface &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Runnable&lt;/span&gt; para que se cumpla dicho cometido.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Como tal, el método público &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;run(&lt;/span&gt;) se define en la interface Runnable, y como la clase Thread implementa dicha interface, hereda automáticamente éste método.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Teniendo en cuenta de que contamos con dos formas de implementar un&amp;nbsp;&lt;i&gt;Thread en Java&lt;/i&gt;, una pregunta que tal vez puede surgirnos es saber cuál de las dos es mejor: extendiendo de la clase&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Thread&lt;/span&gt;&amp;nbsp;o implementando la interface&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Runnable&lt;/span&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Por cuestiones de diseño, considero que la mejor forma es implementando la interface Runnable, ya que si tenemos en cuenta de que en Java sólo podemos extender de una sola clase, si extendemos de la clase Thread, ya no podríamos hacerlo de alguna otra clase, mientras que implementando la interface Runnable, podremos implementar otra interface en cualquier momento que necesitemos.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Además, tengamos en cuenta que según la&amp;nbsp;&lt;b&gt;&lt;a href=&quot;http://www.eljavatar.com/2014/04/Paradigmas-de-Programacion-IV-Programacion-Orientada-a-Objetos.html&quot; target=&quot;_blank&quot;&gt;Programación Orientada a Objetos&lt;/a&gt;&lt;/b&gt;, el propósito de extender una clase es proporcionar alguna característica o funcionalidad nueva, así que si nuestro propósito es simplemente usar el método&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;run()&lt;/span&gt;, el cual usaremos solamente para definir qué parte de nuestro código se ejecutará en otro hilo, la opción más razonable sería implementar la interface Runnable.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Así que después de decidir de qué forma se creará el&amp;nbsp;&lt;b&gt;&lt;i&gt;&lt;u&gt;Thread en java&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;, lo siguiente que debemos hacer es crear el objeto de nuestro thread e iniciar el sub-proceso. Esto creará una ruta de ejecución separada paralela al hilo principal de la aplicación.&lt;/div&gt;
&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;Cómo se ejecuta un Thread en Java&lt;/b&gt;&lt;/h3&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhReK25ri8Gc9EDZPLb90uDRQzls0OwKn7fK55BUtFjRzetq4Bzd7zEp46Ady6xJxaGqRRcFjB8ixPKugxvoDZNa6scpoOO46_Q-qHSJcPYaAisVIVTy0ILH0dmM5ahdunfMurreAXdkQyU/s1600/C%25C3%25B3mo+implementar+un+Thread+%2528Hilo%2529+en+Java.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Cómo implementar un Thread (Hilo) en Java&quot; border=&quot;0&quot; data-original-height=&quot;705&quot; data-original-width=&quot;1600&quot; height=&quot;280&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhReK25ri8Gc9EDZPLb90uDRQzls0OwKn7fK55BUtFjRzetq4Bzd7zEp46Ady6xJxaGqRRcFjB8ixPKugxvoDZNa6scpoOO46_Q-qHSJcPYaAisVIVTy0ILH0dmM5ahdunfMurreAXdkQyU/s640/C%25C3%25B3mo+implementar+un+Thread+%2528Hilo%2529+en+Java.png&quot; title=&quot;Cómo implementar un Thread (Hilo) en Java&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Un&amp;nbsp;&lt;b&gt;&lt;i&gt;thread en java&lt;/i&gt;&lt;/b&gt;&amp;nbsp;está basado en estados, así que cuando se crea un objeto de la clase del thread que definimos extendiendo de la clase Thread o implementando de la interface Runnable, éste solamente se crea con un estado predefinido, pero no se iniciará hasta que se llame al método&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;start()&lt;/span&gt;&amp;nbsp;de la clase&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;java.lang.Thread&lt;/span&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Entonces, cuando creamos el objeto del thread en java, éste quedará en un estado&amp;nbsp;&lt;u&gt;New&lt;/u&gt;, y al llamar al método&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;start()&lt;/span&gt;, la&amp;nbsp;&lt;b&gt;Máquina Virtual de Java&lt;/b&gt;&amp;nbsp;ejecuta el método&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;run()&lt;/span&gt;&amp;nbsp;de la clase que definimos, lo que hace que el thread pase al estado&amp;nbsp;&lt;u&gt;Runnable&lt;/u&gt;. A partir de aquí, sera el planificador de Threads el encargado de asignar CPU a este sub-proceso (hilo).&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Ya después de esto, el thread puede pasar a estado&amp;nbsp;&lt;u&gt;Terminated&lt;/u&gt;&amp;nbsp;o quedar en estado&amp;nbsp;&lt;u&gt;Waiting&lt;/u&gt;,&amp;nbsp;&lt;u&gt;Time Waiting&lt;/u&gt;&amp;nbsp;o&amp;nbsp;&lt;u&gt;Blocked&lt;/u&gt;. Veamos el código:&lt;/div&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Ejemplo de implementación de un Thread en Java&lt;/b&gt;&lt;/h3&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;// Implementación de hilos extendiendo de la clase Thread
public class MyThread extends Thread {

    public void run() {
        System.out.println(&quot;Thread Running &quot; + Thread.currentThread().getName());
    }

}


// Implementación de hilos implementando la interface Runnable
public class MyRunnable implements Runnable {         

    public void run() {
        System.out.println(&quot;Creamos Thread &quot; + Thread.currentThread().getName());
    }

}


// Iniciando Threads en Java
Thread mythread = new MyThread(); // Se crea el Thread pero no inicia
mythread.setName(&quot;Thread 1&quot;);
Thread myrunnable = new Thread(new MyRunnable(),&quot;Thread 2&quot;); // Thread creado       

mythread.start(); // Inicia el Thread (No necesariamente indica que haya empezado a ejecutarse) 
myrunnable.start();
&lt;/pre&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
¿Qué pasaría en caso de que en vez de llamar al método&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;start()&lt;/span&gt;, intentemos ejecutar directamente el método&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;run()&lt;/span&gt;? No tendríamos error ni una Excepción; simplemente se ejecutará en el mismo thread (hilo) desde el que se llama el método. ¿Y si intentamos llamar dos veces al método&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;start()&lt;/span&gt;&amp;nbsp;del mismo objeto Thread?&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;mythread.start(); 
mythread.start(); // Esta línea lanzará una excepción de tipo IllegalThreadStateException
&lt;/pre&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Puntos a tener en cuenta sobre crear un Thread en Java&lt;/b&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;1)&lt;/b&gt; Este ejemplo no garantiza que el hilo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;mythread&lt;/span&gt; se inicie antes que el hilo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;myrunnable&lt;/span&gt;. Como se explicó, esto depende del planificador de Threads.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;2)&lt;/b&gt;&amp;nbsp;Un Thread pasará a estado muerto una vez que finaliza la ejecución del método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;run()&lt;/span&gt;, y por tanto, dicho Thread no puede volver a iniciar otra vez.&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/4335084701239684484/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2017/10/como-implementar-un-thread-hilo-en-java.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/4335084701239684484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/4335084701239684484'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2017/10/como-implementar-un-thread-hilo-en-java.html' title='Cómo implementar un Thread (Hilo) en Java'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE6b8HtvDM6tS-t6QEL9sTDYCVFoxtzQvgAN6-I3nNIM1IpO2u_CggnA80iunfmt8-hJPYNogpnS5k9PW2-PZFUAmyxtSqZuujI8j_nxNwnODBueGupqM1a2Gu-rxzyQVJXq5QhVughqKM/s72-c/C%25C3%25B3mo+implementar+un+Thread+%2528Hilo%2529+en+Java+2.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-4941540754510390848</id><published>2017-10-23T11:07:00.000-05:00</published><updated>2017-10-23T11:14:07.328-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java Swing"/><category scheme="http://www.blogger.com/atom/ns#" term="SwingUtils"/><title type='text'>SwingUtils - Crear JTable con Modelo de Datos Genérico (Java Swing)</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
Hace tiempo publiqué un artículo en el que enseñaba &lt;a href=&quot;http://www.eljavatar.com/2016/03/Como-Hacer-un-Modelo-de-Datos-Personalizado-para-un-JTable-en-Java.html&quot; target=&quot;_blank&quot;&gt;Cómo crear un modelo de datos personalizado para un JTable en Java Swing&lt;/a&gt;, en el cual podemos ver cómo el &lt;b&gt;API de Java Swing&lt;/b&gt; separa la vista de un &lt;b&gt;JTable&lt;/b&gt; y su modelo de datos. Teniendo en cuenta lo que enseño en dicho artículo, decidí crear un Modelo de datos Pseudo-genérico dentro de la librería &lt;i&gt;&lt;b&gt;SwingUtils&lt;/b&gt;&lt;/i&gt;, de tal forma que los modelos de datos que creemos para nuestras tablas sean lo menos verbosos posible.&lt;br /&gt;
&lt;br /&gt;
No me expandiré mucho en los detalles acerca de cómo funciona un modelo de datos en un &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JTable&lt;/span&gt; de &lt;u&gt;Java Swing&lt;/u&gt;, ya que eso lo explico en &lt;a href=&quot;http://www.eljavatar.com/2016/03/Como-Hacer-un-Modelo-de-Datos-Personalizado-para-un-JTable-en-Java.html&quot; target=&quot;_blank&quot;&gt;este artículo&lt;/a&gt;; así que veamos directamente qué es lo que nos provee la librería &lt;i&gt;SwingUtils&lt;/i&gt; para crear los modelos de datos de los JTable de forma rápida y sencilla.&lt;br /&gt;
&lt;!-- anuncios --&gt;

Lo primero que debemos hacer es importar la librería &lt;i&gt;&lt;b&gt;SwingUtils&lt;/b&gt;&lt;/i&gt; a nuestro proyecto. Puedes ver las instrucciones en el siguiente enlace:&lt;br /&gt;
&lt;br /&gt;
==&amp;gt; &lt;b&gt;&lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Libreria-de-Utilidades-para-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;SwingUtils - Librería de Utilidades para Java Swing&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
La librería &lt;u&gt;SwingUtils&lt;/u&gt; nos provee la clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;TableModelGeneric&lt;/span&gt; de la cual podemos extender los modelos de datos que creemos para nuestros &lt;b&gt;JTable&lt;/b&gt;. Así que veamos primero la clase modelo que usaremos para nuestro ejemplo:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;public class Pais {
    
    private Integer id;
    private String codigo;
    private String nombre;

    public Pais(Integer id, String codigo, String nombre) {
        this.id = id;
        this.codigo = codigo;
        this.nombre = nombre;
    }

    public Pais() {
    }

    public Integer getId() {
        return id;
    }

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

    public String getCodigo() {
        return codigo;
    }

    public void setCodigo(String codigo) {
        this.codigo = codigo;
    }

    public String getNombre() {
        return nombre;
    }

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

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 13 * hash + Objects.hashCode(this.id);
        hash = 13 * hash + Objects.hashCode(this.codigo);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Pais other = (Pais) obj;
        if (!Objects.equals(this.codigo, other.codigo)) {
            return false;
        }
        if (!Objects.equals(this.id, other.id)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return nombre;
    }
    
}
&lt;/pre&gt;
&lt;br /&gt;
Éste será el tipo de dato que ocuparán los datos de nuestro &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JTable&lt;/span&gt;. Ahora veamos el modelo de datos que usará el JTable de nuestro modelo:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;public class MiModeloTabla extends TableModelGeneric&amp;lt;Pais&amp;gt; {
    
    /**
     * Este Constructor sin parámetros lo usaríamos para el comportamiento por
     * defecto de un JTable el cual deseemos inicializar con las propiedades
     * de tipo de dato y título de columnas predefinidas pero sin lista de datos
     */
    public MiModeloTabla() {
        super(
                new Class[]{Integer.class, String.class, String.class}, 
                new String[]{&quot;Id&quot;, &quot;Código&quot;, &quot;Nombre&quot;}, 
                new ArrayList&amp;lt;&amp;gt;()
        );
    }
    
    /**
     * Este Constructor lo usaríamos para el comportamiento de un JTable el cual
     * deseemos inicializar con las propiedades de tipo de dato y título de
     * columnas predefinidas, pero con una lista de datos proveída por nosotros
     * desde la creación del modelo de datos
     * @param listElements 
     */
    public MiModeloTabla(List&amp;lt;Pais&amp;gt; listElements) {
        super(
                new Class[]{Integer.class, String.class, String.class}, 
                new String[]{&quot;Id&quot;, &quot;Código&quot;, &quot;Nombre&quot;}, 
                listElements
        );
    }
    
    /**
     * Este Constructor lo usaríamos para el caso en que deseemos proporcionar
     * todas las propiedades de un JTable desde el momento en que creamos
     * nuestro modelo de datos
     * @param typeColumns
     * @param titleColumns
     * @param listElements 
     */
    public MiModeloTabla(Class[] typeColumns, String[] titleColumns, List&amp;lt;Pais&amp;gt; listElements) {
        super(typeColumns, titleColumns, listElements);
    }
    
    /**
     * Este método es necesario que lo sobre-escribamos, ya que mediante éste
     * indicamos los datos que se muestran en cada columna y fila del JTable
     * @param rowIndex
     * @param columnIndex
     * @return 
     */
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        switch (columnIndex) {
            case 0:
                return getListElements().get(rowIndex).getId();
            case 1:
                return getListElements().get(rowIndex).getCodigo();
            case 2:
                return getListElements().get(rowIndex).getNombre();
            default:
                return null;
        }
    }
    
}
&lt;/pre&gt;
&lt;br /&gt;
En nuestro modelo de datos sólo necesitamos de tres cosas:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1.&lt;/b&gt; Extender de la clase&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;TableModelGeneric&lt;/span&gt; la cual nos provee la librería &lt;b&gt;SwingUtils&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2.&lt;/b&gt; Crear un constructor que llame al constructor de la clase&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;TableModelGeneric&lt;/span&gt;. En este ejemplo vemos tres ejemplos, aunque en verdad sólo bastaría con un constructor; todo depende de cómo necesitemos crear nuestros JTable e inicializar sus respectivos modelos de datos.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3.&lt;/b&gt; Sobre-escribir el método&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;getValueAt()&lt;/span&gt; el cual pertenece a la interface &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;TableModel&lt;/span&gt;, ya que mediante éste método indicamos los datos que se muestran en cada columna y fila del JTable.&lt;br /&gt;
&lt;br /&gt;
Con ésto sólo nos resta inicializar nuestro modelo de datos y asignarlo al JTable.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Implementar nuestro modelo de datos en un JTable de Java Swing&lt;/b&gt;&lt;/h3&gt;
Mediante la librería &lt;b&gt;&lt;i&gt;&lt;u&gt;SwingUtils&lt;/u&gt;&lt;/i&gt;&lt;/b&gt; podemos implementar nuestro modelo de datos de forma rápida, ya que nos provee algunos métodos a través de la clase&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JTableUtils&lt;/span&gt;, aunque en este caso sólo haremos uso de uno de ellos. Veamos entonces como quedaría nuestro ejemplo:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;public class MiVista extends javax.swing.JFrame {
   
    private javax.swing.JTable jTable1;
       
    public MiVista() {
        initComponents();
         
        List&amp;lt;Pais&amp;gt; listaPaises = new ArrayList&amp;lt;&amp;gt;();
        listaPaises.add(new Pais(1, &quot;CO&quot;, &quot;Colombia&quot;));
        listaPaises.add(new Pais(2, &quot;AR&quot;, &quot;Argentina&quot;));
        listaPaises.add(new Pais(3, &quot;VE&quot;, &quot;Venezuela&quot;));
        listaPaises.add(new Pais(4, &quot;EC&quot;, &quot;Ecuador&quot;));
        listaPaises.add(new Pais(5, &quot;PE&quot;, &quot;Perú&quot;));
        listaPaises.add(new Pais(6, &quot;BO&quot;, &quot;Bolivia&quot;));
        listaPaises.add(new Pais(7, &quot;MX&quot;, &quot;México&quot;));
         
        JTableUtils.setProperties(jTable1, new Font(&quot;Arial&quot;, Font.BOLD, 13), new MiModeloTabla(listaPaises));
    }

    private void initComponents() {
        // Código generado por NetBeans
    }
       
}
&lt;/pre&gt;
&lt;br /&gt;
En este caso, usamos uno de los métodos estáticos &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;setProperties()&lt;/span&gt; de la clase&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JTableUtils&lt;/span&gt;; cabe aclarar que esta clase sobrecarga varias veces éste método, así que para este ejemplo ocupamos el que recibe tres parámetros: El JTable que usaremos, la fuente de los títulos del JTable y la inicialización del modelo de datos que creamos.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_xNMmOGe3LczdXkwJpHQbkv55kesX7MvNRP6Zau7Sp2qkeXv_4eDgbaJiA7mPZH6LP8hTdbviV_toybtoKqQypV6lV9xe8JiWQtOXxXr12dY-H3mqDjJItMVvG-8RnWlPaUGfzNKyYDgq/s1600/SwingUtils+-+Crear+JTable+con+Modelo+de+Datos+Gen%25C3%25A9rico+%2528Java+Swing%2529.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;SwingUtils - Crear JTable con Modelo de Datos Genérico (Java Swing)&quot; border=&quot;0&quot; data-original-height=&quot;157&quot; data-original-width=&quot;354&quot; height=&quot;176&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_xNMmOGe3LczdXkwJpHQbkv55kesX7MvNRP6Zau7Sp2qkeXv_4eDgbaJiA7mPZH6LP8hTdbviV_toybtoKqQypV6lV9xe8JiWQtOXxXr12dY-H3mqDjJItMVvG-8RnWlPaUGfzNKyYDgq/s400/SwingUtils+-+Crear+JTable+con+Modelo+de+Datos+Gen%25C3%25A9rico+%2528Java+Swing%2529.jpg&quot; title=&quot;SwingUtils - Crear JTable con Modelo de Datos Genérico (Java Swing)&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Esta es la captura de pantalla de nuestro ejemplo. Como hemos visto, es muy sencillo crear modelos de datos pseudo-genéricos e implementarlos en nuestros &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JTable&lt;/span&gt; a través de la librería &lt;b&gt;&lt;i&gt;&lt;u&gt;SwingUtils&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/4941540754510390848/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2017/10/SwingUtils-Crear-JTable-con-Modelo-de-Datos-Generico-Java-Swing.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/4941540754510390848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/4941540754510390848'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2017/10/SwingUtils-Crear-JTable-con-Modelo-de-Datos-Generico-Java-Swing.html' title='SwingUtils - Crear JTable con Modelo de Datos Genérico (Java Swing)'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_xNMmOGe3LczdXkwJpHQbkv55kesX7MvNRP6Zau7Sp2qkeXv_4eDgbaJiA7mPZH6LP8hTdbviV_toybtoKqQypV6lV9xe8JiWQtOXxXr12dY-H3mqDjJItMVvG-8RnWlPaUGfzNKyYDgq/s72-c/SwingUtils+-+Crear+JTable+con+Modelo+de+Datos+Gen%25C3%25A9rico+%2528Java+Swing%2529.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-8083090691561454694</id><published>2017-09-27T14:24:00.001-05:00</published><updated>2019-02-23T23:26:19.149-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java Swing"/><category scheme="http://www.blogger.com/atom/ns#" term="SwingUtils"/><title type='text'>SwingUtils - Sincronizar datos de un JComboBox con el Controlador (Java Swing)</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
En un artículo anterior estuve explicando &lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Crear-JComboBox-con-Modelo-de-Datos-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;cómo crear un &lt;u&gt;JComboBox&lt;/u&gt; en Java usando un Modelo de Datos genérico&lt;/a&gt; que nos provee la librería &lt;u&gt;&lt;i&gt;&lt;b&gt;SwingUtils&lt;/b&gt;&lt;/i&gt;&lt;/u&gt;. Ahora veremos cómo &lt;i&gt;sincronizar los datos de un JComboBox&lt;/i&gt; con un objeto de nuestro modelo de datos declarado en el controlador.&lt;br /&gt;
&lt;br /&gt;
Como estuvimos viendo, un &lt;b&gt;JComboBox&lt;/b&gt; nos permite trabajar con tipos de datos genéricos y dicho dato genérico es heredado por su modelo de datos, lo cual quiere decir que podemos trabajar incluso con tipos de datos de clases creadas por nosotros mismos.&lt;br /&gt;
&lt;br /&gt;
Lo primero que debemos hacer es descargarnos la librería &lt;b&gt;SwingUtils&lt;/b&gt;. Para hacerlo puedes revisar las instrucciones en el siguiente artículo:&lt;br /&gt;
&lt;br /&gt;
==&amp;gt; &lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Libreria-de-Utilidades-para-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;SwingUtils - Librería de Utilidades para Java Swing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Anotaciones para usar en el Controlador&lt;/b&gt;&lt;/h3&gt;
Las anotaciones que podemos usar en el Controlador según sean nuestras necesidades son las siguientes:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&lt;/b&gt; ModelBean&lt;br /&gt;
&lt;b&gt;-&lt;/b&gt; PropertyController&lt;br /&gt;
&lt;br /&gt;
Para saber como usar estas anotaciones puedes revisar esta misma sección de &quot;Anotaciones para usar en el Controlador&quot; en el siguiente artículo:&lt;br /&gt;
&lt;br /&gt;
==&amp;gt; &lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Sincronizar-datos-de-un-JTextField-con-el-Controlador-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;SwingUtils - Sincronizar datos de un JTextField con el Controlador (Java Swing)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
El modelo de datos que usaremos para nuestro JComboBox será el siguiente:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;public class Pais {
    
    private Integer id;
    private String codigo;
    private String nombre;

    public Pais(Integer id, String codigo, String nombre) {
        this.id = id;
        this.codigo = codigo;
        this.nombre = nombre;
    }

    public Pais() {
    }

    public Integer getId() {
        return id;
    }

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

    public String getCodigo() {
        return codigo;
    }

    public void setCodigo(String codigo) {
        this.codigo = codigo;
    }

    public String getNombre() {
        return nombre;
    }

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

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 13 * hash + Objects.hashCode(this.id);
        hash = 13 * hash + Objects.hashCode(this.codigo);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Pais other = (Pais) obj;
        if (!Objects.equals(this.codigo, other.codigo)) {
            return false;
        }
        if (!Objects.equals(this.id, other.id)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return nombre;
    }
    
}
&lt;/pre&gt;
&lt;br /&gt;
Como vemos, es necesario sobrescribir los métodos &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;toString()&lt;/span&gt;, &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;equals()&lt;/span&gt; y &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;hashCode()&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
El modelo de datos que usaremos para sincronizarlo con la vista será el siguiente:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;public class MiModelo {

    private Pais pais;

    public Pais getPais() {
        return pais;
    }

    public void setPais(Pais pais) {
        this.pais = pais;
    }
    
}
&lt;/pre&gt;
&lt;br /&gt;
Recuerda que los Getter y Setter de los atributos son requeridos para asignar y obtener el valor de los atributos.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Anotaciones para usar en un JComboBox de Java Swing&lt;/b&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;!-- anuncios --&gt;
La librería &lt;i&gt;SwingUtils&lt;/i&gt; en su actual versión, permite asignar la siguiente anotación a un componente &lt;b&gt;Java Swing&lt;/b&gt; de tipo &lt;u&gt;JComboBox&lt;/u&gt;:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; ComboBoxView&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Como ya he mencionado, el tipo de dato del API de Java a usar en el modelo de datos puede ser de cualquier tipo, ya que los &lt;i&gt;JComboBox&lt;/i&gt; nos permiten trabajar con tipos de datos genéricos. Así pues, la forma de usar esta anotación sería la siguiente:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: java&quot;&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;
@ComboBoxView(name = &quot;miModelo1.pais&quot;, required = true, requiredMessage = &quot;Debe seleccionar un elemento&quot;)&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
private javax.swing.JComboBox&amp;lt;Pais&amp;gt; jComboBox1;&lt;/div&gt;
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Además del nombre del componente (&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;name&lt;/span&gt;), es posible usar también los atributos&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;required&lt;/span&gt;&amp;nbsp;y&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;requiredMessage&lt;/span&gt;. El primero, es una propiedad booleana mediante la cual podemos indicar si queremos que sea obligatoria o no la selección de un elemento; y el segundo, es un mensaje personalizado que se mostrará al usuario en formato de error, en caso de que la propiedad required sea true y no se haya seleccionado ningún elemento del JComboBox.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Declaramos nuestro controlador en la vista e inyectamos la dependencia de ésta para poder sincronizarlos. Además setearemos el modelo de datos para nuestro &lt;i&gt;JComboBox&lt;/i&gt;, para lo cual haremos uso de la clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JComboBoxUtils&lt;/span&gt; de la librería &lt;b&gt;SwingUtils&lt;/b&gt;:&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;public class MiVista extends javax.swing.JFrame {
  
    private final MiControlador miControlador;
      
    public MiVista() {
        initComponents();
          
        this.miControlador = new MiControlador(this);
        
        List&amp;lt;Pais&amp;gt; listaPaises = new ArrayList&amp;lt;&amp;gt;();
        listaPaises.add(new Pais(1, &quot;CO&quot;, &quot;Colombia&quot;));
        listaPaises.add(new Pais(2, &quot;AR&quot;, &quot;Argentina&quot;));
        listaPaises.add(new Pais(3, &quot;VE&quot;, &quot;Venezuela&quot;));
        listaPaises.add(new Pais(4, &quot;EC&quot;, &quot;Ecuador&quot;));
        listaPaises.add(new Pais(5, &quot;PE&quot;, &quot;Perú&quot;));
        listaPaises.add(new Pais(6, &quot;BO&quot;, &quot;Bolivia&quot;));
        listaPaises.add(new Pais(7, &quot;MX&quot;, &quot;México&quot;));
        
        JComboBoxUtils.setProperties(jComboBox1, listaPaises);
    }
      
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Tal cual como lo vimos en el artículo sobre &lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Sincronizar-datos-de-un-JTextField-con-el-Controlador-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;Cómo sincronizar un JTextField con el controlador&lt;/a&gt;, los datos los obtendríamos y seteariamos en la vista de la siguiente forma:&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;// Método para guardar los datos
public void guardar() {
    super.changeData(TipoUpdateEnum.MODEL);
    printConsole();
}
  
// Método para limpiar el formulario
public void limpiar() {
    miModelo1 = new MiModelo();
    super.changeData(TipoUpdateEnum.VIEW);
}
  
// Método para imprimir los datos por consola
public void printConsole() {
    System.out.println(&quot;País Seleccionado Modelo 1: &quot; + miModelo1.getPais());
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Puedes revisar &lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Sincronizar-datos-de-un-JTextField-con-el-Controlador-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;este artículo&lt;/a&gt; para comprender a fondo cómo funciona éste método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;super.changeData()&lt;/span&gt;, que como tal es el que realiza la actualización automática de los datos de la vista al modelo de datos en el controlador y viceversa.&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhde0i3N-Zjc9PFea9f0rwjabUk_13CMDAUrcHYqb6fcXBX0-zyL7ltyTtxGrJLcMY_eWibGxCqE4e9qHVOtu0su35w6NoSvJL_Fkxbpj5lZRYDV7SCShVansBLPGc0CDcBZQDzbhYACTl7/s1600/SwingUtils+-+Sincronizar+datos+de+un+JComboBox+con+el+Controlador+%2528Java+Swing%2529.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;SwingUtils - Sincronizar datos de un JComboBox con el Controlador (Java Swing)&quot; border=&quot;0&quot; data-original-height=&quot;90&quot; data-original-width=&quot;215&quot; height=&quot;133&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhde0i3N-Zjc9PFea9f0rwjabUk_13CMDAUrcHYqb6fcXBX0-zyL7ltyTtxGrJLcMY_eWibGxCqE4e9qHVOtu0su35w6NoSvJL_Fkxbpj5lZRYDV7SCShVansBLPGc0CDcBZQDzbhYACTl7/s320/SwingUtils+-+Sincronizar+datos+de+un+JComboBox+con+el+Controlador+%2528Java+Swing%2529.png&quot; title=&quot;SwingUtils - Sincronizar datos de un JComboBox con el Controlador (Java Swing)&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Como podemos apreciar, usando la librería &lt;b&gt;&lt;i&gt;&lt;u&gt;SwingUtils&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;,&amp;nbsp; es muy rápido sincronizar fácilmente datos de un &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JComboBox&lt;/span&gt; con el Controlador para que la información de nuestra vista se actualice rápidamente en el modelo de datos y viceversa.&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/8083090691561454694/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2017/09/SwingUtils-Sincronizar-datos-de-un-JComboBox-con-el-Controlador-Java-Swing.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/8083090691561454694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/8083090691561454694'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2017/09/SwingUtils-Sincronizar-datos-de-un-JComboBox-con-el-Controlador-Java-Swing.html' title='SwingUtils - Sincronizar datos de un JComboBox con el Controlador (Java Swing)'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhde0i3N-Zjc9PFea9f0rwjabUk_13CMDAUrcHYqb6fcXBX0-zyL7ltyTtxGrJLcMY_eWibGxCqE4e9qHVOtu0su35w6NoSvJL_Fkxbpj5lZRYDV7SCShVansBLPGc0CDcBZQDzbhYACTl7/s72-c/SwingUtils+-+Sincronizar+datos+de+un+JComboBox+con+el+Controlador+%2528Java+Swing%2529.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-4421242592490946869</id><published>2017-09-20T12:10:00.003-05:00</published><updated>2018-03-01T15:27:31.087-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java Swing"/><category scheme="http://www.blogger.com/atom/ns#" term="SwingUtils"/><title type='text'>SwingUtils - Crear JComboBox con Modelo de Datos Generico (Java Swing)</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-InivL1Wg_X8ddVxT9UGq4OBXY3G0lQ_2ybqvJn1PuH1ZPXSHjlg7Qtx4fDIz9Du-uvqFLLRszRCU2H3L9zt9ugBmqZOjJlQqGa-UJGnTKd0rlRlXNZvEMe46jSh0zYQ_rEkl6I5I4zbi/s1600/SwingUtils+-+Crear+JComboBox+con+Modelo+de+Datos+Generico+%2528Java+Swing%2529+-+JComboBox.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;SwingUtils - Crear JComboBox con Modelo de Datos Generico (Java Swing) - JComboBox Desplegado&quot; border=&quot;0&quot; data-original-height=&quot;257&quot; data-original-width=&quot;159&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-InivL1Wg_X8ddVxT9UGq4OBXY3G0lQ_2ybqvJn1PuH1ZPXSHjlg7Qtx4fDIz9Du-uvqFLLRszRCU2H3L9zt9ugBmqZOjJlQqGa-UJGnTKd0rlRlXNZvEMe46jSh0zYQ_rEkl6I5I4zbi/s1600/SwingUtils+-+Crear+JComboBox+con+Modelo+de+Datos+Generico+%2528Java+Swing%2529+-+JComboBox.png&quot; title=&quot;SwingUtils - Crear JComboBox con Modelo de Datos Generico (Java Swing) - JComboBox Desplegado&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
En este artículo veremos las opciones que nos ofrece la librería &lt;b&gt;&lt;i&gt;SwingUtils&lt;/i&gt;&lt;/b&gt; para trabajar de forma sencilla con componentes de tipo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;javax.swing.JComboBox&lt;/span&gt; y un modelo de datos genérico.&lt;br /&gt;
&lt;br /&gt;
El &lt;u&gt;API de Java Swing&lt;/u&gt; nos ofrece por defecto la clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/javase/8/docs/api/javax/swing/DefaultComboBoxModel.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;javax.swing.DefaultComboBoxModel&lt;/a&gt;&lt;/span&gt; para setearle un Model a nuestros JComboBox, sin embargo, al analizarla a detalle, encontré cosas que no me convencieron de trabajar directamente con dicha clase:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&lt;/b&gt; La primera es que la clase &lt;b&gt;DefaultComboBoxModel&lt;/b&gt; guarda los datos en un &lt;b&gt;Vector&lt;/b&gt;, lo que hace que los datos estén sincronizados por defecto, y al menos en mi experiencia, son muy pocos los casos en los que vamos a necesitar una colección de datos sincronizada dentro de un &lt;i&gt;JComboBox&lt;/i&gt;, además recordemos que la sincronización requiere de más recursos de máquina.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&lt;/b&gt; La segunda, es que podemos encontrarnos casos en los que pasemos una colección de datos la cual por defecto no permita modificaciones, como el caso de &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Arrays.asList(T ...a)&lt;/span&gt; del paquete &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;java.util.Arrays&lt;/span&gt;; si nosotros le pasamos por ejemplo la colección &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Arrays.asList(&quot;a&quot;, &quot;b&quot;, &quot;c&quot;).toArray()&lt;/span&gt; al constructor de &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;DefaultComboBoxModel(E[] item)&lt;/span&gt;, éste lo tomará tal cual y no podremos modificar dicho modelo de datos posteriormente, es decir, que si quisiéramos agregar el elemento &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&quot;d&quot;&lt;/span&gt;, obtendríamos una excepción.&lt;br /&gt;
&lt;br /&gt;
Por estas razones, decidí agregar la clase&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ComboBoxModelGeneric&lt;/span&gt; a la librería &lt;b&gt;SwingUtils&lt;/b&gt;, la cual, a pesar de estar basada en la clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;DefaultComboBoxModel&lt;/span&gt;, difiere de ésta en lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&lt;/b&gt; La clase &lt;b&gt;ComboBoxModelGeneric&lt;/b&gt; guarda los datos en un &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;java.util.List&lt;/span&gt;, lo que evita la sincronización por defecto y ahorra recursos de máquina. ¿Y en caso de que necesitemos sincronización? Como mencioné, no es muy frecuente que necesitemos sincronización de datos, sin embargo &lt;i&gt;SwingUtils&lt;/i&gt; también soporta el uso de listas sincronizadas en caso de que lo requiramos.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&lt;/b&gt; Por otro lado, los constructores de la clase &lt;b&gt;ComboBoxModelGeneric&lt;/b&gt; siempre van a convertir los datos que reciban, en una colección de tipo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;java.util.ArrayList&lt;/span&gt;, lo que garantiza que podamos modificar los datos del modelo de nuestro &lt;i&gt;JComboBox&lt;/i&gt; cuando así se requiera.&lt;br /&gt;
&lt;br /&gt;
Ahora si, vamos a ver cómo podemos hacer uso de un modelo de datos para nuestro &lt;u&gt;JComboBox&lt;/u&gt; a través de la clase &lt;b&gt;ComboBoxModelGeneric&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Usar un Modelo de Datos Genérico en un JComboBox de Java Swing&lt;/b&gt;&lt;/h3&gt;
&lt;!-- anuncios --&gt;
Lo primero que debemos hacer es importar la librería &lt;b&gt;&lt;u&gt;SwingUtils&lt;/u&gt;&lt;/b&gt; a nuestro proyecto. Puedes ver las instrucciones en el siguiente enlace:&lt;br /&gt;
&lt;br /&gt;
==&amp;gt; &lt;b&gt;&lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Libreria-de-Utilidades-para-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;SwingUtils - Librería de Utilidades para Java Swing&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Para usar un modelo de la clase &lt;b&gt;ComboBoxModelGeneric&lt;/b&gt;, no necesitamos mucho código. Esta clase podemos usarla de forma genérica en cualquier &lt;i&gt;JComboBox&lt;/i&gt;, por lo tanto, decidí crear una clase de utilería llamada &lt;b&gt;JComboBoxUtils&lt;/b&gt;, mediante la cual es muy fácil asociar nuestro modelo de datos.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Esta clase contiene varios métodos estáticos. Algunos de estos métodos son:&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;setProperties(final JComboBox&amp;lt;E&amp;gt; jComboBox, List&amp;lt;E&amp;gt; list)

setProperties(final JComboBox&amp;lt;E&amp;gt; jComboBox, List&amp;lt;E&amp;gt; list, boolean addElementNullDefault, String textNoSeleccionable)

setProperties(final JComboBox&amp;lt;E&amp;gt; jComboBox, List&amp;lt;E&amp;gt; list, boolean addElementNullDefault, String textNoSeleccionable, boolean isSynchronized, boolean needDetectConcurrentModifications, Class clazz, String nameMethod)
&lt;/pre&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
El primer método es la configuración rápida por defecto. Con éste método, tan sólo debemos pasar nuestro JComboBox, el cual ya debe estar inicializado previamente, y la lista de datos que deseamos agregar a nuestro modelo. Éste método además de crear el modelo de datos usando la clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ComboBoxModelGeneric&lt;/span&gt; y asociárselo al &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JComboBox&lt;/span&gt;, crea un elemento &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;null&lt;/span&gt; con la leyenda &quot;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;- Seleccione -&lt;/span&gt;&quot; al principio de la lista de datos.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
El segundo método funciona de forma similar al segundo; sin embargo, a éste podemos indicarle si queremos que agregue el elemento &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;null&lt;/span&gt; por defecto al principio de la lista de datos o no, y la leyenda que quisiéramos que tuviera este elemento en caso de que indiquemos &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;true&lt;/span&gt; al parámetro &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;addElementNullDefault&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
El tercer método, correspondería a la configuración completa, y además de las configuraciones mencionadas en los dos métodos anteriores, podemos indicarle si queremos que sea una lista de datos sincronizada o no, además de poderle indicar si queremos que nuestra lista detecte modificaciones concurrentes. Para entender en qué afecta este atributo a la lista de datos, puedes revisar el siguiente artículo:&amp;nbsp;&lt;a href=&quot;http://www.eljavatar.com/2017/11/Diferencias-entre-ArrayList-sincronizado-y-CopyOnWriteArrayList-en-Java.html&quot; target=&quot;_blank&quot;&gt;Diferencias entre ArrayList sincronizado y CopyOnWriteArrayList en Java&lt;/a&gt;. Este cambio sólo tendrá efecto si se pasa el parámetro&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;isSynchronized&lt;/span&gt; en &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;true&lt;/span&gt;. Los dos últimos parámetros corresponden a cómo queremos que se muestren los datos; veamos cómo los usaríamos.&lt;br /&gt;
&lt;br /&gt;
Lo que se muestra en los ítems de un &lt;i&gt;JComboBox&lt;/i&gt; por defecto son String, así que si le pasamos una lista de objetos creados por nosotros, por defecto se mostrará lo que esté en el método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;toString()&lt;/span&gt;. ¿Pero qué pasa si nuestro método toString() ya está siendo usado para otra cosa? No se, supongamos que para alguna característica de nuestra aplicación se está devolviendo un código o algo así, pero en nuestro JComboBox lo que deseamos es mostrar una descripción, ¿Qué hacemos en dicho caso?&lt;br /&gt;
&lt;br /&gt;
Para eso son estos dos últimos parámetros. El primero es el &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;class&lt;/span&gt; de nuestro objeto, que dicho sea de paso, debe ser del mismo tipo que la lista de datos que estamos pasando al &lt;b&gt;JComboBox&lt;/b&gt;, y el segundo es el nombre del método que retornará el valor a mostrar en cada ítem; dicho método debe retornar un valor de tipo String y debe estar declarado en la clase que pasamos en el primer parámetro.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Veamos un sencillo ejemplo de cómo podemos hacer uso de uno de éstos métodos:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;List&amp;lt;String&amp;gt; lista = Arrays.asList(&quot;Amarillo&quot;, &quot;Azul&quot;, &quot;Rojo&quot;, &quot;Verde&quot;, &quot;Gris&quot;, &quot;Negro&quot;, &quot;Blanco&quot;);
JComboBoxUtils.setProperties(miJComboBox, lista);
&lt;/pre&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF6mqUn4W7jTxmeBvBD7JzZkhMFgf1kxlN3t-KYu4Dmhnnlm-wpMy9uf1fRoMdOeDq1z82Kchk421Is-HKrRkF6aLd0naXNZQzyONAPLJzYvE2nqLFyW9z1AgaIbAdnFmFaFd3e_v2SGKb/s1600/SwingUtils+-+Crear+JComboBox+con+Modelo+de+Datos+Generico+%2528Java+Swing%2529+-+Elemento+null+seleccionado.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;SwingUtils - Crear JComboBox con Modelo de Datos Generico (Java Swing) - Elemento null seleccionado&quot; border=&quot;0&quot; data-original-height=&quot;264&quot; data-original-width=&quot;474&quot; height=&quot;178&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF6mqUn4W7jTxmeBvBD7JzZkhMFgf1kxlN3t-KYu4Dmhnnlm-wpMy9uf1fRoMdOeDq1z82Kchk421Is-HKrRkF6aLd0naXNZQzyONAPLJzYvE2nqLFyW9z1AgaIbAdnFmFaFd3e_v2SGKb/s320/SwingUtils+-+Crear+JComboBox+con+Modelo+de+Datos+Generico+%2528Java+Swing%2529+-+Elemento+null+seleccionado.png&quot; title=&quot;SwingUtils - Crear JComboBox con Modelo de Datos Generico (Java Swing) - Elemento null seleccionado&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhf95sd2J2_uKToCFI0Md4gcORJf0fDMZcFKzJLGQMXTxUvy0LrVMdkGyJjVz3LV5tWhpgWx66LbJfpygKjnQTWNI9cbpOmgEqdL3CQZCHooLrG0rc_Co136uLiebXomaR1WDwhiCJWc4Rh/s1600/SwingUtils+-+Crear+JComboBox+con+Modelo+de+Datos+Generico+%2528Java+Swing%2529+-+Elemento+Verde+seleccionado.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;SwingUtils - Crear JComboBox con Modelo de Datos Generico (Java Swing) - Elemento Verde seleccionado&quot; border=&quot;0&quot; data-original-height=&quot;267&quot; data-original-width=&quot;482&quot; height=&quot;177&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhf95sd2J2_uKToCFI0Md4gcORJf0fDMZcFKzJLGQMXTxUvy0LrVMdkGyJjVz3LV5tWhpgWx66LbJfpygKjnQTWNI9cbpOmgEqdL3CQZCHooLrG0rc_Co136uLiebXomaR1WDwhiCJWc4Rh/s320/SwingUtils+-+Crear+JComboBox+con+Modelo+de+Datos+Generico+%2528Java+Swing%2529+-+Elemento+Verde+seleccionado.png&quot; title=&quot;SwingUtils - Crear JComboBox con Modelo de Datos Generico (Java Swing) - Elemento Verde seleccionado&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Recordemos que un &lt;b&gt;JComboBox&lt;/b&gt; nos permite trabajar con tipos de datos genéricos y dicho dato genérico es heredado por su modelo de datos, es decir, que no solamente nos debemos limitar a trabajar con datos de tipo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;String&lt;/span&gt;, sino que podemos tener modelos de datos con otros tipos como enums u objetos creados por nosotros mismos.&lt;br /&gt;
&lt;br /&gt;
Lo único que debemos tener en cuenta es realizar los siguientes ajustes en la clase que usaremos como tipo de dato para nuestro &lt;i&gt;JComboBox&lt;/i&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&lt;/b&gt; Sobrescribir el método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;toString()&lt;/span&gt;, ya que este es el texto que se mostrará en cada ítem del &lt;u&gt;JComboBox&lt;/u&gt;&amp;nbsp;en caso de que no pasemos los dos últimos parámetros que explicamos. Si pasamos dichos parámetros, necesitaríamos crear el método que nos retornará el texto que se mostraría en cada ítem.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&lt;/b&gt; Sobrescribir los métodos &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;hashCode()&lt;/span&gt; y &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;equals()&lt;/span&gt;. En caso de que sean enums, estos métodos no son necesarios; sin embargo, si se trata de una clase creada por nosotros, debemos sobrescribirlos pues son los que se usan para asignar y obtener un valor de un &lt;b&gt;JComboBox&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Como podemos apreciar, es muy sencillo asociar un modelo de datos genérico a cualquier JComboBox de &lt;b&gt;&lt;a href=&quot;http://www.eljavatar.com/search/label/Java%20Swing?&amp;amp;max-results=7&quot; target=&quot;_blank&quot;&gt;Java Swing&lt;/a&gt;&lt;/b&gt; que tengamos usando la librería &lt;b&gt;&lt;i&gt;&lt;u&gt;SwingUtils&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;.&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/4421242592490946869/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2017/09/SwingUtils-Crear-JComboBox-con-Modelo-de-Datos-Java-Swing.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/4421242592490946869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/4421242592490946869'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2017/09/SwingUtils-Crear-JComboBox-con-Modelo-de-Datos-Java-Swing.html' title='SwingUtils - Crear JComboBox con Modelo de Datos Generico (Java Swing)'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-InivL1Wg_X8ddVxT9UGq4OBXY3G0lQ_2ybqvJn1PuH1ZPXSHjlg7Qtx4fDIz9Du-uvqFLLRszRCU2H3L9zt9ugBmqZOjJlQqGa-UJGnTKd0rlRlXNZvEMe46jSh0zYQ_rEkl6I5I4zbi/s72-c/SwingUtils+-+Crear+JComboBox+con+Modelo+de+Datos+Generico+%2528Java+Swing%2529+-+JComboBox.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-1823642340847834998</id><published>2017-09-15T15:36:00.000-05:00</published><updated>2018-02-27T15:28:57.504-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java Swing"/><category scheme="http://www.blogger.com/atom/ns#" term="SwingUtils"/><title type='text'>SwingUtils - Sincronizar datos de un JCheckBox con el Controlador (Java Swing)</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
En este artículo veremos como sincronizar un &lt;b&gt;JCheckBox&lt;/b&gt; de &lt;i&gt;java swing&lt;/i&gt; con un atributo de tipo booleano del controlador para que los datos se actualicen automáticamente tanto en la vista (JCheckBox) como en el modelo de datos (atributo independiente u atributo de objeto compuesto declarados en el controlador), usando la librería &lt;b&gt;SwingUtils&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
La librería &lt;u&gt;SwingUtils&lt;/u&gt; no sólo permite hacer esta sincronización con componentes de tipo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;javax.swing.JCheckBox&lt;/span&gt;; también es posible usarla con componentes de tipo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;javax.swing.JToggleButton&lt;/span&gt; y los otros componentes que heredan de esta clase:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;javax.swing.JToggleButton
javax.swing.JCheckBox
javax.swing.JRadioButton
&lt;/pre&gt;
&lt;br /&gt;
Lo primero que debemos hacer es descargar la librería &lt;i&gt;SwingUtils&lt;/i&gt;, para lo cual puedes revisar las instrucciones en el siguiente enlace:&lt;br /&gt;
&lt;br /&gt;
==&amp;gt; &lt;b&gt;&lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Libreria-de-Utilidades-para-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;SwingUtils - Librería de Utilidades para Java Swing&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;Anotaciones para usar en el Controlador&lt;/b&gt;&lt;/h3&gt;
Las anotaciones que podemos usar en el Controlador según sean nuestras necesidades son las siguientes:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&lt;/b&gt; ModelBean&lt;br /&gt;
&lt;b&gt;-&lt;/b&gt; PropertyController&lt;br /&gt;
&lt;br /&gt;
Para saber como usar estas anotaciones puedes revisar esta misma sección de &quot;&lt;i&gt;Anotaciones para usar en el Controlador&lt;/i&gt;&quot; en el siguiente artículo:&lt;br /&gt;
&lt;br /&gt;
==&amp;gt; &lt;b&gt;&lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Sincronizar-datos-de-un-JTextField-con-el-Controlador-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;SwingUtils - Sincronizar datos de un JTextField con el Controlador (Java Swing)&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
El modelo de datos que usaremos es el siguiente:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;public class MiModelo {

    private Boolean booleanModelo;

    public Boolean getBooleanModelo() {
        return booleanModelo;
    }

    public void setBooleanModelo(Boolean booleanModelo) {
        this.booleanModelo = booleanModelo;
    }
    
}
&lt;/pre&gt;
&lt;br /&gt;
Recuerda que los Getter y Setter de los atributos son requeridos para asignar y obtener el valor de los atributos.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Anotaciones para usar en un JCheckBox, JRadioButton o JToggleButton de Java Swing&lt;/b&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;!-- anuncios --&gt;
La librería &lt;b&gt;&lt;i&gt;SwingUtils&lt;/i&gt;&lt;/b&gt; en su actual versión, permite asignar un tipo de anotación a un componente de tipo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JCheckBox&lt;/span&gt;, &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JRadioButton&lt;/span&gt; o &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JToggleButton&lt;/span&gt;:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; ToggleButtonView&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Ésta anotación puede ser usada indistintamente de la misma forma en cualquiera de estos tres tipos de componente, pues el valor que nos devuelve cada uno de ellos es siempre un booleano, por lo tanto, el tipo de dato del API de Java a usar en el modelo de datos puede ser:&lt;/div&gt;
&lt;br /&gt;
&lt;pre&gt;Boolean o boolean
&lt;/pre&gt;
&lt;br /&gt;
Como podemos apreciar, podemos usar indistintamente el objeto o el tipo primitivo.&lt;br /&gt;
&lt;br /&gt;
La forma de usar ésta anotación sería la siguiente:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;@ToggleButtonView(name = &quot;miModelo1.booleanModelo&quot;)
private javax.swing.JCheckBox jCheckBox1;
&lt;/pre&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Recuerda que el uso para componentes de tipo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JRadioButton&lt;/span&gt; o &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JToggleButton&lt;/span&gt; es igual, sin embargo, para este tutorial sólo haremos el ejemplo con un &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JCheckBox&lt;/span&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Declaramos nuestro controlador en la vista e inyectamos la dependencia de ésta para poder sincronizarlos:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: java&quot;&gt;public class MiVista extends javax.swing.JFrame {
 
    private final MiControlador miControlador;
     
    public MiVista() {
        initComponents();
         
        this.miControlador = new MiControlador(this);
    }
     
}
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Tal cual como lo vimos en el artículo sobre &lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Sincronizar-datos-de-un-JTextField-con-el-Controlador-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;Cómo sincronizar un JTextField con el controlador&lt;/a&gt;, los datos los obtendríamos y seteariamos en la vista de la siguiente forma:&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: java&quot;&gt;// Método para guardar los datos
public void guardar() {
    super.changeData(TipoUpdateEnum.MODEL);
    printConsole();
}
 
// Método para limpiar el formulario
public void limpiar() {
    miModelo1 = new MiModelo();
    super.changeData(TipoUpdateEnum.VIEW);
}
 
// Método para imprimir los datos por consola
public void printConsole() {
    System.out.println(&quot;Boolean Modelo 1: &quot; + miModelo1.getBooleanModelo());
}
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Puedes revisar &lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Sincronizar-datos-de-un-JTextField-con-el-Controlador-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;este artículo&lt;/a&gt; para comprender a fondo cómo funciona éste método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;super.changeData()&lt;/span&gt;, que como tal es el que realiza la actualización automática de los datos de la vista al modelo de datos en el controlador y viceversa.&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii18Zrpzb7nhIIljFcy3Z8MAO9mzZTX-U4WfvkOKLyZJqJ92zJe3cJAQUKrBdLch2Q8PizKbVNy73XQEk77_neDq0wysJ64I-mt0j_3uNyQ-AeRMqNtv8QrrtvTrcpSxsjotl_w3Cc6MD4/s1600/SwingUtils+-+Sincronizar+datos+de+un+JCheckBox+con+el+Controlador+%2528Java+Swing%2529.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;SwingUtils - Sincronizar datos de un JCheckBox con el Controlador (Java Swing)&quot; border=&quot;0&quot; data-original-height=&quot;108&quot; data-original-width=&quot;201&quot; height=&quot;171&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii18Zrpzb7nhIIljFcy3Z8MAO9mzZTX-U4WfvkOKLyZJqJ92zJe3cJAQUKrBdLch2Q8PizKbVNy73XQEk77_neDq0wysJ64I-mt0j_3uNyQ-AeRMqNtv8QrrtvTrcpSxsjotl_w3Cc6MD4/s320/SwingUtils+-+Sincronizar+datos+de+un+JCheckBox+con+el+Controlador+%2528Java+Swing%2529.png&quot; title=&quot;SwingUtils - Sincronizar datos de un JCheckBox con el Controlador (Java Swing)&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Como podemos apreciar, usando la librería &lt;b&gt;&lt;i&gt;SwingUtils&lt;/i&gt;&lt;/b&gt;, &amp;nbsp;es muy rápido sincronizar fácilmente datos de un &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JCheckBox&lt;/span&gt;, un &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JRadioButton&lt;/span&gt; o un &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;JToggleButton&lt;/span&gt; con el Controlador para que la información de nuestra vista se actualice rápidamente en el modelo de datos y viceversa.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/1823642340847834998/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2017/09/SwingUtils-Sincronizar-datos-de-un-JCheckBox-con-el-Controlador-Java-Swing.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/1823642340847834998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/1823642340847834998'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2017/09/SwingUtils-Sincronizar-datos-de-un-JCheckBox-con-el-Controlador-Java-Swing.html' title='SwingUtils - Sincronizar datos de un JCheckBox con el Controlador (Java Swing)'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii18Zrpzb7nhIIljFcy3Z8MAO9mzZTX-U4WfvkOKLyZJqJ92zJe3cJAQUKrBdLch2Q8PizKbVNy73XQEk77_neDq0wysJ64I-mt0j_3uNyQ-AeRMqNtv8QrrtvTrcpSxsjotl_w3Cc6MD4/s72-c/SwingUtils+-+Sincronizar+datos+de+un+JCheckBox+con+el+Controlador+%2528Java+Swing%2529.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-5126878318824742909</id><published>2017-09-14T16:12:00.000-05:00</published><updated>2019-02-23T23:26:35.627-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java Swing"/><category scheme="http://www.blogger.com/atom/ns#" term="SwingUtils"/><title type='text'>SwingUtils - Sincronizar datos de un JTextField con el Controlador (Java Swing)</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
En este artículo veremos como sincronizar un &lt;b&gt;JTextField&lt;/b&gt; de java swing con un atributo del controlador para que los datos se actualicen automáticamente tanto en la vista (JTextField) como en el modelo de datos (atributo independiente u atributo de objeto compuesto declarados en el controlador), usando la librería &lt;b&gt;&lt;i&gt;SwingUtils&lt;/i&gt;&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
La librería &lt;i&gt;SwingUtils&lt;/i&gt; no sólo permite hacer esta sincronización con componentes de tipo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;javax.swing.JTextField&lt;/span&gt;; también es posible usarla con los otros componentes que heredan de la clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;javax.swing.JTextComponent&lt;/span&gt;:&lt;/div&gt;
&lt;br /&gt;
&lt;pre&gt;javax.swing.JTextField
javax.swing.JFormattedTextField
javax.swing.JPasswordField
javax.swing.JTextArea
javax.swing.JEditorPane
javax.swing.JTextPane
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Lo primero que debemos hacer es descargar la librería &lt;u&gt;SwingUtils&lt;/u&gt;; para ésto puedes ver las instrucciones en el siguiente enlace:&lt;br /&gt;
&lt;br /&gt;
==&amp;gt; &lt;b&gt;&lt;a href=&quot;http://www.eljavatar.com/2017/09/SwingUtils-Libreria-de-Utilidades-para-Java-Swing.html&quot; target=&quot;_blank&quot;&gt;SwingUtils - Librería de Utilidades para Java Swing&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;h3&gt;
&lt;b&gt;Anotaciones para usar en el Controlador&lt;/b&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
En el controlador podemos usar dos anotaciones según sea el caso que necesitemos:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; ModelBean&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; PropertyController&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Veamos cómo podemos usar cada una de estas:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java; highlight: [1, 3, 6, 9, 12, 21]&quot;&gt;public class MiControlador extends AbstractObserverController {

    @PropertyController
    private String texto1;

    @PropertyController(name = &quot;miTexto&quot;)
    private String texto2;

    @ModelBean
    private MiModelo miModelo1;

    @ModelBean(name = &quot;pruebaModelo&quot;)
    private MiModelo miModelo2;

    private final MiVista miVista;

    public MiControlador(MiVista miVista) {
        this.miVista = miVista;
        this.miModelo1 = new MiModelo();
        this.miModelo2 = new MiModelo();
        super.setListeners(this, this.miVista);
    }

    public String getTexto1() {
        return texto1;
    }

    public void setTexto1(String texto1) {
        this.texto1 = texto1;
    }

    public String getTexto2() {
        return texto2;
    }

    public void setTexto2(String texto2) {
        this.texto2 = texto2;
    }

    public MiModelo getMiModelo1() {
        return miModelo1;
    }

    public void setMiModelo1(MiModelo miModelo1) {
        this.miModelo1 = miModelo1;
    }

    public MiModelo getMiModelo2() {
        return miModelo2;
    }

    public void setMiModelo2(MiModelo miModelo2) {
        this.miModelo2 = miModelo2;
    }
   
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
A continuación explicaré éste código:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Línea 1:&lt;/b&gt; Nuestro controlador debe extender de la clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;AbstractObserverController&lt;/span&gt; de la librería &lt;b&gt;JavaSwing&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Línea 3:&lt;/b&gt; Anotación&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;@PropertyController&lt;/span&gt; sin ningún atributo. Esto quiere decir que para acceder a esta propiedad en la vista, debemos hacerlo usando su mismo nombre, es decir, para este caso: &quot;texto1&quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Línea 6:&lt;/b&gt; Anotación&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;@PropertyController&lt;/span&gt; con atributo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;name&lt;/span&gt; definido. Es decir, que para acceder a esta propiedad en la vista, debemos hacerlo usando el valor que hemos definido en &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;name&lt;/span&gt;, que para este caso es &quot;miTexto&quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Línea 9:&lt;/b&gt;&amp;nbsp;Anotación&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;@ModelBean&lt;/span&gt;&amp;nbsp;sin ningún atributo. Esto quiere decir que para acceder a este objeto en la vista, debemos hacerlo usando su mismo nombre, es decir, para este caso: &quot;miModelo1.atributo&quot;. Los atributos en un objeto compuesto, debemos de llamarlos tal cual están definidos en la clase.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Línea 12:&lt;/b&gt;&amp;nbsp;Anotación&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;@PropertyController&lt;/span&gt;&amp;nbsp;con atributo&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;name&lt;/span&gt;&amp;nbsp;definido. Es decir, que para acceder a esta propiedad en la vista, debemos hacerlo usando el valor que hemos definido en&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;name&lt;/span&gt;, que para este caso es &quot;pruebaModelo.atributo&quot;. Como en el caso anterior, los atributos en un objeto compuesto, debemos de llamarlos como están definidos en la clase.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Línea 21:&lt;/b&gt; Seteamos los objetos del Controlador y la Vista que escucharán los cambios. Lo más recomendable es asignarlos al final del constructor.&lt;br /&gt;
&lt;br /&gt;
El resto de métodos son los Getter y Setter de las propiedades a las que les hemos asignado las anotaciones. Estos métodos son obligatorios para asignar y obtener los datos.&lt;br /&gt;
&lt;br /&gt;
Veamos a continuación el modelo que usaremos:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;public class MiModelo {
    
    private String textoModelo;
    private Date fechaModelo;
    private Integer numeroModelo;

    public String getTextoModelo() {
        return textoModelo;
    }

    public void setTextoModelo(String textoModelo) {
        this.textoModelo = textoModelo;
    }

    public Date getFechaModelo() {
        return fechaModelo;
    }

    public void setFechaModelo(Date fechaModelo) {
        this.fechaModelo = fechaModelo;
    }

    public Integer getNumeroModelo() {
        return numeroModelo;
    }

    public void setNumeroModelo(Integer numeroModelo) {
        this.numeroModelo = numeroModelo;
    }
    
}
&lt;/pre&gt;
&lt;br /&gt;
Recuerda que en una clase de modelo, al igual que en el controlador, también son obligatorios los métodos Getter y Setter para cada uno de los atributos definidos.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;h3&gt;
&lt;b&gt;Anotaciones para usar en un JTextField de Java Swing&lt;/b&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;!-- anuncios --&gt;

&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
La librería &lt;b&gt;SwingUtils&lt;/b&gt; en su actual versión, permite asignar tres tipos de anotaciones a un componente de tipo JTextField:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; TextView&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; DateTextView&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; NumberTextView&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Estas anotaciones pueden ser usadas en cualquier campo de tipo texto de java swing, sin embargo cada una tiene ciertas particularidades; &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;@TextView&lt;/span&gt; puede ser usada para sincronizar el JTextField con cualquiera de los siguientes tipos de datos del API de Java:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;String
Character o char
Byte o byte
Short o short
Integer o int
Long o long
Float o float
Double o double
BigInteger
BigDecimal
Boolean o boolean
java.util.Date
java.sql.Date
java.sql.Time
java.sql.Timestamp
java.time.LocalDate
java.time.LocalTime
java.time.LocalDateTime
&lt;/pre&gt;
&lt;br /&gt;
Como podemos ver, también es posible usar tipos de datos primitivos.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;@DateTextView&lt;/span&gt; es conveniente usarlo para sincronizar el &lt;i&gt;JTextFiel&lt;/i&gt; con tipos de datos que heredan de la clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;java.util.Date&lt;/span&gt; y &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;java.time.temporal.Temporal&lt;/span&gt;, ya que esta anotación nos permite definir un atributo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;pattern&lt;/span&gt; en caso que queramos personalizar el formato de fecha, y un locale mediante la clase&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;LocaleEnum&amp;nbsp;&lt;/span&gt;de la misma librería&amp;nbsp;&lt;i&gt;&lt;b&gt;SwingUtils&lt;/b&gt;&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;@NumberTextView&lt;/span&gt; es conveniente usarlo para sincronizar el &lt;i&gt;JTextField&lt;/i&gt; con tipos de datos que heredan de la clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;java.lang.Number&lt;/span&gt;, ya que esta anotación nos permite definir un atributo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;pattern&lt;/span&gt; en caso que queramos personalizar el formato de número, y un locale mediante la clase &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;LocaleEnum &lt;/span&gt;de la misma librería &lt;i&gt;SwingUtils&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
En cada una de estas tres anotaciones es posible usar también los atributos &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;required&lt;/span&gt; y &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;requiredMessage&lt;/span&gt;. El primero, es una propiedad booleana mediante la cual podemos indicar si queremos que el valor a ingresar sea obligatorio o no; y el segundo, es un mensaje personalizado que se mostrará al usuario en formato de error, en caso de que la propiedad required sea true y no se haya ingresado ningún valor en el campo de texto.&lt;br /&gt;
&lt;br /&gt;
Veamos cómo podemos usar estas anotaciones:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;@TextView(name = &quot;miModelo1.textoModelo&quot;, required = true, requiredMessage = &quot;Debe ingresar un valor&quot;)
private javax.swing.JTextField jTextField1;

@DateTextView(name = &quot;miModelo1.fechaModelo&quot;, pattern = &quot;dd-MM-yyyy&quot;, locale = LocaleEnum.UK, required = true requiredMessage = &quot;Debe ingresar un valor&quot;)&lt;/pre&gt;
&lt;pre class=&quot;brush: java&quot;&gt;private javax.swing.JTextField jTextField2;

@NumberTextView(name = &quot;miModelo1.numeroModelo&quot;, pattern = &quot;#,###&quot;, locale = LocaleEnum.US, required = true, requiredMessage = &quot;Debe ingresar un valor&quot;)&lt;/pre&gt;
&lt;pre class=&quot;brush: java&quot;&gt;private javax.swing.JTextField jTextField3;
&lt;/pre&gt;
&lt;br /&gt;
En éste código sólo hemos tomado el objeto &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;miModelo1&lt;/span&gt; de la clase MiControlador para simplificar un poco el ejemplo, pero si quisiéramos usar las otras propiedades lo haríamos así:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;@TextView(name = &quot;texto1&quot;)
private javax.swing.JTextField jTFtexto1;

@TextView(name = &quot;miTexto&quot;)
private javax.swing.JTextField jTFtexto2;

@TextView(name = &quot;pruebaModelo.textoModelo&quot;)
private javax.swing.JTextField jTFtexto3;
&lt;/pre&gt;
&lt;br /&gt;
Veamos ahora cómo deberíamos definir entonces el controlador en nuestra vista y cómo deberíamos inyectarle la dependencia de ésta (la vista) para poder sincronizarlos:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;public class MiVista extends javax.swing.JFrame {

    private final MiControlador miControlador;
    
    public MiVista() {
        initComponents();
        
        this.miControlador = new MiControlador(this);
    }
    
}
&lt;/pre&gt;
&lt;br /&gt;
Cabe aclarar que no es obligatorio que nuestras vistas extiendan de &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;javax.swing.Frame&lt;/span&gt; u otro componente de &lt;b&gt;java swing&lt;/b&gt;. En este caso yo lo tengo así, ya que el editor de interfaces de &lt;i&gt;NetBeans&lt;/i&gt; es quien me crea la clase así.&lt;br /&gt;
&lt;br /&gt;
Con esto es más que suficiente en cuanto a declarar nuestras variables se trata. Ahora vamos a crear dos funcionalidades sencillas mediante dos botones las cuales serán Guardar y Limpiar. La primera nos mostrará por consola los datos ingresados en el formulario, y la segunda deja vacíos los campos del formulario.&lt;br /&gt;
&lt;br /&gt;
La idea de trabajar con un patrón &lt;b&gt;MVC&lt;/b&gt; es que los cambios que hagamos en la Vista se vean reflejados en el Modelo a través del Controlador, y del mismo modo, que cuando tengamos cambios en el Modelo y se quieran mostrar al usuario, éstos se vean reflejados en la Vista también a través del Controlador.&lt;br /&gt;
&lt;br /&gt;
En este ejemplo, crearemos los 3 siguientes métodos en el Controlador:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java; highlight: [3, 10]&quot;&gt;// Método para guardar los datos
public void guardar() {
    super.changeData(TipoUpdateEnum.MODEL);
    printConsole();
}

// Método para limpiar el formulario
public void limpiar() {
    miModelo1 = new MiModelo();
    super.changeData(TipoUpdateEnum.VIEW);
}

// Método para imprimir los datos por consola
public void printConsole() {
    System.out.println(&quot;Texto Modelo 1: &quot; + miModelo1.getTextoModelo());
    System.out.println(&quot;Fecha Modelo 1: &quot; + miModelo2.getFechaModelo());
    System.out.println(&quot;Numero Modelo 1: &quot; + miModelo2.getNumeroModelo());
}
&lt;/pre&gt;
&lt;br /&gt;
En éste código cabe destacar las líneas 3 y 10. En el método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;guardar()&lt;/span&gt;, lo primero que hacemos es indicar que tenemos datos en la vista que deben ser actualizados en el modelo de datos, por lo tanto, con la sentencia &lt;b&gt;super.changeData(TipoUpdateEnum.MODEL)&lt;/b&gt; estamos sincronizando todos los datos de la Vista con el o los modelos de datos o atributos independientes que tengamos en nuestro Controlador, de tal manera que al llamar el método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;printConsole()&lt;/span&gt; se mostrará todo lo que haya escrito en el formulario.&lt;br /&gt;
&lt;br /&gt;
En el método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;limpiar()&lt;/span&gt;, como lo que queremos hacer es vaciar los campos del formulario, lo primero que deberíamos hacer es limpiar dichos valores en nuestro modelo de datos, y como en este caso sólo estamos tomando el objeto &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;miModelo1&lt;/span&gt;, lo único que deberíamos de hacer es re-inicializar dicho objeto. De esta forma, a continuación con la sentencia &lt;b&gt;super.changeData(TipoUpdateEnum.VIEW)&lt;/b&gt; sincronizamos todos los datos del o los modelos de datos o atributos independientes que tengamos en nuestro Controlador con la Vista, y en este caso lo que haría es mostrar vacíos los campos de texto, ya que nuestro modelo de datos no tiene valores.&lt;br /&gt;
&lt;br /&gt;
Podemos ver que con &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;TipoUpdateEnum.MODEL&lt;/span&gt; indicamos que queremos actualizar el modelo de datos, y con &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;TipoUpdateEnum.VIEW&lt;/span&gt; indicamos que queremos actualizar la vista con los datos que están en el modelo de datos.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhipiAF8bboFGPjHgwfCBP35m4m5fSLDYJwu5rP11rTVYfNPaPEtXDE1WNRAR7PKW7W_wAsdY0mAQFCZY-i3nCc3kgylFjomvacWIMB9S6lLFSfca_kdBYXd8kwTm5ORTCxAO45f2eZgXTD/s1600/SwingUtils+-+Sincronizar+datos+de+un+JTextField+con+el+++%2528Java+Swing%2529.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;SwingUtils - Sincronizar datos de un JTextField con el Controlador (Java Swing) - Formulario&quot; border=&quot;0&quot; data-original-height=&quot;173&quot; data-original-width=&quot;381&quot; height=&quot;181&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhipiAF8bboFGPjHgwfCBP35m4m5fSLDYJwu5rP11rTVYfNPaPEtXDE1WNRAR7PKW7W_wAsdY0mAQFCZY-i3nCc3kgylFjomvacWIMB9S6lLFSfca_kdBYXd8kwTm5ORTCxAO45f2eZgXTD/s400/SwingUtils+-+Sincronizar+datos+de+un+JTextField+con+el+++%2528Java+Swing%2529.png&quot; title=&quot;SwingUtils - Sincronizar datos de un JTextField con el Controlador (Java Swing) - Formulario&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b style=&quot;text-align: left;&quot;&gt;¿Y en caso de que no queramos actualizar todo el modelo de datos?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Como vimos, a través de la sentencia &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;super.changeData()&lt;/span&gt;, es que se logra la actualización inmediata de datos entre la Vista y el Modelo de datos, y para este ejemplo se hacía una actualización a nivel de todos los modelos de datos y/o atributos independientes que tengamos declarados en nuestro Controlador.&lt;br /&gt;
&lt;br /&gt;
Sin embargo, pueden haber casos en los que sólo deseamos actualizar, un modelo con todos sus atributos (en caso de que tengamos declarados varios modelos), un sólo atributo que tengamos declarado con la anotación&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;@PropertyController&lt;/span&gt;, un sólo atributo de alguno de nuestros modelos, o incluso una pequeña lista de datos que queramos actualizar en el Modelo o en la Vista.&lt;br /&gt;
&lt;br /&gt;
Para esto, el método&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;super.changeData()&lt;/span&gt;&amp;nbsp;está preparado para recibir dos tipos de objetos. Uno es de tipo enum &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;TipoUpdateEnum&lt;/span&gt; el cual ya vimos como usarlo; y el otro es de tipo &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ObjectUpdate&lt;/span&gt;, el cual tiene tres constructores con los cuales puede ser instanciado:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;new ObjectUpdate(TipoUpdateEnum tipoUpdateEnum)

new ObjectUpdate(TipoUpdateEnum tipoUpdateEnum, String component)

new ObjectUpdate(TipoUpdateEnum tipoUpdateEnum, List&amp;lt;string&amp;gt; listComponents)
&lt;/pre&gt;
&lt;br /&gt;
El primer constructor funciona de la misma forma que si pasáramos sólo el enum al método &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;changeData()&lt;/span&gt;. El segundo constructor, nos pide el enum con el tipo de actualización y adicionalmente el componente a actualizar; y el tercer constructor nos pide el enum con el tipo de actualización y una lista de componentes que deseemos actualizar.&lt;br /&gt;
&lt;br /&gt;
Veamos distintos ejemplos de como podemos usar estas instancias usando los atributos que declaramos al principio de este artículo. En los siguientes ejemplos, actualizaremos los datos en el modelo de datos, pero si lo que deseamos es actualizar los valores que se muestra en la vista, lo haríamos de la misma forma pero usando TipoUpdaeEnum.VIEW:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot;&gt;// Indicamos que sólo queremos que se actualice el modelo miModelo2.
// Al ser declarado con la anotación @ModelBean y con un nombre
// personalizado (pruebaModelo), SwingUtils reconoce que éste es
// un modelo de datos y debe actualizar todos los atributos que
// tenga éste objeto
super.changeData(new ObjectUpdate(TipoUpdateEnum.MODEL, &quot;pruebaModelo&quot;));


// Indicamos que sólo queremos que se actualice el atributo numeroModelo
// del objeto miModelo1. Al ser declarado con la anotación @ModelBean,
// SwingUtils reconoce que éste es un modelo de datos y actualizará sólo
// el atributo de este objeto que le indiquemos
super.changeData(new ObjectUpdate(TipoUpdateEnum.MODEL, &quot;miModelo1.numeroModelo&quot;));


// Indicamos que sólo quieremos que se actualice el atributo texto2.
// Al estar declarado con la anotación @PropertyController y con un
// nombre personalizado (miTexto), SwingUtils reconoce que éste es
// un atributo independiente en el controlador y sólo debe actualizar
// dicho atributo
super.changeData(new ObjectUpdate(TipoUpdateEnum.MODEL, &quot;miTexto&quot;));


// En caso que queramos pasar una lista de componentes, pasamos un List
// de tipo String con los nombres de los componentes que deseemos
// actualizar de la misma forma como lo vimos en los casos anteriores
super.changeData(new ObjectUpdate(TipoUpdateEnum.MODEL, Arrays.asList(&quot;texto1&quot;, &quot;pruebaModelo&quot;, &quot;miModelo1.fechaModelo&quot;));
&lt;/pre&gt;
&lt;br /&gt;
Con éstos ejemplos, damos por concluido éste artículo en donde hemos visto como podemos sincronizar fácilmente datos de un &lt;b&gt;JTextField&lt;/b&gt; con el Controlador usando la librería &lt;b&gt;&lt;u&gt;SwingUtils&lt;/u&gt;&lt;/b&gt; para que la información de nuestra vista se actualice rápidamente en el modelo de datos y viceversa.&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/5126878318824742909/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2017/09/SwingUtils-Sincronizar-datos-de-un-JTextField-con-el-Controlador-Java-Swing.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/5126878318824742909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/5126878318824742909'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2017/09/SwingUtils-Sincronizar-datos-de-un-JTextField-con-el-Controlador-Java-Swing.html' title='SwingUtils - Sincronizar datos de un JTextField con el Controlador (Java Swing)'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhipiAF8bboFGPjHgwfCBP35m4m5fSLDYJwu5rP11rTVYfNPaPEtXDE1WNRAR7PKW7W_wAsdY0mAQFCZY-i3nCc3kgylFjomvacWIMB9S6lLFSfca_kdBYXd8kwTm5ORTCxAO45f2eZgXTD/s72-c/SwingUtils+-+Sincronizar+datos+de+un+JTextField+con+el+++%2528Java+Swing%2529.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-5620001002463214304</id><published>2017-09-13T17:09:00.000-05:00</published><updated>2019-02-24T17:01:17.252-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Java Swing"/><category scheme="http://www.blogger.com/atom/ns#" term="SwingUtils"/><title type='text'>SwingUtils - Librería de Utilidades para Java Swing</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisCk0N7YxoUkUPyYj9zKFRxiPh4NFb4q0EwnorInA3iy4vHBFmHmdopb1I04WldNarf8oPEVAKBRWdzfVnPxsPJ9-TZ1BosYYXVc0VooFQp0zkv0DBmnKKsY4wqCqfjKkE_Y2ieaFLZ9GY/s1600/SwingUtils+-+Librer%25C3%25ADa+de+Utilidades+para+Java+Swing.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img alt=&quot;SwingUtils - Librería de Utilidades para Java Swing&quot; border=&quot;0&quot; data-original-height=&quot;233&quot; data-original-width=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisCk0N7YxoUkUPyYj9zKFRxiPh4NFb4q0EwnorInA3iy4vHBFmHmdopb1I04WldNarf8oPEVAKBRWdzfVnPxsPJ9-TZ1BosYYXVc0VooFQp0zkv0DBmnKKsY4wqCqfjKkE_Y2ieaFLZ9GY/s1600/SwingUtils+-+Librer%25C3%25ADa+de+Utilidades+para+Java+Swing.png&quot; title=&quot;SwingUtils - Librería de Utilidades para Java Swing&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
Existen muchas librerías de utilidades disponibles para trabajar con &lt;b&gt;Java Swing&lt;/b&gt; que hacen una u otra cosa y que facilitan el trabajo ya sea a nivel de vista, de modelo o de controlador. Sin embargo, siempre hay algo que requerimos pero que las librerías que encontramos no cumplen con esas necesidades.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Por eso decidí crear &lt;u&gt;&lt;b&gt;SwingUtils&lt;/b&gt;&lt;/u&gt;, una librería con una serie de utilidades que suelo usar en muchos proyectos que he desarrollado usando Java Swing.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;h3&gt;
&lt;b&gt;¿En qué consiste SwingUtils?&lt;/b&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Como ya lo mencioné, la librería &lt;i&gt;SwingUtils&lt;/i&gt; posee una serie de utilidades que pueden facilitar el desarrollo de ciertos componentes cuando trabajamos con el &lt;u&gt;API de Java Swing&lt;/u&gt;, sin embargo, una de las principales características y que fue la que me motivó a desarrollar esta librería es la siguiente:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Cuando trabajas con Java Enterprise Edition y el framework de JavaServer Faces, notas lo fácil que es la sincronización de datos entre una vista y el controlador, ya que los &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;value&lt;/span&gt; en la vista tan sólo deben ser declarados usando EL (Expression Language) de la forma &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;#{claseControlador.atributo}&lt;/span&gt; donde &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;atributo&lt;/span&gt; puede ser un objeto del API de Java o un objeto de una clase creada por nosotros y a través del cual podemos acceder a sus atributos de la forma &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;#{claseControlador.miObjeto.atributo}&lt;/span&gt;; y por otro lado, el controlador es un bean el cual lo único que debe tener es una inyección de dependencias usando la anotación&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;@Named&lt;/span&gt;.&lt;/div&gt;
&lt;span style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;!-- anuncios --&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
En otro artículo entraré más a fondo sobre todo este mundo de &lt;i&gt;Java Enterprise Edition&lt;/i&gt;, por ahora sólo me interesa que se aprecie lo fácil que se hace la sincronización de datos entre la vista y el controlador cuando hacemos uso de JEE; sin embargo, cuando trabajamos con Java Standard Edition y el &lt;b&gt;API de Java Swing&lt;/b&gt; para desarrollar vistas, vemos que el trabajo se hace un poco más tedioso.&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Si has trabajado con Java Swing, sabrás que si quieres obtener los datos de 8 campos de texto por ejemplo, tendrás que hacerlo uno a uno de la siguiente forma:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: java&quot;&gt;String dato1 = vista.jTFdato1.getText();
String dato2 = vista.jTFdato2.getText();
...
String dato8 = vista.jTFdato8.getText();
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Y en caso de que quieras mostrar valores en dichos campos de texto, igualmente debes hacerlo uno a uno de la siguiente forma:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: java&quot;&gt;vista.jTFdato1.setText(&quot;Texto 1...&quot;);
vista.jTFdato2.setText(&quot;Texto 2...&quot;);
...
vista.jTFdato8.setText(&quot;Texto 8...&quot;);
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Como verás, es algo que se vuelve un poco tedioso, sobre todo cuando nuestras vistas tienen formularios un poco grandes.&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Me di a la tarea de buscar primero si el &lt;u&gt;API de Java Swing&lt;/u&gt; tenía una forma de simplificar este trabajo tal como lo hace &lt;b&gt;JavaServer Faces&lt;/b&gt;, sin embargo no la encontré; busqué en algunas librerías, y sólo encontré &lt;a href=&quot;http://www.jdal.org/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;JDAL&lt;/a&gt;, la cual tiene cosas muy interesantes, sin embargo no me convencía del todo ya que debía hacer grandes cambios en vistas que ya estuvieran desarrolladas.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Así que pensé en crear anotaciones mediante las cuales podría controlar los cambios tanto desde la vista como desde el controlador, y hacer uso del patrón Observer para notificar dichos cambios tanto a la vista como al controlador.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;h3&gt;
&lt;b&gt;Entendiendo Cómo Funciona SwingUtils&lt;/b&gt;&lt;/h3&gt;
Actualmente, SwingUtils posee dos packages principales: core y utils. En el package core, tenemos todas las utilidades relacionadas directamente con el uso de de &lt;i&gt;Java Swing&lt;/i&gt;; En el package utils, tenemos clases de utilería general.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;- Package &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;com.eljavatar.swingutils.core&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Como mencioné, en este package están contenidas las clases de utilería que están relacionadas con el uso de Java Swing, y a su vez, éste contiente los siguientes packages: annotations, beansupdate, components, componentsutils, modelcomponents y renderercomponents.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&amp;nbsp;&lt;/b&gt;&lt;b&gt;Package&lt;/b&gt;&lt;b&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;com.eljavatar.swingutils.core.annotations&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Este package contiene las anotaciones que deben ser usadas en la vista o en el controlador para permitir la gestión de actualizaciones en cualquiera de los dos.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Anotaciones para usar en la vista:&lt;/b&gt;&lt;br /&gt;
- ComboBoxView&lt;br /&gt;
- ComponentView&lt;br /&gt;
- DateTextView&lt;br /&gt;
- NumberTextView&lt;br /&gt;
- PaginatedTableView&lt;br /&gt;
- TableView&lt;br /&gt;
- TextView&lt;br /&gt;
- ToggleButtonView&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Anotaciones para usar en el controlador:&lt;/b&gt;&lt;br /&gt;
- ModelBean&lt;br /&gt;
- PropertyController&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&amp;nbsp;&lt;/b&gt;&lt;b&gt;Package&lt;/b&gt;&lt;b&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;com.eljavatar.swingutils.core.beansupdate&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Este package contiene las clases que implementan la lógica para notificar los cambios a la vista y al controlador.&lt;br /&gt;
&lt;br /&gt;
- AbstractObservable&lt;br /&gt;
- AbstractObserverController (ésta es la clase que debe ser extendida desde el controlador)&lt;br /&gt;
- ObjectUpdate&lt;br /&gt;
- TipoUpdateEnum&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&amp;nbsp;&lt;/b&gt;&lt;b&gt;Package&lt;/b&gt;&lt;b&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;com.eljavatar.swingutils.core.components&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Este package contiene algunos componentes gráficos de utilería que extienden de componentes del &lt;i&gt;&lt;b&gt;API de Java Swing&lt;/b&gt;&lt;/i&gt;. En el momento sólo existen dos componentes:&lt;br /&gt;
&lt;br /&gt;
- JPanelImage&lt;br /&gt;
- PaginatedTable&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&amp;nbsp;&lt;/b&gt;&lt;b&gt;Package&lt;/b&gt;&lt;b&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;com.eljavatar.swingutils.core.componentsutils&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Este package contiene clases de utilería para trabajar con los distintos componentes de Java Swing; actualmente sólo hay unos pocos, que son los que más frecuentemente uso, pero la idea es ampliar la lista ;)&lt;br /&gt;
&lt;br /&gt;
- JComboBoxUtils&lt;br /&gt;
- JTableUtils&lt;br /&gt;
- NotifyUtils&lt;br /&gt;
- SwingComponentsUtils&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&amp;nbsp;&lt;/b&gt;&lt;b&gt;Package&lt;/b&gt;&lt;b&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;com.eljavatar.swingutils.core.modelcomponents&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Este package contiene clases para manejar el modelo de datos que usen los distintos componentes de Java Swing o los implementados en &lt;u&gt;&lt;i&gt;SwingUtils&lt;/i&gt;&lt;/u&gt;.&lt;br /&gt;
&lt;br /&gt;
- ComboBoxModelGeneric&lt;br /&gt;
- JTableDataProvider&lt;br /&gt;
- LazyDataProvider&lt;br /&gt;
- ObjectFiler&lt;br /&gt;
- PaginationDataProvider&lt;br /&gt;
- TableModelGeneric&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&amp;nbsp;&lt;/b&gt;&lt;b&gt;Package&lt;/b&gt;&lt;b&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;com.eljavatar.swingutils.core.renderercomponents&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Este package contiene clases para manejar el renderer que usen los distintos componentes de Java Swing.&lt;br /&gt;
&lt;br /&gt;
- ComboBoxRendererDefault&lt;br /&gt;
- TitlesTableRendererDefault&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&amp;nbsp;&lt;/b&gt;&lt;b&gt;Package&lt;/b&gt;&lt;b&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;com.eljavatar.swingutils.utils&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Como ya dije antes, este package contiene clases de utilería pero que no están necesariamente relacionadas con el uso de Java Swing. En el momento, este paquete contiene las siguientes clases:&lt;br /&gt;
&lt;br /&gt;
- StringUtils&lt;br /&gt;
- LocaleEnum&lt;br /&gt;
&lt;br /&gt;
Aquí sólo me limitaré a mencionar las clases que posee la librería, ya que posteriormente le realizaré un artículo a cada una de las características de la misma.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;Cómo descargar SwingUtils&lt;/b&gt;&lt;/h3&gt;
Para descargar la librería sólo se debe agregar la siguiente dependencia Maven:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;&amp;lt;dependency&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;lt;groupId&amp;gt;com.eljavatar&amp;lt;/groupId&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;lt;artifactId&amp;gt;SwingUtils&amp;lt;/artifactId&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;lt;version&amp;gt;1.3.2&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
En caso de no tener un proyecto gestionado con maven, puede descargar la librería directamente desde su enlace en el repositorio maven e importarla al proyecto que se desee:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;==&amp;gt;&lt;/b&gt; &lt;a href=&quot;https://search.maven.org/remotecontent?filepath=com/eljavatar/SwingUtils/1.3.2/SwingUtils-1.3.2.jar&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Proyecto SwingUtils v1.3.2&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;iframe allow=&quot;autoplay; encrypted-media&quot; allowfullscreen=&quot;&quot; frameborder=&quot;0&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/uP8JXQTHlbo?rel=0&quot; width=&quot;560&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/5620001002463214304/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2017/09/SwingUtils-Libreria-de-Utilidades-para-Java-Swing.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/5620001002463214304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/5620001002463214304'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2017/09/SwingUtils-Libreria-de-Utilidades-para-Java-Swing.html' title='SwingUtils - Librería de Utilidades para Java Swing'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisCk0N7YxoUkUPyYj9zKFRxiPh4NFb4q0EwnorInA3iy4vHBFmHmdopb1I04WldNarf8oPEVAKBRWdzfVnPxsPJ9-TZ1BosYYXVc0VooFQp0zkv0DBmnKKsY4wqCqfjKkE_Y2ieaFLZ9GY/s72-c/SwingUtils+-+Librer%25C3%25ADa+de+Utilidades+para+Java+Swing.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-4336460838873156693</id><published>2017-01-30T15:40:00.000-05:00</published><updated>2017-01-30T15:41:30.785-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Patrones de Diseño"/><category scheme="http://www.blogger.com/atom/ns#" term="Tutorial Java"/><category scheme="http://www.blogger.com/atom/ns#" term="UML"/><title type='text'>¿Cómo se Clasifican los Patrones de Diseño?</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
Para &lt;b&gt;clasificar los patrones de diseño&lt;/b&gt;, nos basaremos en la organización que se presenta en el libro &quot;GoF&quot;, el cual los clasifica según su objetivo; así tenemos entonces los patrones de construcción, patrones de estructuración y patrones de comportamiento.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;!-- anuncios --&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTgX8Hkx9LyvZd4ZgJowZSkjXTYefKJKKy9q5mQdWW2slOgNHuD4nYfrit5Rgk6bVIbQuBzU-UTFLE7YsVIanaDop7KRUQhtTze-JnfuSMUI0MCm4Lj97m4zfPIrPyffbge8uHuMsX-0Lu/s1600/C%25C3%25B3mo+se+Clasifican+los+Patrones+de+Dise%25C3%25B1o.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Cómo se Clasifican los Patrones de Diseño&quot; border=&quot;0&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTgX8Hkx9LyvZd4ZgJowZSkjXTYefKJKKy9q5mQdWW2slOgNHuD4nYfrit5Rgk6bVIbQuBzU-UTFLE7YsVIanaDop7KRUQhtTze-JnfuSMUI0MCm4Lj97m4zfPIrPyffbge8uHuMsX-0Lu/s400/C%25C3%25B3mo+se+Clasifican+los+Patrones+de+Dise%25C3%25B1o.jpg&quot; title=&quot;Cómo se Clasifican los Patrones de Diseño&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Los &lt;b&gt;patrones de construcción&lt;/b&gt; tienen como objetivo organizar la creación de objetos. Estos patrones son: Abstract Factory, Builder, Factory Method, Prototype y Singleton.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Los &lt;b&gt;patrones de estructuración&lt;/b&gt; facilitan la organización de la jerarquía de clases y de sus relaciones. Estos patrones son: Adapter, Bridge, Composite, Decorator, Facade, Flyweight y Proxy.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Por último, los &lt;b&gt;patrones de comportamiento&lt;/b&gt; son los que proporcionan soluciones para organizar las interacciones y para repartir el procesamiento entre los objetos. Estos patrones son Chain of responsability, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method y Visitor.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;¿Cómo escoger y utilizar un patrón de diseño para resolver un problema?&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Para saber si existe un patrón de diseño que responde a un problema concreto, el primer paso consiste en ver las descripciones de cada uno de los patrones anteriores, las cuales pueden verse en el artículo &quot;&lt;a href=&quot;http://www.eljavatar.com/2016/04/Una-Mirada-General-a-los-Patrones-de-Diseno.html&quot; target=&quot;_blank&quot;&gt;Una Mirada General a los Patrones de Diseño&lt;/a&gt;&quot;, y determinar si existe uno o varios patrones cuya descripción se acerque a la del problema.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Es importante estudiar a fondo la estructura genérica de los patrones de diseño y entender el objetivo que persigue el problema planteado, lo cual nos servirá como base para utilizar un patrón.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/4336460838873156693/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2017/01/Como-se-Clasifican-los-Patrones-de-Diseno.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/4336460838873156693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/4336460838873156693'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2017/01/Como-se-Clasifican-los-Patrones-de-Diseno.html' title='¿Cómo se Clasifican los Patrones de Diseño?'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTgX8Hkx9LyvZd4ZgJowZSkjXTYefKJKKy9q5mQdWW2slOgNHuD4nYfrit5Rgk6bVIbQuBzU-UTFLE7YsVIanaDop7KRUQhtTze-JnfuSMUI0MCm4Lj97m4zfPIrPyffbge8uHuMsX-0Lu/s72-c/C%25C3%25B3mo+se+Clasifican+los+Patrones+de+Dise%25C3%25B1o.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-1150585586386293743</id><published>2016-11-23T15:12:00.002-05:00</published><updated>2017-02-09T12:00:25.206-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Cpp"/><category scheme="http://www.blogger.com/atom/ns#" term="POO"/><category scheme="http://www.blogger.com/atom/ns#" term="Programación Orientada a Objetos"/><title type='text'>Programación Orientada a Objetos en C++ | Clases y Objetos</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Clases&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
La base de la &lt;b&gt;&lt;i&gt;Programación Orientada a Objetos&lt;/i&gt;&lt;/b&gt; es la abstracción de los datos o los Tipos de Datos Abstractos, y dicha abstracción de los datos es posible gracias a las clases y a los objetos.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrHb-YXYSDkNdoLSuO4ZtCD2g_B8pFuAzam9MPoTWRgWEwva20NID7-tJzCFffXnbHJOwUvUAZzxVrxXqxpJxylnEzCzqbA_L-t6jSYXvDo3hYZZclhYIu8GvNBAew9ZyPZkPP9qAQKoAp/s1600/Programaci%25C3%25B3n+Orientada+a+Objetos+en+Cpp+-+Clases+y+Objetos.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Programación Orientada a Objetos en C++: Clases y Objetos&quot; border=&quot;0&quot; height=&quot;216&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrHb-YXYSDkNdoLSuO4ZtCD2g_B8pFuAzam9MPoTWRgWEwva20NID7-tJzCFffXnbHJOwUvUAZzxVrxXqxpJxylnEzCzqbA_L-t6jSYXvDo3hYZZclhYIu8GvNBAew9ZyPZkPP9qAQKoAp/s400/Programaci%25C3%25B3n+Orientada+a+Objetos+en+Cpp+-+Clases+y+Objetos.jpg&quot; title=&quot;Programación Orientada a Objetos en C++: Clases y Objetos&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Podemos decir entonces que una clase es aquella que nos proporciona una estructura de datos con sus respectivas operaciones. Los datos son conocidos como atributos y las operaciones se conocen como métodos. Podemos concluir entonces que una clase es el molde que nos sirve para la creación de un objeto.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Así pues, la unión entre los atributos y los métodos es la que define el comportamiento de un objeto o grupo de objetos según sea el caso.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Algunos ejemplos de clases pueden ser: Auto, Empresa, Libro, Persona, etc.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Objetos e Instancias&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
La instanciación es una de las principales características de los &lt;u&gt;lenguajes de programación orientados a objetos&lt;/u&gt;. Recordemos que la instanciación es la capacidad que tienen los nuevos tipos de datos, en este caso, las clases, de ser &quot;&lt;u&gt;&lt;i&gt;instanciadas&lt;/i&gt;&lt;/u&gt;&quot; en cualquier momento.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
El instanciar una clase produce un objeto o instancia de la clase que asigna un determinado espacio en la memoria para ser gestionada o destruida posteriormente según sea el caso.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Un objeto es por tanto y a grandes rasgos, una instancia de una clase. Todo objeto puede ser identificado en forma única a través de su nombre; además, define un estado el cuál es definido por los valores de sus atributos en un momento dado.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
El estado de un objeto cambia de acuerdo a los métodos que le son aplicados. A esta posible secuencia de cambios de estado es la que conocemos como el comportamiento del objeto.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;&lt;u&gt;Instanciación&lt;/u&gt;:&lt;/b&gt; Los objetos pueden ser creados de dos formas al igual que una estructura de datos: &lt;i&gt;Estáticamente&lt;/i&gt; y &lt;i&gt;Dinámicamente&lt;/i&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;1) Estáticamente:&lt;/b&gt; En &lt;b&gt;tiempo de compilación&lt;/b&gt; se le asigna un área de memoria al objeto.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;2) Dinámicamente:&lt;/b&gt; En &lt;b&gt;tiempo de ejecución&lt;/b&gt; se le asigna un área de memoria al objeto y su existencia es temporal. Es necesario liberar el espacio usado por el objeto en memoria cuando éste ya no es útil. En algunos lenguajes como Java, el lenguaje nos proporciona mecanismos de recolección de basura y por tanto no debemos preocuparnos por liberar el espacio de memoria usada por los objetos, sin embargo en C++ sí debemos hacerlo explícitamente.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Clases en C++&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
La definición de una clase define nuevos &lt;b&gt;Tipos de Datos Abstractos&lt;/b&gt;. La definición en C++ se realiza mediante la palabra reservada &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;class&lt;/span&gt;, seguida del nombre de la clase y finalmente el cuerpo de la clase encerrado entre llaves &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;{}&lt;/span&gt; y finalizando con un punto y coma (&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;;&lt;/span&gt;).&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
El cuerpo de la clase contiene la declaración de los &lt;b&gt;atributos&lt;/b&gt; (&lt;i&gt;variables&lt;/i&gt;) y la declaración de los &lt;b&gt;métodos&lt;/b&gt; (&lt;i&gt;funciones&lt;/i&gt;). Tanto los atributos como los métodos pertenecen exclusivamente a la clase y sólo pueden ser usados a través de un objeto de dicha clase.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Sintaxis:&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;class &amp;lt;nombre_clase&amp;gt; {
    &amp;lt;cuerpo de la clase&amp;gt;
};  // Finaliza declaración de la clase
&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Ejemplo:&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;class Triangulo {
    int base;
    int altura;
    int area;

    void calcularArea() {
        area = (base * altura) / 2;
    }
};
&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Miembros de una clase&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmzSDCIxuC44h6GwYv_v_ciBwfo5kypUJD2sJdBW6UOdqxVvb0rfQkdrBNlvRXRMBIRUab4hkBZJrtkvUDbOkwSG5Ak5VSc7t-e12wAuHX5XmmTnZRGktToArooDARlGY5q3OYjEk8Zhuv/s1600/Miembros+de+una+Clase+-+Programaci%25C3%25B3n+Orientada+a+Objetos+en+Cpp.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Miembros de una Clase - Programación Orientada a Objetos en C++&quot; border=&quot;0&quot; height=&quot;296&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmzSDCIxuC44h6GwYv_v_ciBwfo5kypUJD2sJdBW6UOdqxVvb0rfQkdrBNlvRXRMBIRUab4hkBZJrtkvUDbOkwSG5Ak5VSc7t-e12wAuHX5XmmTnZRGktToArooDARlGY5q3OYjEk8Zhuv/s400/Miembros+de+una+Clase+-+Programaci%25C3%25B3n+Orientada+a+Objetos+en+Cpp.jpg&quot; title=&quot;Miembros de una Clase - Programación Orientada a Objetos en C++&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Una clase está formada por un conjunto de miembros que pueden ser datos, funciones, clases anidadas, enumeraciones, tipos de dato, etc. Primeramente nos enfocaremos en los datos y las funciones (&lt;i&gt;atributos&lt;/i&gt; y &lt;i&gt;métodos&lt;/i&gt;).&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Hay que tener en cuenta que un miembro no puede ser declarado más de una vez. Tampoco es posible añadir miembros después de la declaración de la clase, es decir, después de la llave y el punto y coma (&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;};&lt;/span&gt;).&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Ejemplo:&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;class ClaseEjemplo {
    int a;
    int b;
    int a;    // error
    int metodo(int, int);
};
&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;&lt;u&gt;Atributos miembro&lt;/u&gt;:&lt;/b&gt; Todos los atributos que forman parte de una clase deben ser declarados dentro de la misma.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;&lt;u&gt;Métodos miembro&lt;/u&gt;:&lt;/b&gt; Al igual que los atributos, los métodos deben ser definidos dentro de la declaración de la clase; sin embargo, el cuerpo de la función puede ir dentro o fuera de la clase. Si un método se declara completo dentro de la clase, éste se considera como &lt;i&gt;inline&lt;/i&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
La declaración dentro de la clase no cambia con respecto a la declaración de una función, salvo que se hace dentro de la clase. Retomemos la clase del ejemplo inicial, pero ahora la modificaremos agregando un método con el cuerpo del mismo fuera del cuerpo de la clase:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Ejemplo:&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;class Triangulo {
    public:
        int base;
        int altura;
        int area;
        void calcularArea() {
            area = (base * altura) / 2;
        }
        int obtenerPerimetro(int, int, int);
};
&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Podemos apreciar que en la definición de la clase se incluye un método en línea o inline (&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;calcularArea&lt;/span&gt;) y un prototipo de otro método (&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;obtenerPerimetro&lt;/span&gt;).&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Para definir un método miembro de una clase fuera de la misma, se debe escribir antes del nombre del método la clase con la que el método está asociado. Para esto, se hace uso del operador de resolución de alcance &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;::&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Continuación del ejemplo:&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;int Triangulo::obtenerPerimetro(int lado1, int lado2, int lado3) {
    int perimetro = lado1 + lado2 + lado3;
    return perimetro;
}
&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Es importante tener muy en cuenta que al declarar los métodos fuera de la clase, &lt;b&gt;No&lt;/b&gt; es posible mencionar la declaración de un método que no esté contemplado dentro de la clase, ya que si esto fuera posible, cualquiera podría tener acceso a la clase con sólo declarar un método adicional.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Ejemplo:&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;// Error en la declaración de un método
class MiClase {
    public:
        int a;
        void m();
};

// Esto es un error, ya que el método algo() no ha sido declarado
// dentro de la clase MiClase
int MiClase::algo() {
    return 0;
}
&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
La declaración de un método miembro es considerada dentro del ámbito de su clase, lo cual significa que puede usar nombres de miembros de la clase directamente sin usar el operador de acceso de miembro de la clase.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Recordemos que por convención, en la programación orientada a objetos, las funciones son llamadas métodos, y la invocación o llamada a dichos métodos es conocida como mensaje.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Acceso a miembros&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Una de las características de la &lt;i&gt;Programación Orientada a Objetos&lt;/i&gt; es la posibilidad de encapsular datos, ocultándolos de otros objetos si es necesario. En C++, existen tres tipos de calificadores que definen a los datos y métodos como &lt;i&gt;públicos&lt;/i&gt;, &lt;i&gt;privados&lt;/i&gt; o &lt;i&gt;protegidos&lt;/i&gt;, aunque por el momento sólo nos enfocaremos en los miembros públicos y privados.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;&lt;u&gt;Miembros públicos&lt;/u&gt;:&lt;/b&gt; Se utiliza cuando queremos dar a usuarios o clientes de una clase el acceso a miembros de esa clase. Los miembros deben ser declarados públicos a través de la palabra reservada &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;public:&lt;/span&gt; La sintaxis es la siguiente:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Sintaxis:&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;public:
    &amp;lt;definición de miembros&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;&lt;u&gt;Miembros privados&lt;/u&gt;:&lt;/b&gt; Se utiliza cuando queremos ocultar ciertos miembros de una clase de los usuarios o clientes de la misma. De esta manera, nadie más que los miembros de la misma clase pueden usar a los miembros privados. Por omisión, los miembros se consideran privados. Sin embargo, en una estructura de datos se consideran públicos por omisión. Los miembros deben ser declarados públicos a través de la palabra reservada&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;private:&lt;/span&gt;&amp;nbsp;La sintaxis es la siguiente:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Sintaxis:&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;private:
    &amp;lt;definición de miembros&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Normalmente, y por buenas prácticas de programación orientada a objetos, se trata de que los atributos de la clase sean privados, y el acceso a dichos atributos se realiza mediante métodos públicos conocidos como Getters y Setters.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Así mismo, los métodos que no sean necesarios externamente, o que puedan conducir a un estado inconsistente del objeto, también deberían declararse como privados.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Ejemplo:&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;class Fecha {
    private:
        int dia;
        int mes;
        int anio;

    public:
        void setDia(int);    // Asigna día
        int getDia();    // Obtiene día
        void setMes(int);
        int getMes();
        void setAnio(int);
        int getAnio();
};
&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Objetos de clase&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Ya hemos visto como se define una clase, la forma de declarar sus atributos y sus métodos, los cuales hemos aprendido que pueden ir dentro de la definición de la clase (inline) o fuera de ella. Ahora veremos cómo es posible crear objetos o instancias de esa clase.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Recordemos que una de las características de los objetos es que cada uno guarda un estado particular de acuerdo al valor de sus atributos. La importancia de los &lt;b&gt;lenguajes Orientados a Objetos&lt;/b&gt; es precisamente el objeto, el cual no es más que una identidad lógica que contiene datos y código que manipula dichos datos.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
En C++, un objeto es una variable de un tipo definido por el usuario. Veamos ahora un ejemplo completo:
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;

using namespace std;

class MiClase {
    public:
        string a;
        string b;
};

int main() {
    MiClase c1;
    MiClase c2;
    
    c1.a = &quot;Hola&quot;;
    c1.b = &quot;Mundo&quot;;
    
    c2.a = &quot;Hello&quot;;
    c2.b = &quot;World&quot;;
    
    cout &amp;lt;&amp;lt; c1.a &amp;lt;&amp;lt; &quot; &quot; &amp;lt;&amp;lt; c1.b &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; c2.a &amp;lt;&amp;lt; &quot; &quot; &amp;lt;&amp;lt; c2.b &amp;lt;&amp;lt; endl;
    
    return 0;
}
&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Veamos ahora el mismo ejemplo, pero instanciando objetos de la clase y usando métodos mediante los cuales accedemos a los atributos de la misma:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;

using namespace std;

class MiClase {
    private:
        string a;
        string b;

    public:
        string getA();
        void setA(string);
        string getB();
        void setB(string);
        string concatenar();
};

string MiClase::concatenar() {
    return this-&amp;gt;a + &quot; &quot; + this-&amp;gt;b;
}

string MiClase::getA() {
    return this-&amp;gt;a;
}

void MiClase::setA(string a) {
    this-&amp;gt;a = a;
}

string MiClase::getB() {
    return this-&amp;gt;b;
}

void MiClase::setB(string b) {
    this-&amp;gt;b = b;
}

// Método main
int main() {
    MiClase *c1 = new MiClase;
    MiClase *c2 = new MiClase;
    
    c1-&amp;gt;setA(&quot;Hola&quot;);
    c1-&amp;gt;setB(&quot;Mundo&quot;);
    
    c2-&amp;gt;setA(&quot;Hello&quot;);
    c2-&amp;gt;setB(&quot;World&quot;);
    
    cout &amp;lt;&amp;lt; c1-&amp;gt;concatenar() &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; c2-&amp;gt;concatenar() &amp;lt;&amp;lt; endl;
    
    delete c1;
    delete c2;
    
    return 0;
}
&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;NOTA: Es recomendable manejar la declaración de las clases mediante archivos &lt;i&gt;.h&lt;/i&gt; y la implementación de los métodos de la misma mediante archivos &lt;i&gt;.cpp&lt;/i&gt;; de esta forma, en el proyecto se puede incluir el correspondiente objeto importando solamente el archivo .h y sin proporcionar el código de su implementación.&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
La forma de hacerlo sería la siguiente:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;#ifndef MICLASE_H
#define MICLASE_H

&amp;lt;definición de la clase&amp;gt;

#endif
&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;Alcance de Clase&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
El nombre de un miembro de una clase es local a la clase y las funciones no miembros se definen en un alcance de archivo.&lt;br /&gt;
&lt;br /&gt;
Dentro de la clase, los miembros pueden ser accedidos directamente por todos los métodos miembros. Fuera del alcance de la clase, los miembros de la clase se pueden utilizar seguidos del &lt;b&gt;operador de selección de miembro&lt;/b&gt; de punto (&lt;b&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;.&lt;/span&gt;&lt;/b&gt;) ó del operador de selección de miembro de flecha (&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;b&gt;-&amp;gt;&lt;/b&gt;&lt;/span&gt;), posterior al &lt;b&gt;nombre de un objeto de la clase&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ejemplo:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;class ClaseEjemplo {
    public:
        void metodoPrueba();
}

void main() {
    ClaseEjemplo ce1;
    ce1.metodoPrueba();

    ClaseEjemplo *ce2 = new ClaseEjemplo;
    ce2-&amp;gt;metodoPrueba();
}
&lt;/pre&gt;
&lt;br /&gt;
Cuando usamos el operador de &lt;b&gt;&lt;i&gt;desreferencia&lt;/i&gt;&lt;/b&gt; u operador de &lt;b&gt;&lt;i&gt;indirección&lt;/i&gt;&lt;/b&gt; (&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;b&gt;*&lt;/b&gt;&lt;/span&gt;) en un objeto, debemos acceder a los campos o métodos de dicha clase usando el operador de flecha (&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;-&amp;gt;&lt;/span&gt;), o bien podemos hacerlo mediante el operador punto (&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;.&lt;/span&gt;) siempre y cuando desreferenciemos dicho puntero.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ejemplo:&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;#include &amp;lt;iostream&amp;gt;

using namespace std;

class MiClase {
    public:
        int a;
};

int main() {
    MiClase obj;

    (&amp;amp;obj)-&amp;gt;a = 1;   // Referenciamos el objeto
    cout &amp;lt;&amp;lt; (&amp;amp;obj)-&amp;gt;a &amp;lt;&amp;lt; endl;

    MiClase *obj2 = new MiClase;
    
    (*obj2).a = 2;   // Desreferenciamos el objeto
    cout &amp;lt;&amp;lt; (*obj2).a &amp;lt;&amp;lt; endl;
    
    return 0;
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;Sobrecarga de operaciones&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
En C++, al igual que otros &lt;b&gt;lenguajes de programación Orientados a Objetos&lt;/b&gt; como Java, es posible tener el mismo nombre para un método, con la condición de que su firma sea distinta, es decir, que tenga parámetros diferentes. La diferencia debe ser al menos en el tipo de datos de loas parámetros que recibe el método.&lt;br /&gt;
&lt;br /&gt;
Un método está sobrecargado cuando se tienen dos o más métodos con el mismo nombre, pero diferentes parámetros.&lt;br /&gt;
&lt;br /&gt;
El compilador de C++ sabe qué operación debe ejecutar a través de la firma del método, la cual es la combinación entre el nombre del método y el número y tipo de los parámetros que recibe. Del mismo modo, el tipo de retorno del método puede ser igual o diferente.&lt;br /&gt;
&lt;br /&gt;
La sobrecarga de operaciones de gran importancia, ya que es muy útil para escribir código más legible y modular. La idea de este concepto es utilizar el mismo nombre para operaciones relacionadas; de esta forma, si no tienen nada que ver, entonces es mejor utilizar un nombre distinto.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ejemplo&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;class MiClase {
    int num;
    
    public:
        void cambiaValor() {
            num++;
        }
        
        void cambiaValor(int x) {
            num = num + x;
        }
};
&lt;/pre&gt;
&lt;br /&gt;
En C++ también es posible usar la sobrecarga de operaciones por fuera de las clases:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ejemplo&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;#include &amp;lt;iostream&amp;gt;

int multipliacion(int x) {
    return x * x;
}

double multiplicacion(double y) {
    return y * y;
}

int main() {
  std::cout &amp;lt;&amp;lt; &quot;4 multiplicado por 4 = &quot; &amp;lt;&amp;lt; multiplicacion(4) &amp;lt;&amp;lt; std::endl;
  std::cout &amp;lt;&amp;lt; &quot;6.8 multiplicado por 6.8 = &quot; &amp;lt;&amp;lt; multiplicacion(6.8) &amp;lt;&amp;lt; std::endl;
  
  return 0;
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;Constructores y destructores&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Cunado trabajamos con datos primitivos en C++, el compilador se encarga directamente de reservar la memoria, y así mismo de liberarla cuando estos datos salen de su ámbito.&lt;br /&gt;
&lt;br /&gt;
En la &lt;i&gt;programación orientada a objetos&lt;/i&gt;, se trata de proporcionar mecanismos similares. En C++,&amp;nbsp;cuando se crea un objeto, se llama a un método conocido como &lt;b&gt;Constructor&lt;/b&gt;, y al salir, se llama a otro conocido como &lt;b&gt;Destructor&lt;/b&gt;. Si no se proporcionan dichos métodos, se asume la acción más simple.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Constructor&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Un &lt;b&gt;constructor&lt;/b&gt; no es más que un método que posee el mismo nombre de la clase. Este método no puede tener un tipo de dato de retorno, sin embargo, al igual que los métodos, si permite la sobrecarga.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ejemplo&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;class EjemploConstructor {
    private:
        string saludo;
    
    public:
        EjemploConstructor();
        void setSaludo(string);
        string getSaludo();
};

// Implementación del constructor
EjemploConstructor::EjemploConstructor() {
    this-&amp;gt;saludo = &quot;Hola Mundo&quot;;
    cout &amp;lt;&amp;lt; &quot;Se ha inicializado la clase&quot; &amp;lt; endl;
}
&lt;/pre&gt;
&lt;br /&gt;
Hay que tener en cuenta que un constructor si puede ser llamado desde un método de la clase.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Destructor&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
La contraparte del constructor es el &lt;b&gt;destructor&lt;/b&gt;. Este es ejecutado momentos antes de que el objeto sea destruido, ya sea porque salen de su ámbito o por medio de la palabra reservada &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;delete&lt;/span&gt;. El uso más común para un destructor es liberar la memoria asignada dinámicamente, aunque puede ser también utilizado para otras tareas de finalización, como cerrar archivos, una conexión de red, etc.&lt;br /&gt;
&lt;br /&gt;
El destructor, al igual que el destructor, tiene el nombre de la clase pero con una tilde de negativo como prefijo (&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;~&lt;/span&gt;).&lt;br /&gt;
&lt;br /&gt;
Al igual que el constructor, el destructor tampoco regresa valores, sin embargo, éste último tampoco tiene parámetros.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ejemplo&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;class EjemploClase {
    private:
        string saludo;
    
    public:
        EjemploClase();   // Constructor
        ~EjemploClase();  // Destructor
        void setSaludo(string);
        string getSaludo();
};

// Implementación del constructor
EjemploClase::~EjemploClase() {
    cout &amp;lt;&amp;lt; &quot;Clase destruida&quot; &amp;lt;&amp;lt; endl;
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;Miembros estáticos&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
En la &lt;b&gt;Programación Orientada a Objetos&lt;/b&gt;, cada objeto tiene su propio estado, sin embargo, en muchas ocasiones es pertinente tener atributos por clase que conserven su valor a nivel de aplicación, y no por objeto mediante los cuales se obtiene su valor a nivel de instancia. En esos es necesario tener atributos &lt;b&gt;estáticos&lt;/b&gt;, los cuales pueden ser compartidos por todos los objetos de la clase.&lt;br /&gt;
&lt;br /&gt;
De este modo, sólo existe una copia de un miembro estático, y dicho miembro no forma parte de los objetos de la clase.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ejemplo:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;class EjemploStatic {
    private:
        string nombre;
        static int cantidadObjetos;
    
    public:
        EjemploStatic(string texto);
        ~EjemploStatic();
};


EjemploStatic::EjemploStatic(string texto) {
    nombre = texto;
    cantidadObjetos++;
}

EjemploStatic::~EjemploStatic() {
    cantidadObjetos--;
}
&lt;/pre&gt;
&lt;br /&gt;
Un miembro estático, ya sea un atributo o un método, puede ser accedido desde cualquier objeto de la clase, o mediante el operador de resolución de alcance binario (&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;::&lt;/span&gt;) y el nombre de la clase, debido a que un miembro estático existe a nivel de aplicación aunque no haya instancias de la clase.&lt;br /&gt;
&lt;br /&gt;
Sin embargo, hay que tener en cuenta que el acceso a un miembro estático se restringe a las reglas de acceso a miembros que ya hemos visto anteriormente:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&lt;/b&gt; Si se quiere acceder a un miembro estático que es privado, se debe hacer a través de un miembro público.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;-&lt;/b&gt; Si no existe ninguna instancia de la clase, el acceso al miembro debe hacerse entonces a través de un método público estático.&lt;br /&gt;
&lt;br /&gt;
Por otro lado, hay que tener en cuenta que un método estático &lt;b&gt;SÓLO&lt;/b&gt; puede tener acceso a miembros estáticos. Además, los atributos estáticos se deben inicializar al igual que lo hacemos con los atributos constantes, fuera de la declaración de la clase. Por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;int Clase::atributoEstatico = 0;
int const Clase::atributoConstante = 30;
&lt;/pre&gt;
&lt;br /&gt;
Veamos ahora un ejemplo un poco más completo:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

using namespace std;

class EjemploStatic {
    private:
        static int cantidadObjetos;
        static const int CANTIDAD_MAXIMA;
        char *nombre;
    
    public:
        EjemploStatic(char *texto = NULL);
        ~EjemploStatic();
        static int getCantidadMaxima() {
            return CANTIDAD_MAXIMA;
        };
        static int getCantidadObjetos() {
            return cantidadObjetos;
        };
};

// Inicializamos atributos estáticos
int EjemploStatic::cantidadObjetos = 0;
const int EjemploStatic::CANTIDAD_MAXIMA = 10;

EjemploStatic::EjemploStatic(char *texto) {
    if (texto != NULL) {
        this-&amp;gt;nombre = new char[strlen(texto) + 1];
        strcpy(this-&amp;gt;nombre, texto);
    } else {
        this-&amp;gt;nombre = &quot;NULL&quot;;
    }
    cout &amp;lt;&amp;lt; &quot;Nombre: &quot; &amp;lt;&amp;lt; this-&amp;gt;nombre &amp;lt;&amp;lt; endl;
    cantidadObjetos++;
}

EjemploStatic::~EjemploStatic() {
    cout &amp;lt;&amp;lt; &quot;Eliminando nombre: &quot; &amp;lt;&amp;lt; this-&amp;gt;nombre &amp;lt;&amp;lt; endl;
    if (this-&amp;gt;nombre) {
        delete []nombre;
    }
    cantidadObjetos--;
}


// Método main
int main() {
    cout &amp;lt;&amp;lt; &quot;Cantidad Maxima de Objetos: &quot; &amp;lt;&amp;lt; EjemploStatic::getCantidadMaxima() &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; &quot;Cantidad de Objetos: &quot; &amp;lt;&amp;lt; EjemploStatic::getCantidadObjetos() &amp;lt;&amp;lt; endl;
    
    EjemploStatic obj1;
    cout &amp;lt;&amp;lt; &quot;Cantidad Maxima de Objetos: &quot; &amp;lt;&amp;lt; EjemploStatic::getCantidadMaxima() &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; &quot;Cantidad de Objetos: &quot; &amp;lt;&amp;lt; EjemploStatic::getCantidadObjetos() &amp;lt;&amp;lt; endl;
    
    EjemploStatic obj2(&quot;nombre 1&quot;);
    cout &amp;lt;&amp;lt; &quot;Cantidad Maxima de Objetos: &quot; &amp;lt;&amp;lt; EjemploStatic::getCantidadMaxima() &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; &quot;Cantidad de Objetos: &quot; &amp;lt;&amp;lt; EjemploStatic::getCantidadObjetos() &amp;lt;&amp;lt; endl;
    
    return 0;
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;Objetos constantes&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
En C++ es posible crear objetos de tipo constante, los cuales no van a poder ser modificados en ningún momento durante la ejecución de una aplicación, lo cual ayuda a cumplir el principio del mínimo privilegio, donde se debe restringir al máximo el acceso a los datos cuando este acceso estaría de sobra.&lt;br /&gt;
&lt;br /&gt;
Si tratamos de modificar un objeto constante, obtendremos un error en tiempo de compilación.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Sintaxis:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;const &amp;lt;clase&amp;gt; &amp;lt;lista de objetos&amp;gt;

const cHora h1(9, 30, 20);
&lt;/pre&gt;
&lt;br /&gt;
Para estos objetos, existen compiladores lo bastante rígidos en el cumplimiento de esta instrucción, que no nos permiten hacer llamadas a métodos sobre estos objetos. Por ejemplo, en el caso de C++ de Borland, el compilador tan sólo manda una advertencia y permite que se ejecute la aplicación, pero advierte que debe ser considerado como un error.&lt;br /&gt;
&lt;br /&gt;
Sin embargo, es posible que queramos consultar el estado del objeto a través de llamadas a métodos &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;get&lt;/span&gt;, y para esto lo correcto es declarar métodos con la palabra reservada &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;const&lt;/span&gt;, pues de esta forma podemos actuar libremente sobre el objeto sin modificarlo.&lt;br /&gt;
&lt;br /&gt;
La sintaxis consiste en añadir después de la lista de parámetros la palabra reservada &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;const&lt;/span&gt; en la declaración y en su definición.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Sintaxis&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Declaración:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;&amp;lt;tipo&amp;gt; &amp;lt;nombre&amp;gt; (&amp;lt;parámetros&amp;gt;) const;
&lt;/pre&gt;
&lt;br /&gt;
Definición del método fuera de la declaración de la clase:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;&amp;lt;tipo&amp;gt; &amp;lt;clase&amp;gt; :: &amp;lt;nombres&amp;gt; (&amp;lt;parámetros&amp;gt;) const {
    &amp;lt;código&amp;gt;
}
&lt;/pre&gt;
&lt;br /&gt;
Definición del método dentro de la declaración de la clase:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;&amp;lt;tipo&amp;gt; &amp;lt;nombres&amp;gt; (&amp;lt;parámetros&amp;gt;) const {
    &amp;lt;código&amp;gt;
}
&lt;/pre&gt;
&lt;br /&gt;
El compilador de Borland permite usar los métodos constantes de manera indiferente para objetos constantes y no constantes, siempre y cuando no modifiquen al objeto; sin embargo hay compiladores que incluso restringen el uso de métodos constantes a objetos constantes. Para solucionar esto, es posible sobrecargar el método con la única diferencia de la palabra &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;const&lt;/span&gt;, aunque el resto de la firma del método sea la misma.&lt;br /&gt;
&lt;br /&gt;
Los constructores no necesitan la declaración &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;const&lt;/span&gt;, puesto que deben poder modificar al objeto. Veamos ahora un ejemplo completo:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ejemplo:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

using namespace std;

class ObjetoConstante {
    private:
        int a[10];
    public:
        ObjetoConstante(int x = 0) {
            for (int i = 0; i &amp;lt; 10; i++) {
                if (x == 0) {
                    x = random();
                }
                a[i] = x;
            }
        }
        char set(int, int);
        int get(int) const;
        int get(int);
};

// Implementación de los métodos
char ObjetoConstante::set(int pos, int val) {
    if (pos &amp;gt;= 0 &amp;amp;&amp;amp; pos &amp;lt; 10) {
        a[pos] = val;
        return 1;
    }
    return 0;
}

int ObjetoConstante::get(int pos) const {
    if (pos &amp;gt;= 0 &amp;amp;&amp;amp; pos &amp;lt; 10) {
        return a[pos];
    }
}

int ObjetoConstante::get(int pos) { // En este caso no es necesario sobrecargar
    if (pos &amp;gt;= 0 &amp;amp;&amp;amp; pos &amp;lt; 10) {
        return a[pos];
    }
}

// Método main
int main () {
    const ObjetoConstante a(5), b;
    ObjetoConstante c;
    
    //a.set(0, 1);    // Esto nos genera un error de compilación porque llamamos a un
    //b.set(0, 2);    // método que modifica un objeto que ha sido declarado constante
    c.set(0, 3);
    //a.set(1, 11);
    //b.set(1, 22);
    c.set(1, 33);
    
    cout &amp;lt;&amp;lt; a.get(0) &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; a.get(1) &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; b.get(0) &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; b.get(1) &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; c.get(0) &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; c.get(1) &amp;lt;&amp;lt; endl;
}
&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/1150585586386293743/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2016/11/Programacion-Orientada-a-Objetos-en-Cpp-Clases-y-Objetos.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/1150585586386293743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/1150585586386293743'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2016/11/Programacion-Orientada-a-Objetos-en-Cpp-Clases-y-Objetos.html' title='Programación Orientada a Objetos en C++ | Clases y Objetos'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrHb-YXYSDkNdoLSuO4ZtCD2g_B8pFuAzam9MPoTWRgWEwva20NID7-tJzCFffXnbHJOwUvUAZzxVrxXqxpJxylnEzCzqbA_L-t6jSYXvDo3hYZZclhYIu8GvNBAew9ZyPZkPP9qAQKoAp/s72-c/Programaci%25C3%25B3n+Orientada+a+Objetos+en+Cpp+-+Clases+y+Objetos.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-5065206655325544113</id><published>2016-11-15T14:08:00.002-05:00</published><updated>2017-09-10T01:41:08.237-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Cpp"/><category scheme="http://www.blogger.com/atom/ns#" term="POO"/><category scheme="http://www.blogger.com/atom/ns#" term="Programación Orientada a Objetos"/><title type='text'>Introducción a la Programación Orientada a Objetos en C++</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
Hace unos días estuve colaborándole a un amigo en la elaboración de una aplicación que debía realizar usando &lt;b&gt;Programación Orientada a Objetos en C++.&lt;/b&gt; La mayoría de aplicaciones que he desarrollado, las hecho en Java, y ya que Java es un lenguaje que ha sido influido por C++, pensé que no habría mucha diferencia entre el uno y el otro, y vaya sorpresa que me di ;)&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMyOqWbHuuUL7L4ZprtfgnnNerCLZLVr_7RV-A2nthmkQxcpXMcCQH5SM7igUpMXiszhd_mudjCWrmBf3Qt04NOktumFJU2hSHxUu9zfEjMomnUPOBbkNtZ6SBfgg32FBZhnWxZZOtjwqi/s1600/Introducci%25C3%25B3n+a+la+Programaci%25C3%25B3n+Orientada+a+Objetos+en+Cpp.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Introducción a la Programación Orientada a Objetos en C++&quot; border=&quot;0&quot; height=&quot;300&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMyOqWbHuuUL7L4ZprtfgnnNerCLZLVr_7RV-A2nthmkQxcpXMcCQH5SM7igUpMXiszhd_mudjCWrmBf3Qt04NOktumFJU2hSHxUu9zfEjMomnUPOBbkNtZ6SBfgg32FBZhnWxZZOtjwqi/s400/Introducci%25C3%25B3n+a+la+Programaci%25C3%25B3n+Orientada+a+Objetos+en+Cpp.jpg&quot; title=&quot;Introducción a la Programación Orientada a Objetos en C++&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
La verdad es que en muchos aspectos se me presentaron bastantes inconvenientes. Recordemos que C++ es un lenguaje que extiende del lenguaje de programación C mecanismos que nos permiten la manipulación de objetos, es decir, que no es un lenguaje meramente orientado a objetos como Java o C#, sino que es más bien un lenguaje híbrido.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Cabe aclarar que estos tutoriales no son básicos, es decir que ya debes de tener algún conocimiento en el lenguaje de programación C++, como sus tipos de datos, declaración de variables, operaciones, ciclos, importación de librerías, uso de namespaces, en fin.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Después de esta breve introducción y antes de adentrarnos en los detalles específicos de la &lt;i&gt;programación orientada a objetos en C++&lt;/i&gt;, demos un pequeño repaso a lo que es la POO y sus características.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
En el siguiente enlace puedes ver un artículo sobre las características del &lt;a href=&quot;http://www.eljavatar.com/2014/04/Paradigmas-de-Programacion-IV-Programacion-Orientada-a-Objetos.html&quot; target=&quot;_blank&quot;&gt;Paradigma de Programación Orientado a Objetos&lt;/a&gt;. Sin embargo, mencionaremos a continuación algunas de ellas y aspectos principales a tener en cuenta:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Programación Orientada a Objetos en C++&lt;/b&gt;&lt;/h3&gt;
&lt;!-- anuncios --&gt;

&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii2erwPoqSvYuqk3-y_N32NAohhZK0kuNVpd_AIxePOfTNV-muB2nP7wlADRBeuxtYBy5C6n2ClibdWO852ICGebs_O_XcBcZsfkUo-YF4S3WBKfA7yoeLYfJDfQp0j5ZjnvETBSiFZqZ8/s1600/Caracteristicas+de+la+Programacion+Orientada+a+Objetos+POO.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img alt=&quot;Caracteristicas de la Programacion Orientada a Objetos POO&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii2erwPoqSvYuqk3-y_N32NAohhZK0kuNVpd_AIxePOfTNV-muB2nP7wlADRBeuxtYBy5C6n2ClibdWO852ICGebs_O_XcBcZsfkUo-YF4S3WBKfA7yoeLYfJDfQp0j5ZjnvETBSiFZqZ8/s1600/Caracteristicas+de+la+Programacion+Orientada+a+Objetos+POO.jpg&quot; title=&quot;Caracteristicas de la Programacion Orientada a Objetos POO&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;b&gt;1) Objetos: &lt;/b&gt;Un objetos es la entidad básica del paradigma de programación Orientado a Objetos y es el que integra la estructura de datos (atributos) y un comportamiento (operaciones). Se distinguen entre sí por medio de su propia identidad, aunque internamente los valores de los atributos sean iguales.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;2) Clases:&lt;/b&gt; Las clases describen posibles objetos, con una estructura y comportamiento común. Aquellos objetos que contienen los mismos atributos y operaciones pertenecen a la misma clase. La estructura de clases integra las operaciones con los atributos a los cuales se aplican.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;3) Instancia:&lt;/b&gt; El proceso de crear objetos que pertenecen a una clase se denomina instanciación. De cierta clase, pueden ser instanciados un número indefinido de objetos.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;4) Herencia: &lt;/b&gt;En una jerarquía de clases, es posible compartir atributos y operaciones entre clases basados en la generalización de clases. Dicha generalización se construye mediante la herencia. Las clases más generales se conocen como superclases y las clases más especializadas se conocen como subclases. En C++, a diferencia de otros lenguajes, la herencia puede ser simple o múltiple.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;5) Abstracción: &lt;/b&gt;La abstracción se concentra en lo primordial de una entidad y no en sus propiedades secundarias, además de en qué es lo que hace el objeto y no en cómo lo hace. En este sentido, se da énfasis a cuáles son los objetos y no cómo son usados.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;6) Encapsulamiento: &lt;/b&gt;El encapsulamiento es la separación de las propiedades externas de un objeto de los detalles de implementación internos del objeto. Al separar la interfaz del objeto de su implementación, se limita la complejidad a mostrarse sólo la información relevante. Por otra parte, disminuye el impacto a cambios en la implementación, ya que los cambios a las propiedades internas del objeto no afectan su interacción externa.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;7) Modularidad:&lt;/b&gt; El encapsulamiento de los objetos trae como consecuencia una gran modularidad. Cada módulo se concentra en una sola clase de objetos, así, cada módulo se concentra en una sola clase objetos. Los módulos tienden a ser pequeños y concisos. La modularidad ofrece la ventaja que facilita el encontrar y corregir problemas, además de que la complejidad de un sistema se reduce facilitando así su mantenimiento.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;8) Extensibilidad: &lt;/b&gt;La extensibilidad permite hacer cambios en un sistema sin afectar lo que ya existe. De esta forma nuevas clases pueden ser definidas sin tener que cambiar la interfaz del resto del sistema. La definición de los objetos existentes puede ser extendida sin necesidad de cambios más allá del propio objeto.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;9) Polimorfismo: &lt;/b&gt;El polimorfismo es la característica de definir las mismas operaciones con diferente comportamiento en diferentes clases. De esta forma es posible llamar una operación sin preocuparse &amp;nbsp;de cuál implementación es requerida en qué clase, siendo responsabilidad de la jerarquía de clases y no del programador.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;10) Reusabilidad de código:&lt;/b&gt; La programación orientada a objetos apoya el reuso de código en un sistema, ya que los componentes orientados a objetos se pueden utilizar para estructurar librerías reusables. El reuso reduce el tamaño de un sistema durante la creación y ejecución. La herencia es uno de los factores más importantes contribuyendo al incremento en el reuso de código dentro de un proyecto.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Con estos conceptos finalizamos este artículo, el cual ha sido un poco teórico. Ya en los siguientes empezaremos a ver algo de código para comprender mejor como se usa la &lt;i&gt;&lt;b&gt;Programación Orientada a Objetos en C++&lt;/b&gt;&lt;/i&gt;.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/5065206655325544113/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2016/11/Introduccion-la-Programacion-Orientada-a-Objetos-en-Cpp.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/5065206655325544113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/5065206655325544113'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2016/11/Introduccion-la-Programacion-Orientada-a-Objetos-en-Cpp.html' title='Introducción a la Programación Orientada a Objetos en C++'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMyOqWbHuuUL7L4ZprtfgnnNerCLZLVr_7RV-A2nthmkQxcpXMcCQH5SM7igUpMXiszhd_mudjCWrmBf3Qt04NOktumFJU2hSHxUu9zfEjMomnUPOBbkNtZ6SBfgg32FBZhnWxZZOtjwqi/s72-c/Introducci%25C3%25B3n+a+la+Programaci%25C3%25B3n+Orientada+a+Objetos+en+Cpp.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-2037323949647122897</id><published>2016-04-10T23:54:00.001-05:00</published><updated>2017-09-10T01:40:13.909-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Patrones de Diseño"/><category scheme="http://www.blogger.com/atom/ns#" term="Tutorial Java"/><category scheme="http://www.blogger.com/atom/ns#" term="UML"/><title type='text'>Una Mirada General a los Patrones de Diseño</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
Como lo mencioné en un anterior artículo, &lt;i&gt;&lt;a href=&quot;http://www.eljavatar.com/2016/03/Introduccion-a-los-Patrones-de-Diseno-o-Design-Patterns.html&quot; target=&quot;_blank&quot;&gt;Introducción a los Patrones de Diseño o Design Patterns&lt;/a&gt;&lt;/i&gt;, iremos viendo los patrones de diseño que se describen en el libro de referencia &quot;GoF&quot;. Estos patrones son diversas respuestas a problemas conocidos de la &lt;u&gt;&lt;a href=&quot;http://www.eljavatar.com/2014/04/Paradigmas-de-Programacion-IV-Programacion-Orientada-a-Objetos.html&quot; target=&quot;_blank&quot;&gt;programación orientada a objetos&lt;/a&gt;&lt;/u&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoGCDtmnIdHx1smXESVhRPuFiV7ErvaOfFiLGK0F1acdPF5MNCEhK9dea67tsPdGA_4r5U5A4W4iO6mxHX5b4kOproJSPWCbexBBiaWlu3EjuEJH_H4RfIRZQnzJHq6JACa5iJpwKSQWhv/s1600/Una+Mirada+General+a+los+Patrones+de+Dise%25C3%25B1o.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Una Mirada General a los Patrones de Diseño&quot; border=&quot;0&quot; height=&quot;266&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoGCDtmnIdHx1smXESVhRPuFiV7ErvaOfFiLGK0F1acdPF5MNCEhK9dea67tsPdGA_4r5U5A4W4iO6mxHX5b4kOproJSPWCbexBBiaWlu3EjuEJH_H4RfIRZQnzJHq6JACa5iJpwKSQWhv/s400/Una+Mirada+General+a+los+Patrones+de+Dise%25C3%25B1o.png&quot; title=&quot;Una Mirada General a los Patrones de Diseño&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
A continuación veremos la lista de los patrones de diseño que iré explicando en posteriores entradas.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Lista o Catálogo de Patrones de Diseño&lt;/b&gt;&lt;/h3&gt;
&lt;div style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;!-- anuncios --&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Abstract Factory:&lt;/b&gt; Tiene como objetivo la creación de objetos reagrupados en familias sin tener que conocer las clases concretas destinadas a la creación de estos objetos.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Builder:&lt;/b&gt; Permite separar la construcción de objetos complejos de su implementación de modo que un cliente pueda crear estos objetos complejos con implementaciones diferentes.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Factory Method:&lt;/b&gt; Tiene como objetivo presentar un método abstracto para la creación de un objeto reportando a las subclases concretas la creación efectiva.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Prototype:&lt;/b&gt; Permite crear nuevos objetos por duplicación de objetos existentes llamados prototipos que disponen de la capacidad de clonación.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Singleton:&lt;/b&gt; Permite asegurar que de una clase concreta existe una única instancia y proporciona un método único que la devuelve.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Adapter:&lt;/b&gt; Tiene como objetivo convertir la interfaz de una clase existente en la interfaz esperada por los clientes también existentes para que puedan trabajar de forma conjunta.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Bridge:&lt;/b&gt; Tiene como objetivo separar los aspectos conceptuales de una jerarquía de clases de su implementación.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Composite:&lt;/b&gt; Proporciona un marco de diseño de una composición de objetos con una profundidad de composición variable, basando el diseño en un árbol.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Decorator:&lt;/b&gt; Permite agregar dinámicamente funcionalidades suplementarias a un objeto.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Facade:&lt;/b&gt; Tiene como objetivo reagrupar las interfaces de un conjunto de objetos en una interfaz unificada que resulte más fácil de utilizar.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Flyweight:&lt;/b&gt; Facilita la comparación de un conjunto importante de objetos con granularidad muy fina.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Proxy:&lt;/b&gt; Construye un objeto que se substituye por otro objeto y que controla su acceso.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Chain of responsability:&lt;/b&gt; Crea una cadena de objetos tal que si un objeto de la cadena no puede responder a una petición, la pueda transmitir a sus sucesores hasta que uno de ellos responda.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Command:&lt;/b&gt; Tiene como objetivo transformar una consulta en un objeto, facilitando operaciones como la anulación, la actualización de consultas y su seguimiento.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Interpreter:&lt;/b&gt; Proporciona un marco para dar una representación mediante objetos de la gramática de un lenguaje con el objetivo de evaluar, interpretando las experiencias escritas en este lenguaje.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Iterator:&lt;/b&gt; Proporciona un acceso secuencial a una colección de objetos sin que los clientes se preocupen de la implementación de esta colección.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Mediator:&lt;/b&gt; Construye un objeto cuya vocación es la gestión y el control de las interacciones en el seno de un conjunto de objetos sin que estos elementos se conozcan mutuamente.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Memento:&lt;/b&gt; Salvaguarda y restaura el estado de un objeto.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Observer:&lt;/b&gt; Construye una dependencia entre un sujeto y sus observadores de modo que cada modificación del sujeto sea notificada a los observadores para que puedan actualizar su estado.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- State:&lt;/b&gt; Permite a un objeto adaptar su comportamiento en función de su estado interno.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Strategy:&lt;/b&gt; Adapta el comportamiento y los algoritmos de un objeto en función de una necesidad concreta sin por ello cargar las interacciones con los clientes de este objeto.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Template Method:&lt;/b&gt; Permite reportar en las subclases ciertas etapas de una de las operaciones de un objeto, estando éstas descritas en las subclases.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Visitor:&lt;/b&gt; Construye una operación a realizar en los elementos de un conjunto de objetos. Es posible agregar nuevas operaciones sin modificar las clases de estos objetos.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Estos son los 23 Patrones de Diseño que se describen en el libro de referencia &quot;GoF&quot;, y que iremos estudiando más a detalle en posteriores entradas a través de ejemplos usando diagramas UML y el lenguaje de programación &lt;b&gt;Java&lt;/b&gt;.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/2037323949647122897/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2016/04/Una-Mirada-General-a-los-Patrones-de-Diseno.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/2037323949647122897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/2037323949647122897'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2016/04/Una-Mirada-General-a-los-Patrones-de-Diseno.html' title='Una Mirada General a los Patrones de Diseño'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoGCDtmnIdHx1smXESVhRPuFiV7ErvaOfFiLGK0F1acdPF5MNCEhK9dea67tsPdGA_4r5U5A4W4iO6mxHX5b4kOproJSPWCbexBBiaWlu3EjuEJH_H4RfIRZQnzJHq6JACa5iJpwKSQWhv/s72-c/Una+Mirada+General+a+los+Patrones+de+Dise%25C3%25B1o.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-7872069361096278969</id><published>2016-04-01T02:16:00.001-05:00</published><updated>2016-04-01T02:19:16.608-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><category scheme="http://www.blogger.com/atom/ns#" term="Nodejs"/><title type='text'>Google App Engine Ahora Soporta Node.js</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhn56Qm61dJa88yUGbCRT-oJ44ZtisbwrENIR_OetvYsDS8feTswqRigbQRS6oCixJYfxJE_hLozZtXzRBXJkxfymPmmtY49fGoltxEL9iEnlg4pvToWH9FUrEQL1LywcV7YprEzF5MmU7e/s1600/Google+App+Engine+Ahora+Soporta+Node.js.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img alt=&quot;Ahora ya es posible ejecutar Node.js sobre Google App Engine&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhn56Qm61dJa88yUGbCRT-oJ44ZtisbwrENIR_OetvYsDS8feTswqRigbQRS6oCixJYfxJE_hLozZtXzRBXJkxfymPmmtY49fGoltxEL9iEnlg4pvToWH9FUrEQL1LywcV7YprEzF5MmU7e/s1600/Google+App+Engine+Ahora+Soporta+Node.js.png&quot; title=&quot;Google App Engine Ahora Soporta Node.js&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Ahora ya es posible ejecutar Node.js sobre Google App Engine.&lt;/b&gt;&lt;/h4&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Google ha anunciado una asociación con &lt;a href=&quot;https://nodesource.com/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;NodeSource&lt;/a&gt;, proveedora de plataformas empresariales para Node.js, en la cual &lt;a href=&quot;https://nodesource.com/products/nsolid&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;NSolid&lt;/a&gt;, que es precisamente la plataforma a nivel empresarial para Node.js de NodeSource, estará en la plataforma de &lt;a href=&quot;https://cloud.google.com/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Google Cloud&lt;/a&gt;, la cual a su vez cuenta con App Engine.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Ofrecida en una versión beta desde la semana pasada, el entorno en tiempo de ejecución para la popular plataforma JavaScript del lado del servidor le permite a los desarrolladores construir Back-ends para aplicaciones web y móviles con JavaScript y escalar estos sistemas a la nube de Google.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Hasta ahora, &lt;a href=&quot;https://cloud.google.com/appengine/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Google App Engine&lt;/a&gt; ya había añadido soporte para el desarrollo de aplicaciones en &lt;b&gt;&lt;a href=&quot;http://www.eljavatar.com/search/label/Java&quot; target=&quot;_blank&quot;&gt;Java&lt;/a&gt;&lt;/b&gt;, Python, PHP y Go.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;!-- anuncios --&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&quot;NodeSource está asociado con Google para ser el principal proveedor de un entorno de ejecución Node.js sobre la plataforma de Google Cloud&quot;, dijo Mark Piening de NodeSource. &quot;Esta asociación le ofrecerá a los desarrolladores de Node.js una sencilla solución &lt;i&gt;fuera de la caja&lt;/i&gt; (out-of-the-box) para conseguir una visión profunda dentro de sus aplicaciones Node.js que se están ejecutando en la plataforma de Google Cloud.&quot;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOKghyphenhyphenlwlFJxv7BjtfxIhyTRtu6dVlDwm_GbW77I5h9zF7gMPJHwV29xxHPVlwYX_Dvdd0nYHcem4Jo5Own7bJB1ChRIE1VZfs5RZlyh2wnolOJq8R2Dbs8jpWgSW9a1ugwkitOcq0VDer/s1600/Google+proveera+herramientas+para+Nodejs.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Google proveera herramientas para Nodejs&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOKghyphenhyphenlwlFJxv7BjtfxIhyTRtu6dVlDwm_GbW77I5h9zF7gMPJHwV29xxHPVlwYX_Dvdd0nYHcem4Jo5Own7bJB1ChRIE1VZfs5RZlyh2wnolOJq8R2Dbs8jpWgSW9a1ugwkitOcq0VDer/s1600/Google+proveera+herramientas+para+Nodejs.jpg&quot; title=&quot;Google proveera herramientas para Nodejs&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Google hizo hincapié en las herramientas disponibles en la App Engine para los usuarios de Node.js: &quot;Cuando ejecutas una aplicación Node.js sobre la App Engine, puedes usar las herramientas y bases de datos que actualmente conoces y más te gustan. Puedes usar &lt;a href=&quot;http://expressjs.com/es/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Express&lt;/a&gt;, &lt;a href=&quot;http://hapijs.com/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Hapi&lt;/a&gt;, &lt;a href=&quot;https://parse.com/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Parse-server&lt;/a&gt;, o cualquier otro servidor Web para construir tu aplicación. &amp;nbsp;Puedes usar &lt;a href=&quot;https://www.mongodb.org/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;MongoDB&lt;/a&gt;, &lt;a href=&quot;http://redis.io/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Redis&lt;/a&gt;, o &lt;a href=&quot;https://cloud.google.com/datastore/docs/concepts/overview&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Google Cloud Datastore&lt;/a&gt; para almacenar tus datos.&quot; dice Justin Beckwith, Gerente de Producto para la plataforma de Google Cloud, en un detallado boletín sobre el soporte a Node.js&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Los usuarios también podrán usar herramientas de Google como &lt;a href=&quot;https://cloud.google.com/container-engine/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Google Container Engine&lt;/a&gt; para ejecutar contenedores Docker, o &lt;a href=&quot;https://cloud.google.com/compute/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Google Compute Engine&lt;/a&gt;, el cual proporciona máquinas virtuales.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
El &lt;a href=&quot;https://cloud.google.com/sdk/gcloud/reference/preview/app/modules/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;módulo NPM gcloud&lt;/a&gt;, por su parte, permite el uso de APIs y servicios de Google, incliyendo el API de &lt;a href=&quot;https://cloud.google.com/vision/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Google Cloud Vision&lt;/a&gt;, para integrar características de detección visual como el etiquetado de imágenes, y &lt;a href=&quot;https://cloud.google.com/bigquery/what-is-bigquery&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Google BigQuery&lt;/a&gt;, para la consulta de un conjunto de datos masivos.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Más cosas vendrán por parte de Google para Node.js, &quot;Esto es sólo el principio, mantén tus oídos atentos para ser testigo de la próxima ola de características que se ofrecerán para Node.js en la plataforma de Google Cloud&quot;, dijo Beckwith.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Bien, así que qué les parece esto, creo que es una gran noticia para los amantes de JavaScript :-)&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/7872069361096278969/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2016/04/google-app-engine-ahora-soporta-nodejs.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/7872069361096278969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/7872069361096278969'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2016/04/google-app-engine-ahora-soporta-nodejs.html' title='Google App Engine Ahora Soporta Node.js'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhn56Qm61dJa88yUGbCRT-oJ44ZtisbwrENIR_OetvYsDS8feTswqRigbQRS6oCixJYfxJE_hLozZtXzRBXJkxfymPmmtY49fGoltxEL9iEnlg4pvToWH9FUrEQL1LywcV7YprEzF5MmU7e/s72-c/Google+App+Engine+Ahora+Soporta+Node.js.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-4531878921624514126</id><published>2016-03-23T01:42:00.000-05:00</published><updated>2017-09-10T01:38:31.898-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Patrones de Diseño"/><category scheme="http://www.blogger.com/atom/ns#" term="Tutorial Java"/><category scheme="http://www.blogger.com/atom/ns#" term="UML"/><title type='text'>Introducción a los Patrones de Diseño o Design Patterns</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
Cuando trabajamos con proyectos medianos o grandes, es bueno contar con &lt;b&gt;metodologías&lt;/b&gt; que nos ayuden en muchas ocasiones a &lt;b&gt;simplificar el trabajo&lt;/b&gt;, sea que trabajemos solos o en equipo, y si trabajamos en equipo, que tengamos la añadidura de todos hablar el mismo &quot;&lt;i&gt;idioma&lt;/i&gt;&quot;, o mejor, el mismo &quot;&lt;i&gt;dialecto&lt;/i&gt;&quot; (ya que el idioma vendría siendo el lenguaje :-) jejeje) gracias a dichas metodologías.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Por ésta razón he decidido empezar una serie de artículos en las que iremos estudiando poco a poco algunos &lt;b&gt;patrones de diseño&lt;/b&gt; y cómo implementarlos en &lt;a href=&quot;http://www.eljavatar.com/search/label/Java&quot; target=&quot;_blank&quot;&gt;Java&lt;/a&gt;. Pero antes que nada, veamos qué son los &lt;i&gt;patrones de diseño&lt;/i&gt; o &lt;i&gt;design patterns&lt;/i&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEho3yfNoi_5FmMsMkR67WVhJzfeq8pC_D_p8teThtXzqyfW09zdSane4UQp7D79uAo_0ni5thnTRZsdjy4OovxVfsvpCGeYYYH5bCPUxGzAPM7VYWfw-rA6sEbNJ9hREifnBCxSG5M7eKEg/s1600/Introducci%25C3%25B3n+a+los+Patrones+de+Dise%25C3%25B1o+%25C3%25B3+Design+Patterns.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Introducción a los Patrones de Diseño ó Design Patterns&quot; border=&quot;0&quot; height=&quot;191&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEho3yfNoi_5FmMsMkR67WVhJzfeq8pC_D_p8teThtXzqyfW09zdSane4UQp7D79uAo_0ni5thnTRZsdjy4OovxVfsvpCGeYYYH5bCPUxGzAPM7VYWfw-rA6sEbNJ9hREifnBCxSG5M7eKEg/s400/Introducci%25C3%25B3n+a+los+Patrones+de+Dise%25C3%25B1o+%25C3%25B3+Design+Patterns.png&quot; title=&quot;Introducción a los Patrones de Diseño ó Design Patterns&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;¿Qué son los Patrones de Diseño o Design Patterns?&lt;/b&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Un &lt;b&gt;patrón de diseño&lt;/b&gt; o &lt;b&gt;pattern design&lt;/b&gt; consiste en un &lt;i&gt;diagrama de objetos&lt;/i&gt; que forma una solución a un problema conocido y frecuente. Dicho diagrama de objetos está constituido por un conjunto de objetos descritos por clases y las relaciones que enlazan los objetos.&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;!-- anuncios --&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Así como en otras áreas de la Ingeniería se han desarrollado a lo largo de la historia modelos a seguir, por ejemplo en la &lt;i&gt;Ingeniería Civil&lt;/i&gt;, existen modelos de buenas prácticas para llevar a cabo una Obra, muchos de los cuales incluso son obligatorios de implementar en ciertos casos; sin embargo en la programación esa palabra &quot;&lt;i&gt;obligación&lt;/i&gt;&quot; desaparece, ya que a la final, &lt;b&gt;es el programador quien decide cuál es la mejor solución&lt;/b&gt; para su problema en cuestión y tiene &amp;nbsp;la total libertad de decidirse a usar o no un &lt;u&gt;Patrón de Diseño&lt;/u&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Los patrones de diseño responden a problemas de diseño de aplicaciones en el marco de la &lt;b&gt;Programación Orientada a Objetos&lt;/b&gt;. Se trata de soluciones conocidas y probadas cuyo diseño proviene de la experiencia de los programadores. No existe un aspecto teórico en los patrones, en particular no existe una formalización (a diferencia como sucede en el caso de los algoritmos).&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Los patrones de diseño están basados en las &lt;u&gt;buenas prácticas de la programación orientada a Objetos&lt;/u&gt;. Por ejemplo, la siguiente figura muestra el patrón &lt;b&gt;Template method&lt;/b&gt; que describiremos en una posterior entrada. En éste patrón, el método &lt;i&gt;calculaPrecioConIVA &lt;/i&gt;invoca al método &lt;i&gt;calculaIVA &lt;/i&gt;abstracto de la clase &lt;i&gt;Pedido&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Dicho método (&lt;i&gt;calculaIVA&lt;/i&gt;) Está definido en las subclases de &lt;i&gt;Pedido&lt;/i&gt;, en este caso, las clases &lt;i&gt;PedidoEspaña &lt;/i&gt;y &lt;i&gt;PedidoColombia&lt;/i&gt;. En efecto, el IVA varía en función del país. Al método &lt;i&gt;calculaPrecioConIVA &lt;/i&gt;se le llama &quot;&lt;b&gt;modelo&lt;/b&gt;&quot; (template method). Este método introduce un algoritmo basado en un método abstracto.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivHyd2hcrbeHMFxw3t4hrOCxZpvpSxmyJXOXPPdH6Poz-LQDH-ahwbKOJE-b2qRJOs6YtWU6Gy9jDhvPf7KeV1eKAQvebD866JvcGEoDZ56D8A7A-5ISOMr7L29M1cm_alpJ5rsq73rui-/s1600/Ejemplo+Patron+de+Dise%25C3%25B1o+en+Java.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Ejemplo de Patrón de Diseño en Java&quot; border=&quot;0&quot; height=&quot;160&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivHyd2hcrbeHMFxw3t4hrOCxZpvpSxmyJXOXPPdH6Poz-LQDH-ahwbKOJE-b2qRJOs6YtWU6Gy9jDhvPf7KeV1eKAQvebD866JvcGEoDZ56D8A7A-5ISOMr7L29M1cm_alpJ5rsq73rui-/s400/Ejemplo+Patron+de+Dise%25C3%25B1o+en+Java.png&quot; title=&quot;Ejemplo de Pattern Design Template en Java&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Este patrón está basado en el &lt;b&gt;polimorfismo&lt;/b&gt;, una propiedad importante de la &lt;a href=&quot;http://www.eljavatar.com/2014/05/Paradigmas-de-Programacion-VIII-Programacion-Orientada-a-Eventos.html&quot; target=&quot;_blank&quot;&gt;programación orientada a objetos&lt;/a&gt;. El precio de un pedido en España o en Colombia está sometido a un impuesto sobre el valor añadido. No obstante &amp;nbsp;la tasa no es la misma, y el cálculo del IVA difiere en España y en Colombia. Por consiguiente, el patrón &lt;i&gt;Template method&lt;/i&gt; constituye una buena ilustración del polimorfismo.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Los patrones se introducen en 1995 con el libro del llamado &quot;GoF&quot;, de Gang of Four (en referencia a la &quot;banda de los cuatro&quot; autores), llamado &quot;&lt;i&gt;Dessign Patterns -Elements of Reusable Object-Oriented Software&lt;/i&gt;&quot; escrito por &lt;b&gt;Erich Gama&lt;/b&gt;, &lt;b&gt;Richard Helm&lt;/b&gt;, &lt;b&gt;Ralph Johnson&lt;/b&gt; y &lt;b&gt;John Vlissides&lt;/b&gt;. Este libro constituye la obra de referencia acerca de patrones de diseño.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Los patrones de diseño no son exclusividad del lenguaje de programación Java, ya que como lo dije anteriormente, son la implementación de buenas prácticas en la &lt;b&gt;programación Orientada a Objetos&lt;/b&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Sin embargo, &lt;b&gt;Java es un lenguaje Orientado a Objetos por excelencia&lt;/b&gt;, así que éste será el lenguaje escogido para ejemplificar cada uno de los patrones de diseño que iremos estudiando. Así mismo, también usaré el lenguaje de modelización UML, ya que éste nos permite comprender de manera rápida y gráfica los ejemplos expuestos mediante Diagramas de Clase y/o Diagramas de Objetos.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/4531878921624514126/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2016/03/Introduccion-a-los-Patrones-de-Diseno-o-Design-Patterns.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/4531878921624514126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/4531878921624514126'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2016/03/Introduccion-a-los-Patrones-de-Diseno-o-Design-Patterns.html' title='Introducción a los Patrones de Diseño o Design Patterns'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEho3yfNoi_5FmMsMkR67WVhJzfeq8pC_D_p8teThtXzqyfW09zdSane4UQp7D79uAo_0ni5thnTRZsdjy4OovxVfsvpCGeYYYH5bCPUxGzAPM7VYWfw-rA6sEbNJ9hREifnBCxSG5M7eKEg/s72-c/Introducci%25C3%25B3n+a+los+Patrones+de+Dise%25C3%25B1o+%25C3%25B3+Design+Patterns.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-6866198894816051332</id><published>2016-03-21T10:36:00.004-05:00</published><updated>2017-09-10T01:34:53.069-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Tutorial Java"/><title type='text'>Cómo Hacer un Modelo de Datos Personalizado para un JTable en Java</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
Una de las mejores formas de organizar y mostrar la información que obtenemos ya sea de una &lt;b&gt;Base de Datos&lt;/b&gt; o de alguna otra fuente de datos, o incluso información estática en nuestros programas es a través de tablas, y en este artículo veremos &lt;b&gt;como crear modelos de datos personalizados&lt;/b&gt; para no sólo mostrar información en un &lt;i&gt;JTable en Java&lt;/i&gt;, sino también para acceder a la información que se encuentra en ellos, e incluso para modificarla de forma sencilla en caso de que así lo necesitemos.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-p5r6mGsoIv-nBEoqyoQcQIzNFMs-1CPom6wU81n4ZHpvPkh4vEvnNcl35e_SRoHkwxzpoCy5x50_9omr4tkzKBEJFX3vwPeN3eEvX8MFTlPUXYrvZFofFrSodR53Q6xbh5CVV1zzyx82/s1600/Datos+de+Persona+Seleccionada+en+Ejemplo+AbstractTableModel+en+Java.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Cómo Hacer un Modelo de Datos Personalizado para un JTable en Java&quot; border=&quot;0&quot; height=&quot;292&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-p5r6mGsoIv-nBEoqyoQcQIzNFMs-1CPom6wU81n4ZHpvPkh4vEvnNcl35e_SRoHkwxzpoCy5x50_9omr4tkzKBEJFX3vwPeN3eEvX8MFTlPUXYrvZFofFrSodR53Q6xbh5CVV1zzyx82/s400/Datos+de+Persona+Seleccionada+en+Ejemplo+AbstractTableModel+en+Java.png&quot; title=&quot;Cómo Hacer un Modelo de Datos Personalizado para un JTable en Java&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Cuando queremos mostrar información en un JTable, normalmente lo hacemos a través de una clase del &lt;u&gt;API de Java&lt;/u&gt;: &lt;i&gt;DefaultTableModel&lt;/i&gt;, que sería la forma más sencilla de hacerlo, sin embargo, desde que aprendí esta forma que les enseñaré a continuación, es decir, usando un &lt;b&gt;Modelo de Datos personalizado&lt;/b&gt;, procuro tratar de usarlo, ya que como su nombre lo indica, lo que hacemos es crear un Modelo de Datos, que separa el Modelo de la Vista, de esta forma, lo único que haremos es manipular siempre nuestro modelo, y la vista se actualizará de acuerdo a este.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;h3&gt;
&lt;b&gt;Uso de Modelos de Datos para JTable en Java&lt;/b&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;!-- anuncios --&gt;

&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Bien, primero que nada, veamos un poco de teoría... sí, lo se, a veces no nos gusta mucho la teoría, pero muchas veces es necesaria para entender lo que estamos haciendo, sin embargo, vamos a explicar la teoría de una forma sencilla y enfocándonos en lo que nos interesa para este tutorial :-)&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Cuando vamos a gestionar los datos dentro de un &lt;b&gt;JTable&lt;/b&gt;, siempre debemos hacerlo a través de un modelo de datos, y cómo había mencionado anteriormente, lo más sencillo es hacerlo a través de un DefaultTableModel, ya que lo único que haríamos es lo siguiente:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;DefaultTableModel modelo = new DefaultTableModel();
JTable tabla = new JTable(modelo);&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
O en caso de que ya tuviésemos nuestra instancia de JTable creada como sucede cuando trabajamos con el editor gráfico de NetBeans, asignaríamos nuestro modelo de la siguiente forma:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;DefaultTableModel modelo = new DefaultTableModel();
tabla.setModel(modelo);&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Y esta es la forma más sencilla, puesto que la clase &lt;a href=&quot;https://docs.oracle.com/javase/7/docs/api/javax/swing/table/DefaultTableModel.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;DefaultTableModel&lt;/a&gt; implementa todos los métodos de la interface &lt;a href=&quot;https://docs.oracle.com/javase/7/docs/api/javax/swing/table/TableModel.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;TableModel&lt;/a&gt;, y de la clase abstracta &lt;a href=&quot;https://docs.oracle.com/javase/7/docs/api/javax/swing/table/AbstractTableModel.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;AbstractTableModel&lt;/a&gt;, brindándonos un comportamiento por defecto para todos nuestros JTables e incluso permitiéndonos sobre-escribir sus métodos para casos en los que necesitemos comportamientos más personalizados.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Esto nos puede ser práctico en caso de que sólo deseáramos mostrar datos que no van a cambiar, por ejemplo, una tabla con valores estáticos, a la cual no nos interesa acceder a sus datos y en la que por ejemplo sólo nos interesara que no se permitiera editar el valor de sus celdas. Esto lo haríamos más o menos de la siguiente forma:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;DefaultTableModel modelo = new DefaultTableModel() {
    @Override
    public boolean isCellEditable (int row, int column){
        return false;
    }
};
tabla.setModel(modelo);
// Podemos añadir los datos antes o después de asignar el modelo
// Supongamos que añadimos 10 filas de datos
for (int i = 0; i &amp;lt; 10; i++) {
    modelo.addRow(new Object[]{&quot;Columna 1&quot;, &quot;Columna 2&quot;, &quot;Columna 3&quot;, 1000, 50.8});
}&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Esto es totalmente válido, y como vemos, muy rápido de hacer, y hasta podríamos decir que un poco práctico, aunque la verdad no tanto, y ya veremos el por qué, a menos claro, que como lo había mencionado, sólo nos interese mostrar los datos y nada más dejarlos ahí quieticos, incluso sin querer acceder a ellos, lo cual es algo que normalmente no suele suceder.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Empecemos a plantear algunos casos. Primero, supongamos que deseamos obtener los datos de una fila para una operación, o para pasarlo a algún método, o alguna otra tarea que necesitemos; en este caso supongamos que es para mostrarlo en un &lt;b&gt;String&lt;/b&gt;; para esto haríamos lo siguiente:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;int fila = tabla.getSelectedRow();
String valores = &quot;&quot;;
for (int i = 0; i &amp;lt; tabla.getColumnCount(); i++) {
    valores&amp;nbsp;+= tabla.getValueAt(fila, i).toString()&amp;nbsp;+ &quot;, &quot;;
}&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
El método &lt;i&gt;getValueAt(row, column)&lt;/i&gt; devuelve un dato de tipo &lt;b&gt;Object&lt;/b&gt;, por eso usamos su método &lt;i&gt;toString()&lt;/i&gt; para pasarlo a &lt;b&gt;String&lt;/b&gt;. Hasta aquí, todo está normal y se puede hacer sin ningún problema, aunque desde ya podemos visualizar que acceder a los datos de un JTable a través de este método implica perder comunicación con nuestras &lt;b&gt;clases Bean&lt;/b&gt;, en caso de que las usemos para crear las instancias de los datos, ya veremos más adelante a lo que me refiero.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Bueno, de igual modo, si deseamos insertar algún valor, o más bien, modificar algún valor que ya tenemos dentro del &lt;b&gt;JTable&lt;/b&gt; lo haríamos con el método:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;...
tabla.setValueAt(value, row, column);
...&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Bueno, pero vayamos un poco más allá. Supongamos que por ejemplo en las filas en las que agregamos valores numéricos, nosotros deseamos que éstos se vean con un formato específico, por ejemplo con el formato &lt;b&gt;#.##0,##&lt;/b&gt; Esto lo haríamos así:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;DecimalFormatSymbols simbolos = new DecimalFormatSymbols();
simbolos.setDecimalSeparator(&#39;,&#39;);
simbolos.setGroupingSeparator(&#39;.&#39;);
DecimalFormat formato = new DecimalFormat(&quot;#,##0.##&quot;,simbolos);

for (int i = 0; i &amp;lt; 10; i++) {
    modelo.addRow(new Object[]{&quot;Columna 1&quot;, &quot;Columna 2&quot;, &quot;Columna 3&quot;, formato.format(1000), formato.format(50.8)});
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Bien, parece que ahora nuestros valores numéricos se muestran un poco más bonitos al tener un formato específico. ¿Pero qué pasaría si nosotros deseamos obtener todos los valores de una columna numérica para por ejemplo hacer una suma con ellos?&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
El método &lt;i&gt;getValueAt(row, column)&lt;/i&gt; nos devuelve un objeto el cual podemos castear al tipo de dato que el compilador reconoce para los datos que el JTable encuentra en esa columna. Así que si deseamos obtener por ejemplo un double, lo haríamos así:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;double valor = (double) tabla.getValueAt(row, column);
// También podemos hacerlo a través de esta otra forma:
double valor2 = Double.parseDouble(tabla.getValueAt(row, column).toString());
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Si el valor que se obtiene es en efecto un double, no habrá ningún problema, pero en caso de no serlo, se nos arrojará una Excepción en tiempo de ejecución de tipo&amp;nbsp;&lt;a href=&quot;https://docs.oracle.com/javase/7/docs/api/java/lang/ClassCastException.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;ClassCastException&lt;/a&gt; para el primer caso, o de &lt;a href=&quot;https://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;NumberFormatException&lt;/a&gt; para el segundo, lo cual es lo que muy seguro nos pasará ahora.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
¿Por qué estoy seguro que tendremos una excepción? Si no me crees, haz una prueba como te he dicho y aplicando los formatos que indico anteriormente y me cuentas jejeje ;-)&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Pues bien, recuerda que hemos añadido un formato, y al ingresar un número formateado, no estamos ingresando en el JTable un número, sino un String, así que si intentamos hacer un casting de String a double, obtendremos una Excepción.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Bien, ahora me dirás, ¿y si uso la segundo forma, es decir, haciendo un parsing usando los métodos respectivos de las clases de tipo numérico? Esto puede funcionar, claro, si la cadena obtenida tiene el formato adecuado.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Sin embargo, éste no es el caso, porque para Java un número almacenado en un String puede ser convertido a Integer si éste no posee ningún separador, y a Double si sólamente tiene el separador de decimales, el cual es por defecto el &quot;&lt;b&gt;.&lt;/b&gt;&quot;, y recuerda que en los formatos hemos indicado que nuestros valores se mostrarán con separador de miles, y además el separador de decimales que hemos asignado es la &quot;&lt;b&gt;,&lt;/b&gt;&quot;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Vaya, menudo problema, y no estoy diciendo que no tenga solución si lo hiciéramos así, pero dicha solución sería muy artificiosa, ya que cada vez que obtengamos un valor, primero tendríamos que obtener el String, eliminarle el separador de miles, y posteriormente cambiarle el símbolo decimal, lo cual es un derroche de recursos que sólo hace que nuestra aplicación vaya más lenta.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Así que por estas, y por muchas otras razones, la mejor solución es usar un &lt;b&gt;Modelo de datos que tenga independencia de nuestra JTable&lt;/b&gt;. para lo cual crearemos una clase que extienda de la clase &lt;i&gt;AbstractTableModel&lt;/i&gt;. También podríamos hacerlo implementando la clase TableModel, sin embargo, al heredar de la clase AbstractTableModel evitamos tener que sobre-escribir los métodos para notificar a los suscriptores, además de que nos evitamos tener que crear un &lt;b&gt;TableModelEvent&lt;/b&gt;, rellenarlo con los datos adecuados y avisar a los suscriptores cuando hacemos alguna modificación en los datos.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: #ffd966;&quot;&gt;Un &lt;b&gt;suscriptor &lt;/b&gt;es cualquier clase que quiera enterarse de cambios en los datos del modelo. El JTable es un ejemplo claro. El JTable se suscribe a cambios de datos en el modelo y de esta forma, en cuanto cambiemos datos en el modelo, el JTable se entera y se repinta automáticamente la pantalla.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Bien, yo creo que ya es suficiente de teoría y podemos dejar hasta aquí esta introducción. Entremos ahora sí en materia de este tutorial que es aprender &lt;b&gt;cómo hacer un modelo de datos personalizados para un JTable en Java&lt;/b&gt;:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;¿Qué Usaremos Para Este Tutorial?&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; NetBeans 8.1&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; Java 1.8&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Nivel:&lt;/b&gt; Intermedio&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Tiempo:&lt;/b&gt;&amp;nbsp;30 minutos&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;1.&lt;/b&gt; Creamos un proyecto en NetBeans con la siguiente estructura:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn_ws5uZz6MWf6oZqhL5X1HJVAWTXy9v16KxsfjuxnRitTOEr7yrs-dBngmoU5YEiaFNXY5e9i4JK0zi8zgEOF5dUoWZsn8m-bwS3RTWPsQr1rAYDEA24BCN03pR467MDyRui1008AhQcb/s1600/Estructura+de+Proyecto+Ejemplo+AbstractTableModel+para+JTable+Java.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Estructura de Proyecto Ejemplo AbstractTableModel para JTable Java&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn_ws5uZz6MWf6oZqhL5X1HJVAWTXy9v16KxsfjuxnRitTOEr7yrs-dBngmoU5YEiaFNXY5e9i4JK0zi8zgEOF5dUoWZsn8m-bwS3RTWPsQr1rAYDEA24BCN03pR467MDyRui1008AhQcb/s1600/Estructura+de+Proyecto+Ejemplo+AbstractTableModel+para+JTable+Java.png&quot; title=&quot;Cómo hacer un Modelo de Datos Personalizado para un JTable en Java - Estructura del Proyecto&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Aquí podemos observar 3 clases. &lt;b&gt;VentanaPrincipal&lt;/b&gt;, que es la clase Main y en la que tendremos nuestros componentes visuales como nuestro JTable, la clase &lt;b&gt;ModeloDatosTablaPersonas&lt;/b&gt; que será nuestro Modelo de Datos para el JTable, y nuestra clase &lt;b&gt;Persona&lt;/b&gt; que será el Bean de nuestro Modelo de Datos.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;2.&lt;/b&gt;&amp;nbsp;Creamos la interfaz de usuario la cual comprende un &lt;b&gt;JFrame&lt;/b&gt; donde hemos agregado un &lt;b&gt;JTable&lt;/b&gt; y un &lt;b&gt;JButton&lt;/b&gt; que usaremos para obtener los datos de una fila seleccionada.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaeJilhhthFavuKJsDTyPj6DKSKsnlTzsKnygVDJBj-QE8I2cDArTH_ymVTlNS5O42Jp6Q3Tt9lVRYs9LMY8mN6AMZOhHDPP6ZKQVBUZA0m3IZOigKCx4xqXAiNl9DIAg5sq5YR2e8Sz3C/s1600/Interfaz+Grafica+del+Ejemplo+AbstractTableModel+para+JTable+en+Java.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Interfaz Grafica del Ejemplo AbstractTableModel para JTable en Java&quot; border=&quot;0&quot; height=&quot;275&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaeJilhhthFavuKJsDTyPj6DKSKsnlTzsKnygVDJBj-QE8I2cDArTH_ymVTlNS5O42Jp6Q3Tt9lVRYs9LMY8mN6AMZOhHDPP6ZKQVBUZA0m3IZOigKCx4xqXAiNl9DIAg5sq5YR2e8Sz3C/s400/Interfaz+Grafica+del+Ejemplo+AbstractTableModel+para+JTable+en+Java.png&quot; title=&quot;Cómo Hacer un Modelo de Datos Personalizado para un JTable en Java - Interfaz Gráfica&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;3.&lt;/b&gt; Creamos el Bean de nuestro modelo de acuerdo a la estructura de esta JTable. Así que nuestra clase &lt;b&gt;Persona&lt;/b&gt; nos quedaría de la siguiente forma:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;package com.eljavatar.ejemploabstracttablemodel;

/**
 *
 * @author Andres
 */
public class Persona {
    
    private String codigo;
    private String nombres;
    private int edad;
    private double valorDeuda;

    public Persona(String codigo, String nombres, int edas, double valorDeuda) {
        this.codigo = codigo;
        this.nombres = nombres;
        this.edad = edas;
        this.valorDeuda = valorDeuda;
    }

    public Persona() {
    }

    public String getCodigo() {
        return codigo;
    }

    public void setCodigo(String codigo) {
        this.codigo = codigo;
    }

    public String getNombres() {
        return nombres;
    }

    public void setNombres(String nombres) {
        this.nombres = nombres;
    }

    public int getEdad() {
        return edad;
    }

    public void setEdad(int edad) {
        this.edad = edad;
    }

    public double getValorDeuda() {
        return valorDeuda;
    }

    public void setValorDeuda(double valorDeuda) {
        this.valorDeuda = valorDeuda;
    }
    
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
En ésta clase sólamente hemos creado los parámetros que necesitamos, dos constructores, uno con todos los atributos de la clase y uno por defecto vacío, y los &lt;i&gt;Getters&lt;/i&gt; y &lt;i&gt;Setters&lt;/i&gt; de cada uno de los atributos, es decir, una clase &lt;a href=&quot;https://es.wikipedia.org/wiki/Plain_Old_Java_Object&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;POJO&lt;/a&gt; común y corriente.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;4.&lt;/b&gt; Ahora vamos a nuestra clase &lt;b&gt;ModeloDatosTablaPersona&lt;/b&gt;. lo primero que debemos hacer es heredar de la clase AbstractTableModel, por lo cual debemos importar dicha clase, pero además, ésta posee tres métodos abstractos los cuales debemos implementar; así pues, nuestra clase empezaría teniendo la siguiente forma:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;package com.eljavatar.ejemploabstracttablemodel;

import javax.swing.table.AbstractTableModel;

public class ModeloDatosTablaPersonas extends AbstractTableModel {

    @Override
    public int getRowCount() {
        throw new UnsupportedOperationException(&quot;Not supported yet.&quot;); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public int getColumnCount() {
        throw new UnsupportedOperationException(&quot;Not supported yet.&quot;); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        throw new UnsupportedOperationException(&quot;Not supported yet.&quot;); //To change body of generated methods, choose Tools | Templates.
    }

}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
En un momento iremos editando el código de estos tres métodos, por ahora seguiremos con lo siguiente:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;5.&lt;/b&gt; Creamos tres atributos. Un &lt;b&gt;array de tipo Class&lt;/b&gt; que contendrá el tipo de dato de las columnas, un &lt;b&gt;array de tipo String&lt;/b&gt; que contendrá los títulos de las columnas, y una &lt;b&gt;lista de tipo List&amp;lt;Persona&amp;gt;&lt;/b&gt; que contendrá los datos de nuestro JTable. Además crearemos el respectivo Get y Set para la lista de datos:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;private final Class[] tipoColumnas;
private final String[] titleColumnas;
private List&amp;lt;Persona&amp;gt; personas;

public List&amp;lt;Persona&amp;gt; getPersonas() {
    return personas;
}

public void setPersonas(List&amp;lt;Persona&amp;gt; personas) {
    this.personas = personas;
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;6.&lt;/b&gt; Ahora creamos el constructor de la clase en donde inicializaremos la lista y asignaremos los nombres de las columnas y sus correspondientes tipos de datos:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;public ModeloDatosTablaPersonas() {
    personas = new ArrayList();
    this.titleColumnas = new String[]{&quot;Código&quot;, &quot;Nombres&quot;, &quot;Edad&quot;, &quot;Valor Deuda&quot;};
    this.tipoColumnas = new Class[]{String.class, String.class, Integer.class, Double.class};
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;7.&lt;/b&gt; Ahora sobre-escribiremos tres métodos de la clase &lt;b&gt;AbstractTableModel &lt;/b&gt;mediante los cuales retornaremos el &lt;i&gt;título de nuestras columnas&lt;/i&gt;, &lt;i&gt;su tipo de dato&lt;/i&gt;, y además &lt;i&gt;modificaremos el comportamiento por defecto de la edición de las celdas&lt;/i&gt; para que éstas puedan ser editadas:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;@Override
public String getColumnName(int column) {
    return titleColumnas[column];
}

@Override
public Class&amp;lt;?&amp;gt; getColumnClass(int columnIndex) {
    return tipoColumnas[columnIndex];
}

@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
     return true;
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;8.&lt;/b&gt; Bien, ahora vamos a ver como quedarían los métodos que implementamos inicialmente:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;@Override
public int getRowCount() {
    return personas.size();
}

@Override
public int getColumnCount() {
    return titleColumnas.length;
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Con éstos dos métodos lo que hacemos es obtener la &lt;u&gt;cantidad de filas&lt;/u&gt; según la cantidad de elementos que tiene nuestro List, y la &lt;u&gt;cantidad de columnas&lt;/u&gt; según la cantidad de elementos que tiene el array que guarda los títulos de las columnas.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Y el método&amp;nbsp;&lt;i&gt;getValueAt(int rowIndex, int columnIndex)&lt;/i&gt; nos quedaría de la siguiente forma:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    switch (columnIndex) {
        case 0:
            return personas.get(rowIndex).getCodigo();
        case 1:
            return personas.get(rowIndex).getNombres();
        case 2:
            return personas.get(rowIndex).getEdad();
        case 3:
            return personas.get(rowIndex).getValorDeuda();
        default:
            return null;
    }
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Es con éste método con el que mostramos los datos en el JTable.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;9.&lt;/b&gt; Para poder cambiar datos en el &lt;b&gt;JTable&lt;/b&gt;, debemos sobre-escribir el método&amp;nbsp;&lt;i&gt;setValueAt(Object aValue, int rowIndex, int columnIndex)&lt;/i&gt; de la clase &lt;b&gt;AbstractTableModel &lt;/b&gt;y hacerlo de forma similar a como lo hicimos con el método &lt;i&gt;getValueAt&lt;/i&gt;, pero además, notificamos la modificación en los datos a través de dos métodos de ésta misma clase:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    switch (columnIndex) {
        case 0:
            personas.get(rowIndex).setCodigo(aValue.toString());
            break;
        case 1:
            personas.get(rowIndex).setNombres(aValue.toString());
            break;
        case 2:
            personas.get(rowIndex).setEdad((int) aValue);
            break;
        case 3:
            personas.get(rowIndex).setValorDeuda((double) aValue);
        default: ;
    }
    this.fireTableCellUpdated(rowIndex, columnIndex);
    this.fireTableRowsUpdated(rowIndex, rowIndex);
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Como podemos apreciar, cuando modificamos entonces ahora un valor en el JTable, este no se afecta directamente en el JTable, sino en la lista de tipo Persona, la cual es la que se encarga de gestionar los datos y no un Object genérico como sucedía cuando usábamos DefaultTableModel.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Bueno, parece que ya todo está tomando forma. Ahora sólo nos falta hacer uso de este modelo, pero antes, veamos cómo quedó completa nuestra clase &lt;b&gt;ModeloDatosTablaPersonas&lt;/b&gt;:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;package com.eljavatar.ejemploabstracttablemodel;

import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;

/**
 *
 * @author Andres
 */
public class ModeloDatosTablaPersonas extends AbstractTableModel {

    private final Class[] tipoColumnas;
    private final String[] titleColumnas;
    private List&amp;lt;Persona&amp;gt; personas;

    public List&amp;lt;Persona&amp;gt; getPersonas() {
        return personas;
    }

    public void setPersonas(List&amp;lt;Persona&amp;gt; personas) {
        this.personas = personas;
    }

    public ModeloDatosTablaPersonas() {
        personas = new ArrayList();
        this.titleColumnas = new String[]{&quot;Código&quot;, &quot;Nombres&quot;, &quot;Edad&quot;, &quot;Valor Deuda&quot;};
        this.tipoColumnas = new Class[]{String.class, String.class, Integer.class, Double.class};
    }

    @Override
    public String getColumnName(int column) {
        return titleColumnas[column];
    }

    @Override
    public Class&amp;lt;?&amp;gt; getColumnClass(int columnIndex) {
        return tipoColumnas[columnIndex];
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return true;
    }

    @Override
    public int getRowCount() {
        return personas.size();
    }

    @Override
    public int getColumnCount() {
        return titleColumnas.length;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        switch (columnIndex) {
            case 0:
                return personas.get(rowIndex).getCodigo();
            case 1:
                return personas.get(rowIndex).getNombres();
            case 2:
                return personas.get(rowIndex).getEdad();
            case 3: 
                return personas.get(rowIndex).getValorDeuda();
            default:
                return null;
        }
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        switch (columnIndex) {
            case 0:
                personas.get(rowIndex).setCodigo(aValue.toString());
                break;
            case 1:
                personas.get(rowIndex).setNombres(aValue.toString());
                break;
            case 2:
                personas.get(rowIndex).setEdad((int) aValue);
                break;
            case 3:
                personas.get(rowIndex).setValorDeuda((double) aValue);
            default: ;
        }
        this.fireTableCellUpdated(rowIndex, columnIndex);
        this.fireTableRowsUpdated(rowIndex, rowIndex);
    }

}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;10.&lt;/b&gt; En nuestra clase &lt;b&gt;VentanaPrincipal &lt;/b&gt;que es donde hemos creado nuestro JTable, creamos un atributo de tipo &lt;b&gt;ModeloDatosTablaPersonas &lt;/b&gt;y creamos un método en el que asignaremos nuestro respectivo modelo:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;private ModeloDatosTablaPersonas modeloTablaPersonas;

private void setModeloTabla() {
    modeloTablaPersonas = new ModeloDatosTablaPersonas();
    modeloTablaPersonas.setPersonas(obtenerPersonas());
    this.jTpersonas.setModel(modeloTablaPersonas);
    this.jTpersonas.getColumnModel().getColumn(3).setCellRenderer(new DecimalFormatRenderer());
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;11.&lt;/b&gt; El método &lt;i&gt;obtenerPersonas()&lt;/i&gt; es cualquier método que nos retorne un &lt;b&gt;ArrayList con datos&lt;/b&gt; ya sea de una base de datos, o de algún otro lado, pero en este caso será una lista de datos que crearemos a lo más Hard Coding :-P&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;public ArrayList&amp;lt;Persona&amp;gt; obtenerPersonas() {
    ArrayList&amp;lt;Persona&amp;gt; lista = new ArrayList();
    lista.add(new Persona(&quot;Cod001&quot;, &quot;Juan&quot;, 24, 5000.4));
    lista.add(new Persona(&quot;Cod002&quot;, &quot;Felipe&quot;, 27, 6700.8));
    lista.add(new Persona(&quot;Cod003&quot;, &quot;Diana&quot;, 31, 354.9));
    lista.add(new Persona(&quot;Cod004&quot;, &quot;María&quot;, 46, 5300));
    lista.add(new Persona(&quot;Cod005&quot;, &quot;Camilo&quot;, 28, 2890.6));
    lista.add(new Persona(&quot;Cod006&quot;, &quot;Pedro&quot;, 52, 1600.5));
    lista.add(new Persona(&quot;Cod007&quot;, &quot;Sandra&quot;, 43, 2000));
    lista.add(new Persona(&quot;Cod008&quot;, &quot;Esteban&quot;, 39, 752));
    lista.add(new Persona(&quot;Cod009&quot;, &quot;Pablo&quot;, 26, 2430.1));
    lista.add(new Persona(&quot;Cod010&quot;, &quot;Ana&quot;, 38, 3470.3));
    return lista;
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;12.&lt;/b&gt; La clase &lt;b&gt;DecimalFormatRenderer &lt;/b&gt;es una clase estática dentro de nuestra clase encargada de darle formato a los valores decimales, en este caso de la columna 3:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;static class DecimalFormatRenderer extends DefaultTableCellRenderer {
        
    private static DecimalFormatSymbols simbolos;
    private static DecimalFormat formato;
        
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        simbolos = new DecimalFormatSymbols();
        simbolos.setDecimalSeparator(&#39;,&#39;);
        simbolos.setGroupingSeparator(&#39;.&#39;);
        formato = new DecimalFormat(&quot;#,##0.##&quot;, simbolos);
        value = formato.format((Number) value);
        return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    }
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Sé lo que algunos estarán pensando, y si.. es cierto, esto mismo lo hubiéramos podido hacer con el DefaultTableModel, pero a poco no es más bonita esta implementación jejejeje... bueno hablando en serio, la mayor ventaja de hacerlo de este modo es que no perdemos la referencia de los datos que instanciamos a través de nuestra clase Bean, lo cual veremos ahora cuando queramos obtener los datos de alguna fila, pero antes, añadamos el método &lt;i&gt;setModeloTabla()&lt;/i&gt; a nuestro constructor:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;public VentanaPrincipal() {
    initComponents();
    setModeloTabla();
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;13.&lt;/b&gt; Vamos a añadir un evento de tipo &lt;b&gt;ActionListener &lt;/b&gt;a nuestro botón, para ello, basta con hacer doble clic sobre el botón, y NetBeans automáticamente nos añadirá el evento y nos ubicará dentro del método en el cual escribiremos las acciones que se realizarán cuando se haga clic sobre el botón. Así pues, el código de nuestro botón sería el siguiente:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;private void jBobtenerDatosActionPerformed(java.awt.event.ActionEvent evt) {
    int fila = this.jTpersonas.getSelectedRow();
    if (fila &amp;lt; 0) {
        JOptionPane.showMessageDialog(this, &quot;Debe Seleccionar una Fila&quot;, &quot;Error&quot;, JOptionPane.ERROR_MESSAGE);
        return;
    }
    Persona persona = modeloTablaPersonas.getPersonas().get(fila);
    String mensaje = &quot;Datos de la Persona Seleccionada\n&quot;
            + &quot;Código: &quot; + persona.getCodigo() + &quot;\n&quot;
            + &quot;Nombre: &quot; + persona.getNombres() + &quot;\n&quot;
            + &quot;Edad: &quot; + persona.getEdad() + &quot;\n&quot;
            + &quot;Valor Deuda: &quot; + persona.getValorDeuda();
    JOptionPane.showMessageDialog(this, mensaje, &quot;Datos&quot;, JOptionPane.INFORMATION_MESSAGE);
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Como podemos apreciar, los datos no los estamos recuperando del JTable, sino del &lt;b&gt;List&amp;lt;Persona&amp;gt;&lt;/b&gt;, lo cual es por un lado mucho más práctico ya que evitamos tener que castear los datos cuando los recuperamos ahorrando así recursos y agilizando el rendimiento de nuestras aplicaciones, y por otro lado seguimos buenas prácticas de Programación en las que separamos las vistas de los modelos de datos.&lt;br /&gt;
&lt;br /&gt;
Además como lo he venido mencionando a lo largo de éste tutorial, &lt;b&gt;no perdemos la referencia que tenemos con nuestra clase Bean&lt;/b&gt;, que en este caso es Persona, ya que cuando lo hacemos a través de un DefaultTableModel, la perdemos desde que ingresamos los datos en el JTable ya que debemos meter nuestros datos en un array de tipo Object para poder hacerlo, y para recuperarlos en un Bean si así lo quisiéramos, tendríamos que recuperar los datos como Objects y castearlos; mientras que con esta forma, &lt;b&gt;ingresamos un objeto de tipo Persona&lt;/b&gt;, y &lt;b&gt;de igual forma recuperamos un objeto de tipo Persona&lt;/b&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Así pues, el código completo de nuestra clase &lt;b&gt;VentanaPrincipal&lt;/b&gt;, y omitiendo el código auto-generado por NetBeans, nos quedaría así:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush:java&quot;&gt;package com.eljavatar.ejemploabstracttablemodel;

import java.awt.Component;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

/**
 *
 * @author Andres
 */
public class VentanaPrincipal extends javax.swing.JFrame {

    private ModeloDatosTablaPersonas modeloTablaPersonas;

    /**
     * Creates new form VentanaPrincipal
     */
    public VentanaPrincipal() {
        initComponents();
        setModeloTabla();
    }

    public ArrayList&amp;lt;Persona&amp;gt; obtenerPersonas() {
        ArrayList&amp;lt;Persona&amp;gt; lista = new ArrayList();
        lista.add(new Persona(&quot;Cod001&quot;, &quot;Juan&quot;, 24, 5000.4));
        lista.add(new Persona(&quot;Cod002&quot;, &quot;Felipe&quot;, 27, 6700.8));
        lista.add(new Persona(&quot;Cod003&quot;, &quot;Diana&quot;, 31, 354.9));
        lista.add(new Persona(&quot;Cod004&quot;, &quot;María&quot;, 46, 5300));
        lista.add(new Persona(&quot;Cod005&quot;, &quot;Camilo&quot;, 28, 2890.6));
        lista.add(new Persona(&quot;Cod006&quot;, &quot;Pedro&quot;, 52, 1600.5));
        lista.add(new Persona(&quot;Cod007&quot;, &quot;Sandra&quot;, 43, 2000));
        lista.add(new Persona(&quot;Cod008&quot;, &quot;Esteban&quot;, 39, 752));
        lista.add(new Persona(&quot;Cod009&quot;, &quot;Pablo&quot;, 26, 2430.1));
        lista.add(new Persona(&quot;Cod010&quot;, &quot;Ana&quot;, 38, 3470.3));
        return lista;
    }

    private void setModeloTabla() {
        modeloTablaPersonas = new ModeloDatosTablaPersonas();
        modeloTablaPersonas.setPersonas(obtenerPersonas());
        this.jTpersonas.setModel(modeloTablaPersonas);
        this.jTpersonas.getColumnModel().getColumn(3).setCellRenderer(new DecimalFormatRenderer());
    }

    static class DecimalFormatRenderer extends DefaultTableCellRenderer {
        
        private static DecimalFormatSymbols simbolos;
        private static DecimalFormat formato;
        
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            simbolos = new DecimalFormatSymbols();
            simbolos.setDecimalSeparator(&#39;,&#39;);
            simbolos.setGroupingSeparator(&#39;.&#39;);
            formato = new DecimalFormat(&quot;#,##0.##&quot;, simbolos);
            value = formato.format((Number) value);
            return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings(&quot;unchecked&quot;)                       
    private void initComponents() {
     // Código Generado por NetBeans
    }

    private void jBobtenerDatosActionPerformed(java.awt.event.ActionEvent evt) {
        int fila = this.jTpersonas.getSelectedRow();
        if (fila &amp;lt; 0) {
            JOptionPane.showMessageDialog(this, &quot;Debe Seleccionar una Fila&quot;, &quot;Error&quot;, JOptionPane.ERROR_MESSAGE);
            return;
        }
        Persona persona = modeloTablaPersonas.getPersonas().get(fila);
        String mensaje = &quot;Datos de la Persona Seleccionada\n&quot;
                + &quot;Código: &quot; + persona.getCodigo() + &quot;\n&quot;
                + &quot;Nombre: &quot; + persona.getNombres() + &quot;\n&quot;
                + &quot;Edad: &quot; + persona.getEdad() + &quot;\n&quot;
                + &quot;Valor Deuda: &quot; + persona.getValorDeuda();
        JOptionPane.showMessageDialog(this, mensaje, &quot;Datos&quot;, JOptionPane.INFORMATION_MESSAGE);
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        // Código Generado por NetBeans
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton jBobtenerDatos;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTpersonas;
    // End of variables declaration                   
}
&lt;/pre&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Con esto ya tendríamos todo listo, y si ejecutamos nuestro proyecto obtendremos el siguiente resultado:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisGuaoDLsqRFCEAoRKVdRclbPOLxB-y63pLNltm85gmAnEjo6xPCfiuBmricHNTNw9SlDRwcATcUAZZ-LS_2Mk75Q5TdcTW8GY0290W0EdEvhCN9PHd2bBJFh9qLpK53rvVnTxo40EDgQN/s1600/Ejecuci%25C3%25B3n+del+Proyecto+Ejemplo+AbstractTableModel+Java.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Ejecución del Proyecto Ejemplo AbstractTableModel Java&quot; border=&quot;0&quot; height=&quot;292&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisGuaoDLsqRFCEAoRKVdRclbPOLxB-y63pLNltm85gmAnEjo6xPCfiuBmricHNTNw9SlDRwcATcUAZZ-LS_2Mk75Q5TdcTW8GY0290W0EdEvhCN9PHd2bBJFh9qLpK53rvVnTxo40EDgQN/s400/Ejecuci%25C3%25B3n+del+Proyecto+Ejemplo+AbstractTableModel+Java.png&quot; title=&quot;Cómo Hacer un Modelo de Datos Personalizado para un JTable en Java - Ejecución del Proyecto&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Y si seleccionamos una fila, y damos clic sobre el botón &quot;&lt;u&gt;Obtener Datos de Fila Seleccionada&lt;/u&gt;&quot; lo que obtenemos seríamos un &lt;b&gt;JOptionPane &lt;/b&gt;que muestra la siguiente información:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLNZgVz50MBDfKdYWrBtYeSoRVER-_0DDxWORFaC8uwaaUpP3xL8xkIHLiIAyDLkHtBrzsWWk2TtBjI4-D1SfG7Fntemgah2aQI5fGR7teFKPcoxUnno4TqYWPEaelR_U0GstPtuCo8bMC/s1600/Datos+de+Persona+Seleccionada+en+Ejemplo+AbstractTableModel+en+Java.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Datos de Persona Seleccionada en Ejemplo AbstractTableModel en Java&quot; border=&quot;0&quot; height=&quot;292&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLNZgVz50MBDfKdYWrBtYeSoRVER-_0DDxWORFaC8uwaaUpP3xL8xkIHLiIAyDLkHtBrzsWWk2TtBjI4-D1SfG7Fntemgah2aQI5fGR7teFKPcoxUnno4TqYWPEaelR_U0GstPtuCo8bMC/s400/Datos+de+Persona+Seleccionada+en+Ejemplo+AbstractTableModel+en+Java.png&quot; title=&quot;Modelo de Datos Personalizado para un JTable en Java - Datos de fila Seleccionada&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Bueno, eso es todo por este artículo... creo que me salió un poco largo ;-) jejeje pero bueno, quería que todo quedara lo más claro posible.&lt;br /&gt;
&lt;br /&gt;
Sin embargo, si tienes alguna duda, puedes hacérmela sabre a través de los comentarios y yo trataré de responderla a la mayor brevedad posible.&lt;br /&gt;
&lt;br /&gt;
Si lo deseas, puedes descargar el código fuente de este proyecto en GitHub:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;==&amp;gt; &lt;a href=&quot;https://github.com/eljavatar/Ejemplo-AbstractTableModel&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Ejemplo AbstractTableModel en GitHub&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/6866198894816051332/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2016/03/Como-Hacer-un-Modelo-de-Datos-Personalizado-para-un-JTable-en-Java.html#comment-form' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/6866198894816051332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/6866198894816051332'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2016/03/Como-Hacer-un-Modelo-de-Datos-Personalizado-para-un-JTable-en-Java.html' title='Cómo Hacer un Modelo de Datos Personalizado para un JTable en Java'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-p5r6mGsoIv-nBEoqyoQcQIzNFMs-1CPom6wU81n4ZHpvPkh4vEvnNcl35e_SRoHkwxzpoCy5x50_9omr4tkzKBEJFX3vwPeN3eEvX8MFTlPUXYrvZFofFrSodR53Q6xbh5CVV1zzyx82/s72-c/Datos+de+Persona+Seleccionada+en+Ejemplo+AbstractTableModel+en+Java.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-7558643267197530744</id><published>2016-02-12T01:58:00.000-05:00</published><updated>2017-09-10T01:29:38.357-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Tutorial Java"/><title type='text'>Tutorial Java - Características de Java</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo19XQi0KIL4ld2ul4qdjusVW6WKh2JyXxwb_OV44O1GKkzhT6xhddd0zPPztVLEegq0mkEsdNitz5vBU3J2odIcingLwfeWZj7pNtZG99TGfdCIDRFnBgWy09dx9DYbUfJ_QY1R0csw3P/s1600/Tutorial+Java+-+Caracter%25C3%25ADsticas+de+Java.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img alt=&quot;Tutorial Java - Características de Java&quot; border=&quot;0&quot; height=&quot;193&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo19XQi0KIL4ld2ul4qdjusVW6WKh2JyXxwb_OV44O1GKkzhT6xhddd0zPPztVLEegq0mkEsdNitz5vBU3J2odIcingLwfeWZj7pNtZG99TGfdCIDRFnBgWy09dx9DYbUfJ_QY1R0csw3P/s320/Tutorial+Java+-+Caracter%25C3%25ADsticas+de+Java.jpg&quot; title=&quot;Tutorial Java - Características de Java&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
En sí, las principales &lt;b&gt;características que caracterizan&lt;/b&gt; (valga la redundancia) &lt;b&gt;al lenguaje Java&lt;/b&gt;, no son muchas, sin embargo, son suficientes para definir la esencia de éste, y así empezar a entender cómo funciona:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Simple&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Orientado a Objetos&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Independencia de Plataforma&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Seguro&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Robusto&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Arquitectura Neutra&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Portable&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Dinámico&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Interpretado&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Alto rendimiento (High Performance)&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Multi-hilos (Multithreaded)&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Distribuido&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
A continuación veremos en qué consisten cada una de estas características:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;center&gt;
&lt;!-- anuncios --&gt;&lt;/center&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;1. Simple&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Según Sun MicroSystems, (ahora propiedad de Oracle), Java es un lenguaje sencillo porque su sintaxis es basada en C++ (lo cual lo hace un lenguaje fácil de aprender para aquellos programadores que han trabajado antes con C++), eliminando muchas características confusas y/o un poco extrañas para algunos usuarios como por ejemplo el uso explícito de punteros, sobre-carga de operadores, entre otras.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Además, no es necesario eliminar los Objetos de la memoria, ya que el Recolector de Basura de Java se encarga de esta tarea.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;2. Orientado a Objetos&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Al programar con un lenguaje Orientado a Objetos, significa que podemos organizar nuestro Software como una combinación de diferentes tipos de objetos en los que se incorporan tanto sus atributos o características, como su comportamiento.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
La programación orientada a objetos (POO) es una metodología que simplifican el desarrollo y el mantenimiento de software, proporcionando algunas reglas para ello. Los conceptos básicos de la Programación Orientada a Objetos son los siguientes:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Objeto&lt;/li&gt;
&lt;li&gt;Clase&lt;/li&gt;
&lt;li&gt;Herencia&lt;/li&gt;
&lt;li&gt;Polimorfismo&lt;/li&gt;
&lt;li&gt;Abstracción&lt;/li&gt;
&lt;li&gt;Encapsulamiento&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Para entender un poco más sobre cómo funciona la Programación Orientada a Objetos, puedes leer el siguiente artículo: &lt;a href=&quot;http://www.eljavatar.com/2014/04/Paradigmas-de-Programacion-IV-Programacion-Orientada-a-Objetos.html&quot; target=&quot;_blank&quot;&gt;Paradigmas de Programación IV: Programación Orientada a Objetos&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;3. Independencia de Plataforma&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Podemos considerar en este punto una plataforma como el entorno de hardware o software en el que se ejecuta un programa. Hay entonces dos tipos de plataformas: las basadas en hardware, y las basadas en software, y Java proporciona una plataforma basada en software.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
La plataforma sobre la cual se ejecuta Java difiere de la mayoría de otras plataformas en el sentido de que es una plataforma basada en software que se ejecuta sobre otra plataforma basada en hardware. La plataforma Java se compone de dos componentes principales:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;El Entorno de Ejecución (Java Runtime Enviroment)&lt;/li&gt;
&lt;li&gt;API (Interfaz de Programación de Aplicaciones)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbWoPfTfjJbzefgujpIt8V29xDIIzv0cHavM85twVijhnqCv9boUGa4TGlmgRgGkOKLplL34MFkJ4dIqJ-56OSBIxS-Pv1EMasxUaVtZP3NHg9i56sjDpzz1mS6BvXP0j4Bd_oD7z6Qw99/s1600/Tutorial+Java+-+Caracter%25C3%25ADsticas+de+Java+-+Independencia+de+Plataforma.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Tutorial Java - Características de Java - Independencia de Plataforma&quot; border=&quot;0&quot; height=&quot;295&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbWoPfTfjJbzefgujpIt8V29xDIIzv0cHavM85twVijhnqCv9boUGa4TGlmgRgGkOKLplL34MFkJ4dIqJ-56OSBIxS-Pv1EMasxUaVtZP3NHg9i56sjDpzz1mS6BvXP0j4Bd_oD7z6Qw99/s320/Tutorial+Java+-+Caracter%25C3%25ADsticas+de+Java+-+Independencia+de+Plataforma.png&quot; title=&quot;Tutorial Java - Características de Java - Independencia de Plataforma&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
El código Java puede ejecutarse en múltiples plataformas o Sistemas Operativos como Windows, Linux, Mac OS,entre otros. El código escrito en Java es compilado por el compilador y convertido a bytecode. Este bytecode es independiente de la plataforma, ya que no se ejecuta propiamente sobre el Sistema Operativo, sino sobre la Máquina Virtual de Java, haciendo alusión así a la promesa de James Gosling:&amp;nbsp;&lt;i&gt;Write Once Run Anywhere&lt;/i&gt; (Escribe una vez, Ejecuta donde quieras).&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;4. Seguro&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Java es seguro porque:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; No hace uso de punteros explícitos, lo cual indica que no se trabaja directamente sobre la memoria del computador.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;-&lt;/b&gt; Los programas escritos en Java se ejecutan sobre la Máquina Virtual de Java, la cual se encarga de gestionar la seguridad.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Classloader:&lt;/b&gt; Añade seguridad al separar el paquete para las clases del sistema de archivos local, de los que se importan a través de fuentes de red.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Verificador de Bytecode:&lt;/b&gt; Comprueba los fragmentos de código para evitar que código malicioso pueda violar el debido acceso de los objetos a la memoria.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;- Security Manager:&lt;/b&gt; Determina qué recursos de una clase pueden acceder con permisos tanto de lectura y escritura al disco local.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Estos son los aspectos en seguridad proporcionados por la plataforma de Java. Algunas características de seguridad también puede ser proporcionadas por los mismos desarrolladores para sus aplicaciones como puede ser SSL, JAAS, criptografía, etc.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;5. Robusto&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Robusto simplemente significa fuerte. Java utiliza una sólida gestión de la memoria. Además, al no haber punteros se evitan problemas de seguridad.&amp;nbsp;La recolección de basura en Java es automática. Tiene manejo de excepciones y un mecanismo de verificación de tipos. Todos estos puntos, hacen de Java un lenguaje bastante robusto.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;6. Arquitectura Neutra&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Un lenguaje o tecnología se dice que es de arquitectura neutra cuando puede ejecutarse en cualquier procesador disponible en el mundo real, sin tener en cuenta a la arquitectura y el proveedor en el proceso de desarrollo y compilación, y Java cumple con estas características.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;7. Portable&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
El bytecode de Java puede ser ejecutado en cualquier plataforma.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;8. Dinámico&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
El proceso de asignación del espacio de memoria al entrar a un programa en tiempo de ejecución se conoce como asignación de memoria dinámica; cuando programamos en Java, para asignar un espacio de memoria dinámicamente a un nuevo objeto, usamos la palabra reservada del lenguaje &quot;&lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt;&quot;, algo que veremos en más detalle en próximos tutoriales.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;9. Alto rendimiento (High Performance)&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Java es más rápido que los lenguajes interpretados tradicionales, ya que el bytecode es muy cercano al código nativo siendo sólo un poco más lento que un lenguaje compilado como C++.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;10. Distribuido&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Podemos crear aplicaciones distribuidas en Java. Los RMI y EJB se utilizan para la creación de aplicaciones distribuidas. Así, podemos acceder a los archivos haciendo llamadas a los diversos métodos desde cualquier máquina en Internet.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi27NDHg_mTee6XRFj4v6VJCwN45gVSnHYrhDR3YjHMV-E1oT2kidBCcvTrpi0SYPHBGNnGnlGwREaJylOPu83N2njmpizxY4-tPU_Q11LOcUKSSF350pmvJ2lbKn-WzKmj6650q3njIKk1/s1600/Tutorial+Java+-+Caracter%25C3%25ADsticas+de+Java+-+Distribuido.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Tutorial Java - Características de Java - Distribuido&quot; border=&quot;0&quot; height=&quot;371&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi27NDHg_mTee6XRFj4v6VJCwN45gVSnHYrhDR3YjHMV-E1oT2kidBCcvTrpi0SYPHBGNnGnlGwREaJylOPu83N2njmpizxY4-tPU_Q11LOcUKSSF350pmvJ2lbKn-WzKmj6650q3njIKk1/s400/Tutorial+Java+-+Caracter%25C3%25ADsticas+de+Java+-+Distribuido.png&quot; title=&quot;Tutorial Java - Características de Java - Distribuido&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;11. Multi-hilos (Multithreaded)&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Un hilo o thread es como un programa separado ejecutándose al mismo tiempo que el programa principal. Podemos escribir programas en Java que se ocupan de muchas tareas a la vez mediante la definición de múltiples hilos.&amp;nbsp;La principal ventaja del multi-threading es que se comparte la misma memoria del proceso principal del programa. Los hilos son importantes para multimedia, aplicaciones web, etc.&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/7558643267197530744/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2016/02/tutorial-java-caracteristicas-de-java.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/7558643267197530744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/7558643267197530744'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2016/02/tutorial-java-caracteristicas-de-java.html' title='Tutorial Java - Características de Java'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo19XQi0KIL4ld2ul4qdjusVW6WKh2JyXxwb_OV44O1GKkzhT6xhddd0zPPztVLEegq0mkEsdNitz5vBU3J2odIcingLwfeWZj7pNtZG99TGfdCIDRFnBgWy09dx9DYbUfJ_QY1R0csw3P/s72-c/Tutorial+Java+-+Caracter%25C3%25ADsticas+de+Java.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-3560457983930385399</id><published>2016-01-14T02:03:00.000-05:00</published><updated>2017-09-10T01:25:58.031-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Tutorial Java"/><title type='text'>Tutorial Java - Historia de Java</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
Es interesante conocer la &lt;b&gt;historia de Java&lt;/b&gt;. La &lt;i&gt;historia de Java&lt;/i&gt; data sus inicios desde el Proyecto Green. Los miembros del equipo de Java (también conocido como equipo Green) dirigidos por &lt;a href=&quot;https://es.wikipedia.org/wiki/James_Gosling&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;James Gosling&lt;/a&gt;, iniciaron una revolucionaria tarea de desarrollar un lenguaje para dispositivos digitales tales como decodificadores, lavadoras, televisores, etc.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9j7fSHclwcZ6tSiZX29kJnalFoi6H5ZwhZDSyf-_O2mkAGS2Z61kMzstWhO9dEsviotuF6um-4QDaNG2Spw_UUkRpiKlw5kSwm9gu821wvD2hCrYyoztM9MEm5J3rOkgIudiogPQHpVjz/s1600/Tutorial+Java+-+Historia+de+Java.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img alt=&quot;Tutorial Java - Historia de Java&quot; border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9j7fSHclwcZ6tSiZX29kJnalFoi6H5ZwhZDSyf-_O2mkAGS2Z61kMzstWhO9dEsviotuF6um-4QDaNG2Spw_UUkRpiKlw5kSwm9gu821wvD2hCrYyoztM9MEm5J3rOkgIudiogPQHpVjz/s320/Tutorial+Java+-+Historia+de+Java.jpg&quot; title=&quot;Tutorial Java - Historia de Java&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Para los miembros del equipo Green, este era un concepto un poco avanzado para la época, pero sin embargo fueron más allá, y lo adaptaron para la programación de la entonces creciente Internet. Así pues, más tarde la &lt;b&gt;tecnología Java&lt;/b&gt; sería incorporada en &lt;a href=&quot;https://es.wikipedia.org/wiki/Netscape_Navigator&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Netscape&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Actualmente, Java se utiliza para programar sobre entornos web, de escritorio, dispositivos móviles, juegos, soluciones empresariales, etc. A continuación veremos los principales puntos que describen la historia de Java:&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;
Principales puntos en la Historia de Java&lt;/b&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;!-- anuncios --&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;1)&lt;/b&gt;&amp;nbsp;&lt;b&gt;James Gosling&lt;/b&gt;, &lt;b&gt;Mike Sheridan&lt;/b&gt;, y &lt;b&gt;Patrick Naughton&lt;/b&gt; inician el proyecto para desarrollar el lenguaje Java en Junio de 1991. El pequeño equipo compuesto por trece ingenieros de Sun MicroSystems, fue llamado &lt;i&gt;equipo Green&lt;/i&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;2)&lt;/b&gt; Originalmente fue diseñado para sistemas pequeños integrados en equipos electrónicos tales como decodificadores.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;3)&lt;/b&gt; Primeramente, James Gosling denominó al lenguaje &quot;&lt;b&gt;Greentalk&lt;/b&gt;&quot;, y la extensión del archivo era .gt.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdsD6oD15f5J-M4NNABk8OjcJXmMeACKbrKU_rTNK0jq58sEOY5VYgxBxR8ZfNXjCRU3xXthVeNmPF_r9-OKRfxldiMeV5RgPcRKOl2d5D6mCpqjVOfZa8pUHsgUJBBAIZUnMp7MCQK4or/s1600/Tutorial+Java+-+Historia+de+Java+-+Oak.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Tutorial Java - Historia de Java - Oak&quot; border=&quot;0&quot; height=&quot;172&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdsD6oD15f5J-M4NNABk8OjcJXmMeACKbrKU_rTNK0jq58sEOY5VYgxBxR8ZfNXjCRU3xXthVeNmPF_r9-OKRfxldiMeV5RgPcRKOl2d5D6mCpqjVOfZa8pUHsgUJBBAIZUnMp7MCQK4or/s200/Tutorial+Java+-+Historia+de+Java+-+Oak.jpg&quot; title=&quot;Tutorial Java - Historia de Java - Oak&quot; width=&quot;200&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;4)&lt;/b&gt; Después de esto, fue llamado &quot;&lt;b&gt;Oak&lt;/b&gt;&quot;, y fue desarrollado como parte del &lt;b&gt;Proyecto Green&lt;/b&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;¿Por qué se le puso el nombre Oak al lenguaje?&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;5)&lt;/b&gt; ¿Por qué Oak? Oak es el nombre de un árbol, es símbolo de fuerza y ha sido elegido como el árbol nacional en muchos países como Estados Unidos, Francia, Alemania, Rumania, etc.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;6)&lt;/b&gt; En 1995, Oak fue rebautizado como &quot;&lt;b&gt;Java&lt;/b&gt;&quot;, porque era una marca comercial registrada usada por &quot;&lt;i&gt;Tecnologías Oak&lt;/i&gt;&quot;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;¿Por qué se le puso el nombre Java al lenguaje?&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;7)&lt;/b&gt; ¿Por qué se escogió el nombre de Java para el Lenguaje? El equipo tuvo que reunirse para elegir un nuevo nombre; se sugirieron palabras como &quot;dinámico&quot;, &quot;revolucionario&quot;, &quot;Silk&quot;, &quot;Jolt&quot;, entre otras. Querían algo que reflejara la esencia de la tecnología que habían creado: Revolucionaria, dinámica, animada, fresca, única y fácil de deletrear.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Según James Gosling &quot;Java fue una de las mejores opciones&quot;. Java era un nombre tan único, que la mayoría de los miembros del equipo lo prefirió.&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Otra hipótesis, y quizás una de las más fuertes, indican que el nombre de Java se debe a un tipo de café que vendían en una cafetería cercana, de ahí que el ícono de java sea una taza de café caliente.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;8)&lt;/b&gt;&amp;nbsp;Los objetivos de James Gosling eran implementar una máquina virtual y un lenguaje con una estructura y sintaxis similar a C++.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;9)&lt;/b&gt; Entre junio y julio de 1994, tras una sesión maratónica de tres días entre John Gaga, James Gosling, Patrick Naughton, Wayne Rosing y Eric Schmidt, el equipo reorientó la plataforma hacia la Web&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;10)&lt;/b&gt; La primera versión &amp;nbsp;de Java, la 1.0a estuvo disponible para su descarga por primera vez en 1994, pero hubo que esperar hasta el 23 de mayo de 1995, durante las conferencias de SunWorld, a que se vieran la luz pública Java y HotJava, el navegador Web.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFYaBa0Z9xhL0apaEtTE7YR9dZU7oVAG2VFsed-KyHxLN6_JVTavey8xvQKR93HDXiroYrF70qcylpdDOvhOmxF4LmW2LXA7lXMBHapoQLTi53qkNhAYYKGF4yPS58YCEivqBwKR0T4RxV/s1600/Tutorial+Java+-+Historia+de+Java+-+James+Gosling.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img alt=&quot;Tutorial Java - Historia de Java - James Gosling&quot; border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFYaBa0Z9xhL0apaEtTE7YR9dZU7oVAG2VFsed-KyHxLN6_JVTavey8xvQKR93HDXiroYrF70qcylpdDOvhOmxF4LmW2LXA7lXMBHapoQLTi53qkNhAYYKGF4yPS58YCEivqBwKR0T4RxV/s200/Tutorial+Java+-+Historia+de+Java+-+James+Gosling.jpg&quot; title=&quot;Tutorial Java - Historia de Java - James Gosling&quot; width=&quot;178&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;11)&lt;/b&gt;&amp;nbsp;La promesa inicial de Gosling era &lt;i&gt;Write Once, Run Anywhere&lt;/i&gt; (Escríbelo una vez, ejecútalo en cualquier lugar), proporcionando un lenguaje independiente de la plataforma y un entorno de ejecución (la Máquina Virtual de Java) ligero y gratuito para las plataformas más populares de forma que los binarios (bytecode) de las aplicaciones Java pudiesen ejecutarse en cualquier plataforma.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;12)&lt;/b&gt; En 1995, la revista &lt;a href=&quot;http://time.com/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Time&lt;/a&gt;, nombró a Java como uno de los mejores productos de 1995.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;13)&lt;/b&gt; La versión 1.0 del JDK es lanzada el 23 de enero de 1996&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;14)&lt;/b&gt; Desde su primer lanzamiento, Java ha experimentado numerosos cambios, así como un enorme crecimiento en el número de clases y paquetes que componen la biblioteca estándar.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;15)&lt;/b&gt;&amp;nbsp;Desde la versión J2SE 1.4, la evolución del lenguaje ha sido regulada por el JCP (Java Community Process), que usa Java Specification Requests (JSRs) para proponer y especificar cambios en la plataforma Java.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Historial de las Versiones de Java&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;JDK Alpha and Beta (Mayo de 1995)&lt;/li&gt;
&lt;li&gt;JDK 1.0 (23 de Enero de 1996)&lt;/li&gt;
&lt;li&gt;JDK 1.1 (19 de Febrero de 1997)&lt;/li&gt;
&lt;li&gt;J2SE 1.2 (8 de Diciembre de 1998)&lt;/li&gt;
&lt;li&gt;J2SE 1.3 (8 de Mayo de 2000)&lt;/li&gt;
&lt;li&gt;J2SE 1.4 (6 de Febrero de 2002)&lt;/li&gt;
&lt;li&gt;J2SE 5.0 (30 de Septiembre de 2004)&lt;/li&gt;
&lt;li&gt;Java SE 6 (11 de Diciembre de 2006)&lt;/li&gt;
&lt;li&gt;Java SE 7 (28 de Julio de 2011)&lt;/li&gt;
&lt;li&gt;Java SE 8 (18 de Marzo de 2014)&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;h4&gt;
&lt;b&gt;
Articulo anterior del Tutorial Java:&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;b&gt;==&amp;gt;&lt;/b&gt; &lt;b&gt;&lt;a href=&quot;http://www.eljavatar.com/2016/01/Tutorial-Java-Introduccion-a-Java.html&quot; target=&quot;_blank&quot;&gt;Tutorial Java - Introducción a Java&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
&lt;b&gt;
Artículo siguiente del Tutorial Java:&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;b&gt;==&amp;gt;&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;http://www.eljavatar.com/2016/02/tutorial-java-caracteristicas-de-java.html&quot; style=&quot;font-weight: bold;&quot; target=&quot;_blank&quot;&gt;Tutorial Java - Características de Java&lt;/a&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/3560457983930385399/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2016/01/tutorial-java-historia-de-java.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/3560457983930385399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/3560457983930385399'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2016/01/tutorial-java-historia-de-java.html' title='Tutorial Java - Historia de Java'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9j7fSHclwcZ6tSiZX29kJnalFoi6H5ZwhZDSyf-_O2mkAGS2Z61kMzstWhO9dEsviotuF6um-4QDaNG2Spw_UUkRpiKlw5kSwm9gu821wvD2hCrYyoztM9MEm5J3rOkgIudiogPQHpVjz/s72-c/Tutorial+Java+-+Historia+de+Java.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-3456787274139451020</id><published>2016-01-06T04:29:00.000-05:00</published><updated>2017-09-10T01:20:25.078-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Tutorial Java"/><title type='text'>Tutorial Java - Introducción a Java</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc2Agn5jHYhh_R4U96ZcItYy4zKRMkVZ40b5stdAUtYGyu1rJjLT97t-h1U-KyU_SjgQ-YCY8rfo66IfOxqcWqEkCuKffNZPabRLdPbpKVE_YmsQvJs_zvcAEdWbPT5GiVz6hhA8xS4YC1/s1600/Tutorial+Java+-+Introducci%25C3%25B3n+a+Java.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img alt=&quot;Tutorial Java - Introducción a Java&quot; border=&quot;0&quot; height=&quot;186&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc2Agn5jHYhh_R4U96ZcItYy4zKRMkVZ40b5stdAUtYGyu1rJjLT97t-h1U-KyU_SjgQ-YCY8rfo66IfOxqcWqEkCuKffNZPabRLdPbpKVE_YmsQvJs_zvcAEdWbPT5GiVz6hhA8xS4YC1/s320/Tutorial+Java+-+Introducci%25C3%25B3n+a+Java.jpg&quot; title=&quot;Tutorial Java - Introducción a Java&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;¿Qué es Java?&lt;/b&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Java no sólo es un &lt;b&gt;lenguaje de programación&lt;/b&gt;, también es una &lt;b&gt;plataforma&lt;/b&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Java es un lenguaje de programación de alto nivel, robusto, seguro, &lt;a href=&quot;https://es.wikipedia.org/wiki/Computaci%C3%B3n_concurrente&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;concurrente&lt;/a&gt;, de &lt;a href=&quot;https://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n_de_prop%C3%B3sito_general&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;propósito general&lt;/a&gt; y &lt;a href=&quot;http://www.eljavatar.com/2014/04/Paradigmas-de-Programacion-IV-Programacion-Orientada-a-Objetos.html&quot; target=&quot;_blank&quot;&gt;orientado a objetos&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Se considera como una plataforma cualquier entorno de hardware o software en el que un programa se ejecuta. Java tiene su propio entorno de ejecución llamado &lt;i&gt;Java Runtime Environment&lt;/i&gt; (&lt;b&gt;JRE&lt;/b&gt;) que traducido al español significa &lt;i&gt;Entorno en Tiempo de Ejecución de Java&lt;/i&gt;, y su propia &lt;a href=&quot;http://www.eljavatar.com/2014/05/que-es-una-api.html&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;API&lt;/i&gt;&lt;/a&gt;; al conjunto de estos dos elementos se le conoce como &lt;b&gt;plataforma Java&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;h3&gt;
&lt;b&gt;Ejemplo de Código Java&lt;/b&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;!-- anuncios --&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
A continuación veremos un ejemplo rápido de programación en java. En este caso veremos el código del famoso &lt;a href=&quot;http://www.eljavatar.com/2014/03/hola-mundo-en-java.html&quot; target=&quot;_blank&quot;&gt;Hola Mundo&lt;/a&gt;; En los siguientes artículos de este &lt;b&gt;Tutorial de Java&lt;/b&gt; iremos entendiendo el funcionamiento de éstas líneas de código:&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:java&quot;&gt;public class HolaMundo {
    public static void main(String[] args) {
        System.out.println(&quot;Hola ElJavatar&quot;);
    }
}&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;
&lt;b style=&quot;text-align: justify;&quot;&gt;¿Dónde se utiliza Java?&lt;/b&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
Según Oracle, 3 mil millones de dispositivos ejecutan Java. Existen muchos dispositivos en los cuales Java está siendo usado, y algunos de ellos son los siguientes:&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmBdPlVJGwDCGI3vJTtIxw7WichK_WrT4cTnsCydzedbPGlruX6NJU8z8m4eOcjm2kh7eqRF_dYVAj06WfZ0BIURXudkWCs_QQ-jVx3nadTuKw4GcpuFtg04XXi7JnMHUGGIgGsSZ5KHr8/s1600/Tutorial+Java+-+D%25C3%25B3nde+se+utiliza+Java.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Tutorial Java - Dónde se utiliza Java&quot; border=&quot;0&quot; height=&quot;247&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmBdPlVJGwDCGI3vJTtIxw7WichK_WrT4cTnsCydzedbPGlruX6NJU8z8m4eOcjm2kh7eqRF_dYVAj06WfZ0BIURXudkWCs_QQ-jVx3nadTuKw4GcpuFtg04XXi7JnMHUGGIgGsSZ5KHr8/s400/Tutorial+Java+-+D%25C3%25B3nde+se+utiliza+Java.jpg&quot; title=&quot;Tutorial Java - Dónde se utiliza Java&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;ol style=&quot;line-height: 30px;&quot;&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Aplicaciones de escritorio como &lt;i&gt;Acrobat Reader&lt;/i&gt;, &lt;i&gt;Reproductores multimedia&lt;/i&gt;, &lt;i&gt;antivirus&lt;/i&gt;, etc.&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Aplicaciones web como &lt;a href=&quot;https://muisca.dian.gov.co/WebArquitectura/DefLogin.faces&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Servicios en Línea DIAN&lt;/a&gt; (Colombia) y &lt;a href=&quot;http://coj.uci.cu/index.xhtml&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Caribbean Online Judge&lt;/a&gt;.&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Aplicaciones empresariales, tales como aplicaciones bancarias e intranets.&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Aplicaciones móviles&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Sistemas Embebidos&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Tarjetas Inteligentes&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Robots&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;Juegos, etc.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4F-cFO0utX8xfFN0Pt2sD9nmWtKhWOUtma71NkujRiinfYZTaGgji1FbaAZVATv7JSDbYrzH-ZjnpLz__A_vqZzcjeOXH5AjufV1efq8QljLSIX0x1ltT3MXAonKLGTqTUUei5Db2N4zD/s1600/Tutorial+Java+-+Tipos+de+Aplicaciones+Java.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Tutorial Java - Tipos de Aplicaciones Java&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4F-cFO0utX8xfFN0Pt2sD9nmWtKhWOUtma71NkujRiinfYZTaGgji1FbaAZVATv7JSDbYrzH-ZjnpLz__A_vqZzcjeOXH5AjufV1efq8QljLSIX0x1ltT3MXAonKLGTqTUUei5Db2N4zD/s1600/Tutorial+Java+-+Tipos+de+Aplicaciones+Java.png&quot; title=&quot;Tutorial Java - Tipos de Aplicaciones Java&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h3&gt;
&lt;b&gt;Tipos de Aplicaciones Java&lt;/b&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Hay 4 principales tipos de aplicaciones que se pueden crear usando &lt;i&gt;lenguaje Java&lt;/i&gt;:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;h4&gt;
&lt;b&gt;1) Aplicaciones Standalone&lt;/b&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Son también conocidas como aplicaciones de escritorio o aplicaciones basadas en ventanas. Son el tipo de aplicaciones que tenemos que instalar como pueden ser reproductores multimedia, antivirus, software utilitario, etc. Para crear aplicaciones standalone con Java usamos &lt;b&gt;AWT&lt;/b&gt; y &lt;b&gt;Swing&lt;/b&gt;, los cuales veremos en próximos tutoriales.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;h4&gt;
&lt;b&gt;2) Aplicaciones Web&lt;/b&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Una aplicación que se ejecuta en el lado del servidor y crea páginas dinámicas, se denomina aplicación web.&amp;nbsp;Actualmente, tecnologías como &lt;b&gt;Servlets&lt;/b&gt;, &lt;b&gt;JSP&lt;/b&gt;, &lt;b&gt;Struts&lt;/b&gt;, &lt;b&gt;JSF&lt;/b&gt;, etc., son usadas para la creación de aplicaciones web usando Java.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;h4&gt;
&lt;b&gt;3) Aplicaciones Empresariales&lt;/b&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Son aplicaciones que se distribuyen en el mundo empresarial, como lo son aplicaciones bancarias e intranets para empresas. Tienen la ventaja de contar con un alto nivel de seguridad, balanceo de cargas, gestión de concurrencia y manejo de &lt;a href=&quot;https://es.wikipedia.org/wiki/Cl%C3%BAster_(inform%C3%A1tica)&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;agrupamiento&lt;/a&gt;. En Java, el estándar es el uso de &lt;a href=&quot;https://es.wikipedia.org/wiki/Enterprise_JavaBeans&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;EJB&lt;/a&gt; para la creación de aplicaciones empresariales.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;h4&gt;
&lt;b&gt;4) Aplicaciones Móviles&lt;/b&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Son aplicaciones creadas para dispositivos móviles como SmartPhones, SmartTV, Relojes Inteligentes, etc. Actualmente se utilizan Android y Java ME para la creación de aplicaciones móviles.&lt;br /&gt;
&lt;br /&gt;
A continuación encontrarás el siguiente artículo de este &lt;b&gt;Tutorial de Java&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.eljavatar.com/2016/01/tutorial-java-historia-de-java.html&quot; target=&quot;_blank&quot;&gt;Tutorial Java - Historia de Java&lt;/a&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/3456787274139451020/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2016/01/Tutorial-Java-Introduccion-a-Java.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/3456787274139451020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/3456787274139451020'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2016/01/Tutorial-Java-Introduccion-a-Java.html' title='Tutorial Java - Introducción a Java'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc2Agn5jHYhh_R4U96ZcItYy4zKRMkVZ40b5stdAUtYGyu1rJjLT97t-h1U-KyU_SjgQ-YCY8rfo66IfOxqcWqEkCuKffNZPabRLdPbpKVE_YmsQvJs_zvcAEdWbPT5GiVz6hhA8xS4YC1/s72-c/Tutorial+Java+-+Introducci%25C3%25B3n+a+Java.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-7269498472677761373</id><published>2015-07-23T02:14:00.000-05:00</published><updated>2017-09-10T01:13:03.892-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Aplicaciones Moviles"/><title type='text'>Aplicaciones Móviles: Apps Nativas VS Apps Web VS App Híbridas</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcySxnrpOqoSQqydLC5wFhrYItPsbqxpIYK5NppAunXSKoSzaAKpMdb1UN60nP9cFZUA6dakDktUW97KUM43euDbcjgNHJgvEQdtaQTvzyF7vh5zQgZYGhlMCb-NxHmT_J5lSr17lYG6Wa/s1600/Aplicaciones+Moviles.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img alt=&quot;Aplicaciones Moviles&quot; border=&quot;0&quot; height=&quot;174&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcySxnrpOqoSQqydLC5wFhrYItPsbqxpIYK5NppAunXSKoSzaAKpMdb1UN60nP9cFZUA6dakDktUW97KUM43euDbcjgNHJgvEQdtaQTvzyF7vh5zQgZYGhlMCb-NxHmT_J5lSr17lYG6Wa/s320/Aplicaciones+Moviles.png&quot; title=&quot;Aplicaciones Moviles&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
Ya hace más de un año que no publico en mi blog por razones de estudio y trabajo, sin embargo he decidido volver a darle vida a esta bitácora :) En este largo periodo de tiempo he incursionado bastante en el mundo móvil, y por tal razón he decidido empezar hablando del &lt;b&gt;desarrollo de aplicaciones móviles&lt;/b&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Y es que para nadie es un secreto que el mercado móvil cada día crece más y más, no sólo por la cantidad creciente de usuarios, sino por la cantidad de plataformas que están disponibles en el mercado, lo cual representa también para nosotros como desarrolladores un gran abanico de opciones a la hora de escoger una tecnología para crear apps, ya que nuestro ideal sería llegar a la mayor cantidad de usuarios posibles.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
En este orden de ideas lo primero que hemos de saber es que existen &lt;u&gt;&lt;b&gt;tres tipos de aplicaciones móviles&lt;/b&gt;&lt;/u&gt; con sus respectivas características, y cada una de ellas posee una serie de ventajas y desventajas, las cuales se valoran de acuerdo al tipo de desarrollo que vayamos a llevar a cabo.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Los tres tipos de &lt;i&gt;Aplicaciones Móviles&lt;/i&gt; son:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Apps Nativas&lt;/li&gt;
&lt;li&gt;Apps Web&lt;/li&gt;
&lt;li&gt;Apps Híbridas&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqN7snMRaEbhH7MsRlzk7VOOGZKJgkvE4g-FV_2WBNjztp2v66yPFOB-v4P7xAj_6b-IbXtqp8zWxAXKXnW-dcZzXYovX-5KYqV0ZdXtGpzqB249X1Cc7NIE7KyvEChOgBMAbQJRtPI9s6/s1600/Aplicaciones+Moviles+-+Apps+Nativas+VS+Apps+Web+VS+Apps+Hibridas.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Aplicaciones Moviles - Apps Nativas VS Apps Web VS Apps Hibridas&quot; border=&quot;0&quot; height=&quot;243&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqN7snMRaEbhH7MsRlzk7VOOGZKJgkvE4g-FV_2WBNjztp2v66yPFOB-v4P7xAj_6b-IbXtqp8zWxAXKXnW-dcZzXYovX-5KYqV0ZdXtGpzqB249X1Cc7NIE7KyvEChOgBMAbQJRtPI9s6/s400/Aplicaciones+Moviles+-+Apps+Nativas+VS+Apps+Web+VS+Apps+Hibridas.jpg&quot; title=&quot;Aplicaciones Moviles - Apps Nativas VS Apps Web VS Apps Hibridas&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
A continuación veremos en que consiste cada una de ellas, y como decía, sus respectivas ventajas y desventajas o inconvenientes que pueden presentar cada una de ellas.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;h3&gt;
&lt;b&gt;1. Apps Nativas&lt;/b&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Una &lt;b&gt;aplicación nativa&lt;/b&gt; es aquella que se desarrolla un determinado sistema operativo en específico, usando su respectivo SDK (&lt;i&gt;Software Development Kit&lt;/i&gt;). Cada una de las plataformas, Android, iOS, Windows Phone, Blackberry, entre otros, tienen un sistema diferente, por lo tanto, si quisiéramos que una app esté disponible en todas las plataformas haciendo uso de un desarrollo nativo, se deberán crear varias apps y cada una con el lenguaje del sistema operativo correspondiente.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div&gt;
Por ejemplo:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Las apps para &lt;b&gt;iOS&lt;/b&gt; se desarrollan con lenguaje &lt;b&gt;Objective-C&lt;/b&gt; o &lt;b&gt;Swift&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Las apps para &lt;b&gt;Android&lt;/b&gt; se desarrollan con lenguaje &lt;b&gt;Java&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Las apps en &lt;b&gt;Windows Phone&lt;/b&gt; se desarrollan en &lt;b&gt;.Net&lt;/b&gt; (Visual Basic o C#)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Ventajas de las Apps Nativas&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Acceso completo a todas las características del hardware del móvil (GPS, cámara, acelerómetro, agenda, almacenamiento, etc.)&lt;/li&gt;
&lt;li&gt;Mejor experiencia de usuario&lt;/li&gt;
&lt;li&gt;Por lo general, la ejecución es más fluída&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Inconvenientes de las Apps Nativas&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Se debe tener dominio de cada uno de los lenguajes y herramientas de desarrollo para cada una de las plataformas de destino&lt;/li&gt;
&lt;li&gt;El desarrollo de una app conlleva tanto tiempo según cada una de las plataformas de destino&lt;/li&gt;
&lt;li&gt;El código no es reutilizable entre las diferentes plataformas&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: center;&quot;&gt;
&lt;b&gt;
2. Apps Web&lt;/b&gt;&lt;/h3&gt;
Una &lt;b&gt;aplicación web&lt;/b&gt; o &lt;b&gt;webapp&lt;/b&gt; es aquella que se desarrolla con lenguajes como &lt;i&gt;HTML&lt;/i&gt;, &lt;i&gt;Javascript&lt;/i&gt; y &lt;i&gt;CSS&lt;/i&gt;. La principal ventaja de este tipo de app con respecto a la nativa es la posibilidad de programar independientemente del sistema operativo en el que se usará la aplicación. De esta forma, una app se puede ejecutar en diferentes dispositivos sin tener que crear varias aplicaciones para cada plataforma.&lt;br /&gt;
&lt;br /&gt;
Las aplicaciones web &lt;b&gt;se ejecutan dentro del propio navegador web&lt;/b&gt; del dispositivo a través de una URL. Una de las cosas a tener en cuenta a la hora de desarrollar este tipo de aplicaciones es que el contenido debe adaptarse a la pantalla de cada uno de los dispositivos en los cuales se ejecuta adquiriendo un aspecto de navegación APP.&lt;br /&gt;
&lt;br /&gt;
La gran diferencia con una aplicación nativa (además de los inconvenientes que veremos a continuación) es que una webapp no necesita instalación, por lo que no pueden estar visibles en los app store y por tanto la promoción y comercialización debe realizarse de forma independiente. De todas formas se puede crear un acceso directo que sería como “instalar” la aplicación en el dispositivo.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ventajas de las Apps Web&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;El mismo código es reutilizado en múltiples plataformas&lt;/li&gt;
&lt;li&gt;El proceso de desarrollo es más rápido&lt;/li&gt;
&lt;li&gt;No necesitan ninguna aprobación externa para publicarse&lt;/li&gt;
&lt;li&gt;El usuario siempre dispone de la última versión&lt;/li&gt;
&lt;li&gt;Pueden reutilizarse sitios &quot;&lt;b&gt;responsive&lt;/b&gt;&quot; ya diseñados&lt;/li&gt;
&lt;/ul&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Inconvenientes de las Apps Web&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Requieren siempre de conexión a Internet&lt;/li&gt;
&lt;li&gt;Acceso muy limitado a las características hardware del dispositivo&lt;/li&gt;
&lt;li&gt;La experiencia de usuario en cuanto a navegación e interacción y tiempos de respuesta es menor que en una app nativa&lt;/li&gt;
&lt;li&gt;Requieren de mayor esfuerzo en cuanto a promoción y visibilidad&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;h3&gt;
&lt;b&gt;3. Apps Híbridas&lt;/b&gt;&lt;/h3&gt;
&lt;/div&gt;
Una &lt;b&gt;aplicación híbrida&lt;/b&gt; o &lt;b&gt;web app nativa&lt;/b&gt; es una combinación de las dos anteriores, se podría decir que recoge lo mejor de cada una de ellas. Las apps híbridas se desarrollan con lenguajes propios de las webapp, es decir, HTML, Javascript y CSS por lo que permite su uso en diferentes plataformas, pero también dan la posibilidad de acceder a gran parte de las características del hardware del dispositivo. La principal ventaja es que a pesar de estar desarrollada con HTML, Javascript y CSS, &lt;b&gt;es posible agrupar los códigos y distribuirla en los app store&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Para el desarrollo de apps híbridas es común el uso de frameworks que agilizan el desarrollo de las mismas, y uno de los más utilizados es &lt;b&gt;PhoneGap&lt;/b&gt; (&lt;b&gt;Apache Cordova&lt;/b&gt;).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ventajas de las Apps Híbridas&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;El mismo código es reutilizado en múltiples plataformas&lt;/li&gt;
&lt;li&gt;Acceso a la gran mayoría de las características hardware del dispositivo&lt;/li&gt;
&lt;li&gt;Instalación nativa pero construida con HTML, Javascript y CSS&lt;/li&gt;
&lt;/ul&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Inconvenientes de las Apps Híbridas&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;La experiencia de usuario en cuanto a navegación e interacción y tiempos de respuesta es menor que en una app nativa&lt;/li&gt;
&lt;li&gt;El Diseño visual no siempre va acorde con el sistema operativo en el que se muestra&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGe9WHHnJmfiKsl3swVjTZXNP9HYIveXCRc5_kVU3o3jjD1Xq3QbV6jWfTxik3YHUdG3ljAPF_9dYtx3au53GQH3GXHj5u-WeoFb_1G7ax4jne6L4A-JaPmAAdHrnKqDwdXFPfmbbyWD07/s1600/Aplicaciones+Moviles+-+Cual+es+la+Mejor+opcion+a+elegir.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Aplicaciones Moviles - Cual es la Mejor opcion a elegir&quot; border=&quot;0&quot; height=&quot;224&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGe9WHHnJmfiKsl3swVjTZXNP9HYIveXCRc5_kVU3o3jjD1Xq3QbV6jWfTxik3YHUdG3ljAPF_9dYtx3au53GQH3GXHj5u-WeoFb_1G7ax4jne6L4A-JaPmAAdHrnKqDwdXFPfmbbyWD07/s320/Aplicaciones+Moviles+-+Cual+es+la+Mejor+opcion+a+elegir.jpg&quot; title=&quot;Aplicaciones Moviles - Cual es la Mejor opcion a elegir&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;b&gt;¿Cuál es la mejor Opción a elegir?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Para nosotros como desarrolladores, seleccionar el tipo de app más adecuado va a depender de diversos factores. Por un lado, si el desarrollo es para un cliente que nos está contratando debemos tener en cuenta el coste que éste está dispuesto a asumir.&lt;br /&gt;
&lt;br /&gt;
Por otra parte, también debemos considerar el tipo de aplicación, ya que si por ejemplo deseamos desarrollar un juego, a pesar de que HTML5 está muy avanzado en este campo, debemos tener en cuenta que los recursos de memoria y procesamiento de un dispositivo móvil son más limitados que los de un computador, por lo cual sería preferible inclinarnos a desarrollar una app nativa que nos proporcione una mejor experiencia de usuario y mayor fluidez en los gráficos.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si nuestra aplicación no requiere acceso a las características hardware del dispositivo, podríamos pensar mejor en el desarrollo de una web app o una app híbrida dependiendo de las necesidades de la misma.&lt;br /&gt;
&lt;br /&gt;
En conclusión, como podrás darte cuenta, son muchas las opciones con las que cuentas, pero a fin de cuentas, lo más importante es definir primero las características y necesidades de tu app, ya que éstas te indicarán cual es la mejor opción a elegir a la hora de desarrollar una &lt;i&gt;aplicación móvil&lt;/i&gt;.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/7269498472677761373/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2015/07/Aplicaciones-Moviles-Apps-Nativas-VS-Apps-Web-VS-App-Hibridas.html#comment-form' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/7269498472677761373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/7269498472677761373'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2015/07/Aplicaciones-Moviles-Apps-Nativas-VS-Apps-Web-VS-App-Hibridas.html' title='Aplicaciones Móviles: Apps Nativas VS Apps Web VS App Híbridas'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcySxnrpOqoSQqydLC5wFhrYItPsbqxpIYK5NppAunXSKoSzaAKpMdb1UN60nP9cFZUA6dakDktUW97KUM43euDbcjgNHJgvEQdtaQTvzyF7vh5zQgZYGhlMCb-NxHmT_J5lSr17lYG6Wa/s72-c/Aplicaciones+Moviles.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4528125628115572726.post-1842680700058640768</id><published>2014-05-25T22:36:00.002-05:00</published><updated>2014-05-25T22:36:43.104-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="El Javatar"/><title type='text'>¿Qué es una API?</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
Es muy probable que hayas escuchado antes el término API y tal vez tengas una vaga idea acerca de su significado ¿pero realmente sabes qué es una API y para que se usa?&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrLMoZ2Co0T_Dhq-_8MGb1EdDd7EQgkfedp3tD4u_AU7hmqdcvS32aqYL-JWjx7cDPsdcVOoKt3QsBd9sCXKv5TdOscOJBZ1vPUZOA3CLb5jheuz2Y8PjDVPdenLTTb-tTA-pmUht9BYXE/s1600/Qu%C3%A9+es+una+API.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Qué es una API&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrLMoZ2Co0T_Dhq-_8MGb1EdDd7EQgkfedp3tD4u_AU7hmqdcvS32aqYL-JWjx7cDPsdcVOoKt3QsBd9sCXKv5TdOscOJBZ1vPUZOA3CLb5jheuz2Y8PjDVPdenLTTb-tTA-pmUht9BYXE/s1600/Qu%C3%A9+es+una+API.jpg&quot; height=&quot;373&quot; title=&quot;Qué es una API&quot; width=&quot;560&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Una &lt;b&gt;API&lt;/b&gt; es un conjunto de funciones y procedimientos que cumplen una o muchas funciones con el fin de ser utilizadas por otro software. Las siglas API vienen del inglés Application Programming Interface, lo cual traducido al español sería Interfaz de Programación de Aplicaciones.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Una API nos permite implementar las funciones y procedimientos que engloba en nuestro proyecto sin la necesidad de programarlas de nuevo. En términos de programación, es una &lt;b&gt;capa de abstracción&lt;/b&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Por ejemplo, digamos que estas desarrollando una aplicación web y necesitas hacer peticiones HTTP. En lugar de desarrollar todo el código para hacer una petición HTTP, puedes utilizar una API que se encargue de esto, como por ejemplo &lt;a href=&quot;https://pypi.python.org/pypi/requests/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Requests de Python&lt;/a&gt;. Si necesitas utilizar archivos .yaml, puedes usar la API Yaml de Ruby.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Ahora, el término API ha evolucionado un poco con la revolución de los servicios web que dieron a lugar lo que hoy se conoce como &lt;i&gt;API REST&lt;/i&gt;, o como muchos suelen llamarla, solo &lt;i&gt;API&lt;/i&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;¿Qué es una API REST?&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Una API REST es una una biblioteca apoyada totalmente en el estándar HTTP. Visto de una forma más sencilla, una API REST es un servicio que nos provee de funciones que nos dan la capacidad de &lt;b&gt;hacer uso de un servicio web que no es nuestro, dentro de una aplicación propia, de manera segura&lt;/b&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Un ejemplo claro sería la &lt;b&gt;API de Twitter&lt;/b&gt;. Todos los clientes desarrollados por terceros usan esa API, sin importar el sistema operativo para el cual fueron desarrollados. Al implementarla, la API te pone a disposición ciertos métodos o funciones para tu desarrollo.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Al usar una API todo el desarrollo que se quiera realizar estará limitado por los métodos o funciones que ésta incluya, es decir, &lt;b&gt;no pueden ser añadidas nuevas funcionalidades&lt;/b&gt;. De esta manera compañías como Twitter se aseguran de lo que pueden o no hacer los clientes desarrollados por terceros.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;i&gt;Tweetbot&lt;/i&gt;, &lt;i&gt;Birdie&lt;/i&gt;, &lt;i&gt;Turpial&lt;/i&gt;, &lt;i&gt;Fenix&lt;/i&gt;, &lt;i&gt;Carbon&lt;/i&gt;, &lt;i&gt;Metrotwit&lt;/i&gt;; todos son clientes de Twitter diferentes pero construidos usando la misma base, la API de Twitter.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Entonces, ¿para qué perder el tiempo reinventando la rueda cuando una API te permite usar código que otros desarrolladores han probado exitosamente? Es mejor usar esas funciones encapsuladas y enfocarte en tu aplicación y sus características, lo importante es que te asegures de entregar un producto de calidad.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.eljavatar.com/feeds/1842680700058640768/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.eljavatar.com/2014/05/que-es-una-api.html#comment-form' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/1842680700058640768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4528125628115572726/posts/default/1842680700058640768'/><link rel='alternate' type='text/html' href='http://www.eljavatar.com/2014/05/que-es-una-api.html' title='¿Qué es una API?'/><author><name>Andrés Mauricio Barragán</name><uri>http://www.blogger.com/profile/10698728890964483687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrLMoZ2Co0T_Dhq-_8MGb1EdDd7EQgkfedp3tD4u_AU7hmqdcvS32aqYL-JWjx7cDPsdcVOoKt3QsBd9sCXKv5TdOscOJBZ1vPUZOA3CLb5jheuz2Y8PjDVPdenLTTb-tTA-pmUht9BYXE/s72-c/Qu%C3%A9+es+una+API.jpg" height="72" width="72"/><thr:total>1</thr:total></entry></feed>