Foros del Web » Programación para mayores de 30 ;) » Java »

[SOLUCIONADO] Buena practiva Java swing

Estas en el tema de Buena practiva Java swing en el foro de Java en Foros del Web. Hola a todos, tengo una duda sobre la aplicación de buenas prácticas en java swing. Os detallo como tengo montada la aplicación para que me ...
  #1 (permalink)  
Antiguo 22/11/2015, 17:10
Usuario no validado
 
Fecha de Ingreso: abril-2012
Mensajes: 134
Antigüedad: 12 años
Puntos: 0
Buena practiva Java swing

Hola a todos, tengo una duda sobre la aplicación de buenas prácticas en java swing.

Os detallo como tengo montada la aplicación para que me orientéis.

Tengo un Jframe en el que voy mostrando u ocultando Jpanels en función de las necesidades, pero me surge un duda con los métodos.

Por ejemplo, tengo un clase que carga un jpanel de ventas , dentro de ese jpanel tengo varios Jpanel que los cargo a través de métodos, pero alguno de ellos son complejos por las conexiones a base de datos y demás, he pensado en ir fraccionándolos también en métodos, pero serian muchos también.

¿Estaría bien crear un paquete por Jpanels principales? por ejemplo, un paquete que sea para el jpanel de ventas y ahí voy creando los subpaneles en clases y los voy llamando en función de las necesidades. o si por el contrario crear muchos métodos a lo mejor 10-12 y que cada clase sea para un jpanel principal.
  #2 (permalink)  
Antiguo 23/11/2015, 13:29
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Buena practiva Java swing

Buenas,

La logica de las conexiones a las bases de datos no deberia estar dentro de los JPanel, sino en un paquete aparte. No deberias mezclar la logica de negocio con la presentacion.


Un saludo
__________________
If to err is human, then programmers are the most human of us
  #3 (permalink)  
Antiguo 23/11/2015, 14:18
Usuario no validado
 
Fecha de Ingreso: abril-2012
Mensajes: 134
Antigüedad: 12 años
Puntos: 0
Respuesta: Buena practiva Java swing

Muchas gracias por tu respuesta, actualmente la conexión la tengo en otra clase que se llama. te pongo un ejemplo

Código:
// creo la lista
        listCustomer = new JList();
        modelListCustomer = new DefaultListModel();
        listCustomer.setBorder(new EmptyBorder(10, 10, 10, 10)); // Borcer vacio como padding
        scrollListCustomer = new JScrollPane(listCustomer);
        scrollListCustomer.setViewportView(listCustomer);

        // Creamos una conexion
        conexion = new ConexionDatabase();
        // conectamos
        cnx = conexion.Connect();
        // Creamos la consulta
        String sql_search = "select * from person where person.dni = '" + txtSearchConsumer + "'";

        // Lo ejecutamos y almaceno los vendedores en el combobox
        try {
            PreparedStatement ps = cnx.prepareStatement(sql_search);
            ResultSet rs = ps.executeQuery(sql_search);

            while (rs.next()) {
                modelListCustomer.addElement(rs.getString(3) + " " + rs.getString(4) + " " + rs.getString(5));//nombre es el campo de la base de datos
            }
            listCustomer.setModel(modelListCustomer);
            // Cierro la conexion
            cnx.close();
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
        }
Está correcto ?? con respecto a la otra pregunta, es correcto crear una clase por cada panel y ordenarlos en paquetes??
  #4 (permalink)  
Antiguo 24/11/2015, 02:32
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Buena practiva Java swing

Buenas,

No, ese codigo que realiza la consulta deberias encapsularlo aparte y no mezclarlo con la logica del jpanel. Toda la logica de base de datos tendra que tenerla en una capa/paquete aparte.

Una forma de organizarlo correctamente seria con el patron DAO. Aqui tienes una introduccion a dicho patron: http://www.profesorfalken.com/posts/5

Respecto a los jpanel, los paquetes tienes que ir ordenados por funcionalidad. Por ejemplo

mipaquetebase.panel.search
mipaquetebase.panel.detail
mipaquetebase.panel.stats
etc etc

Dentro de cada paquete iran los distintos jpanel de busqueda, de detalle, de estadisticas, etc.

Un saludo
__________________
If to err is human, then programmers are the most human of us
  #5 (permalink)  
Antiguo 24/11/2015, 12:08
Usuario no validado
 
