Criando um menu dinâmico usando XML

 

A princípio este artigo dará uma idéia de como montar um menu usando uma estrutura de XML, é claro que existem outros métodos que não foram aqui abordados. Nos códigos apresentados abaixo eu usei um pouco do conceito de Reflexão.

 

Segue abaixo o código fonte de uma implementação simples, onde o XML contém os parâmetros e a estrutura do menu.

 

Este primeiro código irá buscar cada nodo da estrutura do XML.

 

//---- xmlJmenuBar.java

package Xml;

 

import Principal.OuvinteItemMenu;

import java.awt.Container;

import java.awt.event.ActionEvent;

import java.util.ArrayList;

import java.util.List;

import javax.swing.JCheckBoxMenuItem;

import javax.swing.JMenu;

import javax.swing.JMenuBar;

import javax.swing.JMenuItem;

import javax.swing.JRadioButtonMenuItem;

import org.w3c.dom.Attr;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

 

/**

 *

 * @author Chrystian  Toigo

 */

public class xmlJmenuBar extends JMenuBar {

 

    private Container   content;

 

    /** Creates a new instance of xmlJmenuBar */

    public xmlJmenuBar(Document document) {

        this.add(menuBarAusDocument(document));

    }

 

    public void actionPerformed(ActionEvent event) {

        String cmd = event.getActionCommand();

 

        if (cmd.equals("ende"))

            System.exit(0);

    }

 

    static public List getChildElements(Element element, String name) {

        List list = new ArrayList();

 

        if (element.hasChildNodes())

            for (Node node = element.getFirstChild(); node != null; node = node.getNextSibling())

                if (node.getNodeName().equals(name))

                    list.add(node);

 

        return list;

    }

 

    private JMenuItem itemAusElement(Element element) {

        String tagname = element.getNodeName();

 

        if (tagname.equals("menuBar")) {

            return menuAusElement(element);

        }

 

        if (tagname.equals("menuItem")) {

            JMenuItem   item;

            String      name    = getAttributeValue(element, "name"),

                        command = getAttributeValue(element, "command"),

                        type    = getAttributeValue(element, "type"),

                        classe  = getAttributeValue(element, "classe");

 

            if ("check".equals(type))                   // Checkbox

                item = new JCheckBoxMenuItem(name);

            else if ("radio".equals(type))

                item = new JRadioButtonMenuItem(name);  // Radio

            else

                item = new JMenuItem(name);             // normal

                if (classe.length() == 0) {

                    OuvinteItemMenu ouvinte = new OuvinteItemMenu(classe);

                    item.addActionListener(ouvinte);

                }

            if (command != null)

                item.setActionCommand(command);     // actionCommand setzen

 

            return item;

        }

        return null;

    }

 

    JMenuBar menuBarAusDocument(Document document) {

        JMenuBar    menuBar = new JMenuBar();

        List        menuList = getChildElements(document.getDocumentElement(),"menuBar");

        int         nMenus = menuList.size();

 

        for (int i = 0; i < nMenus; ++i) {

            JMenu menu = menuAusElement((Element)menuList.get(i));

            menuBar.add(menu);

        }

        return menuBar;

    }

 

    private JMenu menuAusElement(Element element) {

        NodeList    items  = element.getChildNodes();

        int         nItems = items.getLength();

        JMenu       menu   = new JMenu(getAttributeValue(element, "name"));

 

        for (int i = 0; i < nItems; ++i) {

            Node    node = items.item(i);

            if (node.getNodeType() == Node.ELEMENT_NODE)

                menu.add(itemAusElement((Element)node));

        }

 

        return menu;

    }

 

    static public String getAttributeValue(Element element, String name) {

        Attr attr = element.getAttributeNode(name);

        return attr != null ? attr.getValue() : null;

    }

}

Listagem 01. xmlJmenuBar.java

 

Estrutura do arquivo XML como irá ficar para que o programa funcione corretamente.

 

//-- implementacao do AccipiensMenu.xml -------------------------------------

<?xml version="1.0" encoding="UTF-8"?>

<AccipiensMenu>

     <menuBar name="Manutencao">

           <menuBar name="Cadastro">

                    <menuItem name="Cliente" classe="Principal.CadastroClientes"></menuItem>

           </menuBar>

           <menuItem name="Relatorios"></menuItem>

           <menuItem name="Consultas"></menuItem>

           <menuItem name="Miscelania"></menuItem>

     </menuBar>

     <menuBar name="Miscelania">

              <menuItem name="Teste"></menuItem>

              <menuItem name="Aqui"></menuItem>

              <menuItem name="Consegui"></menuItem>

     </menuBar>

</AccipiensMenu>

Listagem 02. AccipiensMenu.xml

 

Programa principal que irá chamar a classe que montará a estrutura do menu.

 

//----- jmenuWindow.java

package Principal;

 

import Utilities.jmenuBar;

import Xml.xmlJmenuBar;

import java.awt.BorderLayout;

import java.awt.Dimension;

import java.awt.Toolkit;

import java.awt.event.ActionEvent;  

import java.awt.event.ActionListener;  

import java.io.IOException;

import javax.swing.JDialog;

import javax.swing.JFrame;  

