示例#1
0
 /**
  * Could be used to add all global actions to a menu or a toolbar
  *
  * @param menuOrToolBar a {@link JMenu} or a {@link JToolBar} for instance
  * @param agent the agent that will send the message
  */
 @SuppressWarnings("incomplete-switch")
 public static void addAllActionsTo(JComponent menuOrToolBar, AbstractAgent agent) {
   try { // this bypasses class incompatibility
     final Method add = menuOrToolBar.getClass().getMethod("add", Action.class);
     final Method addSeparator = menuOrToolBar.getClass().getMethod("addSeparator");
     for (KernelAction ka : EnumSet.allOf(KernelAction.class)) {
       if (ka == LAUNCH_AGENT) return;
       if ((ka == LOAD_LOCAL_DEMOS || ka == RESTART) && ActionInfo.javawsIsOn) continue;
       if (ka == JCONSOLE && (findJconsole() == null || ActionInfo.javawsIsOn)) {
         continue;
       }
       add.invoke(menuOrToolBar, ka.getActionFor(agent));
       switch (ka) {
         case EXIT:
         case RESTART:
         case STOP_NETWORK:
         case CONSOLE:
           addSeparator.invoke(menuOrToolBar);
       }
     }
   } catch (InvocationTargetException e) {
   } catch (IllegalArgumentException e) {
     e.printStackTrace();
   } catch (IllegalAccessException e) {
     e.printStackTrace();
   } catch (SecurityException e) {
   } catch (NoSuchMethodException e) {
   }
 }
示例#2
0
 private static Method getBaselineMethod(JComponent component) {
   if (COMPONENT_BASELINE_METHOD != null) {
     return COMPONENT_BASELINE_METHOD;
   }
   Class klass = component.getClass();
   while (klass != null) {
     if (BASELINE_MAP.containsKey(klass)) {
       Method method = (Method) BASELINE_MAP.get(klass);
       return method;
     }
     klass = klass.getSuperclass();
   }
   klass = component.getClass();
   Method[] methods = klass.getMethods();
   for (int i = methods.length - 1; i >= 0; i--) {
     Method method = methods[i];
     if ("getBaseline".equals(method.getName())) {
       Class[] params = method.getParameterTypes();
       if (params.length == 2 && params[0] == int.class && params[1] == int.class) {
         BASELINE_MAP.put(klass, method);
         return method;
       }
     }
   }
   BASELINE_MAP.put(klass, null);
   return null;
 }
示例#3
0
  public void setReports(JComponent menu, CreateReport cReport) {
    if (menu.getClass() == JMenuBar.class) {
      for (int i = 0; i < menu.getComponentCount(); i++) {
        setReports((JComponent) menu.getComponent(i), cReport);
      }
    } else if (menu.getClass() == JMenu.class) {
      for (int i = 0; i < ((JMenu) menu).getItemCount(); i++) {
        JMenuItem item = ((JMenu) menu).getItem(i);
        if (item.getClass() == JMenuItem.class) {
          Template template = new Template();

          template.setDataTemplate(
              ToolsPrLib.getFullPath((String) item.getClientProperty("dataTemplate")));
          template.setId((String) item.getClientProperty("uniqueID"));
          template.setName((String) item.getClientProperty("name"));
          template.setParams((String) item.getClientProperty("params"));
          template.setQuery((String) item.getClientProperty("query"));
          template.setRtfTemplate(
              ToolsPrLib.getFullPath((String) item.getClientProperty("rtfTemplate")));

          String uniqueID = (String) item.getClientProperty("uniqueID");
          if (uniqueID.indexOf("Export") >= 0) {
            String format = (String) item.getClientProperty("format");
            Byte fopFormat = 0;
            if (format.toLowerCase().equals("excel")) {
              fopFormat = FOProcessor.FORMAT_EXCEL;
            } else if (format.toLowerCase().equals("pdf")) {
              fopFormat = FOProcessor.FORMAT_PDF;
            } else if (format.toLowerCase().equals("gif")) {
              fopFormat = FOProcessor.FORMAT_IMAGE_GIF;
            } else if (format.toLowerCase().equals("rtf")) {
              fopFormat = FOProcessor.FORMAT_RTF;
            }

            item.addActionListener(new ActionListenerJMenuItem(fopFormat, cReport));
          } else {
            item.addActionListener(
                new ActionListenerJMenuItem(template, mainFrame.getLbActiveReport(), cReport));
          }

          String def = (String) item.getClientProperty("default");
          if ((def != null) && (def.toString().toLowerCase().equals("true"))) {

            mainFrame.getCreateReport().setTemplate(template);
            mainFrame.getLbActiveReport().setText(template.getName());
          }
        } else if (item.getClass() == JMenu.class) {
          setReports((JMenu) item, cReport);
        }
      }
    }
  }
