001/*
002 * jPOS Project [http://jpos.org]
003 * Copyright (C) 2000-2026 jPOS Software SRL
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.jpos.ui.factory;
020
021import org.jdom2.Element;
022import org.jpos.ui.UI;
023import org.jpos.ui.UIFactory;
024
025import javax.swing.*;
026import javax.swing.event.TreeSelectionEvent;
027import javax.swing.event.TreeSelectionListener;
028import javax.swing.tree.DefaultMutableTreeNode;
029import java.awt.*;
030import java.awt.event.ActionEvent;
031import java.awt.event.ActionListener;
032import java.util.HashMap;
033import java.util.Iterator;
034import java.util.Map;
035import java.util.StringTokenizer;
036
037/**
038 * UIFactory that builds a Swing {@link JTree} from a nested {@code <tree>}/{@code <node>} configuration.
039 *
040 * @author Alejandro Revilla
041 *
042 * Creates a JTree
043 * i.e:
044 * <pre>
045 *  &lt;tree&gt;
046 *   &lt;node&gt;
047 *    ...
048 *   &lt;/node&gt;
049 *   ...
050 *   ...
051 *   &lt;node&gt;
052 *    ...
053 *   &lt;/node&gt;
054 *  &lt;/tree&gt;
055 * </pre>
056 * @see org.jpos.ui.UIFactory
057 */
058@SuppressWarnings("unchecked")
059public class JTreeFactory implements UIFactory {
060    /** Default constructor for {@link UIFactory} discovery. */
061    public JTreeFactory() {}
062    public JComponent create (UI ui, Element e) {
063        final UI parentUI = ui;
064        final Map map = new HashMap ();
065        final JTree tree = new JTree (getNode (e, map));
066        String font = e.getAttributeValue ("font");
067        if (font != null) 
068            tree.setFont (Font.decode (font));
069        tree.setRootVisible (e.getTextTrim().length() > 0);
070
071        tree.addTreeSelectionListener (
072            new TreeSelectionListener() {
073                public void valueChanged(TreeSelectionEvent evt) {
074                    DefaultMutableTreeNode node = 
075                        (DefaultMutableTreeNode) 
076                            tree.getLastSelectedPathComponent();
077                    if (node != null) {
078                        String s = (String) map.get (node);
079                        if (s != null) {
080                            StringTokenizer st = new StringTokenizer (s);
081                            String action  = st.nextToken ();
082                            String command = null;
083                            if (st.hasMoreTokens ())
084                                command = st.nextToken ();
085
086                            ActionListener al = 
087                                (ActionListener) parentUI.get(action);
088                            if (al != null) {
089                                al.actionPerformed (
090                                    new ActionEvent (node, 0, command)
091                                );
092                            }
093                            // System.out.println ("ACTION: " + action);
094                            // System.out.println ("COMMAND: " + command);
095                        }
096                    }
097                }
098            }
099        );
100        return tree;
101    }
102
103    private DefaultMutableTreeNode getNode (Element e, Map map) { 
104        DefaultMutableTreeNode node = new DefaultMutableTreeNode (
105                e.getTextTrim()
106        );
107        String action = e.getAttributeValue ("action");
108        if (action != null) {
109            String command = e.getAttributeValue ("command");
110            if (command != null)
111                action = action + " " + command;
112
113            map.put (node, action);
114        }
115        Iterator iter = e.getChildren().iterator();
116        while (iter.hasNext()) {
117            node.add (getNode ((Element) iter.next (), map));
118        }
119        return node;
120    }
121}
122