AJUDA na Confecção de SISTEMA

Colegas,

Estou começando a desenvolver uma aplicação SWING que será uma Agenda Financeira Pessoal.
Após sua conclusão DISPONIBILIZAREI o sistema completo com fontes e documentação(UML, ER, HELPs, Manuais e ect) para o pessoal aqui do GUJ(Se o WebMaster permitir é claro), só que tem um detalhe: Eu não gostaria de disponibilizar algo que não estivesse dentro dos padrões mais corretos de desenvolvimento e que não possuísse as técnicas mais recomendadas para aplicativos JAVA. Digo isto, pois na busca incessante por exemplos de aplicativos SWING pela WEB, encontrei muito coisa, mas muita coisa fora de padrões(Por exemplo, código de acesso a banco de dados na mesma classe que tem o JFrame), por isso PRECISO da AJUDA dos colegas mais experientes para completar o projeto, pelo menos no que tange a avaliação das técnicas de programação, pois quem pegar este exemplo aqui no site, vai poder ter a certeza de que esta pegando algo que é baseado nos padrões e técnicas mais elegantes e corretas de desenvolvimento de aplicativos JAVA/SWING.

O sistema terá as seguintes funcionalidades:

-> Janela Login			= Tela de Login no Sistema
-> Janela Prinicipal		= Janela Principal do Sistema
-> Log Individual		= Tela de Visualização dos LOGs de atividades do usuário Logado
-> Log Usuário			= Tela de Visualização dos LOGS de atividades dos usuários do sistema
-> Tela Pesquisa		= Tela genérica de pesquisa( Pesquisar usuários, Pessoas, Contas )
-> Tela Filtro			= Tela genérica de Filtro( Filtrar usuários, Pessoas, Contas )
-> Tela Grid			= Tela genérica de GRID( Visualizar usuários, Pessoas, Contas )
-> Tela Relatório		= Tela de Viewer(Visualização) de relatórios
-> Tela Help(F1)		= Tela de HELP quando o usuário precionar F1 em algum campo da tela
-> Cadastro - Usuário, Acesso, Pessoas, Forma Movto, Contas, Erro Interno ( Cadastros do sistema )	
-> Rotina - Lançamento	        = Tela de Lançamento dos agendamentos financeiros.   	
-> Help - Manual		= Manual do sistema
-> Log-Off		
-> Sair		

Lá vai às dúvidas do Projeto:

     - Partindo da premissa que tenho uma tela, Cadastro de Usuários, por exemplo.
          
         1. Qual a maneira mais correta de tratar os eventos de teclado/Mouse ? 
                - Classes Internas(Private)
                - Classes Externas
                - Classes Internas Anônimas
     2. Qual a maneira mais correta de passar/ler os dados para um Banco de Dados ?, ou seja, como faço para ler os dados da tabela "Usuários" e como faço para gravar, incluir, excluir e alterar.
                - Eu ouvi falar em VO's, DAO e etc.
                - Qual a maneira mais correta de se fazer isto ?, ou seja, quais os padrões eu devo utilizar e em que ordem e sequencia ?

Ob.: O Banco de dados será Access em um primeiro momento e após PostGreSQL.
Não quero que os colegas que forem me ajudar tenho o trabalho de escrever código(só se fizer extremamente necessário), mas sim me apontem as técnicas que eu vou atrás.

Desde já agradecendo e contando com a colaboração,
Atenciosamente,
Leandro Severino.

Opa, boa noite :smiley: legal sua iniciativa.

Bem, posso ajudar um pouco na questão dos dados. O padrão DAO é bastante interessante e resolve boa parte dos problemas de independência de databases do sistema.
Ao invés de ficar falando:
http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html

Basicamente DAO é a classe que cuida do acesso e manipulação do banco de dados. Um exemplo rude:

[code]

class Controller
{
public main()
{
ContaBancariaDAO dao = new ContaBancariaDAO();
dao.depositar( 5000 );
}
}

class ContaBancariaDAO
{
public depositar( double amount )
{
// conexão etc
Statement stm = connection.createStatement( “INSERT INTO CONTA VALUES( 5000 )” );
// etc
}
}[/code]

Após ler o link, procure aqui no fórum mesmo pois já aconteceram diversas discussões bastante elucidativas sobre este assunto.