示例#4
0
  /**
   * Creates UI with Look and Feel defined in UIManager
   *
   * @param c
   * @return Component
   */
  public static ComponentUI createUI(JComponent c) {
    String componentName = c.getClass().getName();

    int index = componentName.lastIndexOf('.') + 1;
    StringBuffer sb = new StringBuffer();
    sb.append(componentName.substring(0, index));

    String lookAndFeelName = UIManager.getLookAndFeel().getName();
    if (lookAndFeelName.startsWith("CDE/")) {
      lookAndFeelName = lookAndFeelName.substring(4, lookAndFeelName.length());
    }
    sb.append(lookAndFeelName);
    sb.append(componentName.substring(index));
    sb.append("UI");

    ComponentUI componentUI = getInstance(sb.toString());

    if (componentUI == null) {
      sb.setLength(0);
      sb.append(componentName.substring(0, index));
      sb.append("Basic");
      sb.append(componentName.substring(index));
      sb.append("UI");
      componentUI = getInstance(sb.toString());
    }

    return componentUI;
  }
示例#5
0
 /**
  * Print Oarent of Component
  *
  * @param c component
  */
 static void printParents(JComponent c) {
   if (c.getName() == null) c.setName("C" + String.valueOf(s_no++));
   System.out.print(c.getName());
   System.out.print(" - " + c.getClass().getName());
   System.out.println(
       " ** "
           + c.isOpaque()
           + " bg="
           + (c.getClientProperty(CompiereLookAndFeel.BACKGROUND) != null));
   //
   Container container = c.getParent();
   while (container != null) {
     System.out.print(
         " - "
             + container.getName()
             + " "
             + container.getClass().getName()
             + " ** "
             + container.isOpaque());
     if (container instanceof JComponent)
       System.out.print(
           " bg="
               + (((JComponent) container).getClientProperty(CompiereLookAndFeel.BACKGROUND)
                   != null));
     System.out.println();
     container = container.getParent();
   }
 } //  printParents
示例#6
0
  /**
   * A helper for creating and updating key bindings for components with mnemonics. The {@code
   * pressed} action will be invoked when the mnemonic is activated and the {@code released} action
   * will be invoked when the mnemonic is deactivated.
   *
   * <p>TODO establish an interface for the mnemonic properties, such as {@code MnemonicEnabled} and
   * change signature to {@code public static <T extends JComponent & MnemonicEnabled> void
   * updateMnemonicBinding(T c, String pressed, String released)}
   *
   * @param c the component bindings to update
   * @param pressed the name of the action in the action map to invoke when the mnemonic is pressed
   * @param released the name of the action in the action map to invoke when the mnemonic is
   *     released (if the action is a toggle style, then this parameter should be {@code null})
   * @throws NullPointerException if the component is {@code null}
   */
  public static void updateMnemonicBinding(JComponent c, String pressed, String released) {
    Class<?> clazz = c.getClass();
    int m = -1;

    try {
      Method mtd = clazz.getMethod("getMnemonic");
      m = (Integer) mtd.invoke(c);
    } catch (RuntimeException e) {
      throw e;
    } catch (Exception e) {
      throw new IllegalArgumentException("unable to access mnemonic", e);
    }

    InputMap map = SwingUtilities.getUIInputMap(c, JComponent.WHEN_IN_FOCUSED_WINDOW);

    if (m != 0) {
      if (map == null) {
        map = new ComponentInputMapUIResource(c);
        SwingUtilities.replaceUIInputMap(c, JComponent.WHEN_IN_FOCUSED_WINDOW, map);
      }

      map.clear();

      // TODO is ALT_MASK right for all platforms?
      map.put(KeyStroke.getKeyStroke(m, InputEvent.ALT_MASK, false), pressed);
      map.put(KeyStroke.getKeyStroke(m, InputEvent.ALT_MASK, true), released);
      map.put(KeyStroke.getKeyStroke(m, 0, true), released);
    } else {
      if (map != null) {
        map.clear();
      }
    }
  }
