13
14/7/2014 Apêndice - Mais swing e recursos avançados - Laboratório Java com Testes, XML e Design Patterns http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-mais-swing-e-recursos-avancados/#11-2-exercicios-opcionais-filtrando-por-… 1/13 CAPÍTULO 11 Apêndice - Mais swing e recursos avançados Com o que foi visto de Swing até agora, você já deve conseguir fazer diversas outras brincadeiras apenas procurando mais recursos na API e lembrando que, trabalhando com Swing, sempre usaremos composição de componentes! Esse capítulo mostra algumas outras modificações que você pode fazer no Argentum para torná-lo mais interessante. Além disso, lendo mais adiante você também conhecerá um recurso poderoso ao lidar com processos demorados dentro do Swing. 11.1 - INPUT DE DADOS FORMATADOS: DATAS Usar entrada de datas em um sistema Swing é extremamente fácil: podemos usar a classe JTextField que permite obter e alterar os dados digitados. Essa classe é muito flexível também, possibilitando alterar vários aspectos da exibição dos dados, dos formatos, dos eventos associados, etc. No nosso sistema Argentum, vamos adicionar um campo para entrada de data que permita filtrar a lista de negócios usada para exibir a tabela e o gráfico. Queremos um campo de texto com barras para separar campos da data e , que aceite apenas datas com formatação válida. Uma classe filha de JTextField já faz boa parte desse trabalho: a JFormattedTextField . Podemos criar um JFormattedTextField e associar a ele um javax.swing.text.Formatter , como um DateFormatter , um NumberFormatter ou um MaskFormatter . Vamos usar o MaskFormatter para aplicar uma máscara no campo e permitir um input de datas fácil pelo usuário: MaskFormatter mascara = new MaskFormatter ( "##/##/####" ); mascara .setPlaceholderCharacter( '_' ); APOSTILA LABORATÓRIO JAVA COM TESTES, XML E DESIGN PATTERNS

Mais Swing e Recursos Avançados - Laboratório Java Com Testes, XML e Design Patterns

Embed Size (px)

DESCRIPTION

swing

