Crepz Player O trabalho desenvolvido foi proposto pela disciplina de linguagem de programação II a idéia inicial era de um player de áudio que reproduzisse arquivos do formato mp3, mas na evolução do desenvolvimento outras idéias foram inseridas no projeto, como manipular arquivos em uma playlist, gerenciar música através de uma biblioteca, uso de banco de dados para armazenar informações. Começamos pelo objetivo do trabalho, que era reproduzir arquivos no formato mp3. Começamos com o JMF (Java Media FrameWork) entretanto este já era obsoleto, assim, outro meio deveria ser encontrado. Pelas indicações de usuários de fóruns de discussões, usamos as bibliotecas do javazoom, nessas, é possível manipular as funções básicas do player, como por exemplo, play, pause, controle de volume e balanço. O Segundo recurso que foi desenvolvido foi o editor de propriedades, este que permite edição das tags diretamente no arquivo. Tags está que armazenam os dados do nome da musica, artista, álbum, gênero, etc. A partir destes dados foram feitos a modelagem do objeto musica. No decorrer do trabalho tivemos algumas dificuldades como manipular os dados através de SQL sem instalação de um SGBD como serviço, com acesso direto aos arquivos, executar os arquivos de áudio de forma fluida, modelagem dos objetos e banco de dados e interface amigável e fácil de usar. Para a solução do problema do banco de dados, foi tentado inicialmente utilizar o acess, ou arquivos mdb, porem é necessário configuração de fonte de dados ODBC para o funcionamento, assim após uma incansável pesquisa, encontramos o HSQL (Hiper SQL) banco de dados desenvolvido totalmente em Java, capaz de salvar e executar seus scripts diretamente em arquivos, iniciando o serviço apenas em tempo de execução, porém, também é capaz também de ser executado como serviço como os demais SGBD’s. A biblioteca serve para importar os arquivos de música e organizá-los conforme as preferências do usuário. Quando uma música é importada, os dados que estão no seu cabeçalho são lidos e gravados no banco. Os dados gravados são o nome da música, o nome da banda ou artista, o gênero, o álbum e o endereço. Assim não é necessário ler as informações da música no arquivo toda vez que queremos fazer uma busca ou adicioná-los a lista de reprodução. Temos também a lista de reprodução, que nada mais é que uma lista das músicas que irão tocar. Ela tem algumas funções como salvar sua lista de reprodução internamente (no banco), exportar como M3U (lista de reprodução em um arquivo), ler arquivos M3U. Curiosidades (coisas legais) Criação das tabelas: Para instalação do sistema sem necessidades de configuração do banco de dados manualmente pelo usuário, ao iniciar o programa verifica se existe o banco de dados, caso ocorra o erro especifico as tabelas serão criadas. public void testarTabelas(Connection con) { if (primeiraVez) { primeiraVez = false; System.out.println("Primeira Vez Testa Tabelas"); try { Statement st = con.createStatement(); st.execute("select * from musica limit 1"); } catch (Exception e) { //Se Deu erro pq não tem as tabelas if(e.getMessage().equals("user lacks privilege or object not found: MUSICA")){ try { //dai cria Statement st = con.createStatement(); st.executeUpdate(FileUtils.leArquivo(new File(getClass().getResource("/com/config/config.sql").toURI())).toString()); st.executeUpdate(FileUtils.leArquivo(new File(getClass().getResource("/com/musica/musica.sql").toURI())).toString()); st.executeUpdate(FileUtils.leArquivo(new File(getClass().getResource("/com/playlist/playlist.sql").toURI())).toString()); st.executeUpdate(FileUtils.leArquivo(new File(getClass().getResource("/com/playmusica/playmusica.sql").toURI())).toString()); } catch (Exception ex) { System.out.println("Crepz Fatal."); ex.printStackTrace(); } } } } } Configurações salvas: Quando o Crepz Player é fechado, ele salva numa tabela do banco de dados algumas configurações que o usuário estava usando. Quando ele é aberto, a tabela de configurações é lida o player fica no mesmo estado que estava quando foi fechado. As configurações que são gravadas são: música aberta, tocando, pausada, quantos segundos, volume, balanço, aleatório, repetir lista, bandeja do sistema, posição do miniPlayer e se ele é superior as outras janelas. /**Aplica todas as configurações que foram gravadas quando o player foi fechado pela ultima vez.*/ public void getAllValores() { try { //lê a tabela de configurações que está no banco, list é um HashMap list = ConfigBD.listar(null); //aplica as configurações. if (list.get("musica") != null && !((String) list.get("musica")).trim().equals("")) { String musica = (String) list.get("musica"); String tempo = (String) list.get("tempo"); if (tempo == null || tempo.trim().equals("") || tempo.equalsIgnoreCase("null")) { tempo = "0"; } String pause = (String) list.get("pause"); String tocando = (String) list.get("tocando"); if (Boolean.parseBoolean(tocando)) { setMusica(Integer.valueOf(musica), Long.valueOf(tempo), Boolean.parseBoolean(pause)); } else { setMusica(Integer.valueOf(musica)); } } if (list.get("volume") != null) { setVolume(Integer.parseInt((String) list.get("volume"))); } if (list.get("pan") != null) { setPan(Integer.parseInt((String) list.get("pan"))); } if (list.get("repeat") != null) { setRepetir(Boolean.parseBoolean((String) list.get("repeat"))); } if (list.get("random") != null) { setRandom(Boolean.parseBoolean((String) list.get("random"))); } if (list.get("playList") != null && !list.get("playList").toString().trim().equals("")) { setPlayList(Integer.parseInt((String) list.get("playList"))); } if (list.get("bandeja") != null) { setBandeja(Boolean.parseBoolean((String) list.get("bandeja"))); } if (list.get("miniPosicao") != null) { setPosicao(String.valueOf(list.get("miniPosicao"))); } if (list.get("minitop") != null) { setTop(Boolean.parseBoolean((String) list.get("minitop"))); } } catch (Exception ex) { Logger.getLogger(GerenciadorConfig.class.getName()).log(Level.SEVERE, null, ex); } } /**Grava as todas configurações que estão sendo usadas pelo Player*/ public void setAllValores() { // tela de aguarde (passa muito rápido, nem da tempo de ver) final Aguarde ag = new Aguarde(); new Thread(new Runnable() { public void run() { pr.setVisible(false); ag.setVisible(true); ag.setAlwaysOnTop(true); ag.fechar(); } }).start(); //Cria uma transação com o banco Transacao t = new Transacao(); try { //Inicia a transação t.begin(); //ATENÇÃO! APENAS O PRIMEIRO incluir DEVE MANDAR O PARAMETRO reset COMO true ConfigBD.incluir("tocando", String.valueOf(pr.getTocando()), true, t); ConfigBD.incluir("pause", String.valueOf(pr.getPause()), false, t); if (pr.getMusica() != null) { ConfigBD.incluir("musica", pr.getMusica().getId().toString(), false, t); } else { ConfigBD.incluir("musica", "", false, t); } ConfigBD.incluir("tempo", String.valueOf(pr.getTempo()), false, t); ConfigBD.incluir("volume", String.valueOf(pr.getVolume()), false, t); ConfigBD.incluir("pan", String.valueOf(pr.getBalanco()), false, t); if (pl.getId() != -1) { ConfigBD.incluir("playList", String.valueOf(pl.getId()), false, t); } else { ConfigBD.incluir("playList", "", false, t); } ConfigBD.incluir("random", String.valueOf(pr.isRandom()), false, t); ConfigBD.incluir("repeat", String.valueOf(pr.getRepetir()), false, t); ConfigBD.incluir("bandeja", String.valueOf(pr.isBandeija()), false, t); ConfigBD.incluir("miniPosicao", String.valueOf((int) mini.getLocal().getX() + "X" + (int) mini.getLocal().getY()), false, t); ConfigBD.incluir("minitop", String.valueOf(mini.getTop()), false, t); //salva o que foi mudado t.commit(); } catch (Exception ex) { t.rollback(); Logger.getLogger(GerenciadorConfig.class.getName()).log(Level.SEVERE, null, ex); } finally { ag.setVisible(false); } } Render: Troca as cores se tem seleção ou não... /** Método sobreescrito de TableCellRenderer. */ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { removeAll(); JLista panel=null; try{ panel = (JLista)value; } catch(Exception e){ e.printStackTrace(); } if (panel != null) { panel.setBounds(table.getCellRect(0, 0, false)); add(panel, BorderLayout.CENTER); } if (isSelected) { panel.setOpaque(false); super.setForeground(table.getSelectionForeground()); super.setBackground(table.getSelectionBackground()); } else { panel.setOpaque(true); super.setForeground((unselectedForeground != null) ? unselectedForeground : table.getForeground()); super.setBackground((unselectedBackground != null) ? unselectedBackground : table.getBackground()); } if (hasFocus) { if (table.isCellEditable(row, column)) { super.setForeground( UIManager.getColor("Table.focusCellForeground") ); super.setBackground( UIManager.getColor("Table.focusCellBackground") ); } } return this; }