示例#7
0
 protected boolean isTargetValidForPasting(JComponent targetContainer) {
   if (logger.isLoggable(Level.FINE)) {
     logger.fine(
         "isTargetValidForPasting(): container is a " + targetContainer.getClass().getName());
   }
   return targetContainer instanceof IEContainer;
 }
示例#8
0
 /**
  * Constructs a default <code>JTable</code> that is initialized with a default data model, a
  * default column model, and a default selection model. The identifier JComponent is used to save
  * the state of the table columns in the actual view. Not using this one constructor may lead to
  * inconsistent behavior of the view if this JTable's parent component has no unique name. It is
  * recommended to use this constructor in Yabs.
  *
  * @see #createDefaultDataModel
  * @see #createDefaultColumnModel
  * @see #createDefaultSelectionModel
  */
 public MPTable(JComponent identifier) {
   super();
   setName("43");
   if (identifier.getName() == null) {
     identifier.setName(identifier.getClass().getSimpleName());
   }
   setPersistanceHandler(new TableViewPersistenceHandler(this, identifier));
 }
示例#9
0
  @Override
  public Object clone() {
    if (component != null) {
      try {
        return new UIMenuItem(component.getClass().newInstance());
      } catch (Exception e) {
        throw new ApplicationException(e);
      }
    }

    return new UIMenuItem(menuItem);
  }
示例#10
0
  /**
   * Method to use when we are needing to see if two sets of components are equal when we are
   * considering them as JavaBeans. If all the properties of each component are equal, then the two
   * sets are equal. 'all the properties' is determined by recursing down to the child components
   *
   * @param components first array of components
   * @param components2 second array of components
   * @param widgetClassifier Provides this method with a definition of a component
   */
  public static boolean equalsByProperties(
      JComponent[] components, JComponent[] components2, WidgetClassifierI widgetClassifier) {
    ReasonNotEquals.addClassVisiting("pUtils.equalsByProperties([])");

    boolean result = true;
    if (components.length != components2.length) {
      ReasonNotEquals.addReason(
          "got lists of components of different sizes: "
              + components.length
              + " and "
              + components2.length);
      result = false;
    } else {
      for (int i = 0; i < components.length; i++) {
        JComponent comp1 = components[i];
        JComponent comp2 = components2[i];
        // not work due to diff classloaders having been used
        // if(comp1.getClass() != comp2.getClass())
        if (!comp1.getClass().getName().equals(comp2.getClass().getName())) {
          ReasonNotEquals.addReason(
              "two components were not of the same class: "
                  + comp1.getClass()
                  + " and "
                  + comp2.getClass());
          result = false;
          break;
        } else {
          result = equalsByProperties(comp1, comp2, widgetClassifier);
          if (!result) {
            ReasonNotEquals.addReason(
                "equalsByProperties() failed for 2 classes of type: " + comp1.getClass().getName());
            break;
          }
        }
      }
    }
    return result;
  }
示例#11
0
  /**
   * Sets the name of UI for the Component passed
   *
   * @param c
   */
  public static void setUIName(JComponent c) {
    String key = c.getUIClassID();
    String uiClassName = (String) UIManager.get(key);

    if (uiClassName == null) {
      String componentName = c.getClass().getName();
      int index = componentName.lastIndexOf('.') + 1;
      StringBuffer sb = new StringBuffer();
      sb.append(componentName.substring(0, index));
      String lookAndFeelName = UIManager.getLookAndFeel().getName();
      if (lookAndFeelName.startsWith("CDE/")) {
        lookAndFeelName = lookAndFeelName.substring(4, lookAndFeelName.length());
      }
      sb.append(lookAndFeelName);
      sb.append(key);
      UIManager.put(key, sb.toString());
    }
  }
  /*
   * (non-Javadoc)
   *
   * @see
   * java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
   */
  @Override
  public void actionPerformed(ActionEvent arg0) {

    if (custInfo.getClass().getName() == "pds.ui.CustomerInfoPanel") {
      if (((CustomerInfoPanel) custInfo).getCustPhoneNumber().length() == 10
          && !((CustomerInfoPanel) custInfo).getCustPhoneNumber().endsWith(" ")) {
        if (!((CustomerInfoPanel) custInfo).getCustName().startsWith(" ")) {
          if (((CustomerInfoPanel) custInfo).getCustLocationID() != 0) {
            String number = ((CustomerInfoPanel) custInfo).getCustPhoneNumber();
            String name = ((CustomerInfoPanel) custInfo).getCustName();
            Location loc = ((CustomerInfoPanel) custInfo).getCustLocation();
            Customer cust = mainWindow.getRegister().getCustomerDatabase().get(number);
            if (cust == null) {
              cust = new Customer(name, loc, number);
              mainWindow.getRegister().getCustomerDatabase().put(number, cust);
            }
            try {
              ActionListener ordListener =
                  ((MenuPanel) mainWindow.getMenuPanel())
                      .getNavigationPanel()
                      .getOrderButton()
                      .getActionListeners()[0];
              ((OrderButtonListener) ordListener).setCust(cust);
            } catch (Exception e) {

            }
            ((CustomerInfoPanel) custInfo).clearFields();
            mainWindow.setComponentAt(0, mainWindow.getMenuPanel());
            mainWindow.updateUI();
          } else {
            ((CustomerInfoPanel) custInfo).clearFields();
            JOptionPane.showMessageDialog(null, "No Location Selected");
          }
        } else {
          ((CustomerInfoPanel) custInfo).clearFields();
          JOptionPane.showMessageDialog(null, "Invalid Name");
        }
      } else {
        ((CustomerInfoPanel) custInfo).clearFields();
        JOptionPane.showMessageDialog(null, "Invalid Phone Number");
      }
    }
  }