Fecha de Ingreso: abril-2012
Mensajes: 134
Antigüedad: 12 años
Puntos: 0
Respuesta: Buena practiva Java swing

Muchas gracias Profesor, voy a ponerme manos al obra y limpiar el código. Voy a seguir ese patrón y ordenar todo.
  #6 (permalink)  
Antiguo 24/11/2015, 12:17
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Buena practiva Java swing

Ok, genial. Vete comentandonos como te va e intentaremos ayudar en lo posible.


Un saludo
__________________
If to err is human, then programmers are the most human of us
  #7 (permalink)  
Antiguo 28/11/2015, 16:07
Usuario no validado
 
Fecha de Ingreso: abril-2012
Mensajes: 134
Antigüedad: 12 años
Puntos: 0
Respuesta: Buena practiva Java swing

Hola la verdad que estoy reescribiendo la aplicación con el patrón dao, estoy separando la vista de la lógica:

Está ahora correcto como obtengo los datos??
Código:
private void initActionPanel() {

        JLabel lblSeller = new JLabel("Vendedor", SwingConstants.CENTER);
        JComboBox jcbSeller = new JComboBox();
        jcbSeller.removeAllItems();
        
        try {
            PersonDAOImpl personImplement = new PersonDAOImpl();

            for (Person per : personImplement.showPerson()) {
                String seller;
                seller = per.getRol();
                
                if(seller.equals("seller")){
                    jcbSeller.addItem(per.getName() + " " + per.getSurname1());
                }
            }

        } catch (Exception e) {
            System.err.println(e.getMessage());
        }

        JButton btnRegisterSale = new JButton("Resgistrar venta");
        JButton btnSalesHistory = new JButton("Historico de ventas");

        actionPanel = new JPanel();
        actionPanel.setLayout(new GridLayout(1, 4, 10, 10));
        actionPanel.add(lblSeller);
        actionPanel.add(jcbSeller);
        actionPanel.add(btnRegisterSale);
        actionPanel.add(btnSalesHistory);

    }
Ahora me surge una duda, tengo la interfaz con su clase de implementación donde tengo los métodos para insertar, eliminar, actualizar y listar. En el caso anterior para listar no tengo problemas, ya que con el if localizo los vendedores y muestro los datos, pero tengo un buscador y tengo que cambiar la consulta entera, ¿Es recomendable crear metodos en la clase persona?, o por el contrario creo otra interface y otra clase impl con los metos que necesito en el buscador.

La interfaz es esta
Código:
public interface PersonDAO {

    public void addPerson(Person person) throws SQLException;

    public void updatePerson(Person person) throws SQLException;

    public void removePerson(Person person) throws SQLException;

    public List<Person> showPerson() throws SQLException;

}
La implementacion es esta

Código:
public class PersonDAOImpl extends DBConnection implements PersonDAO {

    @Override
    public List<Person> showPerson() throws SQLException {

        List<Person> listPerson = null;
        try {
            this.connect();
            PreparedStatement st = this.link.prepareStatement("SELECT * FROM person");
            listPerson = new ArrayList();
            ResultSet rs = st.executeQuery();
            while (rs.next()) {
                Person person = new Person();
                person.setIdPerson(rs.getInt("id_person"));
                person.setRol(rs.getString("rol"));
                person.setName(rs.getString("name"));
                person.setSurname1(rs.getString("surname_1"));
                person.setSurname2(rs.getString("surname_2"));
                person.setEmail(rs.getString("email"));
                person.setDni(rs.getString("dni"));
                person.setPhoneNumber(rs.getInt("phone_number"));
                listPerson.add(person);
            }
            rs.close();
            st.close();

        } catch (Exception e) {
            throw e;
        } finally {
            this.disconnect();
        }

        return listPerson;
    }
  #8 (permalink)  
Antiguo 29/11/2015, 02:52
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Buena practiva Java swing

Buenas,

Esta ya infinitamente mejor. Algunas cosillas:
-En lugar de usar new directamente seria mejor usar una factory.
-Debes programar contra la interfaz para abstraerte de la implementacion: PersonDAO personDAO = new PersonDAOImpl();
-Si la excepcion la vas a mostrar por la salida de error standar te resulta mas util hacer un e.printStackTrace() que imprimir solo el mensaje.

Respecto a la segunda pregunta. No, nunca debes aniadir metodos de ese tipo en el objeto Persona. Debe seguir siendo un simple bean. Te bastaria con aniadir al dao (interfaz e implementacion) un nuevo metodo findPersons().


Un saludo
__________________
If to err is human, then programmers are the most human of us
  #9 (permalink)  
Antiguo 29/11/2015, 05:55
Usuario no validado
 
Fecha de Ingreso: abril-2012
Mensajes: 134
Antigüedad: 12 años
Puntos: 0
Respuesta: Buena practiva Java swing

Voy a implementar las correcciones ahora mismo, solo me surgen 2 dudas:

1 - Usar una factory ¿Te refieres al patrón de diseño?, no tengo claro donde implementarlo, de momento he creado un paquete llamado factory y he metido la siguiente clase.

Código:
public class PersonDAOFactory {
    