Citation preview

  • 14/7/2014 Apndice - Mais swing e recursos avanados - Laboratrio Java com Testes, XML e Design Patterns

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-mais-swing-e-recursos-avancados/#11-2-exercicios-opcionais-filtrando-por- 1/13

    CAPTULO 11

    Apndice - Mais swing e recursos

    avanados

    Com o que foi visto de Swing at agora, voc j deve conseguir fazer diversas

    outras brincadeiras apenas procurando mais recursos na API e lembrando que,

    trabalhando com Swing, sempre usaremos composio de componentes!

    Esse captulo mostra algumas outras modificaes que voc pode fazer no

    Argentum para torn-lo mais interessante. Alm disso, lendo mais adiante voc

    tambm conhecer um recurso poderoso ao lidar com processos demorados dentro

    do Swing.

    11.1 - INPUT DE DADOS FORMATADOS: DATAS

    Usar entrada de datas em um sistema Swing extremamente fcil: podemos

    usar a classe JTextField que permite obter e alterar os dados digitados. Essa

    classe muito flexvel tambm, possibilitando alterar vrios aspectos da exibio

    dos dados, dos formatos, dos eventos associados, etc.

    No nosso sistema Argentum, vamos adicionar um campo para entrada de data

    que permita filtrar a lista de negcios usada para exibir a tabela e o grfico.

    Queremos um campo de texto com barras para separar campos da data e , que

    aceite apenas datas com formatao vlida. Uma classe filha de JTextField j faz

    boa parte desse trabalho: a JFormattedTextField.

    Podemos criar um JFormattedTextField e associar a ele um

    javax.swing.text.Formatter, como um DateFormatter, um NumberFormatter

    ou um MaskFormatter. Vamos usar o MaskFormatter para aplicar uma mscara no

    campo e permitir um input de datas fcil pelo usurio:

    MaskFormatter mascara = new MaskFormatter("##/##/####");

    mascara.setPlaceholderCharacter('_');

    APOSTILA LABORATRIO JAVA COM TESTES, XML E DESIGN PATTERNS

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/http://www.caelum.com.br/?utm_source=Apostila_HTML&utm_campaign=FJ-16&utm_medium=referralhttp://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fwww.caelum.com.br%2Fapostila-java-testes-xml-design-patterns%2F

  • 14/7/2014 Apndice - Mais swing e recursos avanados - Laboratrio Java com Testes, XML e Design Patterns

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-mais-swing-e-recursos-avancados/#11-2-exercicios-opcionais-filtrando-por- 2/13

    Repare na chamada ao setPlaceholerCharacter que diz ao componente para

    colocar um underscore nos espaos de digitao enquanto o usurio no preenche

    com a data desejada. Aps o usurio digitar, podemos obter o valor chamando o

    getValue. A partir da, podemos transformar o objeto em um Date para uso:

    11.2 - EXERCCIOS OPCIONAIS: FILTRANDO POR DATA

    1. Abra a classe ArgentumUI e adicione a chamada ao montaCampoData ao mtodo

    montaTela (cuidado com a ordem):

    2. Usando o ctrl + 1 na linha recm adicionada, indique para o Eclipse que ele crie

    esse novo mtodo (preparaCampoData). Implemente o mtodo como abaixo,

    prestando ateno no campoData, que deve ser um atributo (use o Assign

    statement to new field ou equivalente):

    JFormattedTextField campoDataInicio = new JFormattedTextField(mascara);

    String valor = (String) campoDataInicio.getValue(); DateFormat formato = new SimpleDateFormat("dd/MM/yyyy");

    Date date = formato.parse(valor);

    public void montaTela() {

    preparaJanela(); preparaPainelPrincipal(); preparaAbas(); preparaTabela(); preparaPainelBotoes(); preparaCampoData(); preparaBotaoCarregar(); preparaBotaoSair(); mostraJanela();}

    private void preparaCampoData() {

    try {

    JLabel labelData = new JLabel("Apenas a partir de:");

    MaskFormatter mascara = new MaskFormatter("##/##/####");

    mascara.setPlaceholderCharacter('_'); campoData = new JFormattedTextField(mascara);

    painelBotoes.add(labelData); painelBotoes.add(campoData); } catch (ParseException e) {

    e.printStackTrace(); }}

  • 14/7/2014 Apndice - Mais swing e recursos avanados - Laboratrio Java com Testes, XML e Design Patterns

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-mais-swing-e-recursos-avancados/#11-2-exercicios-opcionais-filtrando-por- 3/13

    3. Rode a aplicao e veja o resultado:

    4. Agora, precisamos implementar o filtro da data no momento de carregar o XML.

    Se o campoData estiver preenchido, adicione dentro do carregaDados uma

    chamada ao mtodo filtra de uma nova classe FiltradorPorData, que

    implementaremos na sequncia. Faa isso na linha logo aps a criao da lista.

    5. Vamos pedir que o Eclipse crie essa classe que recebe uma dataDigitada no

    construtor e a converte para um Calendar. Abuse do ctrl + 1 para criar a classe e o

    construtor. Complete a implementao do construtor:

    private void carregaDados() {

    List lista = new EscolhedorDeXML().escolhe();

    if (campoData.getValue() != null) {

    new FiltradorPorData(campoData.getText()).filtra(lista);

    } ArgentumTableModel ntm = new ArgentumTableModel(lista);

    //...

    public class FiltradorPorData {

    private Calendar dataInicial;

    public FiltradorPorData(String dataDigitada) {

    try {

    SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");

    dataInicial = Calendar.getInstance(); dataInicial.setTime(sdf.parse(dataDigitada)); } catch (ParseException e) {

    throw new RuntimeException(e);

    } }}

  • 14/7/2014 Apndice - Mais swing e recursos avanados - Laboratrio Java com Testes, XML e Design Patterns

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-mais-swing-e-recursos-avancados/#11-2-exercicios-opcionais-filtrando-por- 4/13

    6. Estamos quase l! Agora, s falta criar o mtodo filtra que passa pela lista de

    negcios lida do XML removendo dela todos os negcios que sejam de datas

    anteriores data selecionada pelo usurio.

    Dentro da ArgentumUI ainda deve haver um erro de compilao informando de o

    mtodo filtra ainda no existe na classe FiltradorPorData. Mande o Eclipse

    criar esse mtodo para voc e o complete com o cdigo para remover os Negocios

    de antes da data indicada.

    Existe uma limitao da lista quando tentamos fazer uma remoo nela dentro de

    um lao que a percorre. Para conseguir fazer isso, usaremos o Iterator:

    7. Rode novamente sua aplicao e faa alguns testes. Teste carregar sem a data

    setada, setando uma data vlida, uma invlida, etc.

    Iterator e remoes

    Sempre use a classe Iterator quando precisar remover elementos de uma

    Collection enquanto percorre seus elementos.

    8. (opcional) Repare que, ao colocar valores que extrapolem o limite do campo (por

    exemplo um ms 13), assumido que o primeiro ms do ano seguinte. Para

    public void filtra(List lista) {

    if (dataInicial == null)

    return;

    Iterator it = lista.iterator(); while (it.hasNext()) {

    if (it.next().getData().before(dataInicial))

    it.remove(); } }

    1

    2

    3

    4

    5

    6

    7

    8

    9

  • 14/7/2014 Apndice - Mais swing e recursos avanados - Laboratrio Java com Testes, XML e Design Patterns

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-mais-swing-e-recursos-avancados/#11-2-exercicios-opcionais-filtrando-por- 5/13

    mudar esse comportamento, chame setLenient(false) no SimpleDateFormat

    que estamos usando.

    O que acontece quando voc tenta filtrar uma data invlida agora?

    Trate a exceo no mtodo carregaDados, limpando o campoData e dando uma

    mensagem de pop-up para avisar o que aconteceu.

    Seus livros de tecnologia parecem do sculo passado?

    Conhea a Casa do Cdigo, uma nova editora, com autores de

    destaque no mercado, foco em ebooks (PDF, epub, mobi),

    preos imbatveis e assuntos atuais.

    Com a curadoria da Caelum e excelentes autores, uma

    abordagem diferente para livros de tecnologia no Brasil.

    Conhea os ttulos e a nova proposta, voc vai gostar.

    Casa do Cdigo, livros para o programador.

    11.3 - PARA SABER MAIS: BARRA DE MENU

    Para criar uma barra de menu no topo de nossas janelas, basta usarmos a classe

    JMenuBar do Swing. Dentro de um JMenuBar, colocamos vrios JMenu que

    representam cada menu (File, Edit, View Help etc). E, dentro de cada JMenu,

    colocamos vrios JMenuItems que representam cada ao (Abrir, Salvar, Sair etc).

    Existem ainda duas subclasses de JMenuItem, mais especficas, que

    transformam aquela entrada do menu em um checkbox ou radio button,

    JCheckboxMenuItem e JRadioButtonMenuItem.

    public FiltradorPorData(String dataDigitada) {

    try {

    SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");

    sdf.setLenient(false);

    //...

    JMenuBar menuBar = new JMenuBar();

    janela.setJMenuBar(menuBar);

    http://www.casadocodigo.com.br/?utm_source=Apostila_HTML&utm_campaign=FJ-16&utm_medium=referral

  • 14/7/2014 Apndice - Mais swing e recursos avanados - Laboratrio Java com Testes, XML e Design Patterns

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-mais-swing-e-recursos-avancados/#11-2-exercicios-opcionais-filtrando-por- 6/13

    E podemos tratar os eventos desses menus da mesma forma que com botes,

    com ActionListeners.

    11.4 - EXERCCIO: ESCOLHENDO INDICADORES PARA O GRFICO

    Nosso grfico no nos d a chance de escolher quais indicadores queremos ver.

    Vamos, atravs de um JMenuBar, possibilitar ao usurio escolh-los. Para isso,

    criaremos uma barra de menu em uma classe auxiliar chamada MenuIndicadores.

    1. Na classe ArgentumUI, altere novamente o mtodo montaTela para chamar o

    mtodo preparaMenu logo abaixo da janela:

    2. Faa o Eclipse criar esse mtodo para voc e o complete como abaixo:

    3. Crie o construtor da nova classe MenuIndicadores que o Eclipse gerar para

    voc atravs do ctrl + 1 e, nele, instancie cada um dos indicadores possveis e crie

    um JCheckBoxMenuItem para cada um deles. Para facilitar a recuperao dos

    objetos, guardaremos em um HashMap os itens do menu e seus respectivos

    indicadores.

    JMenu menuInicio = new JMenu("Incio");

    menuBar.add(menuInicio);

    JMenu carregar = new JMenu("Carregar");

    menuInicio.add(carregar);

    JMenu sair = new JMenu("Sair");

    menuInicio.add(sair);

    JCheckBoxMenuItem check = new JCheckBoxMenuItem("Checkbox");

    menuInicio.add(check);

    public void montaTela() {

    preparaJanela(); preparaMenu(); preparaPainelPrincipal(); preparaAbas(); preparaTabela(); preparaPainelBotoes(); preparaCampoData(); preparaBotaoCarregar(); preparaBotaoSair(); mostraJanela();}

    private void preparaMenu() {

    menu = new MenuIndicadores();

    janela.setJMenuBar(menu.getMenuBar());}

  • 14/7/2014 Apndice - Mais swing e recursos avanados - Laboratrio Java com Testes, XML e Design Patterns

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-mais-swing-e-recursos-avancados/#11-2-exercicios-opcionais-filtrando-por- 7/13

    Seu cdigo ficar parecido com esse:

    4. No cdigo acima, voc deve ter notado que a barra de menu menuBar foi

    transformada em um atributo. Precisamos, agora, de um getter para esse atributo.

    Na classe MenuIndicadores, faa:

    5. Rode sua aplicao e teste o menu, que, por enquanto no faz nada:

    6. Precisamos agora alterar o mtodo carregaDados para usar os indicadores

    selecionados no menu. Altere as linhas que tratam de chamar o plotaIndicador

    para iterar pela lista de indicadores selecionados:

    public MenuIndicadores() {

    List indicadores = new ArrayList();

    indicadores.add(new IndicadorFechamento());

    indicadores.add(new MediaMovelSimples(new IndicadorFechamento()));

    indicadores.add(new MediaMovelPonderada(new IndicadorFechamento()));

    // mais indicadores, se houver

    menuBar = new JMenuBar();

    JMenu menuIndicadores = new JMenu("Indicadores");

    menuBar.add(menuIndicadores); indicadoresNoMenu = new HashMap();

    for (Indicador indicador : indicadores) {

    JCheckBoxMenuItem opcaoIndicador = new JCheckBoxMenuItem(indicador.toString(), true);

    menuIndicadores.add(opcaoIndicador); indicadoresNoMenu.put(opcaoIndicador, indicador); }}

    getM

    private void carregaDados() {

    // algumas linhas...

    GeradorDeGrafico gerador = new GeradorDeGrafico(serie, 2, serie.getTotal()

    - 1); List indicadores = menu.getIndicadoresSelecionados(); for (Indicador indicador : indicadores) {

    gerador.plotaIndicador(indicador);

  • 14/7/2014 Apndice - Mais swing e recursos avanados - Laboratrio Java com Testes, XML e Design Patterns

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-mais-swing-e-recursos-avancados/#11-2-exercicios-opcionais-filtrando-por- 8/13

    7. Agora, s falta implementar esse mtodo getIndicadoresSelecionados na

    classe MenuIndicadores. Deixe que o Eclipse crie o cabealho do mtodo para voc

    e apenas o preencha verificando quais itens do menu foram marcados

    (item.isSelected()) e devolvendo os Indicadores de acordo.

    8. Rode a aplicao novamente e teste escolher uma data e os indicadores.

    9. (opcional) Faa mais indicadores e adicione-os ao menu. Se for necessrio, crie

    mais menus para melhorar a usabilidade.

    10. (opcional) Faa com que as aes e "Carregar XML" e "Sair" tambm possam

    ser executadas via alguma opo no menu bar.

    } abas.setComponentAt(1, gerador.getPanel());}

    public List getIndicadoresSelecionados() { ArrayList indicadores = new ArrayList(); for (JCheckBoxMenuItem menuItem : indicadoresNoMenu.keySet()) { if (menuItem.isSelected()) indicadores.add(indicadoresNoMenu.get(menuItem)); } return indicadores;}

  • 14/7/2014 Apndice - Mais swing e recursos avanados - Laboratrio Java com Testes, XML e Design Patterns

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-mais-swing-e-recursos-avancados/#11-2-exercicios-opcionais-filtrando-por- 9/13

    11.5 - DIFICULDADES COM THREADS E CONCORRNCIA

    Quando rodamos uma aplicao com Swing/AWT, uma das maiores dificuldades

    trabalhar com threads. Isso porque temos que saber gerenciar o desenho e

    atualizao da tela ao mesmo tempo que queremos executar as lgicas de negcio

    pesadas e complexas.

    Toda vez que rodamos uma aplicao Java, como sabemos, executamos o mtodo

    main na thread principal do programa. Quando rodamos um programa com

    Swing/AWT, uma nova thread criada, alm da principal, para tratar do desenho da

    interface e da interao do usurio.

    Isso quer dizer que quando criamos listeners para eventos do Swing, eles so

    executados pela thread do AWT e no pela thread do main. considerado m

    prtica de programao executar tarefas pesadas (com muita conteno) dentro

    desses listener para no travar a thread do AWT e deixar a interface com aparncia

    de travada.

    Faa o teste: pegue um XML de negocios bem grande (50 mil linhas ou mais) e

    mande seu programa carreg-lo. Ao mesmo tempo, clique no boto de sair. Repare

    que o evento demora muito para ser processado.

    Quando formos executar operaes potencialmente pesadas, a boa prtica que

    o listener do evento no faa essa execuo, mas dispare uma nova thread para

    essa execuo. O problema que quando executamos alguma lgica de negcios

    muito comum ao final fazer alguma alterao nos componentes visuais -- no

    nosso programa, depois de processar o XML, precisamos atualizar o TableModel

    do JTable, por exemplo.

    Mas toda atualizao nos componentes deve ser feita no AWT e no na nova

    thread, j que essa a nica forma de evitar completamente problemas de

    concorrncia: o AWT mantm uma fila de tarefas a serem processadas e as executa

    sem perigo de problemas de concorrncia.

    Gerenciar essas threads todas e conseguir sincronizar tudo corretamente,

    executando tudo no seu devido lugar, um dos pontos mais complexos do Swing. A

    partir do Java 6 existe uma classe que procura simplificar esse trabalho todo:

    SwingWorker.

    Agora a melhor hora de aprender algo novo

    http://www.alura.com.br/

  • 14/7/2014 Apndice - Mais swing e recursos avanados - Laboratrio Java com Testes, XML e Design Patterns

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-mais-swing-e-recursos-avancados/#11-2-exercicios-opcionais-filtrando-por 10/13

    Se voc gosta de estudar essa apostila aberta da Caelum,

    certamente vai gostar dos novos cursos online que

    lanamos na plataforma Alura. Voc estuda a qualquer

    momento com a qualidade Caelum.

    Conhea a Alura.

    11.6 - SWINGWORKER

    O princpio por trs da classe SwingWorker permitir executar cdigos em uma

    thread nova concorrentemente a outras tarefas da thread do AWT. Essa classe traz

    toda a infra-estrutura necessria para fazer a comunicao entre essas threads de

    forma segura.

    Para faz-la funcionar, implementamos dois mtodos:

    doInBackground() - contm o cdigo pesado que deve ser executado na thread

    concorrente. Pode devolver algum objeto que ser enviado para a thread do AWT;

    done() - executado na thread do AWT logo que o doInBackground termina. Aqui

    podemos recuperar o objeto devolvido na outra thread e atualizar itens da

    interface.

    Temos que escrever uma classe que herda de SwingWorker e implementar esses

    mtodos. Na hora de extender o SwingWorker, precisamos passar dois argumentos

    para seu generics: o tipo do objeto que o doInBackground devolve e um outro tipo

    usado (opcionalmente) para indicar progresso (que no precisamos agora).

    Vamos ver uma implementao inicial:

    public class CarregadorXMLWorker extends SwingWorker {

    private final JTable tabela;

    public CarregadorXMLWorker(JTable tabela)

    this.tabela = tabela;

    }

    @Override protected List doInBackground() throws Exception {

    return new EscolheXML().escolher();

    }

    http://www.alura.com.br/

  • 14/7/2014 Apndice - Mais swing e recursos avanados - Laboratrio Java com Testes, XML e Design Patterns

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-mais-swing-e-recursos-avancados/#11-2-exercicios-opcionais-filtrando-por 11/13

    CAPTULO ANTERIOR:

    Apndice: O processo de Build: Ant e Maven

    PRXIMO CAPTULO:

    Repare que o doInBackgroundno salva nada em atributos. O mtodo done

    obtm a lista de negcios a partir da chamada ao mtodo get. Isso feito para

    garantir thread-safety. Repare tambm que passamos a tabela como argumento no

    construtor, j que vamos precisar modific-la.

    Barra de progresso e outras possibilidades

    A classe SwingWorker traz ainda outros recursos mais avanados, como a

    capacidade de se implementar uma barra de progresso fazendo com que a

    thread em background notifique a thread do AWT sobre pequenos

    progressos feitos no seu processamento. Tudo de forma thread-safe e

    robusta.

    11.7 - EXERCCIOS: PESQUISANDO MAIS NA API

    1. Procure saber mais sobre o uso do SwingWorker nos tutoriais da Oracle.

    Esses tutoriais vm desde o tempo da Sun e trazem uma boa idia do que o Swing

    oferece aos desenvolvedores Java.

    2. Outro ponto interessante so aqueles em que a API em si no nos ajuda tanto

    quanto gostaramos.

    Felizmente, a comunidade do Java bastante forte e podemos tirar proveito disso!

    Procure, por exemplo, componentes open source que fazem abrir um widget de

    calendrio para escolhermos uma data.

    @Override protected void done() {

    NegociosTableModel model = new NegociosTableModel(get());

    tabela.setModel(model); }}

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-o-processo-de-build-ant-e-maven/

  • 14/7/2014 Apndice - Mais swing e recursos avanados - Laboratrio Java com Testes, XML e Design Patterns

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-mais-swing-e-recursos-avancados/#11-2-exercicios-opcionais-filtrando-por 12/13

    Apndice - Logging com Log4j

    Voc encontra a Caelum tambm em:

    Blog Caelum

    Cursos Online

    Facebook

    Newsletter

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-logging-com-log4j/http://blog.caelum.com.br/?utm_source=Apostila_HTML&utm_campaign=FJ-16&utm_medium=referralhttp://www.alura.com.br/http://facebook.com/caelumbrhttp://www.caelum.com.br/newsletter/?utm_source=Apostila_HTML&utm_campaign=FJ-16&utm_medium=referral

  • 14/7/2014 Apndice - Mais swing e recursos avanados - Laboratrio Java com Testes, XML e Design Patterns

    http://www.caelum.com.br/apostila-java-testes-xml-design-patterns/apendice-mais-swing-e-recursos-avancados/#11-2-exercicios-opcionais-filtrando-por 13/13

    Casa do Cdigo

    Twitter

    http://casadocodigo.com.br/?utm_source=Apostila_HTML&utm_campaign=FJ-16&utm_medium=referralhttp://twitter.com/caelum