Mostrando postagens com marcador interface gráfica. Mostrar todas as postagens
Mostrando postagens com marcador interface gráfica. Mostrar todas as postagens

quarta-feira, 27 de março de 2013

Modelagem de Domínio





Um modelo de domínio é uma representação visual de classes conceituais ou objetos do mundo real, em um contexto (Fowler, 1996). Ou seja, é uma descrição de coisas/conceitos em uma situação real, mas não de objetos de software, tais como classes em Java, por exemplo. O modelo de domínio, produzido na etapa de análise, ajuda na elaboração da lista de requisitos.

Nesse sentido, um tom determina 8 acordes (sem as variações) a serem tocados. Um tom pode ser maior ou menor; por causa disso, temos que Acordes Maior e Acordes Menor são um tipo de Acorde. Um acorde é composto por 3 notas tocadas simultaneamente. As instâncias C e C#m são apenas um exemplo de nota e acorde, respectivamente.

terça-feira, 15 de janeiro de 2013

Prévia da Interface Gráfica: Stringless Guitar - Parte 4

Nesta última parte da prévia da interface gráfica, vamos abordar o assunto mais intrínseco, que é a lógica de abrir arquivo de áudio. Para isso, há dois jeitos distintos: especificar o caminho de um arquivo local ou por Uniform Resource Locators (URLs). Como o próprio nome já diz, URLs são utilizados para localizar sites na web. Por exemplo, no outro post, o site http://pscode.org/media/EverLove.mid é o URL utilizado pelo programa pra abrir esse arquivo de áudio midi. 

Ao explorar a outra alternativa, devemos informar no código do programa aonde esse arquivo se encontra no computador. 






Em suma, o método abaixo é encarregado de implementar essa operação:


private void D_GMaiorActionPerformed(java.awt.event.ActionEvent evt) {
       InputStream in;
       try{
           in = new FileInputStream(new File("C:\\Users\\Thiago\\Downloads\\D_G Maior.wav"));
           AudioStream audioStream = new AudioStream(in);
           AudioPlayer.player.start(audioStream);
       }
       catch(Exception e){
           JOptionPane.showMessageDialog(null, e);
       } 
    }



Um caractere separador é utilizado para separar diretórios e arquivos no caminho. No Windows, o caractere separador é uma barra invertida (\). Em um sistema UNIX, é uma barra (/). Um erro comum de programação é utilizar '\' como um separador de diretório em vez de '\\'. Uma '\' simples indica que a '\' seguida pelo próximo caractere representa uma sequência de escape.

A diferença aqui é que essa classe, também do pacote javax.sound.sampled (API Java Sound), permite abrir outros formatos de áudio, como o .wav. Isso ajuda bastante, pois obtemos uma qualidade sonora melhor. O MIDI produz um som digitalizado, o que dificulta a experiência de descobrir o som real das notas, objetivo que norteia nosso propósito.



Fontes de Referência

DEITEL, H.M; DEITEL, P.J, Java, Como Programar -8ªed. – São Paulo: Prentice Hall, 2010.
http://docs.oracle.com/javase/7/docs/api/javax/sound/sampled/AudioInputStream.html

quarta-feira, 2 de janeiro de 2013

Prévia da Interface Gráfica: Stringless Guitar - Parte 3


Nessa parte iremos abordar sobre os tratadores de evento de selecionar um item do JComboBox. Ao consultar a documentação (API), descobrimos como prosseguir diante desta situação. Há dois métodos de duas interfaces distintas, respectivamente, ActionListener e ItemListener, que podem ser associados a um JComboBox. Devemos, portanto, criar uma classe que implemente uma dessas interfaces, e instanciar um objeto que será registrado como o handler de evento.

Ambos funcionam, mas é preciso ressaltar a diferença de comportamento entre ambos. Para cada item selecionado, a seleção de outro item é primeiro removida - então ocorrem dois ItemEvents quando um item é selecionado. Ou seja, quando você selecionar um item, este método (itemStateChanged) será disparado duas vezes, ficando propensa a ocorrência de futuros bugs.

Então, optamos por utilizar um action listener. As duas condições dentro do método actionPerformed determinam a origem do evento (se ele é oriundo da primeira ou segunda combo box). 


void addActionListener(ActionListener) : Adiciona um action listener ao combo box. O método actionPerformed do listener é chamado quando o usuário seleciona um item do combo box ou, quando num combo box editável, quando o usuário pressiona Enter.