    public PersonDAO  createPersonDAO(){
        return new PersonDAOImpl();
    }
    
}
y quedaría algo así:

Código:
        try {
            PersonDAOFactory factory = new PersonDAOFactory(); // Lo dejo de prueba
            
            PersonDAO person = factory.createPersonDAO();
            // Busco el rol seller y lo añado al combobox
            for (Person per : person.showPerson()) {
                String seller = per.getRol();

                if (seller.equals("seller")) {
                    jcbSeller.addItem(per.getName() + " " + per.getSurname1());
                }
            }
        } catch (SQLException ex) { 
            Logger.getLogger(SalesView.class.getName()).log(Level.SEVERE, null, ex);
        }
la duda es donde impemento PersonDAOFactory factory = new PersonDAOFactory();, a la altura de constructor, es decir al principio de la clase o lo tendría que llamar cada vez que lo fuera a utilizar..


2 - Respecto a la segunda pregunta, no la expresé bien, me refería a si creo el método findPersons() en PersonDAO - PersonDAOImpl, o por el contrario creo un DAO para cada apartado de la aplicación, SalesDAO - SalesDAOImpl(este dao no esta creado) y coloco el método aquí, dejando en PersonDAO - PersonDAOImpl solo el CRUD, de momento lo tengo en PersonDAO.

PD: Estoy aprendiendo un montón con usted @Profesor_Falken.
PD: Esta es la estructura de archivos por el momento, ¿Es correcta?

Paquete View
- MainView
- SalesView

Paquete dao
- PersonDAO
- ProductDAO

Paquete dto
- Main
- Person
- Product

Paquete factory
- PersonDAOFactory
- ProductDAOFactory

Paquete impl
- PersonDAOImpl
- ProductDAOImpl

Paquete sql
- DBConnection

Última edición por maurikius1983; 29/11/2015 a las 09:51 Razón: Añadida la estructura de paquetes
  #10 (permalink)  
Antiguo 30/11/2015, 01:37
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Buena practiva Java swing

Buenas,

1- La factoria simple es muy sencilla de implementar. Deberia ser una factoria generica para cualquier entidad de tu aplicacion. Algo como:
Código Java:
Ver original
  1. class DAOFactory {
  2.     +getPersonDAO
  3.     +getProductoDAO
  4.     ....
  5. }

Los beneficios de seguir esta estructura pueden no resultar aparentes, pero son reales. Utilizando la factoria te abstraes de la implementacion utilizada. Por ejemplo, el dia de manana podrias querer migrar de JDBC a JPA/Hibernate. Para ello bastaria con crear la implementacion de Hibernate y en cuanto este lista cambiar el factory para que devuelva la implementacion JPA en lugar de JDBC.
La factoria simple es el tipo mas sencilla, luego esta el patron abstract factory, que permite introducir mas iteraciones en la implementacion. Hoy en dia es muy comun utilizar, en lugar de un factory, un mecanismo de inyeccion de dependencias.
https://es.wikipedia.org/wiki/Abstract_Factory
https://es.wikipedia.org/wiki/Inyecc...e_dependencias

En todos los casos como veras el objetivo es siempre el mismo. Abtraerse de las implementaciones utilizadas para hacer mas sencillo el mantenimiento.

2-Eso depende. Eso no se define en funcion de la funcionalidad de tu aplicion. Existe una entidad Sales en el modelo de tu aplicacion? Cuando haces esa busqueda... que devuelves, una lista de Person o de Sales? Si lo que buscas es en la tabla de personas y devuelves personas entonces deberias incluirlo en el DAO de personas (ej: findAllPersonBySales).

Un saludo
__________________
If to err is human, then programmers are the most human of us

Etiquetas: clase, swing
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 15:55.