Utilizando menus pop-up em aplicações Swing

 

O objetivo deste artigo é demonstrar a utilização de menus pop-up Java em aplicações Swing. Para auxílio será utilizada uma mini-aplicação contendo três painéis com diferentes menus.

 

A classe JPopupMenu

Em aplicações Swing, a classe padrão para utilização de menus pop-up é a JPopupMenu, do pacote javax.swing.*. Diferente de JMenu, essa classe permite ao desenvolvedor disponibilizar menus referentes ao contexto, tanto do frame quanto do painel, sendo possível, até mesmo configurar mais de um menu, ativados por combinações no teclado ou diferentes botões do mouse.

Suas propriedades fazem com que um jpopupmenu tenha capacidades semelhantes de adição de componentes as de um jmenu (javax.swing.JMenu). Seus itens, por exemplo, são jmenuitems (javax.swing.JMenuItem), e têm seus eventos adicionados da mesma forma.

 

Outra possibilidade interessante é também a adição de radiobuttons, porém, com uma classe específica, JRadioButtonMenuItem.

 

Mini-aplicação com menus pop-up

Será montada agora uma pequena interface contendo painéis (javax.swing.JPanel); cada um deles com seu menu pop-up específico, para exemplificar a possibilidade dos mesmos estarem relacionados ao contexto do local onde o usuário irá clicar.

 

A Listagem 01 representa a classe AbstractJPopupPanel, uma classe abstrata que permitirá, posteriormente, criar cada painel de acordo com suas funcionalidades.

 

//imports

public abstract class AbstractJPopupPanel extends JPanel implements MouseListener{

       

        private JPopupMenu jPopupMenu;

        private Random random = new Random();

       

        public AbstractJPopupPanel(){

              

               setBackground(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));

              

               jPopupMenu = new JPopupMenu();

              

               String[] menuItems = getMenuItems();

               for (int i = 0; i < menuItems.length; i++) {

                       JMenuItem menuItem = new JMenuItem(menuItems[i]);

                       jPopupMenu.add(menuItem);

               }

                              

               super.addMouseListener(this);

               super.setPreferredSize(new Dimension(100, 300));

        }

       

        public void mouseClicked(MouseEvent e){}

        public void mouseEntered(MouseEvent e){}

        public void mouseExited(MouseEvent e){}

        public void mouseReleased(MouseEvent e){}

        public void mousePressed(MouseEvent event){

               if(event.getButton() == event.BUTTON3){

                       jPopupMenu.show(this, event.getX(), event.getY());

               }

        }

 

        public abstract String[] getMenuItems();

}

Listagem 01

 

A classe acima herda JPanel e implementa MouseListener, para permitir configurar o menu pop-up ser aberto com um clique no botão direito do mouse.

 

Inicialmente declara-se uma instância de JPopupMenu, que é o menu pop-up referente ao tema do painel. Em seguida é criada também uma instância de Random (java.util.*), mas que nada tem a ver com o tema do artigo. Servirá apenas para sortear uma cor de fundo para o painél (isso permitirá diferenciá-los no momento da execução).

 

Dentro do construtor, o método setBackground irá receber um Color (java.awt.Color) aleatório, visto que se utilizará a instância de Random para sortear três valores representando suas propriedades RGB.

 

Pulando parte do código para fazer sentido o for após a instanciação de JPopupMenu, como a classe é abstrata, ela requer que suas classes-filhas implementem getMenuItems, que serão os itens do menu pop-up referente ao seu contexto.

 

(Dificilmente se encontrará aplicações que fazem uso de um método para receber os itens do menu dessa forma, mas ele está dessa maneira afim de focar os menus e visualizá-los.)

 

Voltando ao for no construtor: itera-se por menuItems para adicionar JMenuItems ao JPopupMenu. Para o exemplo não será configurado evento algum, mas que fique claro que isso se faz da mesma forma como adição de eventos a componentes.

 

E finalmente, nas implementações dos métodos de MouseListener, será utilizado apenas o evento mousePressed, onde testa-se qual botão do mouse foi clicado, caso seja o botão direito (event.Button3), chama-se o método show de JPopupMenu.

 

Repare que os métodos show(), e show(boolean b) são marcados como deprecated, e recomenda-se não utilizá-los. Logo, utilizou-se o método show(Component invoker, int x, int y). This, foi passado como primeiro argumento por se tratar de uma classe que herda JPanel, e em seguida, foram retiradas as posições x e y do clique do mouse para que o menu seja aberto ao lado do ponteiro, mas que fique claro que uma posição fixa para ele pode ser definida.

 

As listagens 02, 03 e 04 representam classes que herdam AbstractJPopupPanel e são os painéis com diferentes menus pop-up a serem adicionados à interface posteriormente.

 

package br.com.jm.popupmenus;

 

public class JPopupBands extends AbstractJPopupPanel{

        public String[] getMenuItems() {

               return new String[]{

                       "KISS", "Metallica", "Pink Floyd", "Dream Theater", "Geronimo Jackson"

               };

        }

}

Listagem 02

 

package br.com.jm.popupmenus;

 

public class JPopupColors extends AbstractJPopupPanel{

        public String[] getMenuItems() {

               return new String[]{

                       "Amarelo", "Azul", "Branco", "Preto", "Vermelho"

               };

        }

}

Listagem 03

 

package br.com.jm.popupmenus;

 

public class JPopupTeams extends AbstractJPopupPanel{

        public String[] getMenuItems() {

               return new String[]{

                       "Flamengo", "Vasco", "Fluminense", "Botafogo", "São Paulo", "Tupi"

               };

        }

}

Listagem 04

 

Todas as três “filhas” de AbstractJPopupPanel implementam getMenuItems e retornam diferentes matrizes de Strings, cada uma de acordo com o tema de seu painel.

 

Ao executar a aplicação, serão gerados três painéis com cores distintas e clicando em cada um com o botão direito, aparecerão menus pop-ups de acordo com o tema representado, demonstrando o foco principal do artigo que é exibir estes menus de acordo com o local (ou painel ou posição dentro do painel) onde o usuário deseja abri-lo.

 

Concluindo, os JPopupMenus são mais poderosos do que visto neste artigo e explorar todas as suas funcionalidades e capacidades será de grande importância para qualquer aplicação Swing.

 

Um grande abraço e até a próxima!

Adriano Castro