void addItemListener(ItemListener) : Adiciona um item listener ao combo box. O método itemStateChanged do listener é chamado quando o estado de seleção de qualquer um dos combo box's muda.



import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;


public class TesteEventoJComboBox extends JFrame implements ActionListener {

JComboBox comboBoxTomMenor;
JComboBox comboBoxTomMaior;

public TesteEventoJComboBox(){
super("Teste Evento JComboBox");
Container container = this.getContentPane();
container.setLayout(new FlowLayout());

String[] listaAfinacaoMaior = {"Selecione um tom maior","C", "Db", "D", "Eb", "E", "F", "F#", "G", "Ab", "A", "Bb", "B"};
String[] listaAfinacaoMenor = {"Selecione um tom menor","C", "C#", "D", "Eb", "E", "F", "F#", "G", "G#", "A", "Bb", "B"};

comboBoxTomMaior = new JComboBox(listaAfinacaoMaior);
container.add(comboBoxTomMaior);

comboBoxTomMenor = new JComboBox(listaAfinacaoMenor);
container.add(comboBoxTomMenor);

comboBoxTomMaior.setEditable(false);
comboBoxTomMenor.setEditable(false);

comboBoxTomMaior.addActionListener(this);
comboBoxTomMenor.addActionListener(this);
}


public static void main(String[] args) {
TesteEventoJComboBox t = new TesteEventoJComboBox();
t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
t.setSize(250, 150);
t.setVisible(true);
}


@Override
public void actionPerformed(ActionEvent event) {
if(event.getSource() == comboBoxTomMaior){
JOptionPane.showMessageDialog(null, String.format("Você clicou %s", comboBoxTomMaior.getSelectedItem()));
}

if(event.getSource() == comboBoxTomMenor) {
JOptionPane.showMessageDialog(null, String.format("Você clicou %s", comboBoxTomMenor.getSelectedItem()));
}
}

}








Fontes de Referência

DEITEL, H.M; DEITEL, P.J, Java, Como Programar -8ªed. – São Paulo: Prentice Hall, 2010.
http://geekycoder.wordpress.com/2008/07/28/tipjava-difference-between-actionlistener-and-itemlistener/
http://javafree.uol.com.br/topic-864599-JComboBox-eventos-duplicados.html
http://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html#listeners

sábado, 29 de dezembro de 2012

Prévia da Interface Gráfica: Stringless Guitar - Parte 2


Um JComboBox, que permite ao usuário escolher dentre vários elementos, pode ter duas formas diferentes. O formato padrão é uma combo box não-editável, que caracteriza um botão e uma lista drop-down de itens. A outra, editável, caracteriza um campo de texto com um pequeno botão ao lado. O usuário pode digitar um valor no campo de texto ou clicar no botão para mostrar a lista de itens. Aqui segue as duas formas de combo boxes, da esquerda para a direita, respectivamente, editável e não-editável em Java:


An uneditable combo box                            An editable combo box
An uneditable combo box                         An editable combo box


Outros componentes que podem mostrar uma de várias possibilidades de escolhas são grupos de radio buttons e lists. Selecionar um botão de opção diferente força a remoção da seleção de todos os outros que estão selecionados. Os botões de opção são utilizados para representar opções mutuamente exclusivas (isto é, não é possível selecionar múltiplas opções no grupo ao mesmo tempo).

A intenção de usar dois combo boxes é de fornecer ao usuário duas listas de tons (maior/menor) contendo cada uma 8 possibilidades de acordes para serem tocados (que vão ser representados pelos botões do último post). Segue o código que implementa essa funcionalidade:


import javax.swing.JComboBox;
import javax.swing.JFrame;
import java.awt.Container;
import java.awt.FlowLayout;


public class JComboBoxTeste extends JFrame {


JComboBox comboBoxTomMenor;
JComboBox comboBoxTomMaior;

public JComboBoxTeste(){
super("Teste");
Container container = this.getContentPane();
container.setLayout(new FlowLayout());
String[] listaAfinacaoMaior = {"Selecione um tom maior","C", "Db", "D", "Eb", "E", "F", "F#", "G", "Ab", "A", "Bb", "B"};
String[] listaAfinacaoMenor = {"Selecione um tom menor","C", "C#", "D", "Eb", "E", "F", "F#", "G", "G#", "A", "Bb", "B"};

comboBoxTomMaior = new JComboBox(listaAfinacaoMaior);
container.add(comboBoxTomMaior);

comboBoxTomMenor = new JComboBox(listaAfinacaoMenor);
container.add(comboBoxTomMenor);


comboBoxTomMaior.setEditable(false);
comboBoxTomMenor.setEditable(false);
}



public static void main(String[] args) {
JComboBoxTeste j = new JComboBoxTeste();
j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
j.setSize(250,150);
j.setVisible(true);
}

}







