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