KeyConfigure.java
上传用户:xiekaiwei
上传日期:2015-07-04
资源大小:620k
文件大小:27k
源码类别:

Telnet客户端

开发平台:

Java

  1. /**
  2.  * Title: KeyConfigure
  3.  * Copyright:   Copyright (c) 2001
  4.  * Company:
  5.  * @author  Kenneth J. Pouncey
  6.  * @version 0.4
  7.  *
  8.  * Description:
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2, or (at your option)
  13.  * any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILreITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this software; see the file COPYING.  If not, write to
  22.  * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  23.  * Boston, MA 02111-1307 USA
  24.  *
  25.  */
  26. package org.tn5250j.keyboard.configure;
  27. import java.awt.*;
  28. import javax.swing.*;
  29. import javax.swing.event.*;
  30. import java.awt.event.*;
  31. import java.util.*;
  32. import java.io.*;
  33. import java.text.*;
  34. import java.lang.reflect.*;
  35. import org.tn5250j.encoding.CodePage;
  36. import org.tn5250j.scripting.InterpreterDriverManager;
  37. import org.tn5250j.TN5250jConstants;
  38. import org.tn5250j.keyboard.KeyMapper;
  39. import org.tn5250j.keyboard.KeyStroker;
  40. import org.tn5250j.tools.LangTool;
  41. import org.tn5250j.tools.AlignLayout;
  42. import org.tn5250j.tools.system.OperatingSystem;
  43. public class KeyConfigure extends JDialog implements ActionListener,
  44.                                                          TN5250jConstants {
  45.    Properties props;
  46.    JPanel keyPanel = new JPanel();
  47.    JPanel options = new JPanel();
  48.    JTextArea strokeDesc = new JTextArea();
  49.    JTextArea strokeDescAlt = new JTextArea();
  50.    JLabel strokeLocation = new JLabel();
  51.    JLabel strokeLocationAlt = new JLabel();
  52.    JList functions;
  53.    KeyMapper mapper;
  54.    JFrame jf = null;
  55.    JDialog dialog;
  56.    boolean mods;
  57.    private String[] macrosList;
  58.    DefaultListModel lm = new DefaultListModel();
  59.    private boolean macros;
  60.    private boolean special;
  61.    private CodePage codePage;
  62.    private boolean isLinux;
  63.    private boolean isAltGr;
  64.    private boolean altKey;
  65.    public KeyConfigure(Frame parent, String[] macros, CodePage cp) {
  66.       super(parent);
  67.       codePage = cp;
  68.       macrosList = macros;
  69.       if (OperatingSystem.isUnix() && !OperatingSystem.isMacOS()) {
  70.          isLinux = true;
  71.       }
  72.       try {
  73.          jbInit();
  74.          pack();
  75.       }
  76.       catch(Exception ex) {
  77.          ex.printStackTrace();
  78.       }
  79.    }
  80.    void jbInit() throws Exception {
  81.       // create some reusable borders and layouts
  82.       BorderLayout borderLayout = new BorderLayout();
  83.       mapper = new KeyMapper();
  84.       KeyMapper.init();
  85.       keyPanel.setLayout(borderLayout);
  86.       keyPanel.add(createFunctionsPanel(),BorderLayout.WEST);
  87.       keyPanel.add(createMappingPanel(),BorderLayout.CENTER);
  88.       // add the panels to our dialog
  89.       getContentPane().add(keyPanel,BorderLayout.CENTER);
  90.       getContentPane().add(options, BorderLayout.SOUTH);
  91.       // add option buttons to options panel
  92.       addOptButton(LangTool.getString("key.labelDone","Done"),"DONE",options,true);
  93.       this.setModal(true);
  94.       this.setTitle(LangTool.getString("key.title"));
  95.       // pack it and center it on the screen
  96.       pack();
  97.       Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
  98.       Dimension frameSize = getSize();
  99.       if (frameSize.height > screenSize.height)
  100.          frameSize.height = screenSize.height;
  101.       if (frameSize.width > screenSize.width)
  102.          frameSize.width = screenSize.width;
  103.       setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
  104.       // now show the world what we can do
  105.       setVisible(true);
  106.    }
  107.    private JPanel createFunctionsPanel() {
  108.       functions = new JList(lm);
  109.       // add list selection listener to our functions list so that we
  110.       //   can display the mapped key(s) to the function when a new
  111.       //   function is selected.
  112.       functions.addListSelectionListener(new ListSelectionListener() {
  113.          public void valueChanged(ListSelectionEvent lse) {
  114.             if (!lse.getValueIsAdjusting()) {
  115.                setKeyDescription(functions.getSelectedIndex());
  116.             }
  117.          }
  118.       });
  119.       loadList(LangTool.getString("key.labelKeys"));
  120.       functions.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  121.       JScrollPane functionsScroll = new JScrollPane(functions);
  122.       JPanel fp = new JPanel();
  123.       JComboBox whichKeys = new JComboBox();
  124.       whichKeys.addItem(LangTool.getString("key.labelKeys"));
  125.       whichKeys.addItem(LangTool.getString("key.labelMacros"));
  126.       whichKeys.addItem(LangTool.getString("key.labelSpecial"));
  127.       whichKeys.addActionListener(new ActionListener() {
  128.             public void actionPerformed(ActionEvent e) {
  129.                 JComboBox cb = (JComboBox)e.getSource();
  130.                 loadList((String)cb.getSelectedItem());
  131.             }
  132.         });
  133.       fp.setBorder(BorderFactory.createTitledBorder(
  134.                                     LangTool.getString("key.labelDesc")));
  135.       fp.setLayout(new BoxLayout(fp,BoxLayout.Y_AXIS));
  136.       fp.add(whichKeys);
  137.       fp.add(functionsScroll);
  138.       return fp;
  139.    }
  140.    private JPanel createMappingPanel () {
  141.       // set the descriptions defaults
  142.       strokeDesc.setColumns(30);
  143.       strokeDesc.setBackground(functions.getBackground());
  144.       strokeDesc.setEditable(false);
  145.       strokeDescAlt.setColumns(30);
  146.       strokeDescAlt.setBackground(functions.getBackground());
  147.       strokeDescAlt.setEditable(false);
  148.       // create main panel
  149.       JPanel dp = new JPanel();
  150.       dp.setBorder(BorderFactory.createTitledBorder(
  151.                                     LangTool.getString("key.labelMapTo")));
  152.       dp.setLayout(new BoxLayout(dp,BoxLayout.Y_AXIS));
  153.       // create primary map panel
  154.       JPanel primeKeyMapPanel = new JPanel();
  155.       primeKeyMapPanel.setLayout(new BorderLayout());
  156.       // create key description panel
  157.       JPanel primeKeyPanel = new JPanel();
  158.       primeKeyPanel.setLayout(new AlignLayout(3,5,5));
  159.       primeKeyPanel.add(strokeDesc);
  160.       // add the option buttons
  161.       addOptButton(LangTool.getString("key.labelMap","Map Key"),"MAP-Prime",
  162.                                        primeKeyPanel,true);
  163.       addOptButton(LangTool.getString("key.labelRemove","Remove"),"REMOVE-Prime",
  164.                                        primeKeyPanel,true);
  165.       // add the description to primary map panel
  166.       primeKeyMapPanel.add(primeKeyPanel,BorderLayout.NORTH);
  167.       // create the location description panel
  168.       JPanel loc1 = new JPanel();
  169.       loc1.setLayout(new BorderLayout());
  170.       loc1.add(strokeLocation,BorderLayout.NORTH);
  171.       // add the location description panel to the primary map panel
  172.       primeKeyMapPanel.add(loc1,BorderLayout.CENTER);
  173.       // create the alternate map panel
  174.       JPanel altKeyMapPanel = new JPanel();
  175.       altKeyMapPanel.setLayout(new BorderLayout());
  176.       // create the alternate description panel
  177.       JPanel altKeyPanel = new JPanel();
  178.       altKeyPanel.setLayout(new AlignLayout(3,5,5));
  179.       altKeyPanel.add(strokeDescAlt);
  180.       // add the options to the description panel
  181.       addOptButton(LangTool.getString("key.labelMap","Map Key"),"MAP-Alt",
  182.                                        altKeyPanel,true);
  183.       addOptButton(LangTool.getString("key.labelRemove","Remove"),"REMOVE-Alt",
  184.                                        altKeyPanel,true);
  185.       // add the description panel to the alternate map panel
  186.       altKeyMapPanel.add(altKeyPanel,BorderLayout.NORTH);
  187.       // create the alternate location description panel
  188.       JPanel locAlt = new JPanel();
  189.       locAlt.setLayout(new BorderLayout());
  190.       locAlt.add(strokeLocationAlt,BorderLayout.NORTH);
  191.       // add the alternate location description panel to alternate map panel
  192.       altKeyMapPanel.add(locAlt,BorderLayout.CENTER);
  193.       // add the map panels for display
  194.       dp.add(primeKeyMapPanel);
  195.       dp.add(altKeyMapPanel);
  196.       return dp;
  197.    }
  198.    private void setKeyDescription(int index) {
  199.       // This try and catch is to fix a problem in JDK1.4-betas
  200.       try {
  201.          if (!macros && !special) {
  202.             KeyDescription kd = (KeyDescription)lm.getElementAt(index);
  203.             setKeyInformation(mnemonicData[kd.getIndex()]);
  204.          }
  205.          else {
  206.             if (macros) {
  207.                Object o = lm.getElementAt(index);
  208.                if (o instanceof String) {
  209.                   System.out.println((String)o);
  210.                   setKeyInformation((String)o);
  211.                }
  212.                else
  213.                   if (o instanceof Macro) {
  214.                      Macro m = (Macro)o;
  215.                      setKeyInformation(m.getFullName());
  216.                   }
  217.             }
  218.             if (special) {
  219.                System.out.println((String)lm.getElementAt(index));
  220.                String k = parseSpecialCharacter((String)lm.getElementAt(index));
  221.                setKeyInformation(k);
  222.             }
  223.          }
  224.       }
  225.       catch (ArrayIndexOutOfBoundsException ar) {
  226.          System.out.println("ar at index " + index + " - " + ar.getMessage());
  227.       }
  228.    }
  229.    private void setKeyInformation(String keyDesc) {
  230.       if (keyDesc.endsWith(KeyStroker.altSuffix)) {
  231.          keyDesc = keyDesc.substring(0,keyDesc.indexOf(KeyStroker.altSuffix));
  232.       }
  233.       strokeDesc.setText(KeyMapper.getKeyStrokeDesc(keyDesc));
  234.       strokeDescAlt.setText(KeyMapper.getKeyStrokeDesc(keyDesc +
  235.                               KeyStroker.altSuffix));
  236.       strokeLocation.setText(getLocationDesc(keyDesc));
  237.       strokeLocationAlt.setText(getLocationDesc(keyDesc + KeyStroker.altSuffix));
  238.    }
  239.    private String getLocationDesc(String keyDesc) {
  240.       String locStr = LangTool.getString("key.labelLocUnknown");
  241.       if (KeyMapper.isKeyStrokeDefined(keyDesc)) {
  242.          switch (KeyMapper.getKeyStroker(keyDesc).getLocation()) {
  243.             case KeyStroker.KEY_LOCATION_LEFT:
  244.                locStr = LangTool.getString("key.labelLocLeft");
  245.                break;
  246.             case KeyStroker.KEY_LOCATION_RIGHT:
  247.                locStr = LangTool.getString("key.labelLocRight");
  248.                break;
  249.             case KeyStroker.KEY_LOCATION_STANDARD:
  250.                locStr = LangTool.getString("key.labelLocStandard");
  251.                break;
  252.             case KeyStroker.KEY_LOCATION_NUMPAD:
  253.                locStr = LangTool.getString("key.labelLocNumPad");
  254.                break;
  255.          }
  256.       }
  257.       return locStr;
  258.    }
  259.    private String parseSpecialCharacter(String value) {
  260.       StringTokenizer tokenizer = new StringTokenizer(value, "-");
  261.       if (tokenizer.hasMoreTokens()) {
  262.          String first = tokenizer.nextToken();
  263.          return String.valueOf(value.charAt(first.length() + 2));
  264.       }
  265.       return "";
  266.    }
  267.    private void loadList(String which) {
  268.       lm.clear();
  269.       lm.removeAllElements();
  270.       if (which.equals(LangTool.getString("key.labelKeys"))) {
  271.          Vector lk = new Vector(mnemonicData.length);
  272.          for (int x = 0; x < mnemonicData.length; x++) {
  273.             lk.addElement(new KeyDescription(LangTool.getString("key."+mnemonicData[x]),x));
  274.          }
  275.          Collections.sort(lk,new KeyDescriptionCompare());
  276.          for (int x = 0; x < mnemonicData.length; x++) {
  277.             lm.addElement(lk.get(x));
  278.          }
  279.          macros = false;
  280.          special = false;
  281.       }
  282.       else {
  283.          if (which.equals(LangTool.getString("key.labelMacros"))) {
  284.             Vector macrosVector = new Vector();
  285.             if (macrosList != null)
  286.                for (int x = 0; x < macrosList.length; x++) {
  287.                   macrosVector.add(macrosList[x]);
  288.                }
  289.             scriptDir("scripts",macrosVector);
  290.             loadListModel(lm,macrosVector,null,0);
  291.             macros = true;
  292.             special = false;
  293.          }
  294.          else {
  295.             // we will use a collator here so that we can take advantage of the locales
  296.             Collator collator = Collator.getInstance();
  297.             CollationKey key = null;
  298.             StringBuffer sb = new StringBuffer();
  299.             Set set = new TreeSet();
  300.             for (int x =0;x < 256; x++) {
  301.                char c = codePage.ebcdic2uni(x);
  302.                char ac = codePage.ebcdic2uni(x);
  303.                if (!Character.isISOControl(c)) {
  304.                   sb.setLength(0);
  305.                   if (Integer.toHexString(ac).length() == 1){
  306.                      sb.append("0x0" + Integer.toHexString(ac).toUpperCase());
  307.                   }
  308.                   else {
  309.                      sb.append("0x" + Integer.toHexString(ac).toUpperCase());
  310.                   }
  311.                   sb.append(" - " + c + " - " + getUnicodeString(c));
  312.                   key = collator.getCollationKey(sb.toString());
  313.                   set.add(key);
  314.                }
  315.             }
  316.             Iterator iterator = set.iterator();
  317.             while (iterator.hasNext()) {
  318.                CollationKey keyc = (CollationKey)iterator.next();
  319.                lm.addElement(keyc.getSourceString());
  320.             }
  321.             macros = false;
  322.             special = true;
  323.          }
  324.       }
  325.       if (!lm.isEmpty())
  326.          functions.setSelectedIndex(0);
  327.    }
  328.    private String getUnicodeString(char c) {
  329.       String s = Integer.toHexString(c).toUpperCase();
  330.       int len = s.length();
  331.       switch (len) {
  332.          case 2:
  333.             s = "'\u00" + s + "'";
  334.             break;
  335.          case 3:
  336.             s = "'\u0" + s + "'";
  337.             break;
  338.          default:
  339.             s = "'\u" + s + "'";
  340.       }
  341.       return s;
  342.    }
  343.    private JButton addOptButton(String text,
  344.                               String ac,
  345.                               Container container,
  346.                               boolean enabled) {
  347.       JButton button = new JButton(text);
  348.       button.setEnabled(enabled);
  349.       button.setActionCommand(ac);
  350.       button.addActionListener(this);
  351.       button.setAlignmentX(Component.CENTER_ALIGNMENT);
  352.       container.add(button);
  353.       return button;
  354.    }
  355.    public void actionPerformed(ActionEvent e) {
  356.       if (e.getActionCommand().equals("DONE")) {
  357.          if (mods) {
  358.             KeyMapper.saveKeyMap();
  359.             KeyMapper.fireKeyChangeEvent();
  360.          }
  361.          setVisible(false);
  362.       }
  363.       if (e.getActionCommand().equals("MAP")) {
  364.          mapIt();
  365.       }
  366.       if (e.getActionCommand().equals("REMOVE")) {
  367.          removeIt();
  368.       }
  369.       if (e.getActionCommand().equals("MAP-Prime")) {
  370.          altKey = false;
  371.          mapIt();
  372.       }
  373.       if (e.getActionCommand().equals("REMOVE-Prime")) {
  374.          altKey = false;
  375.          removeIt();
  376.       }
  377.       if (e.getActionCommand().equals("MAP-Alt")) {
  378.          altKey = true;
  379.          mapIt();
  380.       }
  381.       if (e.getActionCommand().equals("REMOVE-Alt")) {
  382.          altKey = true;
  383.          removeIt();
  384.       }
  385.    }
  386.    private void mapIt() {
  387.       Object[]      message = new Object[1];
  388.       JPanel kgp = new JPanel();
  389.       final KeyGetterInterface kg = getMeAKeyProcessor();
  390.       kg.setForeground(Color.blue);
  391.       message[0] = kgp;
  392.       String function;
  393.       if (functions.getSelectedValue() instanceof String)
  394.          function = (String)functions.getSelectedValue();
  395.       else
  396.          if (functions.getSelectedValue() instanceof Macro) {
  397.             function = ((Macro)functions.getSelectedValue()).toString();
  398.          }
  399.          else
  400.             function = ((KeyDescription)functions.getSelectedValue()).toString();
  401.       kg.setText(LangTool.getString("key.labelMessage") +
  402.                         function);
  403.       kgp.add(kg);
  404.       String[] options = new String[1];
  405.       options[0] = LangTool.getString("key.labelClose");
  406.       JOptionPane opain = new JOptionPane(message,
  407.                         JOptionPane.PLAIN_MESSAGE,
  408.                         JOptionPane.DEFAULT_OPTION,        // option type
  409.                         null,
  410.                         options,
  411.                         options[0]);
  412.       dialog = opain.createDialog(this, getTitle());
  413.       kg.setDialog(dialog);
  414.       // add window listener to the dialog so that we can place focus on the
  415.       //   key getter label instead of default and set the new key value when
  416.       //   the window is closed.
  417.       dialog.addWindowListener(new WindowAdapter() {
  418.          boolean gotFocus = false;
  419.          public void windowClosed(WindowEvent we) {
  420.             if (isAvailable(kg.keyevent))
  421.                setNewKeyStrokes(kg.keyevent);
  422.          }
  423.          public void windowActivated(WindowEvent we) {
  424.             // Once window gets focus, set initial focus to our KeyGetter
  425.             //    component
  426.             if (!gotFocus) {
  427.                kg.grabFocus();
  428.                gotFocus = true;
  429.             }
  430.          }
  431.       });
  432.       dialog.setVisible(true);
  433.    }
  434.    private boolean isAvailable(KeyEvent ke) {
  435.       boolean exists = true;
  436.       if (isLinux) {
  437.           exists = KeyMapper.isKeyStrokeDefined(ke,isAltGr);
  438.       }
  439.       else {
  440.          exists = KeyMapper.isKeyStrokeDefined(ke);
  441.       }
  442.       if (exists) {
  443.          Object[] args = {getKeyDescription(ke)};
  444.          int result = JOptionPane.showConfirmDialog(this,
  445.                      LangTool.messageFormat("messages.mapKeyWarning",args),
  446.                      LangTool.getString("key.labelKeyExists"),
  447.                      JOptionPane.YES_NO_OPTION,
  448.                      JOptionPane.WARNING_MESSAGE);
  449.          if (result == JOptionPane.YES_OPTION)
  450.             return true;
  451.          else
  452.             return false;
  453.       }
  454.       return !exists;
  455.    }
  456.    private String getKeyDescription(KeyEvent ke) {
  457.       String desc;
  458.       if (isLinux)
  459.          desc = KeyMapper.getKeyStrokeMnemonic(ke,isAltGr);
  460.       else
  461.          desc = KeyMapper.getKeyStrokeMnemonic(ke,isAltGr);
  462.       if (desc != null && desc.length() > 1 && desc.startsWith("["))
  463.          desc = LangTool.getString("key."+ desc);
  464.       return desc;
  465.    }
  466.    private KeyGetterInterface getMeAKeyProcessor() {
  467.       ClassLoader loader = KeyConfigure.class.getClassLoader();
  468.       if (loader == null)
  469.          loader = ClassLoader.getSystemClassLoader();
  470.       Class       keyProcessorClass;
  471.       Constructor keyProcessorConstructor;
  472.       try {
  473.          String className = "org.tn5250j.keyboard.configure.KeyGetter";
  474.          if (!OperatingSystem.hasJava14())
  475.             className += "13";
  476.          keyProcessorClass = loader.loadClass(className);
  477.          keyProcessorConstructor = keyProcessorClass.getConstructor(null);
  478.          Object obj = keyProcessorConstructor.newInstance(null);
  479.          return (KeyGetterInterface)obj;
  480.       }
  481.       catch (Throwable t) {
  482.       }
  483.       return new KeyGetter13();
  484.    }
  485.    private void removeIt() {
  486.       if (!macros && !special) {
  487.          int index = ((KeyDescription)functions.getSelectedValue()).getIndex();
  488.          String function = mnemonicData[index];
  489.          if (altKey)
  490.             function += KeyStroker.altSuffix;
  491.          KeyMapper.removeKeyStroke(function);
  492.          setKeyInformation(function);
  493.       }
  494.       else {
  495.          if (macros) {
  496.             Object o = functions.getSelectedValue();
  497.             String name;
  498.             if (o instanceof Macro) {
  499.                name = ((Macro)o).getFullName();
  500.             }
  501.             else {
  502.                name = (String)o;
  503.             }
  504.             if (altKey)
  505.                name += KeyStroker.altSuffix;
  506.             KeyMapper.removeKeyStroke(name);
  507.             setKeyInformation(name);
  508.          }
  509.          if (special) {
  510.             String k = "";
  511.             k += ((String)functions.getSelectedValue()).charAt(7);
  512.             if (altKey)
  513.                k += KeyStroker.altSuffix;
  514.             KeyMapper.removeKeyStroke(k);
  515.             setKeyInformation(k);
  516.          }
  517.       }
  518.       mods = true;
  519.    }
  520.    private void setNewKeyStrokes(KeyEvent ke) {
  521.       if (!macros && !special) {
  522.          int index = ((KeyDescription)functions.getSelectedValue()).getIndex();
  523.          String stroke = mnemonicData[index];
  524.          if (altKey)
  525.             stroke += KeyStroker.altSuffix;
  526.          if (isLinux) {
  527.             KeyMapper.setKeyStroke(stroke,ke,isAltGr);
  528.          }
  529.          else {
  530.             KeyMapper.setKeyStroke(stroke,ke);
  531.          }
  532.          setKeyInformation(stroke);
  533.       }
  534.       else {
  535.          if (macros) {
  536.             Object o = functions.getSelectedValue();
  537.             String macro;
  538.             if (o instanceof Macro)
  539.                macro = ((Macro)o).getFullName();
  540.             else
  541.                macro = (String)o;
  542.             if (altKey)
  543.                macro += KeyStroker.altSuffix;
  544.             System.out.println(macro);
  545.             if (isLinux)
  546.                KeyMapper.setKeyStroke(macro,ke,isAltGr);
  547.             else
  548.                KeyMapper.setKeyStroke(macro,ke);
  549.             setKeyInformation(macro);
  550.          }
  551.          if (special) {
  552.             System.out.println((String)functions.getSelectedValue());
  553.             String k = parseSpecialCharacter((String)functions.getSelectedValue());
  554.             if (altKey)
  555.                k += KeyStroker.altSuffix;
  556.             KeyMapper.removeKeyStroke(k);
  557.             if (isLinux) {
  558.                KeyMapper.setKeyStroke(k,ke,isAltGr);
  559.             }
  560.             else {
  561.                KeyMapper.setKeyStroke(k,ke);
  562.             }
  563.             setKeyInformation(k);
  564.          }
  565.       }
  566.       mods = true;
  567.    }
  568.    private static class KeyDescriptionCompare implements Comparator {
  569.       public int compare(Object one, Object two) {
  570.          String s1 = one.toString();
  571.          String s2 = two.toString();
  572.          return s1.compareToIgnoreCase(s2);
  573.       }
  574.    }
  575.    private class KeyDescription {
  576.       private int index;
  577.       private String text;
  578.       public KeyDescription(String text,int index) {
  579.          this.text = text;
  580.          this.index = index;
  581.       }
  582.       public String toString() {
  583.          return text;
  584.       }
  585.       public int getIndex() {
  586.          return index;
  587.       }
  588.    }
  589.    public static void scriptDir(String pathName, Vector scripts) {
  590.       File root = new File(pathName);
  591.       try {
  592.          loadScripts(scripts,root.getCanonicalPath(),root);
  593.       }
  594.       catch (IOException ioe) {
  595.          System.out.println(ioe.getMessage());
  596.       }
  597.    }
  598.    /**
  599.     * Recursively read the scripts directory and add them to our macros vector
  600.     *    holding area
  601.     *
  602.     * @param vector
  603.     * @param path
  604.     * @param directory
  605.     */
  606.    private static void loadScripts(Vector vector,
  607.                                     String path,
  608.                                     File directory) {
  609.       Macro macro;
  610.       File[] macroFiles = directory.listFiles();
  611.       if(macroFiles == null || macroFiles.length == 0)
  612.          return;
  613.       Arrays.sort(macroFiles,new MacroCompare());
  614.       for(int i = 0; i < macroFiles.length; i++) {
  615.          File file = macroFiles[i];
  616.          String fileName = file.getName();
  617.          if(file.isHidden()) {
  618.             /* do nothing! */
  619.             continue;
  620.          }
  621.          else if(file.isDirectory()) {
  622.             Vector subvector = new Vector();
  623.             subvector.addElement(fileName.replace('_',' '));
  624.             loadScripts(subvector,path + fileName + '/',file);
  625.             // if we do not want empty directories to show up uncomment this
  626.             //    line.  It is uncommented here.
  627.             if(subvector.size() != 1)
  628.                vector.addElement(subvector);
  629.          }
  630.          else {
  631.             if (InterpreterDriverManager.isScriptSupported(fileName)) {
  632.                String fn = fileName.replace('_',' ');
  633.                int index = fn.lastIndexOf('.');
  634.                if (index > 0) {
  635.                   fn = fn.substring(0,index);
  636.                }
  637.                macro = new Macro (fn, file.getAbsolutePath(),fileName);
  638.                vector.addElement(macro);
  639.             }
  640.          }
  641.       }
  642.    }
  643.    /**
  644.     * Load the ListModel with the scripts from the vector of macros provided
  645.     *
  646.     * @param menu
  647.     * @param vector
  648.     * @param start
  649.     */
  650.    private static void loadListModel(DefaultListModel lm,
  651.                                           Vector vector,
  652.                                           String prefix,
  653.                                           int start) {
  654.       for (int i = start; i < vector.size(); i++) {
  655.          Object obj = vector.elementAt(i);
  656.          if (obj instanceof Macro) {
  657.             Macro m = (Macro)obj;
  658.             m.setPrefix(prefix);
  659.             lm.addElement(m);
  660.          }
  661.          else
  662.             if (obj instanceof Vector) {
  663.                Vector subvector = (Vector)obj;
  664.                String name = (String)subvector.elementAt(0);
  665.                if (prefix != null)
  666.                   loadListModel(lm,subvector,prefix + '/' + name + '/',1);
  667.                else
  668.                   loadListModel(lm,subvector,name + '/',1);
  669.             }
  670.             else {
  671.                if (obj instanceof String) {
  672.                   lm.addElement((String)obj);
  673.                }
  674.             }
  675.          }
  676.    }
  677.    private static class Macro {
  678.       String name;
  679.       String path;
  680.       String prefix;
  681.       String fileName;
  682.       Macro (String name, String path, String fileName) {
  683.          this.name = name;
  684.          this.path = path;
  685.          this.fileName = fileName;
  686.       }
  687.       /**
  688.        * Setst the directory prefix
  689.        *
  690.        * @param prefix before the name
  691.        */
  692.       public void setPrefix(String prefix) {
  693.          this.prefix = prefix;
  694.       }
  695.       /**
  696.        * This function gets the full name representation of the macro
  697.        *
  698.        * @return the full name non prettied up
  699.        */
  700.       public String getFullName() {
  701.          if (prefix != null)
  702.             return prefix + fileName;
  703.          else
  704.             return fileName;
  705.       }
  706.       /**
  707.        * This function is used for display of the macro name prettied up
  708.        *
  709.        * @return pretty string
  710.        */
  711.       public String toString() {
  712.          if (prefix != null)
  713.             return prefix + name;
  714.          else
  715.             return name;
  716.       }
  717.    }
  718.    public static class MacroCompare implements Comparator {
  719.       public int compare(Object one, Object two) {
  720.          String s1 = one.toString();
  721.          String s2 = two.toString();
  722.          return s1.compareToIgnoreCase(s2);
  723.       }
  724.    }
  725. }