Fontes de Referência

DEITEL, H.M; DEITEL, P.J, Java, Como Programar -8ªed. – São Paulo: Prentice Hall, 2010.
http://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html#eg


domingo, 23 de dezembro de 2012

Prévia da Interface Gráfica: Stringless Guitar - Parte 1


As funcionalidades de nossa interface gráfica, como anteriormente explicitadas, devem ser divididas em níveis de abstração para facilitar o entendimento e a programação. Para isso, vamos atacar o problema pelos seguintes pontos:


  1. JButtons (botões);
  2. JComboBox (lista de itens drop-down);
  3. Tratadores de evento: selecionar um item do JComboBox/clicar em um botão;
  4. Lógica de abrir arquivo de áudio (por URL ou especificar o caminho de um arquivo local C://).



Por enquanto, testamos separadamente para analisar o comportamento dos componentes Swing JButton e JComboBox. O código abaixo testa os 8 botões da aplicação que, no futuro vão aparecer na tela após ser selecionado um item da lista de afinações (JComboBox). Serão 8 botões diferentes para cada item dessa caixa selecionável, contendo um arquivo midi diferente.







 





import javax.swing.JFrame;
import javax.swing.JOptionPane;

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;

public class ButtonFrame extends JFrame {
private JButton button1;
private JButton button2;
private JButton button3;

private JButton button4;
private JButton button5;
private JButton button6;
private JButton button7;
private JButton button8;

private ButtonHandler handler;

/*Em
Am
Dm
G
C
F
Bb
Bdim
*/
public void makeButtons(){ Container c = this.getContentPane(); setLayout(new FlowLayout()); button1 = new JButton("Em"); c.add(button1); button2 = new JButton("Am"); c.add(button2); button3 = new JButton("Dm"); c.add(button3); button4 = new JButton("G"); c.add(button4); button5 = new JButton("C"); c.add(button5); button6 = new JButton("F"); c.add(button6); button7 = new JButton("Bb"); c.add(button7); button8= new JButton("Bdim"); c.add(button8); }

public void tratarEventoBotao(ButtonHandler handler){ //cria novo ButtonHandler para tratamento de evento de botão handler = new ButtonHandler();
button1.addActionListener(handler); button2.addActionListener(handler); button3.addActionListener(handler); button4.addActionListener(handler); button5.addActionListener(handler); button6.addActionListener(handler); button7.addActionListener(handler); button8.addActionListener(handler); }

public ButtonFrame(){
super("Testando JButtons"); makeButtons(); tratarEventoBotao(handler);
}

private class ButtonHandler implements ActionListener{

@Override
public void actionPerformed(ActionEvent event) {
JOptionPane.showMessageDialog(ButtonFrame.this, String.format("Você clicou %s", event.getActionCommand()));

}

}

public static void main(String[] args) {

ButtonFrame b = new ButtonFrame();
b.setSize(250,140);
        b.setVisible(true);
}
}

quinta-feira, 13 de dezembro de 2012

Abrindo um Arquivo de Áudio no Java Sound


Um dos jeitos possíveis de se abrir um arquivo de áudio no Java Sound é armazená-lo em uma URL da web, para o objeto sequencer poder manipulá-lo. Se você abrir este site http://pscode.org/media/EverLove.mid , uma música (MIDI) começará a tocar. O que esse código faz é simplesmente o trabalho de tocar sem ter que abrir o browser para tal.

É bom lembrar que, para conseguir rodar esse programa mais de uma vez, você deve terminar o processo main, pois ele lança uma exceção do tipo MidiUnavailableException. Isso porque um componente MIDI está sendo utilizado pela aplicação.



import javax.sound.midi.*;
import javax.swing.JOptionPane;
import java.net.URL;



public class Main {
public static void main(String[] args) throws Exception {
URL url = new URL("http://pscode.org/media/EverLove.mid");

       Sequence sequence = MidiSystem.getSequence(url);
       Sequencer sequencer = MidiSystem.getSequencer();

       sequencer.open();
       sequencer.setSequence(sequence);

       sequencer.start();
       JOptionPane.showMessageDialog(null, "Everlasting Love");
}

}

quarta-feira, 12 de dezembro de 2012

API Java Sound


Java Sound é uma API (Application Programming Interface - biblioteca de classes) que provê suporte para operações de áudio e MIDI com alta qualidade, tais como: captura, mixagem, gravação, sequenciamento e síntese MIDI. A Java Sound vem junto com o J2SE desde a versão 1.3 e por isso é considerada por
alguns como a fonte do sucesso do Java para a programação musical. Na versão J2SE 1.5 teve grande avanço e correção e alguns de seus principais bugs, como a comunicação MIDI com dispositivos externos.

Em constante evolução e melhoria, são características nativas do Java Sound:

- Suporte aos formatos de arquivos de áudio: AIFF, AU e WAV;
- Suporte aos formatos de arquivos de música: MIDI Type 0, MIDI Type 1, e Rich Music Format (RMF);
- Formatos de som em 8/16 bits, mono e estéreo, com sample rate de 8 a 48 Hz;
- Dados de áudio codificados em linear, a-law e mu-law para qualquer um dos
formatos de áudio suportados; 
- Síntese e seqüenciamento MIDI por software, bem como acesso a qualquer
dispositivo MIDI em hardware;
- Mixer com capacidade para mixar e renderizar mais de 64 canais de áudio digital
e sons MIDI sintetizados.


A API Java Sound é o suporte a áudio de mais baixo nível na plataforma Java,
permitindo aos programas um bom controle nas operações de som. A API não inclui
editores de som sofisticados ou ferramentas gráficas, mas é extensível o suficiente para
que isso seja construído a partir dela, como uma API de baixo nível deve ser.

Existem APIs de mais alto nível para desenvolvimento mais rápido e fácil de
aplicações multimídia. A própria Sun, fabricante do Java Sound, distribui o Java Media
Framework (JMF). O JMF especifica uma arquitetura unificada, protocolo para trocas
de mensagem e interface de programação para captura, execução e sincronização de
mídias baseadas no tempo, como som e vídeo. Porém, nesta pesquisa, ela não será utilizada.

É permitido que terceiros criem e distribuam componentes de software customizados para estender suas
capacidades.

Como exemplos de aplicações potenciais para o Java Sound, cita-se:
  • Frameworks para comunicação, como conferência e telefonia;
  • Sistema de entrega de conteúdo, como media players;
  • Programas interativos como jogos e websites dinâmicos;
  • Criação e edição de conteúdo sonoro e musical;
  • Componentes e ferramentas para manipulação sonora;


·       Java Sound não foi a primeira biblioteca a manipular sons e dados musicais (MIDI) na plataforma Java, mas, sem dúvidas, é a mais importante delas. Apesar das restrições, o Java Sound permite que as aplicações escritas com suas classes funcionem da mesma forma nas diversas plataformas suportadas pelo Java.

Nota-se também que a Sun não tem interesse em desenvolver mais esta API, pois ela vai continuar sendo uma biblioteca de baixo nível para manipulação de som e dados musicais, com uma importante alternativa de expansão, a interface SPI (Server Provider Interfaces). Ela permite desenvolvedores independentes criarem novos recursos de MIDI e áudio que podem ser distribuídos separadamente e conectados (plug-ins) sem que as implementações necessitem modificações no código. Estas implementações podem ser puramente software ou interfaces para melhor uso do hardware.

O Java Sound suporta tanto áudio digital como MIDI, através de seus dois pacotes distintos:

  • javax.sound.sampled: Captura, mixa e toca audio digital (samples);
  • javax.sound.midi: Síntese, sequenciamento e tratamento de eventos MIDI;

Configurações de Áudio

O Java Sound API utiliza os recursos do hardware disponíveis na máquina para desempenhar sua principal função: transportar áudio (mover dados formatados para dentro do sistema). Para executar esta função, o Java Sound implementa métodos de gravação e conversão entre alguns formatos de áudio deixando a cargo de terceiros a implementação de plug-ins que venham suportar novos formatos de áudio.

Muitas API's, para tratamento de som, trabalham com o conceito de dispositivo de áudio(devices). Normalmente, um device é uma interface para um dispositivo físico de E/S. No contexto do Java Sound, devices são representados por objetos do tipo Mixer, que tem a função de juntar e direcionar diversas entradas de áudio a uma ou mais saídas.

O objeto responsável por mover o áudio para dentro e para fora do sistema é a Line. Outros objetos também podem ser vistos como uma Line tais como portas de E/S (microfone, CD-ROM, headphone, etc) e até mesmo o Mixer, pois eles também podem ser caminhos para o áudio. Pode-se fazer uma analogia da Line com uma trilha (track) em um gravador multitrack ligado a um mixer externo, com a diferença que, no Java Sound, uma Line pode ser multi-canal de acordo com o formato de áudio em transporte.

A interface Mixer define métodos para se obter as Lines que ele gerencia, que podem ser do tipo SourceDataLine (input) ou TargetDataLine (output). Esta interface, no entanto, não define métodos de controle de gravação e execução, sendo esses definidos somente nas DataLine's.

Clip é uma DataLine que armazena todo o som na memória antes de sua execução. Graças a essa característica, é possível navegar pela mídia e programar repetições (loop).

Todo recurso de áudio é obtido através da classe que gerencia os recursos de hardware da máquina: AudioSystem.

·        
·       
Fonte de Referência

http://www.lume.ufrgs.br/bitstream/handle/10183/6606/000487146.pdf?sequence=1
http://docs.oracle.com/javase/1.5.0/docs/api/index.html
http://stackoverflow.com/tags/javasound/info

segunda-feira, 29 de outubro de 2012

Lista de Tons Musicais


Cada música possui uma tonalidade que define a nota central à qual estão relacionadas as outras notas da música. Abaixo segue a lista de tons, cujo posicionamento na interface será no canto superior esquerdo, que restringem os acordes que poderão ser tocados.


Maior                                                   
C
Db
D
Eb
E
F
F#
G
Ab
A
Bb
B


Menor
C
C#
D
Eb
E
F
F#
G
G#
A
Bb
B



Estes acordes serão representados cada um por botões, conforme especificado no último post. Cada tom possui 8 acordes. Por exemplo, se você escolhe o tom C(Dó), é possível tocar os acordes  Em, Am, Dm, G, C, F, Bb, Bdim. Assim por diante.

Então, já dá pra prever o funcionamento da GUI: haverá essas duas listas de tons acima na tela. Ao clicar em uma dessas opções de tons, aparecerá 8 botões com cada acorde correspondente, que, quando pressionados, sairá o som desse acorde. Simples, não?



Acordes - Tom Maior(na ordem) 
Em
Am
Dm
G
C
F
Bb
Bdim
Fm
Bbm
Ebm
Ab
Db
Gb
B
Cdim
F#m
Bm
Em
A
D
G
C
C#°
Gm
Cm
Fm
Bb
Eb
Ab
Db
Ddim
G#m
C#m
F#m
B
E
A
D
D#°
Am
Dm
Gm
C
F
Bb
Eb
Edim
A#m
D#m
G#m
C#
F#
B
E
Fdim
Bm
Em
Am
D
G
C
F
F#°
Cm
Fm
Bbm
Eb
Ab
Db
Gb
Gdim
C#m
F#m
Bm
E
A
D
G
G#°
Dm
Gm
Cm
F
Bb
Eb
Ab
Adim
D#m
G#m
C#m
F#
B
E
A
A#°



Acordes – Tom Menor (na ordem)
Eb
Ab
Ddim
Gm
Cm
Fm
Bb
G
E
A
D#°
G#m
C#m
F#m
B
G#
F
Bb
Edim
Am
Dm
Gm
C
A
Gb
B
Fdim
Bbm
Ebm
Abm
Db
Ab
G
C
F#°
Bm
Em
Am
D
B
Ab
Db
Gdim
Cm
Fm
Bbm
Eb
C
A
D
G#°
C#m
F#m
Bm
E
C#
Bb
Eb
Adim
Dm
Gm
Cm
F
D
B
E
A#°
D#m
G#m
C#m
F#
D#
C
F
Bdim
Em
Am
Dm
G
E
Db
Gb
Cdim
Fm
Bbm
Ebm
Ab
F
D
G
C#°
F#m
Bm
Em
A
F#


     Lá = A                                             m = menor

Si = B                                              # = sustenido
Dó = C                                             #m = sustenido menor                                                                               
Ré = D                                              b = bemol
Mi = E                                              bm = bemol menor
Fá = F                                              dim  = diminuto
Sol = G



Obviamente, as variações que compõem os acordes foram omitidas aqui. Não trabalharemos com variações de acordes nesse contexto.