import javax.swing.JPanel;

import javax.swing.UIManager;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;

import org.xml.sax.SAXException;

 

/**

 *

 * @author Chrystian  Toigo

 */

public class jmenuWindow extends JFrame {

 

    private Dimension dimension  = Toolkit.getDefaultToolkit().getScreenSize();          

 

    /** Creates a new instance of jmenuWindow */

    public jmenuWindow() {

        initComponents();

    }

 

    private void initComponents() {

        DocumentBuilderFactory  factory = DocumentBuilderFactory.newInstance();

        DocumentBuilder         builder;

        Document                document;

 

        dimension.height -= 30;

        setSize(dimension.width, dimension.height);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        getContentPane().setLayout(new BorderLayout());

 

        try {

            builder = factory.newDocumentBuilder();

            document = builder.parse("C:/AccipiensMenu.xml");      // 1. Parameter ist Dateiname

            getContentPane().add(new xmlJmenuBar(document),  BorderLayout.NORTH);

        } catch (ParserConfigurationException ex) {

                 ex.printStackTrace();

        } catch (SAXException ex) {

                 ex.printStackTrace();

        } catch (IOException ex) {

                 ex.printStackTrace();

        }

 

   }

   

    public static void main(String[] args) {

 

      JDialog.setDefaultLookAndFeelDecorated(false);

      JFrame.setDefaultLookAndFeelDecorated(true);

      Toolkit.getDefaultToolkit().setDynamicLayout(true);

      System.setProperty("sun.awt.noerasebackground","true");

      UIManager.put("OptionPane.yesButtonText", "Sim");

      UIManager.put("OptionPane.noButtonText", "Não");

      UIManager.put("OptionPane.cancelButtonText", "Cancelar");

      UIManager.put("FileChooser.titleText", "Abrir");

      UIManager.put("FileChooser.cancelButtonText", "Cancelar");

      UIManager.put("FileChooser.cancelButtonToolTipText", "Cancelar a escolha do arquivo");

      UIManager.put("FileChooser.saveButtonText", "Salvar");

      UIManager.put("FileChooser.saveButtonToolTipText", "Salvar o arquivo selecionado");

      UIManager.put("FileChooser.openButtonText", "Abrir");

      UIManager.put("FileChooser.openButtonToolTipText", "Abrir o arquivo selecionado");

 

      try {

            UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());

      } catch (Exception exc) {

            System.err.println("Error loading L&F: " + exc);

      }

        new jmenuWindow().setVisible(true);

    }  

}

Listagem 03. jmenuWindow.java

 

Crie uma classe que será o ouvinte dos eventos não como uma classe interna anônima, mas uma classe separada. Dessa forma, para cada item de menu que for criada, irá criar um novo objeto para ouvir o evento.

 

//-----OuvinteItemMenu.java

package Principal;

 

import java.awt.event.ActionEvent;  

import java.awt.event.ActionListener;  

import javax.swing.JFrame;  

 

/**

 *

 * @author Chrystian  Toigo

 */

public class OuvinteItemMenu implements ActionListener {

 

    private String className = null;

 

    /** Creates a new instance of OuvinteItemMenu */

    public OuvinteItemMenu(String className) {  

        this.className = className;  

    }

 

    public void actionPerformed(ActionEvent e) {  

        Class classe = null;  

        try {  

            classe = Class.forName(this.className);  

            JFrame frame = (JFrame) classe.newInstance();  

            frame.setVisible(true);  

        } catch (Exception ex) {  

            ex.printStackTrace();  

        }  

    }  

}

Listagem 04. OuvinteItemMenu.java

 

Enfim a classe de cadastro de clientes.

 

//-----CadastroClientes.java

package Principal;

 

import javax.swing.JLabel;

 

/**

 *

 * @author  Chrystian  Toigo

 */

public class CadastroClientes extends javax.swing.JFrame {

   

    /** Creates new form CadastroClientes */

    public CadastroClientes() {

        initComponents();

    }

   

    /** This method is called from within the constructor to

     * initialize the form.

     * WARNING: Do NOT modify this code. The content of this method is

     * always regenerated by the Form Editor.

     */

    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents

    private void initComponents() {

        jTextField1 = new javax.swing.JTextField();

 

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jTextField1.setText("jTextField1");

 

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());

        getContentPane().setLayout(layout);

        layout.setHorizontalGroup(

            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)

            .add(layout.createSequentialGroup()

                .add(66, 66, 66)

                .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 396, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)

                .addContainerGap(108, Short.MAX_VALUE))

        );

        layout.setVerticalGroup(

            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)

            .add(layout.createSequentialGroup()

                .add(30, 30, 30)

                .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)

                .addContainerGap(264, Short.MAX_VALUE))

        );

        pack();

    }// </editor-fold>//GEN-END:initComponents

   

    /**

     * @param args the command line arguments

     */

    public static void main(String args[]) {

        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {

                new CadastroClientes().setVisible(true);

            }

        });

    }

   

    // Variables declaration - do not modify//GEN-BEGIN:variables

    private javax.swing.JTextField jTextField1;

    // End of variables declaration//GEN-END:variables

   

}

Listagem 05. CadastroClientes.java