示例#13
0
  /**
   * Creates the menu bar
   *
   * @return Description of the Return Value
   */
  public JToolBar createToolBar() {
    // Create the tool bar
    toolBar = new JToolBar();
    toolBar.putClientProperty("jgoodies.headerStyle", "Both");
    toolBar.setRollover(true);
    toolBar.setFloatable(false);

    for (int i = 0; i < beans.length; i++) {
      Icon icon;
      JButton button;

      try {
        final JComponent bean = beans[i];
        URL iconURL = bean.getClass().getResource("images/" + bean.getName() + "Color16.gif");
        icon = new ImageIcon(iconURL);

        button = new JButton(icon);

        ActionListener actionListener =
            new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                installBean(bean);
              }
            };

        button.addActionListener(actionListener);
      } catch (Exception e) {
        System.out.println("JCalendarDemo.createToolBar(): " + e);
        button = new JButton(beans[i].getName());
      }

      button.setFocusPainted(false);
      toolBar.add(button);
    }

    return toolBar;
  }
示例#14
0
  /**
   * Installes a demo bean.
   *
   * @param bean the demo bean
   */
  private void installBean(JComponent bean) {
    try {
      componentPanel.removeAll();
      componentPanel.add(bean);

      BeanInfo beanInfo =
          Introspector.getBeanInfo(bean.getClass(), bean.getClass().getSuperclass());
      PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

      propertyPanel.removeAll();

      GridBagLayout gridbag = new GridBagLayout();
      GridBagConstraints c = new GridBagConstraints();
      c.fill = GridBagConstraints.BOTH;

      propertyPanel.setLayout(gridbag);

      int count = 0;

      String[] types =
          new String[] {
            "class java.util.Locale",
            "boolean",
            "int",
            "class java.awt.Color",
            "class java.util.Date",
            "class java.lang.String"
          };

      for (int t = 0; t < types.length; t++) {
        for (int i = 0; i < propertyDescriptors.length; i++) {
          if (propertyDescriptors[i].getWriteMethod() != null) {
            String type = propertyDescriptors[i].getPropertyType().toString();

            final PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
            final JComponent currentBean = bean;
            final Method readMethod = propertyDescriptor.getReadMethod();
            final Method writeMethod = propertyDescriptor.getWriteMethod();

            if (type.equals(types[t])
                && (((readMethod != null) && (writeMethod != null))
                    || ("class java.util.Locale".equals(type)))) {
              if ("boolean".equals(type)) {
                boolean isSelected = false;

                try {
                  Boolean booleanObj = ((Boolean) readMethod.invoke(bean, (Object[]) null));
                  isSelected = booleanObj.booleanValue();
                } catch (Exception e) {
                  e.printStackTrace();
                }

                final JCheckBox checkBox = new JCheckBox("", isSelected);
                checkBox.addActionListener(
                    new ActionListener() {
                      public void actionPerformed(ActionEvent event) {
                        try {
                          if (checkBox.isSelected()) {
                            writeMethod.invoke(currentBean, new Object[] {new Boolean(true)});
                          } else {
                            writeMethod.invoke(currentBean, new Object[] {new Boolean(false)});
                          }
                        } catch (Exception e) {
                          e.printStackTrace();
                        }
                      }
                    });
                addProperty(propertyDescriptors[i], checkBox, gridbag);
                count += 1;
              } else if ("int".equals(type)) {
                JSpinField spinField = new JSpinField();
                spinField.addPropertyChangeListener(
                    new PropertyChangeListener() {
                      public void propertyChange(PropertyChangeEvent evt) {
                        try {
                          if (evt.getPropertyName().equals("value")) {
                            writeMethod.invoke(currentBean, new Object[] {evt.getNewValue()});
                          }
                        } catch (Exception e) {
                        }
                      }
                    });

                try {
                  Integer integerObj = ((Integer) readMethod.invoke(bean, (Object[]) null));
                  spinField.setValue(integerObj.intValue());
                } catch (Exception e) {
                  e.printStackTrace();
                }

                addProperty(propertyDescriptors[i], spinField, gridbag);
                count += 1;
              } else if ("class java.lang.String".equals(type)) {
                String string = "";

                try {
                  string = ((String) readMethod.invoke(bean, (Object[]) null));
                } catch (Exception e) {
                  e.printStackTrace();
                }

                JTextField textField = new JTextField(string);
                ActionListener actionListener =
                    new ActionListener() {
                      public void actionPerformed(ActionEvent e) {
                        try {
                          writeMethod.invoke(currentBean, new Object[] {e.getActionCommand()});
                        } catch (Exception ex) {
                        }
                      }
                    };

                textField.addActionListener(actionListener);

                addProperty(propertyDescriptors[i], textField, gridbag);
                count += 1;
              } else if ("class java.util.Locale".equals(type)) {
                JLocaleChooser localeChooser = new JLocaleChooser(bean);
                localeChooser.setPreferredSize(
                    new Dimension(200, localeChooser.getPreferredSize().height));
                addProperty(propertyDescriptors[i], localeChooser, gridbag);
                count += 1;
              } else if ("class java.util.Date".equals(type)) {
                Date date = null;

                try {
                  date = ((Date) readMethod.invoke(bean, (Object[]) null));
                } catch (Exception e) {
                  e.printStackTrace();
                }

                JDateChooser dateChooser = new JDateChooser(date);

                dateChooser.addPropertyChangeListener(
                    new PropertyChangeListener() {
                      public void propertyChange(PropertyChangeEvent evt) {
                        try {
                          if (evt.getPropertyName().equals("date")) {
                            writeMethod.invoke(currentBean, new Object[] {evt.getNewValue()});
                          }
                        } catch (Exception e) {
                        }
                      }
                    });

                addProperty(propertyDescriptors[i], dateChooser, gridbag);
                count += 1;
              } else if ("class java.awt.Color".equals(type)) {
                final JButton button = new JButton();

                try {
                  final Color colorObj = ((Color) readMethod.invoke(bean, (Object[]) null));
                  button.setText("...");
                  button.setBackground(colorObj);

                  ActionListener actionListener =
                      new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                          Color newColor =
                              JColorChooser.showDialog(
                                  JCalendarDemo.this, "Choose Color", colorObj);
                          button.setBackground(newColor);

                          try {
                            writeMethod.invoke(currentBean, new Object[] {newColor});
                          } catch (Exception e1) {
                            e1.printStackTrace();
                          }
                        }
                      };

                  button.addActionListener(actionListener);
                } catch (Exception e) {
                  e.printStackTrace();
                }

                addProperty(propertyDescriptors[i], button, gridbag);
                count += 1;
              }
            }
          }
        }
      }

      URL iconURL = bean.getClass().getResource("images/" + bean.getName() + "Color16.gif");
      ImageIcon icon = new ImageIcon(iconURL);

      componentTitlePanel.setTitle(bean.getName(), icon);
      bean.invalidate();
      propertyPanel.invalidate();
      componentPanel.invalidate();
      componentPanel.repaint();
    } catch (IntrospectionException e) {
      e.printStackTrace();
    }
  }