[quote=“LeandroSeverino”]Colegas,
Após sua conclusão DISPONIBILIZAREI o sistema completo com fontes e documentação(UML, ER, HELPs, Manuais e ect) para o pessoal aqui do GUJ(Se o WebMaster permitir é claro), só que tem um detalhe: Eu não gostaria de disponibilizar algo que não estivesse dentro dos padrões mais corretos de desenvolvimento e que não possuísse as técnicas mais recomendadas para aplicativos JAVA. [/quote]

Leandro, bom dia.
Gostaria de, com todo o respeito, questionar por qual motivo você não optou por manter os fontes e demais artefatos abertos durante o processo de desenvolvimento?

Saudações.

Não sou nenhum heavy-user de Swing, mas creio que classes internas anônimas. Elas têm o escopo reduzido ideal para um simples processamento de evento. Classes externas eu acho totalmente incoerente.

Ouça (leia?) o lipe, esse cara é baum.

DAO vai te dar uma boa chance de mudar o banco mais tarde.

[]s

Bom Dia.

Bem…minha sugestão é que você use o VO (Value Object) para popular os dados
e o DAO para manipular as operações com o BD.
No VO vc só ira dar os gets e sets das variaveis.
e no DAO vc recupera os valores.

Fiz um exemplozinho de Teste para vc de um DAO.
Dê uma olhada e Boa Sorte.


package vpda.ejb.cadastro;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import vpda.ejb.util.DefaultDao;
import vpda.lib.TesteVo;
import vpda.lib.DaoException;
import vpda.util.Constants;
import vpda.util.FormatToolKit;

/**
 * @author Renan Espíndola de Oliveira
 * @Version 1.0
 */

public class TesteDao extends DefaultDao{

	/**
	 * Retorna informações de Teste.
	 * @param codigo
	 * @return vo
	 * @throws DaoException se ocorrer algum erro no acesso ao banco de dados.
	 */
	public TesteVo recuperarTeste(String codigo) throws DaoException {
		
		Connection conn = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;

		TesteVo vo = null;

		StringBuffer sql = new StringBuffer(); 

		sql.append( " SELECT	CCAMPA			as	codigo, " );
		sql.append( "			ICAMPA			as	nome, " );
		sql.append( "			RCAMPA			as	descricao, " );
		sql.append( "			DINIC			as	dataInicio, " );
		sql.append( "			DFNAL			as	dataTermino, " );
		sql.append( "			NPRIOR			as	tipoPrioridade, " );
		sql.append( "			CCANAL			as	codigoCanal, " );
		sql.append( "			CPRODT			as	codigoProduto, " );
		sql.append( "			CMODLD			as	codigoModalidade, " );
		sql.append( "			RPRODT			as	descricaoProduto, " );
		sql.append( "			RMODLD			as	descricaoModalidade, " );
		sql.append( "			EURL			as	URL, " );
		sql.append( "			CSTTUS			as	status, ");
		sql.append( "			RAG_PARTC		as	agenciasParticipantes, ");
		sql.append( "			CTPO_USUAR		as	tipoUsuario, " );
		sql.append( "			CTPO_CLI_CAMPA	as	tipoCliente " );
		
		sql.append( " FROM		CAMPA			as	Teste " );
		sql.append( " WHERE		CCAMPA = ? " );
		
		try {
			conn = getConnection();
			stmt = conn.prepareStatement( sql.toString() );
			stmt.setString(1, codigo);
			
			rs = stmt.executeQuery();

			if (rs.next()){
				vo = new TesteVo();
				vo.setCodigo(rs.getString("codigo"));
				vo.setNome(rs.getString("nome"));
				vo.setDescricao(rs.getString("descricao"));
				vo.setDataInicio(rs.getDate("dataInicio"));
				vo.setDataTermino(rs.getDate("dataTermino"));
				vo.setTipoPrioridade(rs.getInt("tipoPrioridade"));
				vo.setCodigoCanal(rs.getString("codigoCanal"));
				vo.setCodigoProduto(rs.getString("codigoProduto"));
				vo.setCodigoModalidade(rs.getString("codigoModalidade"));
				vo.setDescricaoProduto(rs.getString("descricaoProduto"));
				vo.setDescricaoModalidade(rs.getString("descricaoModalidade"));
				vo.setURL(rs.getString("URL"));
				vo.setStatus(rs.getString("status"));
				vo.setTipoUsuario(rs.getString("tipoUsuario"));
				vo.setTipoCliente(rs.getString("tipoCliente"));
			}
		}catch ( SQLException e ) {
			throw new DaoException( e.getMessage() );
		}finally {
			try { if(null != rs)   rs.close(); } catch ( Exception e ) {}
			try { if(null != stmt) stmt.close(); } catch ( Exception e ) {}
			try { if(null != conn) conn.close(); } catch ( Exception e ) {}
		}
		return vo;
	}
	