示例#15
0
  public void actionPerformed(ActionEvent e) {
    String cmd = e.getActionCommand();

    if (cmd.equals("new")) {
      icons = new Hashtable[0];
      fields = new Hashtable[0];

      tabPane.removeAll();
      repaint();
    } else if (cmd.equals("open")) {
      JFileChooser chooser = new JFileChooser();
      FileFilter filter =
          new FileFilter() {
            public boolean accept(File f) {
              return f.getAbsolutePath().endsWith(".template") || f.isDirectory();
            }

            public String getDescription() {
              return "OME Notes Templates";
            }
          };

      chooser.setFileFilter(filter);

      int status = chooser.showOpenDialog(this);
      if (status == JFileChooser.APPROVE_OPTION) {
        String file = chooser.getSelectedFile().getAbsolutePath();
        try {
          Template t = new Template(file);

          TemplateTab[] tabs = t.getTabs();
          for (int i = 0; i < tabs.length; i++) {
            int rows = tabs[i].getRows();
            int cols = tabs[i].getColumns();
            if (cols == 0) cols = 1;
            if (rows == 0) rows = 1;

            addTab(tabs[i].getName(), rows, cols);
            tabPane.setSelectedIndex(i);

            for (int j = 0; j < tabs[i].getNumFields(); j++) {
              TemplateField f = tabs[i].getField(j);

              int x = f.getRow();
              int y = f.getColumn();
              if (x == -1) x = 1;
              if (y == -1) y = j + 1;

              Point p = new Point(x, y);
              DraggableIcon icon = (DraggableIcon) icons[i].get(p);

              icon.label = new JLabel(f.getName());

              JPanel panel = new JPanel();
              panel.add(f.getComponent());

              icon.setPanel(panel);
            }
          }
        } catch (Exception exc) {
          error("Failed to parse template", exc);
        }

        tabPane.setSelectedIndex(0);
      }
    } else if (cmd.equals("save")) {
      // build up the template from the components

      TemplateTab[] tabs = new TemplateTab[tabPane.getTabCount()];

      for (int i = 0; i < tabs.length; i++) {
        tabs[i] = new TemplateTab();
        tabs[i].setName(tabPane.getTitleAt(i));
        JComponent c = (JComponent) tabPane.getComponentAt(i);
        FormLayout layout = (FormLayout) c.getLayout();

        tabs[i].setRows(layout.getRowCount());
        tabs[i].setColumns(layout.getColumnCount());

        Object[] keys = icons[i].keySet().toArray();

        for (int j = 0; j < keys.length; j++) {
          Point p = (Point) keys[j];
          DraggableIcon icon = (DraggableIcon) icons[i].get(p);
          TemplateField f = (TemplateField) fields[i].get(p);

          if (icon.image != null) {
            Component[] components = icon.image.getComponents();
            JLabel label = icon.label;
            JComponent component = (JComponent) components[0];

            f.setComponent(component);

            for (int k = 0; k < COMPONENTS.length; k++) {
              if (component.getClass().equals(COMPONENTS[k])) {
                f.setType(COMPONENT_TYPES[k]);
                break;
              }
            }

            f.setRow(p.y);
            f.setColumn(p.x);
            f.setDefaultValue(TemplateTools.getComponentValue(component));

            tabs[i].addField(f);
          }
        }
      }

      Template t = new Template(tabs, null);

      // prompt for filename to save to
      if (currentFile == null) {
        JFileChooser chooser = new JFileChooser();

        FileFilter filter =
            new FileFilter() {
              public boolean accept(File f) {
                return true;
              }

              public String getDescription() {
                return "All files";
              }
            };

        chooser.setFileFilter(filter);

        int status = chooser.showSaveDialog(this);
        if (status == JFileChooser.APPROVE_OPTION) {
          currentFile = chooser.getSelectedFile().getAbsolutePath();
          if (currentFile == null) return;
        }
      }

      try {
        t.save(currentFile);
      } catch (IOException io) {
        error("Failed to save template", io);
      }
    } else if (cmd.equals("quit")) dispose();
    else if (cmd.equals("add row")) addRow();
    else if (cmd.equals("add col")) addColumn();
    else if (cmd.equals("prompt tab")) {
      // prompt for tab name
      JPopupMenu menu = new JPopupMenu();
      newTabName = new JTextField();
      newTabName.setPreferredSize(new Dimension(200, 25));
      menu.add(newTabName);
      JButton b = new JButton("OK");
      b.addActionListener(this);
      b.setActionCommand("new tab");
      menu.add(b);

      JComponent s = (JComponent) e.getSource();
      menu.show(s, s.getX(), s.getY());
      newTabName.grabFocus();
    } else if (cmd.equals("new tab")) {
      newTabName.getParent().setVisible(false);
      addTab(newTabName.getText(), 2, 2);
    } else if (cmd.equals("setName")) {
      JPopupMenu menu = (JPopupMenu) ((JComponent) e.getSource()).getParent();
      DraggableIcon icon = (DraggableIcon) menu.getInvoker();
      menu.setVisible(false);

      String text = ((JTextField) menu.getComponents()[0]).getText();

      Point p = new Point(icon.gridx, icon.gridy);
      int ndx = tabPane.getSelectedIndex();
      TemplateField f = (TemplateField) fields[ndx].get(p);
      f.setName(text);
      f.setNameMap(null);

      // set the name
      if (icon.label != null) icon.remove(icon.label);
      icon.remove(icon.image);
      icon.label = new JLabel(text);
      icon.add(icon.label);
      icon.add(icon.image);
      icon.getParent().repaint();
    } else if (cmd.equals("changeName")) {
      // prompt for new field name
      JPopupMenu menu = new JPopupMenu();
      JTextField field = new JTextField();
      field.setPreferredSize(new Dimension(200, 25));
      menu.add(field);
      JButton b = new JButton("OK");
      b.addActionListener(this);
      b.setActionCommand("setName");
      menu.add(b);
      menu.show(lastMenuComponent, lastMenuX, lastMenuY);
      field.grabFocus();
    } else if (cmd.equals("nameMap")) {
      JPopupMenu menu = (JPopupMenu) ((JComponent) e.getSource()).getParent();
      DraggableIcon icon = (DraggableIcon) menu.getInvoker();
      menu.setVisible(false);

      MappingWindow w = new MappingWindow(this, true);
      w.show(lastMenuComponent, lastMenuX, lastMenuY);
    } else if (cmd.equals("map")) {
      JPopupMenu menu = (JPopupMenu) ((JComponent) e.getSource()).getParent();
      DraggableIcon icon = (DraggableIcon) menu.getInvoker();
      menu.setVisible(false);

      MappingWindow w = new MappingWindow(this, false);
      w.show(lastMenuComponent, lastMenuX, lastMenuY);
    } else if (cmd.equals("repeat")) {
      JMenuItem item = (JMenuItem) e.getSource();
      DraggableIcon icon = (DraggableIcon) ((JPopupMenu) item.getParent()).getInvoker();
      TemplateField f = getField(icon);

      if (item.getText().equals("Repeat this field")) {
        item.setText("Don't repeat this field");
        f.setRepeated(true);
      } else {
        item.setText("Repeat this field");
        f.setRepeated(false);
      }
    } else if (cmd.equals("removeField")) {
      JPopupMenu menu = (JPopupMenu) ((JComponent) e.getSource()).getParent();
      DraggableIcon icon = (DraggableIcon) menu.getInvoker();
      menu.setVisible(false);

      int idx = tabPane.getSelectedIndex();
      Object[] keys = icons[idx].keySet().toArray();
      for (int i = 0; i < keys.length; i++) {
        if (icons[idx].get(keys[i]).equals(icon)) {
          icons[idx].remove(keys[i]);
          fields[idx].remove(keys[i]);
          break;
        }
      }

      icon.remove(icon.label);
      icon.remove(icon.image);
      tabPane.repaint();
    } else if (cmd.startsWith("removeRow")) {
      int row = Integer.parseInt(cmd.substring(cmd.indexOf(":") + 1));
      JPopupMenu menu = (JPopupMenu) ((JComponent) e.getSource()).getParent();
      menu.setVisible(false);

      JPanel pane = (JPanel) tabPane.getSelectedComponent();
      FormLayout layout = (FormLayout) pane.getLayout();

      int rows = layout.getRowCount();
      int cols = layout.getColumnCount();

      int idx = tabPane.getSelectedIndex();

      for (int i = 0; i < cols; i++) {
        pane.remove((JComponent) icons[idx].get(new Point(i + 1, row + 1)));
      }

      rekey(row, -1);
      layout.removeRow(row + 1);
      tabPane.repaint();
    } else if (cmd.startsWith("removeColumn")) {
      int col = Integer.parseInt(cmd.substring(cmd.indexOf(":") + 1));
      JPopupMenu menu = (JPopupMenu) ((JComponent) e.getSource()).getParent();
      menu.setVisible(false);

      JPanel pane = (JPanel) tabPane.getSelectedComponent();
      FormLayout layout = (FormLayout) pane.getLayout();

      int rows = layout.getRowCount();
      int cols = layout.getColumnCount();
      int idx = tabPane.getSelectedIndex();

      for (int i = 0; i < rows; i++) {
        pane.remove((JComponent) icons[idx].get(new Point(col + 1, i + 1)));
      }

      rekey(-1, col);
      layout.removeColumn(col + 1);
      tabPane.repaint();
    } else if (cmd.equals("removeTab")) {
      int ndx = tabPane.getSelectedIndex();
      tabPane.remove(ndx);

      Hashtable[] h = new Hashtable[icons.length - 1];
      Hashtable[] f = new Hashtable[fields.length - 1];

      System.arraycopy(icons, 0, h, 0, ndx);
      System.arraycopy(icons, ndx + 1, h, ndx, h.length - ndx);
      System.arraycopy(fields, 0, f, 0, ndx);
      System.arraycopy(fields, ndx + 1, f, ndx, f.length - ndx);

      icons = h;
      fields = f;
    } else if (cmd.equals("specifyChoices")) {
      JMenuItem item = (JMenuItem) e.getSource();
      DraggableIcon icon = (DraggableIcon) ((JPopupMenu) item.getParent()).getInvoker();
      TemplateField f = getField(icon);

      EnumWindow w = new EnumWindow(this, f.getEnums());
      w.show(lastMenuComponent, lastMenuX, lastMenuY);
    } else if (cmd.equals("setThumbSource")) {
      JPopupMenu menu = new JPopupMenu();
      ButtonGroup g = new ButtonGroup();

      JRadioButton dataset = new JRadioButton("Use thumbnail from dataset");
      dataset.setSelected(true);
      g.add(dataset);

      JRadioButton file = new JRadioButton("Use thumbnail from file:");
      g.add(file);

      menu.add(dataset);
      menu.add(file);

      JTextField field = new JTextField();
      field.setPreferredSize(new Dimension(200, 25));
      menu.add(field);

      JButton b = new JButton("OK");
      b.addActionListener(this);
      b.setActionCommand("applyThumbSource");
      menu.add(b);
      menu.show(lastMenuComponent, lastMenuX, lastMenuY);
    } else if (cmd.equals("applyThumbSource")) {
      JPopupMenu menu = (JPopupMenu) ((JComponent) e.getSource()).getParent();
      DraggableIcon icon = (DraggableIcon) menu.getInvoker();

      Component[] c = menu.getComponents();
      JRadioButton dataset = (JRadioButton) c[0];

      String text = null;

      if (!dataset.isSelected()) {
        JTextField t = (JTextField) c[2];
        text = t.getText();
        getField(icon).setValueMap(text);
      }

      menu.setVisible(false);

      if (text != null) {
        try {
          BufferedImageReader reader = new BufferedImageReader();
          reader.setId(text);
          BufferedImage thumb = reader.openThumbImage(0);
          JLabel label = (JLabel) icon.image.getComponents()[0];
          label.setIcon(new ImageIcon(thumb));
          reader.close();
        } catch (FormatException exc) {
          error("Failed to open thumbnail (" + text + ")", exc);
        } catch (IOException exc) {
          error("Failed to open thumbnail (" + text + ")", exc);
        }
      }
    } else if (cmd.equals("ok")) {
      // this event came from an instance of EnumWindow
      JPanel parent = (JPanel) ((JButton) e.getSource()).getParent();
      EnumWindow menu = (EnumWindow) parent.getParent();
      DraggableIcon icon = (DraggableIcon) menu.getInvoker();
      TemplateField f = getField(icon);
      menu.setVisible(false);

      String[] options = menu.getOptions();
      f.setEnums(options);

      JComboBox box = (JComboBox) icon.image.getComponents()[0];
      for (int i = 0; i < options.length; i++) box.addItem(options[i]);
      repaint();
    } else if (cmd.equals("chooseMapping")) {
      // this event came from an instance of MappingWindow
      JTabbedPane parent = (JTabbedPane) ((JButton) e.getSource()).getParent();
      MappingWindow menu = (MappingWindow) parent.getParent();
      DraggableIcon icon = (DraggableIcon) menu.getInvoker();
      TemplateField f = getField(icon);

      String omexmlMap = null;

      if (menu.nameMap) f.setNameMap(omexmlMap);
      else f.setValueMap(omexmlMap);
      menu.setVisible(false);
    }
  }