	private Long getLong(ResultSet rs){
		Long retorno = new Long(null);
		return retorno;
	}
	
	public int atualizarTeste(TesteVo vo) throws DaoException {
		int retorno = 0;
		//if (vo.getTipoAcao().equals(Constants.ACAO_INCLUIR)){
			//retorno =  inserirTeste(vo);
		//} else if (vo.getTipoAcao().equals(Constants.ACAO_ATUALIZAR)){
			retorno = alterarTeste(vo);
		//} 
		return retorno;
	}

	/**
	 * Atualizar Informações da Teste.
	 * @param vo
	 * @return int
	 * @throws DaoException se ocorrer algum erro no acesso ao banco de dados.
	 */
	public int alterarTeste(TesteVo vo) throws DaoException {
		int rowsUpdated = 0;
		Connection conn = null;
		PreparedStatement stmt = null;

		StringBuffer sql = new StringBuffer(); 

		sql.append( "UPDATE  CAMPA SET " );
		sql.append( "   ICAMPA= ?, " );
		sql.append( "   RCAMPA= ?, " );
		sql.append( "   DINIC=?, " );
		sql.append( "   DFNAL=?, " );
		sql.append( "   NPRIOR=?, " );
		sql.append( "   CCANAL=?, " );
		sql.append( "   CPRODT=?, " );
		sql.append( "   CMODLD=?, " );
		sql.append( "   RPRODT=?, " );
		sql.append( "   RMODLD=?, " );
		sql.append( "   EURL=?, " );
		sql.append( "   CSTTUS=?," );
		sql.append( "   RAG_PARTC=?, " );
		sql.append( "   CTPO_USUAR=?, " );
		sql.append( "   CTPO_CLI_CAMPA=? " );
		sql.append( "WHERE CCAMPA=? " );

		try {
			conn = getConnection();
			String teste = sql.toString();
			stmt = conn.prepareStatement( sql.toString());
			
			stmt.setString(1, vo.getNome());
			stmt.setString(2, vo.getDescricao());
			stmt.setString(3, FormatToolKit.dateToStr(vo.getDataInicio(),"yyyy-mm-dd"));
			stmt.setString(4, FormatToolKit.dateToStr(vo.getDataTermino(),"yyyy-mm-dd"));
			stmt.setInt(5, vo.getTipoPrioridade());
			stmt.setString(6, vo.getCodigoCanal());
			stmt.setString(7, vo.getCodigoProduto());
			stmt.setString(8, vo.getCodigoModalidade());
			stmt.setString(9, vo.getDescricaoProduto());
			stmt.setString(10, vo.getDescricaoModalidade());
			stmt.setString(11, vo.getURL());
			stmt.setString(12, vo.getStatus());
			stmt.setString(13, vo.getAgenciasParticipantes());
			stmt.setString(14, vo.getTipoUsuario());
			stmt.setString(15, vo.getTipoCliente());
			
			stmt.setString(16, vo.getCodigo());
	
			stmt.executeUpdate();
			
		}catch (Exception e){
			throw new DaoException(e.getMessage());
		}finally{
			try { if(null != stmt) stmt.close(); } catch ( Exception e ) {}
			try { if(null != conn) conn.close(); } catch ( Exception e ) {}
		}
		
		// Retorna o número de linhas atualizadas.
		return rowsUpdated;
	}

	/**
	 * Inserir informações de Teste.
	 * @param vo
	 * @throws DaoException se ocorrer algum erro no acesso ao banco de dados.
	 */
	public int inserirTeste(TesteVo vo) throws DaoException {
		int rowsUpdated = 0;
		Connection conn = null;
		PreparedStatement stmt = null;

		StringBuffer sql = new StringBuffer(); 

		sql.append( "INSERT INTO CAMPA ( " );
		sql.append( "			CCAMPA, " );
		sql.append( "			ICAMPA, " );
		sql.append( "			RCAMPA, " );
		sql.append( "			DINIC, " );
		sql.append( "			DFNAL, " );
		sql.append( "			NPRIOR, " );
		sql.append( "			CCANAL, " );
		sql.append( "			CPRODT, " );
		sql.append( "			RPRODT, " );
		sql.append( "			CMODLD, " );
		sql.append( "			RMODLD, " );
		sql.append( "			EURL, " );
		sql.append( "			CSTTUS, " );
		sql.append( "			RAG_PARTC, " );
		sql.append( "			CTPO_USUAR, " );
		sql.append( "			CTPO_CLI_CAMPA ) " );
		sql.append( " VALUES	(?, ?, ?, ?, ?, ?, ? ,? ,? ,? ,? ,? ,?, ?, ?, ?)");

		try {
			conn = getConnection();

			stmt = conn.prepareStatement( sql.toString());
			
			stmt.setString(1, vo.getCodigo());
			stmt.setString(2, vo.getNome());
			stmt.setString(3, vo.getDescricao());
			stmt.setString(4, FormatToolKit.dateToStr(vo.getDataInicio(),"dd/MM/yyyy"));
			stmt.setString(5, FormatToolKit.dateToStr(vo.getDataTermino(),"dd/MM/yyyy"));
			stmt.setInt(6, vo.getTipoPrioridade());
			stmt.setString(7, vo.getCodigoCanal());
			stmt.setString(8, vo.getCodigoProduto());
			stmt.setString(9, vo.getDescricaoProduto());
			stmt.setString(10, vo.getCodigoModalidade());
			stmt.setString(11, vo.getDescricaoModalidade());
			stmt.setString(12, vo.getURL());
			stmt.setString(13, vo.getStatus());
			stmt.setString(14, vo.getAgenciasParticipantes());
			stmt.setString(15, vo.getTipoUsuario());
			stmt.setString(16, vo.getTipoCliente());

			stmt.executeUpdate();
			
		}catch (SQLException e){
			e.printStackTrace();
			throw new DaoException(e.getMessage());
		
		}finally{
			try { if(null != stmt) stmt.close(); } catch ( Exception e ) {}
			try { if(null != conn) conn.close(); } catch ( Exception e ) {}
		}
		
		// Retorna o número de linhas inseridas.
		return rowsUpdated;
	}
}

Qualquer dúvida é só gritar!!!

:stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue:

De novo o DTO…

Eu não usaria DTO, a menos que seja um caso com RMI e chamadas de granulação fina, e isso porque não consegui pensar em/achar nada mais light para fazer.

Para evitar quebrar encapsulamento de classes de negócio reais (às vezes você tem um atributo privado inacessível externamente que precisa ser persistido), eu usaria o padrão Memento, da GoF, e persistiria meus Mementos.

[]s

Prezado KIYS e Demais colegas.

Especificamente KIYS,
Agradeço a ajuda e a força e te pergunto como posso fazer para implementar a sua idéia?, pois realmente não sei como fazer isto.

Demais colegas,
Vocês não me deram uma LUZ com estas respostas, mas sim um DataShow digital da Sony, último modelo e geração.

Agradeço a toda a força e assim que puder estarei disponibilizando as novidades.

Um abraço do colega Leandro.

Leandro, dê uma olhada no link http://codigolivre.org.br e qualquer dúvida podemos abrir uma outra thread sobre o uso deste site, pois creio que nossos colegas também tenham interesse em incubadoras de software.

Saudações.

DAO eh em bean???

Lich King: DAO é uma design pattern, na qual vc cria uma classe que realiza toda a coenxão e consulta nos seus dados

LeandroSeverino: para tratar eventos use classes anonimas e passe um refactoring para torna-las classes internas depois

e cadastre seu projeto no site java.net, assim quem quiser pode ajudar a programar tb

Pra todo mundo que AINDA recomenda DAOs e VOs, leiam:

cv, pode nos esclarecer a anti-oosidade do uso de DAOs?

Nada errado com eles, mas que eles podem ajudar a enfraquecer o modelo, podem - eh facil comecar a chamar os DAOs pra fazer miseria no banco de dados a partir do Controller, e a camada de negocios mesmo vira um monte de struct (aka VO :))

bla bla bla
ok…
ainda opto pela simplicidade

o que vc sugere?

microfilo, vc pode gastar mais 3 minutos discordando direito? Se isso tudo eh preguica de perguntar, imagine a minha de responder :mrgreen: